DeliveryOrder: neue typen für Lieferschein
[kivitendo-erp.git] / SL / Controller / DeliveryOrder / TypeData.pm
1 package SL::Controller::DeliveryOrder::TypeData;
2
3 use strict;
4 use Exporter qw(import);
5 use Scalar::Util qw(weaken);
6 use SL::Locale::String qw(t8);
7
8 use constant {
9   SALES_ORDER_TYPE             => 'sales_order',
10   PURCHASE_ORDER_TYPE          => 'purchase_order',
11   SALES_QUOTATION_TYPE         => 'sales_quotation',
12   REQUEST_QUOTATION_TYPE       => 'request_quotation',
13   PURCHASE_DELIVERY_ORDER_TYPE => 'purchase_delivery_order',
14   SALES_DELIVERY_ORDER_TYPE    => 'sales_delivery_order',
15 };
16
17 our @EXPORT_OK = qw(SALES_ORDER_TYPE PURCHASE_ORDER_TYPE SALES_QUOTATION_TYPE REQUEST_QUOTATION_TYPE);
18
19 use Rose::Object::MakeMethods::Generic scalar => [ qw(c) ];
20
21 my %type_data = (
22   SALES_ORDER_TYPE() => {
23     text => {
24       delete => t8('The order has been deleted'),
25       saved  => t8('The order has been saved'),
26       add    => t8("Add Sales Order"),
27       edit   => t8("Edit Sales Order"),
28     },
29     show_menu => {
30       save_and_quotation      => 1,
31       save_and_rfq            => 0,
32       save_and_sales_order    => 0,
33       save_and_purchase_order => 1,
34       save_and_delivery_order => 1,
35       save_and_ap_transaction => 0,
36       delete                  => sub { $::instance_conf->get_sales_order_show_delete },
37     },
38     workflow => {
39       to_order_type        => "purchase_order",
40       to_quotation_type    => "sales_quotation",
41       to_order_copy_shipto => 1,
42     },
43     properties => {
44       customervendor => "customer",
45       is_quotation   => 0,
46       nr_key         => "ordnumber",
47     },
48     part_classification_query => [ "used_for_sale" => 1 ],
49     right => "sales_order_edit",
50   },
51   PURCHASE_ORDER_TYPE() => {
52     text =>{
53       delete => t8('The order has been deleted'),
54       saved  => t8('The order has been saved'),
55       add    => t8("Add Purchase Order"),
56       edit   => t8("Edit Purchase Order"),
57     },
58     show_menu => {
59       save_and_quotation      => 0,
60       save_and_rfq            => 1,
61       save_and_sales_order    => 1,
62       save_and_purchase_order => 0,
63       save_and_delivery_order => 1,
64       save_and_ap_transaction => 1,
65       delete                  => sub { $::instance_conf->get_purchase_order_show_delete },
66     },
67     workflow => {
68       to_order_type        => "sales_order",
69       to_quotation_type    => "request_quotation",
70       to_order_copy_shipto => 0,
71     },
72     properties => {
73       customervendor => "vendor",
74       is_quotation   => 0,
75       nr_key         => "ordnumber",
76     },
77     part_classification_query => [ "used_for_purchase" => 1 ],
78     right => "purchase_order_edit",
79   },
80   SALES_QUOTATION_TYPE() => {
81     text => {
82       delete => t8('The quotation has been deleted'),
83       saved  => t8('The quotation has been saved'),
84       add    => t8("Add Quotation"),
85       edit   => t8("Edit Quotation"),
86     },
87     show_menu => {
88       save_and_quotation      => 0,
89       save_and_rfq            => 0,
90       save_and_sales_order    => 1,
91       save_and_purchase_order => 0,
92       save_and_delivery_order => 0,
93       save_and_ap_transaction => 0,
94       delete                  => 1,
95     },
96     workflow => {
97       to_order_type        => "sales_order",
98       to_quotation_type    => "request_quotation",
99       to_order_copy_shipto => 0,
100     },
101     properties => {
102       customervendor => "customer",
103       is_quotation   => 1,
104       nr_key         => "quonumber",
105     },
106     part_classification_query => [ "used_for_sale" => 1 ],
107     right => "sales_quotation_edit",
108   },
109   REQUEST_QUOTATION_TYPE() => {
110     text => {
111       delete => t8('The rfq has been deleted'),
112       saved  => t8('The rfq has been saved'),
113       add    => t8("Add Request for Quotation"),
114       edit   => t8("Edit Request for Quotation"),
115     },
116     show_menu => {
117       save_and_quotation      => 0,
118       save_and_rfq            => 0,
119       save_and_sales_order    => 0,
120       save_and_purchase_order => 1,
121       save_and_delivery_order => 0,
122       save_and_ap_transaction => 0,
123       delete                  => 1,
124     },
125     workflow => {
126       to_order_type        => "purchase_order",
127       to_quotation_type    => "request_quotation",
128       to_order_copy_shipto => 0,
129     },
130     properties => {
131       customervendor => "vendor",
132       is_quotation   => 1,
133       nr_key         => "quonumber",
134     },
135     part_classification_query => [ "used_for_purchase" => 1 ],
136     right => "request_quotation_edit",
137   },
138   SALES_DELIVERY_ORDER_TYPE() => {
139     text => {
140       delete => t8('Delivery Order has been deleted'),
141       saved  => t8('Delivery Order has been saved'),
142       add    => t8("Add Sales Delivery Order"),
143       edit   => t8("Edit Sales Delivery Order"),
144     },
145     show_menu => {
146       save_and_quotation      => 0,
147       save_and_rfq            => 0,
148       save_and_sales_order    => 0,
149       save_and_purchase_order => 0,
150       save_and_delivery_order => 0,
151       save_and_ap_transaction => 0,
152       delete                  => sub { $::instance_conf->get_sales_delivery_order_show_delete },
153     },
154     properties => {
155       customervendor => "customer",
156       nr_key         => "donumber",
157     },
158     part_classification_query => [ "used_for_sale" => 1 ],
159     right => "sales_delivery_order_edit",
160   },
161   PURCHASE_DELIVERY_ORDER_TYPE() => {
162     text => {
163       delete => t8('Delivery Order has been deleted'),
164       saved  => t8('Delivery Order has been saved'),
165       add    => t8("Add Purchase Delivery Order"),
166       edit   => t8("Edit Purchase Delivery Order"),
167     },
168     show_menu => {
169       save_and_quotation      => 0,
170       save_and_rfq            => 0,
171       save_and_sales_order    => 0,
172       save_and_purchase_order => 0,
173       save_and_delivery_order => 0,
174       save_and_ap_transaction => 0,
175       delete                  => sub { $::instance_conf->get_sales_delivery_order_show_delete },
176     },
177     properties => {
178       customervendor => "vendor",
179       nr_key         => "donumber",
180     },
181     part_classification_query => [ "used_for_purchase" => 1 ],
182     right => "purchase_delivery_order_edit",
183   },
184
185 );
186
187 sub new {
188   my ($class, $controller) = @_;
189   my $o = bless {}, $class;
190   $o->c($controller);
191   weaken($o->{c});
192
193   return $o;
194 }
195
196 sub valid_types {
197   [
198     SALES_ORDER_TYPE,
199     PURCHASE_ORDER_TYPE,
200     SALES_QUOTATION_TYPE,
201     REQUEST_QUOTATION_TYPE,
202     SALES_DELIVERY_ORDER_TYPE,
203     PURCHASE_DELIVERY_ORDER_TYPE,
204   ];
205 }
206
207 sub type {
208   $_[0]->c->type;
209 }
210
211 sub _get {
212   my ($self, $key) = @_;
213
214   my $ret = $type_data{$self->type}->{$key} // die "unknown property '$key'";
215
216   ref $ret eq 'CODE'
217     ? $ret->()
218     : $ret;
219 }
220
221 sub _get3 {
222   my ($self, $topic, $key) = @_;
223
224   my $ret = $type_data{$self->type}->{$topic}->{$key} // die "unknown property '$key' in topic '$topic'";
225
226   ref $ret eq 'CODE'
227     ? $ret->()
228     : $ret;
229 }
230
231 sub text {
232   my ($self, $string) = @_;
233   _get3($self, "text", $string);
234 }
235
236 sub show_menu {
237   my ($self, $string) = @_;
238   _get3($self, "show_menu", $string);
239 }
240
241 sub workflow {
242   my ($self, $string) = @_;
243   _get3($self, "workflow", $string);
244 }
245
246 sub properties {
247   my ($self, $string) = @_;
248   _get3($self, "properties", $string);
249 }
250
251 sub is_valid_type {
252   !!exists $type_data{$_[1]};
253 }
254
255 sub type_data {
256   $type_data{ $_[0]->type } // die "unknown type";
257 }
258
259 sub access {
260   _get($_[0], "right");
261 }
262
263 sub is_quotation {
264   _get3($_[0], "properties", "is_quotation");
265 }
266
267 sub customervendor {
268   _get3($_[0], "properties", "customervendor");
269 }
270
271 sub nr_key {
272   _get3($_[0], "properties", "nr_key");
273 }
274
275 sub part_classification_query {
276   my ($self, $string) = @_;
277   _get($self, "part_classification_query");
278 }
279
280 sub set_reqdate_by_type {
281   my ($self) = @_;
282
283   my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval       :
284                    $self->type eq SALES_ORDER_TYPE     ? $::instance_conf->get_delivery_date_interval : 1;
285
286   if (   ($self->type eq SALES_ORDER_TYPE     &&  $::instance_conf->get_deliverydate_on)
287       || ($self->type eq SALES_QUOTATION_TYPE &&  $::instance_conf->get_reqdate_on)
288       && (!$self->order->reqdate)) {
289     $self->c->order->reqdate(DateTime->today_local->next_workday(extra_days => $extra_days));
290   }
291 }
292
293 sub get_reqdate_by_type {
294   my ($self, $reqdate, $saved_reqdate) = @_;
295
296   if ($reqdate == $saved_reqdate) {
297     my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval       :
298                      $self->type eq SALES_ORDER_TYPE     ? $::instance_conf->get_delivery_date_interval : 1;
299
300     if (   ($self->type eq SALES_ORDER_TYPE     &&  !$::instance_conf->get_deliverydate_on)
301         || ($self->type eq SALES_QUOTATION_TYPE &&  !$::instance_conf->get_reqdate_on)) {
302       return '';
303     } else {
304       return DateTime->today_local->next_workday(extra_days => $extra_days);
305     }
306   } else {
307     return $reqdate;
308   }
309 }