PriceSource: Vor Popup Einheit resetten
[kivitendo-erp.git] / SL / Controller / PriceSource.pm
1 package SL::Controller::PriceSource;
2
3 use strict;
4
5 use parent qw(SL::Controller::Base);
6
7 use List::MoreUtils qw(any uniq apply);
8 use SL::ClientJS;
9 use SL::Locale::String qw(t8);
10 use SL::PriceSource;
11
12 use Rose::Object::MakeMethods::Generic
13 (
14  scalar => [ qw(record_item) ],
15  'scalar --get_set_init' => [ qw(js record) ],
16 );
17
18 __PACKAGE__->run_before('check_auth');
19
20 #
21 # actions
22 #
23
24 sub action_price_popup {
25   my ($self) = @_;
26
27   my $record_item = _make_record_item($::form->{row});
28   my $old_unit;
29   if (($old_unit = $record_item->{__additional_form_attributes}{unit_old}) && $old_unit ne $record_item->unit) {
30     # reset unit changes. the way these interact on update breaks stuff
31     $record_item->unit_obj(SL::DB::Manager::Unit->find_by(name => $old_unit));
32     $self->js->val("select[name='unit_$::form->{row}']", $old_unit);
33   }
34
35   $self->render_price_dialog($record_item);
36 }
37
38 sub render_price_dialog {
39   my ($self, $record_item) = @_;
40
41   my $price_source = SL::PriceSource->new(record_item => $record_item, record => $self->record);
42
43   $self->js
44     ->run(
45       'kivi.io.price_chooser_dialog',
46       t8('Available Prices'),
47       $self->render('oe/price_sources_dialog', { output => 0 }, price_source => $price_source)
48     )
49     ->reinit_widgets;
50
51 #   if (@errors) {
52 #     $self->js->text('#dialog_flash_error_content', join ' ', @errors);
53 #     $self->js->show('#dialog_flash_error');
54 #   }
55
56   $self->js->render($self);
57 }
58
59
60 #
61 # internal stuff
62 #
63
64 sub check_auth {
65   $::auth->assert('edit_prices');
66 }
67
68 sub init_js {
69   SL::ClientJS->new
70 }
71
72 sub init_record {
73   _make_record();
74 }
75
76 sub _make_record_item {
77   my ($row) = @_;
78
79   my $class = {
80     sales_order             => 'OrderItem',
81     purchase_order          => 'OrderItem',
82     sales_quotation         => 'OrderItem',
83     request_quotation       => 'OrderItem',
84     invoice                 => 'InvoiceItem',
85     purchase_invoice        => 'InvoiceItem',
86     credit_note             => 'InvoiceItem',
87     purchase_delivery_order => 'DeliveryOrderItem',
88     sales_delivery_order    => 'DeliveryOrderItem',
89   }->{$::form->{type}};
90
91   return unless $class;
92
93   $class = 'SL::DB::' . $class;
94
95   eval "require $class";
96
97   my $obj = $::form->{"orderitems_id_$row"}
98           ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"})
99           : $class->new;
100
101   for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) {
102     if ($obj->meta->column($method)) {
103       if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
104         $obj->${\"$method\_as_date"}($::form->{"$method\_$row"});
105       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
106         $obj->${\"$method\_as_number"}($::form->{"$method\_$row"});
107       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
108         $obj->$method(!!$::form->{$method});
109       } else {
110         $obj->$method($::form->{"$method\_$row"});
111       }
112     } else {
113       $obj->{__additional_form_attributes}{$method} = $::form->{"$method\_$row"};
114     }
115   }
116
117   if ($::form->{"id_$row"}) {
118     $obj->part(SL::DB::Part->load_cached($::form->{"id_$row"}));
119   }
120
121   return $obj;
122 }
123
124 sub _make_record {
125   my ($with_items) = @_;
126
127   my $class = {
128     sales_order             => 'Order',
129     purchase_order          => 'Order',
130     sales_quotation         => 'Order',
131     request_quotation       => 'Order',
132     purchase_invoice        => 'PurchaseInvoice',
133     purchase_delivery_order => 'DeliveryOrder',
134     sales_delivery_order    => 'DeliveryOrder',
135   }->{$::form->{type}};
136
137   if ($::form->{type} =~ /invoice|credit_note/) {
138     $class = $::form->{vc} eq 'customer' ? 'Invoice'
139            : $::form->{vc} eq 'vendor'   ? 'PurchaseInvoice'
140            : do { die 'unknown invoice type' };
141   }
142
143   return unless $class;
144
145   $class = 'SL::DB::' . $class;
146
147   eval "require $class";
148
149   my $obj = $::form->{id}
150           ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{id})
151           : $class->new;
152
153   for my $method (keys %$::form) {
154     next unless $obj->can($method);
155     next unless $obj->meta->column($method);
156
157     if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
158       $obj->${\"$method\_as_date"}($::form->{$method});
159     } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
160       $obj->${\"$method\_as\_number"}($::form->{$method});
161     } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
162       $obj->$method(!!$::form->{$method});
163     } else {
164       $obj->$method($::form->{$method});
165     }
166   }
167
168   if ($with_items) {
169     my @items;
170     for my $i (1 .. $::form->{rowcount}) {
171       next unless $::form->{"id_$i"};
172       push @items, _make_record_item($i)
173     }
174
175     $obj->items(@items) if @items;
176   }
177   $obj->is_sales(!!$obj->customer_id) if $class eq 'SL::DB::DeliveryOrder';
178
179   return $obj;
180 }
181
182 1;
183