Revision 23874369
Von Werner Hahn vor 7 Tagen hinzugefügt
- ID 238743692805a2ce31e87be10b610b8efc541f7a
- Vorgänger e7c613f2
SL/Controller/POS.pm | ||
---|---|---|
8 | 8 |
use SL::Presenter::Tag qw(select_tag hidden_tag div_tag); |
9 | 9 |
use SL::Locale::String qw(t8); |
10 | 10 |
|
11 |
use SL::DB::Order; |
|
12 |
use SL::DB::OrderItem; |
|
13 |
use SL::DB::Order::TypeData qw(:types); |
|
14 |
use SL::DB::Helper::TypeDataProxy; |
|
15 |
use SL::DB::Helper::Record qw(get_object_name_from_type get_class_from_type); |
|
16 |
use SL::Model::Record; |
|
17 |
|
|
11 | 18 |
use SL::Helper::CreatePDF qw(:all); |
12 | 19 |
use SL::Helper::PrintOptions; |
13 | 20 |
use SL::Helper::ShippedQty; |
... | ... | |
25 | 32 |
use Cwd; |
26 | 33 |
use Sort::Naturally; |
27 | 34 |
|
35 |
use Rose::Object::MakeMethods::Generic |
|
36 |
( |
|
37 |
scalar => [ qw(item_ids_to_delete ) ], |
|
38 |
'scalar --get_set_init' => [ qw(poso valid_types type type_data) ], |
|
39 |
); |
|
40 |
|
|
28 | 41 |
# show form pos |
29 | 42 |
sub action_show_form { |
30 | 43 |
my ($self) = @_; |
44 |
$self->pre_render(); |
|
31 | 45 |
$self->render( |
32 | 46 |
'pos/form', |
33 | 47 |
title => t8('POSO'), |
34 |
{header => 0, |
|
35 |
output => 0, |
|
36 |
layout => 0}, |
|
48 |
%{$self->{template_args}} |
|
37 | 49 |
); |
38 | 50 |
} |
39 | 51 |
|
40 |
sub setup_edit_action_bar { |
|
52 |
# add an item row for a new item entered in the input row |
|
53 |
sub action_add_item { |
|
54 |
my ($self) = @_; |
|
55 |
|
|
56 |
delete $::form->{add_item}->{create_part_type}; |
|
57 |
|
|
58 |
my $form_attr = $::form->{add_item}; |
|
59 |
|
|
60 |
unless ($form_attr->{parts_id}) { |
|
61 |
$self->js->flash('error', t8("No part was selected.")); |
|
62 |
return $self->js->render(); |
|
63 |
} |
|
64 |
|
|
65 |
|
|
66 |
my $item = new_item($self->order, $form_attr); |
|
67 |
|
|
68 |
$self->order->add_items($item); |
|
69 |
|
|
70 |
$self->recalc(); |
|
71 |
|
|
72 |
$self->get_item_cvpartnumber($item); |
|
73 |
|
|
74 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
|
75 |
my $row_as_html = $self->p->render('pos/tabs/_row', |
|
76 |
ITEM => $item, |
|
77 |
ID => $item_id, |
|
78 |
SELF => $self, |
|
79 |
); |
|
80 |
|
|
81 |
if ($::form->{insert_before_item_id}) { |
|
82 |
$self->js |
|
83 |
->before ('.row_entry:has(#item_' . $::form->{insert_before_item_id} . ')', $row_as_html); |
|
84 |
} else { |
|
85 |
$self->js |
|
86 |
->append('#row_table_id', $row_as_html); |
|
87 |
} |
|
88 |
|
|
89 |
$self->js |
|
90 |
->val('.add_item_input', '') |
|
91 |
->run('kivi.Order.init_row_handlers') |
|
92 |
->run('kivi.Order.renumber_positions') |
|
93 |
->focus('#add_item_parts_id_name'); |
|
94 |
|
|
95 |
$self->js->run('kivi.Order.row_table_scroll_down') if !$::form->{insert_before_item_id}; |
|
96 |
|
|
97 |
$self->js_redisplay_amounts_and_taxes; |
|
98 |
$self->js->render(); |
|
99 |
} |
|
100 |
|
|
101 |
# Create a new order object |
|
102 |
# |
|
103 |
# And assign changes from the form to this object. |
|
104 |
# Create/Update items from form (via make_item) and add them. |
|
105 |
sub make_order { |
|
106 |
my ($self) = @_; |
|
107 |
|
|
108 |
# add_items adds items to an order with no items for saving, but they |
|
109 |
# cannot be retrieved via items until the order is saved. Adding empty |
|
110 |
# items to new order here solves this problem. |
|
111 |
my $order = SL::DB::Order->new( |
|
112 |
record_type => 'sales_order', |
|
113 |
orderitems => [], |
|
114 |
currency_id => $::instance_conf->get_currency_id(), |
|
115 |
); |
|
116 |
|
|
117 |
if (!$::form->{id} && $::form->{customer_id}) { |
|
118 |
$order->customer_id($::form->{customer_id}); |
|
119 |
$order = SL::Model::Record->update_after_customer_vendor_change($order); |
|
120 |
} |
|
121 |
|
|
122 |
my $form_orderitems = delete $::form->{order}->{orderitems}; |
|
123 |
|
|
124 |
$order->assign_attributes(%{$::form->{order}}); |
|
125 |
|
|
126 |
#$self->setup_custom_shipto_from_form($order, $::form); |
|
127 |
|
|
128 |
# remove deleted items |
|
129 |
$self->item_ids_to_delete([]); |
|
130 |
foreach my $idx (reverse 0..$#{$order->orderitems}) { |
|
131 |
my $item = $order->orderitems->[$idx]; |
|
132 |
if (none { $item->id == $_->{id} } @{$form_orderitems}) { |
|
133 |
splice @{$order->orderitems}, $idx, 1; |
|
134 |
push @{$self->item_ids_to_delete}, $item->id; |
|
135 |
} |
|
136 |
} |
|
137 |
|
|
138 |
my @items; |
|
139 |
my $pos = 1; |
|
140 |
foreach my $form_attr (@{$form_orderitems}) { |
|
141 |
my $item = make_item($order, $form_attr); |
|
142 |
$item->position($pos); |
|
143 |
push @items, $item; |
|
144 |
$pos++; |
|
145 |
} |
|
146 |
$order->add_items(grep {!$_->id} @items); |
|
147 |
|
|
148 |
return $order; |
|
149 |
} |
|
150 |
|
|
151 |
# create a new item |
|
152 |
# |
|
153 |
# This is used to add one item |
|
154 |
sub new_item { |
|
155 |
my ($record, $attr) = @_; |
|
156 |
|
|
157 |
my $item = SL::DB::OrderItem->new; |
|
158 |
|
|
159 |
# Remove attributes where the user left or set the inputs empty. |
|
160 |
# So these attributes will be undefined and we can distinguish them |
|
161 |
# from zero later on. |
|
162 |
for (qw(qty_as_number sellprice_as_number discount_as_percent)) { |
|
163 |
delete $attr->{$_} if $attr->{$_} eq ''; |
|
164 |
} |
|
165 |
|
|
166 |
$item->assign_attributes(%$attr); |
|
167 |
$item->qty(1.0) if !$item->qty; |
|
168 |
$item->unit($item->part->unit) if !$item->unit; |
|
169 |
|
|
170 |
my ($price_src, $discount_src) = get_best_price_and_discount_source($record, $item, 0); |
|
171 |
|
|
172 |
my %new_attr; |
|
173 |
$new_attr{description} = $item->part->description if ! $item->description; |
|
174 |
$new_attr{qty} = 1.0 if ! $item->qty; |
|
175 |
$new_attr{price_factor_id} = $item->part->price_factor_id if ! $item->price_factor_id; |
|
176 |
$new_attr{sellprice} = $price_src->price; |
|
177 |
$new_attr{discount} = $discount_src->discount; |
|
178 |
$new_attr{active_price_source} = $price_src; |
|
179 |
$new_attr{active_discount_source} = $discount_src; |
|
180 |
$new_attr{longdescription} = $item->part->notes if ! defined $attr->{longdescription}; |
|
181 |
$new_attr{project_id} = $record->globalproject_id; |
|
182 |
$new_attr{lastcost} = $record->is_sales ? $item->part->lastcost : 0; |
|
183 |
|
|
184 |
# add_custom_variables adds cvars to an orderitem with no cvars for saving, but |
|
185 |
# they cannot be retrieved via custom_variables until the order/orderitem is |
|
186 |
# saved. Adding empty custom_variables to new orderitem here solves this problem. |
|
187 |
$new_attr{custom_variables} = []; |
|
188 |
|
|
189 |
my $texts = get_part_texts($item->part, $record->language_id, description => $new_attr{description}, longdescription => $new_attr{longdescription}); |
|
190 |
|
|
191 |
$item->assign_attributes(%new_attr, %{ $texts }); |
|
192 |
|
|
193 |
return $item; |
|
194 |
} |
|
195 |
|
|
196 |
sub _setup_edit_action_bar { |
|
41 | 197 |
my ($self, %params) = @_; |
42 | 198 |
for my $bar ($::request->layout->get('actionbar')) { |
43 | 199 |
$bar->add( |
... | ... | |
50 | 206 |
); |
51 | 207 |
} |
52 | 208 |
} |
209 |
|
|
210 |
sub pre_render { |
|
211 |
my ($self) = @_; |
|
212 |
|
|
213 |
$self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all_sorted(); |
|
214 |
$self->{all_languages} = SL::DB::Manager::Language->get_all_sorted(); |
|
215 |
$self->{all_salesmen} = SL::DB::Manager::Employee->get_all_sorted(); |
|
216 |
$self->{current_employee_id} = SL::DB::Manager::Employee->current->id; |
|
217 |
$self->{all_delivery_terms} = SL::DB::Manager::DeliveryTerm->get_all_sorted(); |
|
218 |
$self->{all_payment_terms} = SL::DB::Manager::PaymentTerm->get_all_sorted(); |
|
219 |
$::request->{layout}->use_javascript("${_}.js") for |
|
220 |
qw(kivi.SalesPurchase kivi.POS kivi.File |
|
221 |
calculate_qty kivi.Validator follow_up |
|
222 |
show_history |
|
223 |
); |
|
224 |
$self->_setup_edit_action_bar; |
|
225 |
} |
|
226 |
|
|
227 |
#inits |
|
228 |
sub init_poso { |
|
229 |
$_[0]->make_order; |
|
230 |
} |
|
231 |
|
|
232 |
sub init_valid_types { |
|
233 |
$_[0]->type_data->valid_types; |
|
234 |
} |
|
235 |
|
|
236 |
sub init_type { |
|
237 |
my ($self) = @_; |
|
238 |
|
|
239 |
my $type = $self->poso->record_type; |
|
240 |
if (none { $type eq $_ } @{$self->valid_types}) { |
|
241 |
die "Not a valid type for order"; |
|
242 |
} |
|
243 |
|
|
244 |
$self->type($type); |
|
245 |
} |
|
246 |
|
|
247 |
sub init_type_data { |
|
248 |
my ($self) = @_; |
|
249 |
SL::DB::Helper::TypeDataProxy->new('SL::DB::Order', $self->poso->record_type); |
|
250 |
} |
|
251 |
|
|
53 | 252 |
1; |
Auch abrufbar als: Unified diff
aktuell 0125