Dokumentation
[kivitendo-erp.git] / SL / DB / Order.pm
1 package SL::DB::Order;
2
3 use utf8;
4 use strict;
5
6 use Carp;
7 use DateTime;
8 use List::Util qw(max);
9
10 use SL::DB::MetaSetup::Order;
11 use SL::DB::Manager::Order;
12 use SL::DB::Invoice;
13 use SL::DB::Helper::LinkedRecords;
14 use SL::DB::Helper::PriceTaxCalculator;
15 use SL::DB::Helper::TransNumberGenerator;
16 use SL::RecordLinks;
17
18 __PACKAGE__->meta->add_relationship(
19   orderitems => {
20     type         => 'one to many',
21     class        => 'SL::DB::OrderItem',
22     column_map   => { id => 'trans_id' },
23     manager_args => {
24       with_objects => [ 'part' ]
25     }
26   },
27   periodic_invoices_config => {
28     type                   => 'one to one',
29     class                  => 'SL::DB::PeriodicInvoicesConfig',
30     column_map             => { id => 'oe_id' },
31   },
32   periodic_invoices        => {
33     type                   => 'one to many',
34     class                  => 'SL::DB::PeriodicInvoice',
35     column_map             => { id => 'oe_id' },
36   },
37   payment_term => {
38     type       => 'one to one',
39     class      => 'SL::DB::PaymentTerm',
40     column_map => { payment_id => 'id' },
41   },
42 );
43
44 __PACKAGE__->meta->initialize;
45
46 # methods
47
48 sub items { goto &orderitems; }
49
50 sub type {
51   my $self = shift;
52
53   return 'sales_order'       if $self->customer_id && ! $self->quotation;
54   return 'purchase_order'    if $self->vendor_id   && ! $self->quotation;
55   return 'sales_quotation'   if $self->customer_id &&   $self->quotation;
56   return 'request_quotation' if $self->vendor_id   &&   $self->quotation;
57
58   return;
59 }
60
61 sub is_type {
62   return shift->type eq shift;
63 }
64
65 sub invoices {
66   my $self   = shift;
67   my %params = @_;
68
69   if ($self->quotation) {
70     return [];
71   } else {
72     return SL::DB::Manager::Invoice->get_all(
73       query => [
74         ordnumber => $self->ordnumber,
75         @{ $params{query} || [] },
76       ]
77     );
78   }
79 }
80
81 sub abschlag_invoices {
82   return shift()->invoices(query => [ abschlag => 1 ]);
83 }
84
85 sub end_invoice {
86   return shift()->invoices(query => [ abschlag => 0 ]);
87 }
88
89 sub convert_to_invoice {
90   my ($self, %params) = @_;
91
92   croak("Conversion to invoices is only supported for sales records") unless $self->customer_id;
93
94   if (!$params{ar_id}) {
95     my $chart = SL::DB::Manager::Chart->get_all(query   => [ SL::DB::Manager::Chart->link_filter('AR') ],
96                                                 sort_by => 'id ASC',
97                                                 limit   => 1)->[0];
98     croak("No AR chart found and no parameter `ar_id' given") unless $chart;
99     $params{ar_id} = $chart->id;
100   }
101
102   my $invoice;
103   if (!$self->db->do_transaction(sub {
104     $invoice = SL::DB::Invoice->new_from($self)->post(%params) || die;
105     $self->link_to_record($invoice);
106     $self->update_attributes(closed => 1);
107     # die;
108   })) {
109     return undef;
110   }
111
112   return $invoice;
113 }
114
115 1;
116
117 __END__
118
119 =head1 NAME
120
121 SL::DB::Order - Order Datenbank Objekt.
122
123 =head1 FUNCTIONS
124
125 =head2 type
126
127 Returns one of the following string types:
128
129 =over 4
130
131 =item saes_order
132
133 =item purchase_order
134
135 =item sales_quotation
136
137 =item request_quotation
138
139 =back
140
141 =head2 is_type TYPE
142
143 Rreturns true if the order is of the given type.
144
145 =item C<convert_to_invoice %params>
146
147 Creates a new invoice with C<$self> as the basis by calling
148 L<SL::DB::Invoice::new_from>. That invoice is posted, and C<$self> is
149 linked to the new invoice via L<SL::DB::RecordLink>. C<$self>'s
150 C<closed> attribute is set to C<true>, and C<$self> is saved.
151
152 The arguments in C<%params> are passed to
153 L<SL::DB::Invoice::post>. One parameter of note is
154 C<$paras{ar_id}>. If set it must be the ID of the accounts receivables
155 chart to post to. If it is not set then the first chart configured for
156 accounts receivables is used.
157
158 Returns the new invoice instance on success and C<undef> on failure.
159
160 At the moment only sales quotations and sales orders can be converted.
161
162 =back
163
164 =head1 BUGS
165
166 Nothing here yet.
167
168 =head1 AUTHOR
169
170 Sven Schöling <s.schoeling@linet-services.de>
171
172 =cut