make_record: Zusätzliche Formvariablen speichern.
[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
29   $self->render_price_dialog($record_item);
30 }
31
32 sub render_price_dialog {
33   my ($self, $record_item) = @_;
34
35   my $price_source = SL::PriceSource->new(record_item => $record_item, record => $self->record);
36
37   $self->js
38     ->run(
39       'kivi.io.price_chooser_dialog',
40       t8('Available Prices'),
41       $self->render('oe/price_sources_dialog', { output => 0 }, price_source => $price_source)
42     )
43     ->reinit_widgets;
44
45 #   if (@errors) {
46 #     $self->js->text('#dialog_flash_error_content', join ' ', @errors);
47 #     $self->js->show('#dialog_flash_error');
48 #   }
49
50   $self->js->render($self);
51 }
52
53
54 #
55 # internal stuff
56 #
57
58 sub check_auth {
59   $::auth->assert('edit_prices');
60 }
61
62 sub init_js {
63   SL::ClientJS->new
64 }
65
66 sub init_record {
67   _make_record();
68 }
69
70 sub _make_record_item {
71   my ($row) = @_;
72
73   my $class = {
74     sales_order             => 'OrderItem',
75     purchase_order          => 'OrderItem',
76     sales_quotation         => 'OrderItem',
77     request_quotation       => 'OrderItem',
78     invoice                 => 'InvoiceItem',
79     purchase_invoice        => 'InvoiceItem',
80     credit_note             => 'InvoiceItem',
81     purchase_delivery_order => 'DeliveryOrderItem',
82     sales_delivery_order    => 'DeliveryOrderItem',
83   }->{$::form->{type}};
84
85   return unless $class;
86
87   $class = 'SL::DB::' . $class;
88
89   eval "require $class";
90
91   my $obj = $::form->{"orderitems_id_$row"}
92           ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"})
93           : $class->new;
94
95   for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) {
96     if ($obj->meta->column($method)) {
97       if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
98         $obj->${\"$method\_as_date"}($::form->{"$method\_$row"});
99       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
100         $obj->${\"$method\_as_number"}($::form->{"$method\_$row"});
101       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
102         $obj->$method(!!$::form->{$method});
103       } else {
104         $obj->$method($::form->{"$method\_$row"});
105       }
106     } else {
107       $obj->{__additional_form_attributes}{$method} = $::form->{"$method\_$row"};
108     }
109   }
110
111   if ($::form->{"id_$row"}) {
112     $obj->part(SL::DB::Part->load_cached($::form->{"id_$row"}));
113   }
114
115   return $obj;
116 }
117
118 sub _make_record {
119   my ($with_items) = @_;
120
121   my $class = {
122     sales_order             => 'Order',
123     purchase_order          => 'Order',
124     sales_quotation         => 'Order',
125     request_quotation       => 'Order',
126     purchase_invoice        => 'PurchaseInvoice',
127     purchase_delivery_order => 'DeliveryOrder',
128     sales_delivery_order    => 'DeliveryOrder',
129   }->{$::form->{type}};
130
131   if ($::form->{type} =~ /invoice|credit_note/) {
132     $class = $::form->{vc} eq 'customer' ? 'Invoice'
133            : $::form->{vc} eq 'vendor'   ? 'PurchaseInvoice'
134            : do { die 'unknown invoice type' };
135   }
136
137   return unless $class;
138
139   $class = 'SL::DB::' . $class;
140
141   eval "require $class";
142
143   my $obj = $::form->{id}
144           ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{id})
145           : $class->new;
146
147   for my $method (keys %$::form) {
148     next unless $obj->can($method);
149     next unless $obj->meta->column($method);
150
151     if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
152       $obj->${\"$method\_as_date"}($::form->{$method});
153     } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
154       $obj->${\"$method\_as\_number"}($::form->{$method});
155     } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
156       $obj->$method(!!$::form->{$method});
157     } else {
158       $obj->$method($::form->{$method});
159     }
160   }
161
162   if ($with_items) {
163     my @items;
164     for my $i (1 .. $::form->{rowcount}) {
165       next unless $::form->{"id_$i"};
166       push @items, _make_record_item($i)
167     }
168
169     $obj->items(@items) if @items;
170   }
171   $obj->is_sales(!!$obj->customer_id) if $class eq 'SL::DB::DeliveryOrder';
172
173   return $obj;
174 }
175
176 1;
177