705d332ebe979a7c9dc3b4869924674f47a42381
[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 };
14
15 our @EXPORT_OK = qw(SALES_ORDER_TYPE PURCHASE_ORDER_TYPE SALES_QUOTATION_TYPE REQUEST_QUOTATION_TYPE);
16
17 use Rose::Object::MakeMethods::Generic scalar => [ qw(c) ];
18
19 my %type_data = (
20   SALES_ORDER_TYPE() => {
21     text => {
22       delete => t8('The order has been deleted'),
23       saved  => t8('The order has been saved'),
24       add    => t8("Add Sales Order"),
25       edit   => t8("Edit Sales Order"),
26     },
27     show_menu => {
28       save_and_quotation      => 1,
29       save_and_rfq            => 0,
30       save_and_sales_order    => 0,
31       save_and_purchase_order => 1,
32       save_and_delivery_order => 1,
33       save_and_ap_transaction => 0,
34       delete                  => sub { $::instance_conf->get_sales_order_show_delete },
35     },
36     workflow => {
37       to_order_type        => "purchase_order",
38       to_quotation_type    => "sales_quotation",
39       to_order_copy_shipto => 1,
40     },
41     properties => {
42       customervendor => "customer",
43       is_quotation   => 0,
44       nr_key         => "ordnumber",
45     },
46     part_classification_query => [ "used_for_sale" => 1 ],
47     right => "sales_order_edit",
48   },
49   PURCHASE_ORDER_TYPE() => {
50     text =>{
51       delete => t8('The order has been deleted'),
52       saved  => t8('The order has been saved'),
53       add    => t8("Add Purchase Order"),
54       edit   => t8("Edit Purchase Order"),
55     },
56     show_menu => {
57       save_and_quotation      => 0,
58       save_and_rfq            => 1,
59       save_and_sales_order    => 1,
60       save_and_purchase_order => 0,
61       save_and_delivery_order => 1,
62       save_and_ap_transaction => 1,
63       delete                  => sub { $::instance_conf->get_purchase_order_show_delete },
64     },
65     workflow => {
66       to_order_type        => "sales_order",
67       to_quotation_type    => "request_quotation",
68       to_order_copy_shipto => 0,
69     },
70     properties => {
71       customervendor => "vendor",
72       is_quotation   => 0,
73       nr_key         => "ordnumber",
74     },
75     part_classification_query => [ "used_for_purchase" => 1 ],
76     right => "purchase_order_edit",
77   },
78   SALES_QUOTATION_TYPE() => {
79     text => {
80       delete => t8('The quotation has been deleted'),
81       saved  => t8('The quotation has been saved'),
82       add    => t8("Add Quotation"),
83       edit   => t8("Edit Quotation"),
84     },
85     show_menu => {
86       save_and_quotation      => 0,
87       save_and_rfq            => 0,
88       save_and_sales_order    => 1,
89       save_and_purchase_order => 0,
90       save_and_delivery_order => 0,
91       save_and_ap_transaction => 0,
92       delete                  => 1,
93     },
94     workflow => {
95       to_order_type        => "sales_order",
96       to_quotation_type    => "request_quotation",
97       to_order_copy_shipto => 0,
98     },
99     properties => {
100       customervendor => "customer",
101       is_quotation   => 1,
102       nr_key         => "quonumber",
103     },
104     part_classification_query => [ "used_for_sale" => 1 ],
105     right => "sales_quotation_edit",
106   },
107   REQUEST_QUOTATION_TYPE() => {
108     text => {
109       delete => t8('The rfq has been deleted'),
110       saved  => t8('The rfq has been saved'),
111       add    => t8("Add Request for Quotation"),
112       edit   => t8("Edit Request for Quotation"),
113     },
114     show_menu => {
115       save_and_quotation      => 0,
116       save_and_rfq            => 0,
117       save_and_sales_order    => 0,
118       save_and_purchase_order => 1,
119       save_and_delivery_order => 0,
120       save_and_ap_transaction => 0,
121       delete                  => 1,
122     },
123     workflow => {
124       to_order_type        => "purchase_order",
125       to_quotation_type    => "request_quotation",
126       to_order_copy_shipto => 0,
127     },
128     properties => {
129       customervendor => "vendor",
130       is_quotation   => 1,
131       nr_key         => "quonumber",
132     },
133     part_classification_query => [ "used_for_purchase" => 1 ],
134     right => "request_quotation_edit",
135   },
136 );
137
138 sub new {
139   my ($class, $controller) = @_;
140   my $o = bless {}, $class;
141   $o->c($controller);
142   weaken($o->{c});
143
144   return $o;
145 }
146
147 sub valid_types {
148   [
149     SALES_ORDER_TYPE,
150     PURCHASE_ORDER_TYPE,
151     SALES_QUOTATION_TYPE,
152     REQUEST_QUOTATION_TYPE,
153   ];
154 }
155
156 sub type {
157   $_[0]->c->type;
158 }
159
160 sub get {
161   my ($self, $key) = @_;
162
163   my $ret = $type_data{$self->type}->{$key} // die "unknown property '$key'";
164
165   ref $ret eq 'CODE'
166     ? $ret->()
167     : $ret;
168 }
169
170 sub _get3 {
171   my ($self, $topic, $key) = @_;
172
173   my $ret = $type_data{$self->type}->{$topic}->{$key} // die "unknown property '$key' in topic '$topic'";
174
175   ref $ret eq 'CODE'
176     ? $ret->()
177     : $ret;
178 }
179
180 sub text {
181   my ($self, $string) = @_;
182   _get3($self, "text", $string);
183 }
184
185 sub show_menu {
186   my ($self, $string) = @_;
187   _get3($self, "show_menu", $string);
188 }
189
190 sub workflow {
191   my ($self, $string) = @_;
192   _get3($self, "workflow", $string);
193 }
194
195 sub properties {
196   my ($self, $string) = @_;
197   _get3($self, "properties", $string);
198 }
199
200 sub is_valid_type {
201   !!exists $type_data{$_[1]};
202 }
203
204 sub type_data {
205   $type_data{ $_[0]->type } // die "unknown type";
206 }
207
208 sub access {
209   $type_data{right};
210 }
211
212 sub is_quotation {
213   _get3($_[0], "properties", "is_quotation");
214 }
215
216 sub customervendor {
217   _get3($_[0], "properties", "customervendor");
218 }
219
220 sub nr_key {
221   _get3($_[0], "properties", "nr_key");
222 }
223
224 sub part_classification_query {
225   my ($self, $string) = @_;
226   _get($self, "part_classification_query");
227 }
228
229 sub set_reqdate_by_type {
230   my ($self) = @_;
231
232   my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval       :
233                    $self->type eq SALES_ORDER_TYPE     ? $::instance_conf->get_delivery_date_interval : 1;
234
235   if (   ($self->type eq SALES_ORDER_TYPE     &&  $::instance_conf->get_deliverydate_on)
236       || ($self->type eq SALES_QUOTATION_TYPE &&  $::instance_conf->get_reqdate_on)
237       && (!$self->order->reqdate)) {
238     $self->c->order->reqdate(DateTime->today_local->next_workday(extra_days => $extra_days));
239   }
240 }
241
242 sub get_reqdate_by_type {
243   my ($self, $reqdate, $saved_reqdate) = @_;
244
245   if ($reqdate == $saved_reqdate) {
246     my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval       :
247                      $self->type eq SALES_ORDER_TYPE     ? $::instance_conf->get_delivery_date_interval : 1;
248
249     if (   ($self->type eq SALES_ORDER_TYPE     &&  !$::instance_conf->get_deliverydate_on)
250         || ($self->type eq SALES_QUOTATION_TYPE &&  !$::instance_conf->get_reqdate_on)) {
251       return '';
252     } else {
253       return DateTime->today_local->next_workday(extra_days => $extra_days);
254     }
255   } else {
256     return $reqdate;
257   }
258 }