Revision 5239714c
Von Kivitendo Admin vor etwa 8 Jahren hinzugefügt
SL/IC.pm | ||
---|---|---|
48 | 48 |
|
49 | 49 |
use strict; |
50 | 50 |
|
51 |
sub get_part { |
|
52 |
$main::lxdebug->enter_sub(); |
|
53 |
|
|
54 |
my ($self, $myconfig, $form) = @_; |
|
55 |
|
|
56 |
# connect to db |
|
57 |
my $dbh = $form->get_standard_dbh; |
|
58 |
|
|
59 |
my $sth; |
|
60 |
|
|
61 |
my $query = |
|
62 |
qq|SELECT p.*, |
|
63 |
c1.accno AS inventory_accno, |
|
64 |
c2.accno AS income_accno, |
|
65 |
c3.accno AS expense_accno, |
|
66 |
pg.partsgroup |
|
67 |
FROM parts p |
|
68 |
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id) |
|
69 |
LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) |
|
70 |
LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) |
|
71 |
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) |
|
72 |
WHERE p.id = ? |; |
|
73 |
my $ref = selectfirst_hashref_query($form, $dbh, $query, conv_i($form->{id})); |
|
74 |
|
|
75 |
# copy to $form variables |
|
76 |
map { $form->{$_} = $ref->{$_} } (keys %{$ref}); |
|
77 |
|
|
78 |
$form->{mtime} = $form->{itime} if !$form->{mtime}; |
|
79 |
$form->{lastmtime} = $form->{mtime}; |
|
80 |
$form->{onhand} *= 1; |
|
81 |
|
|
82 |
# part or service item |
|
83 |
if ($form->{part_type} eq 'assembly') { |
|
84 |
|
|
85 |
# retrieve assembly items |
|
86 |
$query = |
|
87 |
qq|SELECT p.id, p.partnumber, p.description, |
|
88 |
p.sellprice, p.lastcost, p.weight, a.qty, a.bom, p.unit, |
|
89 |
pg.partsgroup, p.price_factor_id, pfac.factor AS price_factor |
|
90 |
FROM parts p |
|
91 |
JOIN assembly a ON (a.parts_id = p.id) |
|
92 |
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) |
|
93 |
LEFT JOIN price_factors pfac ON pfac.id = p.price_factor_id |
|
94 |
WHERE (a.id = ?) |
|
95 |
ORDER BY a.oid|; |
|
96 |
$sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{id})); |
|
97 |
|
|
98 |
$form->{assembly_rows} = 0; |
|
99 |
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) { |
|
100 |
$form->{assembly_rows}++; |
|
101 |
foreach my $key (keys %{$ref}) { |
|
102 |
$form->{"${key}_$form->{assembly_rows}"} = $ref->{$key}; |
|
103 |
} |
|
104 |
} |
|
105 |
$sth->finish; |
|
106 |
|
|
107 |
} |
|
108 |
|
|
109 |
# setup accno hash for <option checked> {amount} is used in create_links |
|
110 |
$form->{amount}{IC} = $form->{inventory_accno}; |
|
111 |
$form->{amount}{IC_income} = $form->{income_accno}; |
|
112 |
$form->{amount}{IC_sale} = $form->{income_accno}; |
|
113 |
$form->{amount}{IC_expense} = $form->{expense_accno}; |
|
114 |
$form->{amount}{IC_cogs} = $form->{expense_accno}; |
|
115 |
|
|
116 |
# get prices |
|
117 |
$query = <<SQL; |
|
118 |
SELECT pg.pricegroup, pg.id AS pricegroup_id, COALESCE(pr.price, 0) AS price |
|
119 |
FROM pricegroup pg |
|
120 |
LEFT JOIN prices pr ON (pr.pricegroup_id = pg.id) AND (pr.parts_id = ?) |
|
121 |
ORDER BY lower(pg.pricegroup) |
|
122 |
SQL |
|
123 |
|
|
124 |
my $row = 1; |
|
125 |
foreach $ref (selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}))) { |
|
126 |
$form->{"${_}_${row}"} = $ref->{$_} for qw(pricegroup_id pricegroup price); |
|
127 |
$row++; |
|
128 |
} |
|
129 |
$form->{price_rows} = $row - 1; |
|
130 |
|
|
131 |
# get makes |
|
132 |
if ($form->{makemodel}) { |
|
133 |
#hli |
|
134 |
$query = qq|SELECT m.make, m.model,m.lastcost,m.lastcost,m.lastupdate,m.sortorder FROM makemodel m | . |
|
135 |
qq|WHERE m.parts_id = ? order by m.sortorder asc|; |
|
136 |
my @values = ($form->{id}); |
|
137 |
$sth = $dbh->prepare($query); |
|
138 |
$sth->execute(@values) || $form->dberror("$query (" . join(', ', @values) . ")"); |
|
139 |
|
|
140 |
my $i = 1; |
|
141 |
|
|
142 |
while (($form->{"make_$i"}, $form->{"model_$i"}, $form->{"old_lastcost_$i"}, |
|
143 |
$form->{"lastcost_$i"}, $form->{"lastupdate_$i"}, $form->{"sortorder_$i"}) = $sth->fetchrow_array) |
|
144 |
{ |
|
145 |
$i++; |
|
146 |
} |
|
147 |
$sth->finish; |
|
148 |
$form->{makemodel_rows} = $i - 1; |
|
149 |
|
|
150 |
} |
|
151 |
|
|
152 |
# get translations |
|
153 |
$query = qq|SELECT language_id, translation, longdescription |
|
154 |
FROM translation |
|
155 |
WHERE parts_id = ?|; |
|
156 |
$form->{translations} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id})); |
|
157 |
|
|
158 |
# is it an orphan |
|
159 |
my @referencing_tables = qw(invoice orderitems inventory); |
|
160 |
my %column_map = ( ); |
|
161 |
my $parts_id = conv_i($form->{id}); |
|
162 |
|
|
163 |
$form->{orphaned} = 1; |
|
164 |
|
|
165 |
foreach my $table (@referencing_tables) { |
|
166 |
my $column = $column_map{$table} || 'parts_id'; |
|
167 |
$query = qq|SELECT $column FROM $table WHERE $column = ? LIMIT 1|; |
|
168 |
my ($found) = selectrow_query($form, $dbh, $query, $parts_id); |
|
169 |
|
|
170 |
if ($found) { |
|
171 |
$form->{orphaned} = 0; |
|
172 |
last; |
|
173 |
} |
|
174 |
} |
|
175 |
|
|
176 |
$form->{"unit_changeable"} = $form->{orphaned}; |
|
177 |
|
|
178 |
Common::webdav_folder($form) if $::lx_office_conf{features}{webdav}; |
|
179 |
|
|
180 |
$main::lxdebug->leave_sub(); |
|
181 |
} |
|
182 |
|
|
183 | 51 |
sub get_pricegroups { |
184 | 52 |
$main::lxdebug->enter_sub(); |
185 | 53 |
|
... | ... | |
223 | 91 |
$main::lxdebug->leave_sub(); |
224 | 92 |
} |
225 | 93 |
|
226 |
sub save { |
|
227 |
my ($self, $myconfig, $form) = @_; |
|
228 |
$main::lxdebug->enter_sub(); |
|
229 |
|
|
230 |
my $rc = SL::DB->client->with_transaction(\&_save, $self, $myconfig, $form); |
|
231 |
|
|
232 |
$main::lxdebug->leave_sub(); |
|
233 |
return $rc; |
|
234 |
} |
|
235 |
|
|
236 |
sub _save { |
|
237 |
my ($self, $myconfig, $form) = @_; |
|
238 |
my @values; |
|
239 |
|
|
240 |
my $dbh = SL::DB->client->dbh; |
|
241 |
my $restricter = SL::HTML::Restrict->create; |
|
242 |
|
|
243 |
# save the part |
|
244 |
# make up a unique handle and store in partnumber field |
|
245 |
# then retrieve the record based on the unique handle to get the id |
|
246 |
# replace the partnumber field with the actual variable |
|
247 |
# add records for makemodel |
|
248 |
|
|
249 |
# if there is a $form->{id} then replace the old entry |
|
250 |
# delete all makemodel entries and add the new ones |
|
251 |
|
|
252 |
# undo amount formatting |
|
253 |
map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) } |
|
254 |
qw(rop weight listprice sellprice gv lastcost); |
|
255 |
|
|
256 |
my $makemodel = ($form->{make_1} || $form->{model_1} || ($form->{makemodel_rows} > 1)) ? 1 : 0; |
|
257 |
|
|
258 |
|
|
259 |
my ($query, $sth); |
|
260 |
|
|
261 |
my $priceupdate = ', priceupdate = current_date'; |
|
262 |
|
|
263 |
if ($form->{id}) { |
|
264 |
my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, id => $form->{id}); |
|
265 |
if (!$trans_number->is_unique) { |
|
266 |
$::lxdebug->leave_sub; |
|
267 |
return 3; |
|
268 |
} |
|
269 |
|
|
270 |
# get old price |
|
271 |
$query = qq|SELECT sellprice FROM parts WHERE id = ?|; |
|
272 |
my ($sellprice) = selectrow_query($form, $dbh, $query, conv_i($form->{id})); |
|
273 |
|
|
274 |
# delete makemodel records |
|
275 |
do_query($form, $dbh, qq|DELETE FROM makemodel WHERE parts_id = ?|, conv_i($form->{id})); |
|
276 |
|
|
277 |
if ($form->{part_type} eq 'assembly') { |
|
278 |
# delete assembly records |
|
279 |
do_query($form, $dbh, qq|DELETE FROM assembly WHERE id = ?|, conv_i($form->{id})); |
|
280 |
} |
|
281 |
|
|
282 |
# delete translations |
|
283 |
do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id})); |
|
284 |
|
|
285 |
# Check whether or not the prices have changed. If they haven't |
|
286 |
# then 'priceupdate' should not be updated. |
|
287 |
my $previous_values = selectfirst_hashref_query($form, $dbh, qq|SELECT * FROM parts WHERE id = ?|, conv_i($form->{id})) || {}; |
|
288 |
$priceupdate = '' if (all { $previous_values->{$_} == $form->{$_} } qw(sellprice lastcost listprice)); |
|
289 |
|
|
290 |
} else { |
|
291 |
my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, save => 1); |
|
292 |
|
|
293 |
if ($form->{partnumber} && !$trans_number->is_unique) { |
|
294 |
$::lxdebug->leave_sub; |
|
295 |
return 3; |
|
296 |
} |
|
297 |
|
|
298 |
$form->{partnumber} ||= $trans_number->create_unique; |
|
299 |
|
|
300 |
($form->{id}) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|); |
|
301 |
do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber, unit, part_type) VALUES (?, ?, ?, ?)|, $form->{id}, $form->{partnumber}, $form->{unit}, $form->{part_type}); |
|
302 |
|
|
303 |
$form->{orphaned} = 1; |
|
304 |
} |
|
305 |
my $partsgroup_id = undef; |
|
306 |
|
|
307 |
if ($form->{partsgroup}) { |
|
308 |
(my $partsgroup, $partsgroup_id) = split(/--/, $form->{partsgroup}); |
|
309 |
} |
|
310 |
|
|
311 |
my ($subq_inventory, $subq_expense, $subq_income); |
|
312 |
if ($form->{part_type} eq "part") { |
|
313 |
$subq_inventory = |
|
314 |
qq|(SELECT bg.inventory_accno_id |
|
315 |
FROM buchungsgruppen bg |
|
316 |
WHERE bg.id = | . conv_i($form->{"buchungsgruppen_id"}, 'NULL') . qq|)|; |
|
317 |
} else { |
|
318 |
$subq_inventory = "NULL"; |
|
319 |
} |
|
320 |
|
|
321 |
if ($form->{part_type} ne "assembly") { |
|
322 |
$subq_expense = |
|
323 |
qq|(SELECT tc.expense_accno_id |
|
324 |
FROM taxzone_charts tc |
|
325 |
WHERE tc.buchungsgruppen_id = | . conv_i($form->{"buchungsgruppen_id"}, 'NULL') . qq| and tc.taxzone_id = 0)|; |
|
326 |
} else { |
|
327 |
$subq_expense = "NULL"; |
|
328 |
} |
|
329 |
|
|
330 |
normalize_text_blocks(); |
|
331 |
|
|
332 |
$query = |
|
333 |
qq|UPDATE parts SET |
|
334 |
partnumber = ?, |
|
335 |
description = ?, |
|
336 |
makemodel = ?, |
|
337 |
listprice = ?, |
|
338 |
sellprice = ?, |
|
339 |
lastcost = ?, |
|
340 |
weight = ?, |
|
341 |
unit = ?, |
|
342 |
notes = ?, |
|
343 |
formel = ?, |
|
344 |
rop = ?, |
|
345 |
warehouse_id = ?, |
|
346 |
bin_id = ?, |
|
347 |
buchungsgruppen_id = ?, |
|
348 |
payment_id = ?, |
|
349 |
inventory_accno_id = $subq_inventory, |
|
350 |
income_accno_id = (SELECT tc.income_accno_id FROM taxzone_charts tc WHERE tc.taxzone_id = 0 and tc.buchungsgruppen_id = ?), |
|
351 |
expense_accno_id = $subq_expense, |
|
352 |
obsolete = ?, |
|
353 |
image = ?, |
|
354 |
drawing = ?, |
|
355 |
shop = ?, |
|
356 |
ve = ?, |
|
357 |
gv = ?, |
|
358 |
ean = ?, |
|
359 |
has_sernumber = ?, |
|
360 |
not_discountable = ?, |
|
361 |
microfiche = ?, |
|
362 |
part_type = ?, |
|
363 |
partsgroup_id = ?, |
|
364 |
price_factor_id = ? |
|
365 |
$priceupdate |
|
366 |
WHERE id = ?|; |
|
367 |
@values = ($form->{partnumber}, |
|
368 |
$form->{description}, |
|
369 |
$makemodel ? 't' : 'f', |
|
370 |
$form->{listprice}, |
|
371 |
$form->{sellprice}, |
|
372 |
$form->{lastcost}, |
|
373 |
$form->{weight}, |
|
374 |
$form->{unit}, |
|
375 |
$restricter->process($form->{notes}), |
|
376 |
$form->{formel}, |
|
377 |
$form->{rop}, |
|
378 |
conv_i($form->{warehouse_id}), |
|
379 |
conv_i($form->{bin_id}), |
|
380 |
conv_i($form->{buchungsgruppen_id}), |
|
381 |
conv_i($form->{payment_id}), |
|
382 |
conv_i($form->{buchungsgruppen_id}), |
|
383 |
$form->{obsolete} ? 't' : 'f', |
|
384 |
$form->{image}, |
|
385 |
$form->{drawing}, |
|
386 |
$form->{shop} ? 't' : 'f', |
|
387 |
conv_i($form->{ve}), |
|
388 |
conv_i($form->{gv}), |
|
389 |
$form->{ean}, |
|
390 |
$form->{has_sernumber} ? 't' : 'f', |
|
391 |
$form->{not_discountable} ? 't' : 'f', |
|
392 |
$form->{microfiche}, |
|
393 |
$form->{part_type}, |
|
394 |
conv_i($partsgroup_id), |
|
395 |
conv_i($form->{price_factor_id}), |
|
396 |
conv_i($form->{id}) |
|
397 |
); |
|
398 |
do_query($form, $dbh, $query, @values); |
|
399 |
|
|
400 |
$form->new_lastmtime('parts'); |
|
401 |
|
|
402 |
# delete translation records |
|
403 |
do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id})); |
|
404 |
|
|
405 |
my @translations = grep { $_->{language_id} && $_->{translation} } @{ $form->{translations} || [] }; |
|
406 |
if (@translations) { |
|
407 |
$query = qq|INSERT into translation (parts_id, language_id, translation, longdescription) |
|
408 |
VALUES ( ?, ?, ?, ? )|; |
|
409 |
$sth = $dbh->prepare($query); |
|
410 |
|
|
411 |
foreach my $translation (@translations) { |
|
412 |
do_statement($form, $sth, $query, conv_i($form->{id}), conv_i($translation->{language_id}), $translation->{translation}, $restricter->process($translation->{longdescription})); |
|
413 |
} |
|
414 |
|
|
415 |
$sth->finish(); |
|
416 |
} |
|
417 |
|
|
418 |
# delete price records |
|
419 |
do_query($form, $dbh, qq|DELETE FROM prices WHERE parts_id = ?|, conv_i($form->{id})); |
|
420 |
|
|
421 |
$query = qq|INSERT INTO prices (parts_id, pricegroup_id, price) VALUES(?, ?, ?)|; |
|
422 |
$sth = prepare_query($form, $dbh, $query); |
|
423 |
|
|
424 |
for my $i (1 .. $form->{price_rows}) { |
|
425 |
my $price = $form->parse_amount($myconfig, $form->{"price_$i"}); |
|
426 |
next unless $price; |
|
427 |
|
|
428 |
@values = (conv_i($form->{id}), conv_i($form->{"pricegroup_id_$i"}), $price); |
|
429 |
do_statement($form, $sth, $query, @values); |
|
430 |
} |
|
431 |
|
|
432 |
$sth->finish; |
|
433 |
|
|
434 |
# insert makemodel records |
|
435 |
my $lastupdate = ''; |
|
436 |
my $value = 0; |
|
437 |
for my $i (1 .. $form->{makemodel_rows}) { |
|
438 |
if (($form->{"make_$i"}) || ($form->{"model_$i"})) { |
|
439 |
#hli |
|
440 |
$value = $form->parse_amount($myconfig, $form->{"lastcost_$i"}); |
|
441 |
if ($value == $form->parse_amount($myconfig, $form->{"old_lastcost_$i"})) |
|
442 |
{ |
|
443 |
if ($form->{"lastupdate_$i"} eq "") { |
|
444 |
$lastupdate = 'now()'; |
|
445 |
} else { |
|
446 |
$lastupdate = $dbh->quote($form->{"lastupdate_$i"}); |
|
447 |
} |
|
448 |
} else { |
|
449 |
$lastupdate = 'now()'; |
|
450 |
} |
|
451 |
$query = qq|INSERT INTO makemodel (parts_id, make, model, lastcost, lastupdate, sortorder) | . |
|
452 |
qq|VALUES (?, ?, ?, ?, ?, ?)|; |
|
453 |
@values = (conv_i($form->{id}), conv_i($form->{"make_$i"}), $form->{"model_$i"}, $value, $lastupdate, conv_i($form->{"sortorder_$i"}) ); |
|
454 |
|
|
455 |
do_query($form, $dbh, $query, @values); |
|
456 |
} |
|
457 |
} |
|
458 |
|
|
459 |
# add assembly records |
|
460 |
if ($form->{part_type} eq 'assembly') { |
|
461 |
# check additional assembly row |
|
462 |
my $i = $form->{assembly_rows}; |
|
463 |
# if last row is not empty add them |
|
464 |
if ($form->{"partnumber_$i"} ne "") { |
|
465 |
$query = qq|SELECT id FROM parts WHERE partnumber = ?|; |
|
466 |
my ($partid) = selectrow_query($form, $dbh, $query,$form->{"partnumber_$i"} ); |
|
467 |
if ( $partid ) { |
|
468 |
$form->{"qty_$i"} = 1 unless ($form->{"qty_$i"}); |
|
469 |
$form->{"id_$i"} = $partid; |
|
470 |
$form->{"bom_$i"} = 0; |
|
471 |
$form->{assembly_rows}++; |
|
472 |
} |
|
473 |
else { |
|
474 |
$::form->error($::locale->text("uncorrect partnumber ").$form->{"partnumber_$i"}); |
|
475 |
} |
|
476 |
} |
|
477 |
|
|
478 |
for my $i (1 .. $form->{assembly_rows}) { |
|
479 |
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); |
|
480 |
|
|
481 |
if ($form->{"qty_$i"} != 0) { |
|
482 |
$form->{"bom_$i"} *= 1; |
|
483 |
$query = qq|INSERT INTO assembly (id, parts_id, qty, bom) | . |
|
484 |
qq|VALUES (?, ?, ?, ?)|; |
|
485 |
@values = (conv_i($form->{id}), conv_i($form->{"id_$i"}), conv_i($form->{"qty_$i"}), $form->{"bom_$i"} ? 't' : 'f'); |
|
486 |
do_query($form, $dbh, $query, @values); |
|
487 |
} |
|
488 |
} |
|
489 |
my @a = localtime; |
|
490 |
$a[5] += 1900; |
|
491 |
$a[4]++; |
|
492 |
my $shippingdate = "$a[5]-$a[4]-$a[3]"; |
|
493 |
|
|
494 |
$form->get_employee($dbh); |
|
495 |
|
|
496 |
} |
|
497 |
|
|
498 |
#set expense_accno=inventory_accno if they are different => bilanz |
|
499 |
my $vendor_accno = |
|
500 |
($form->{expense_accno} != $form->{inventory_accno}) |
|
501 |
? $form->{inventory_accno} |
|
502 |
: $form->{expense_accno}; |
|
503 |
|
|
504 |
# get tax rates and description |
|
505 |
my $accno_id = |
|
506 |
($form->{vc} eq "customer") ? $form->{income_accno} : $vendor_accno; |
|
507 |
$query = |
|
508 |
qq|SELECT c.accno, c.description, t.rate, t.taxnumber |
|
509 |
FROM chart c, tax t |
|
510 |
WHERE (c.id = t.chart_id) AND (t.taxkey IN (SELECT taxkey_id FROM chart where accno = ?)) |
|
511 |
ORDER BY c.accno|; |
|
512 |
my $stw = prepare_execute_query($form, $dbh, $query, $accno_id); |
|
513 |
|
|
514 |
$form->{taxaccount} = ""; |
|
515 |
while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) { |
|
516 |
$form->{taxaccount} .= "$ptr->{accno} "; |
|
517 |
if (!($form->{taxaccount2} =~ /\Q$ptr->{accno}\E/)) { |
|
518 |
$form->{"$ptr->{accno}_rate"} = $ptr->{rate}; |
|
519 |
$form->{"$ptr->{accno}_description"} = $ptr->{description}; |
|
520 |
$form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; |
|
521 |
$form->{taxaccount2} .= " $ptr->{accno} "; |
|
522 |
} |
|
523 |
} |
|
524 |
|
|
525 |
CVar->save_custom_variables(dbh => $dbh, |
|
526 |
module => 'IC', |
|
527 |
trans_id => $form->{id}, |
|
528 |
variables => $form, |
|
529 |
save_validity => 1); |
|
530 |
|
|
531 |
# Delete saved custom variable values for configs that have been |
|
532 |
# marked invalid for this part. |
|
533 |
$query = <<SQL; |
|
534 |
DELETE FROM custom_variables |
|
535 |
WHERE (config_id IN ( |
|
536 |
SELECT val.config_id |
|
537 |
FROM custom_variables_validity val |
|
538 |
LEFT JOIN custom_variable_configs val_cfg ON (val.config_id = val_cfg.id) |
|
539 |
WHERE (val_cfg.module = 'IC') |
|
540 |
AND (val.trans_id = ?))) |
|
541 |
AND (trans_id = ?) |
|
542 |
SQL |
|
543 |
do_query($form, $dbh, $query, ($form->{id}) x 2); |
|
544 |
|
|
545 |
return 1; |
|
546 |
} |
|
547 |
|
|
548 | 94 |
sub retrieve_assemblies { |
549 | 95 |
$main::lxdebug->enter_sub(); |
550 | 96 |
|
... | ... | |
581 | 127 |
$main::lxdebug->leave_sub(); |
582 | 128 |
} |
583 | 129 |
|
584 |
sub delete { |
|
585 |
my ($self, $myconfig, $form) = @_; |
|
586 |
$main::lxdebug->enter_sub(); |
|
587 |
|
|
588 |
my $rc = SL::DB->client->with_transaction(\&_delete, $self, $myconfig, $form); |
|
589 |
|
|
590 |
$main::lxdebug->leave_sub(); |
|
591 |
return $rc; |
|
592 |
} |
|
593 |
|
|
594 |
sub _delete { |
|
595 |
my ($self, $myconfig, $form) = @_; |
|
596 |
my @values = (conv_i($form->{id})); |
|
597 |
|
|
598 |
my %columns = ( "assembly" => "id", "parts" => "id" ); |
|
599 |
|
|
600 |
for my $table (qw(prices makemodel inventory assembly translation parts)) { |
|
601 |
my $column = defined($columns{$table}) ? $columns{$table} : "parts_id"; |
|
602 |
do_query($form, SL::DB->client->dbh, qq|DELETE FROM $table WHERE $column = ?|, @values); |
|
603 |
} |
|
604 |
|
|
605 |
return 1; |
|
606 |
} |
|
607 |
|
|
608 | 130 |
sub assembly_item { |
609 | 131 |
$main::lxdebug->enter_sub(); |
610 | 132 |
|
... | ... | |
1302 | 824 |
return $num_updated; |
1303 | 825 |
} |
1304 | 826 |
|
1305 |
sub create_links { |
|
1306 |
$main::lxdebug->enter_sub(); |
|
1307 |
|
|
1308 |
my ($self, $module, $myconfig, $form) = @_; |
|
1309 |
|
|
1310 |
# connect to database |
|
1311 |
my $dbh = $form->get_standard_dbh; |
|
1312 |
|
|
1313 |
my @values = like($module); |
|
1314 |
my $query; |
|
1315 |
|
|
1316 |
if ($form->{id}) { |
|
1317 |
$query = |
|
1318 |
qq|SELECT c.accno, c.description, c.link, c.id, |
|
1319 |
p.inventory_accno_id, p.income_accno_id, p.expense_accno_id |
|
1320 |
FROM chart c, parts p |
|
1321 |
WHERE (c.link LIKE ?) AND (p.id = ?) |
|
1322 |
ORDER BY c.accno|; |
|
1323 |
push(@values, conv_i($form->{id})); |
|
1324 |
|
|
1325 |
} else { |
|
1326 |
$query = |
|
1327 |
qq|SELECT c.accno, c.description, c.link, c.id, |
|
1328 |
d.inventory_accno_id, d.income_accno_id, d.expense_accno_id |
|
1329 |
FROM chart c, defaults d |
|
1330 |
WHERE c.link LIKE ? |
|
1331 |
ORDER BY c.accno|; |
|
1332 |
} |
|
1333 |
|
|
1334 |
my $sth = prepare_execute_query($form, $dbh, $query, @values); |
|
1335 |
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) { |
|
1336 |
foreach my $key (split(/:/, $ref->{link})) { |
|
1337 |
if ($key =~ /\Q$module\E/) { |
|
1338 |
if ( ($ref->{id} eq $ref->{inventory_accno_id}) |
|
1339 |
|| ($ref->{id} eq $ref->{income_accno_id}) |
|
1340 |
|| ($ref->{id} eq $ref->{expense_accno_id})) { |
|
1341 |
push @{ $form->{"${module}_links"}{$key} }, |
|
1342 |
{ accno => $ref->{accno}, |
|
1343 |
description => $ref->{description}, |
|
1344 |
selected => "selected" }; |
|
1345 |
$form->{"${key}_default"} = "$ref->{accno}--$ref->{description}"; |
|
1346 |
} else { |
|
1347 |
push @{ $form->{"${module}_links"}{$key} }, |
|
1348 |
{ accno => $ref->{accno}, |
|
1349 |
description => $ref->{description}, |
|
1350 |
selected => "" }; |
|
1351 |
} |
|
1352 |
} |
|
1353 |
} |
|
1354 |
} |
|
1355 |
$sth->finish; |
|
1356 |
|
|
1357 |
# get buchungsgruppen |
|
1358 |
$form->{BUCHUNGSGRUPPEN} = selectall_hashref_query($form, $dbh, qq|SELECT id, description FROM buchungsgruppen|); |
|
1359 |
|
|
1360 |
# get payment terms |
|
1361 |
$form->{payment_terms} = selectall_hashref_query($form, $dbh, qq|SELECT id, description FROM payment_terms ORDER BY sortkey|); |
|
1362 |
|
|
1363 |
if (!$form->{id}) { |
|
1364 |
($form->{priceupdate}) = selectrow_query($form, $dbh, qq|SELECT current_date|); |
|
1365 |
} |
|
1366 |
|
|
1367 |
$main::lxdebug->leave_sub(); |
|
1368 |
} |
|
1369 |
|
|
1370 | 827 |
# get partnumber, description, unit, sellprice and soldtotal with choice through $sortorder for Top100 |
1371 | 828 |
sub get_parts { |
1372 | 829 |
$main::lxdebug->enter_sub(); |
... | ... | |
1436 | 893 |
return $sum; |
1437 | 894 |
} #end get_soldtotal |
1438 | 895 |
|
1439 |
sub retrieve_languages { |
|
1440 |
$main::lxdebug->enter_sub(); |
|
1441 |
|
|
1442 |
my ($self, $myconfig, $form) = @_; |
|
1443 |
|
|
1444 |
# connect to database |
|
1445 |
my $dbh = $form->get_standard_dbh; |
|
1446 |
|
|
1447 |
my @values; |
|
1448 |
my $where; |
|
1449 |
my $query; |
|
1450 |
|
|
1451 |
if ($form->{language_values} ne "") { |
|
1452 |
$query = |
|
1453 |
qq|SELECT l.id, l.description, tr.translation, tr.longdescription |
|
1454 |
FROM language l |
|
1455 |
LEFT OUTER JOIN translation tr ON (tr.language_id = l.id) AND (tr.parts_id = ?) |
|
1456 |
ORDER BY lower(l.description)|; |
|
1457 |
@values = (conv_i($form->{id})); |
|
1458 |
|
|
1459 |
} else { |
|
1460 |
$query = qq|SELECT id, description |
|
1461 |
FROM language |
|
1462 |
ORDER BY lower(description)|; |
|
1463 |
} |
|
1464 |
|
|
1465 |
my $languages = selectall_hashref_query($form, $dbh, $query, @values); |
|
1466 |
|
|
1467 |
$main::lxdebug->leave_sub(); |
|
1468 |
|
|
1469 |
return $languages; |
|
1470 |
} |
|
1471 |
|
|
1472 | 896 |
sub follow_account_chain { |
1473 | 897 |
$main::lxdebug->enter_sub(2); |
1474 | 898 |
|
bin/mozilla/ic.pl | ||
---|---|---|
74 | 74 |
|
75 | 75 |
# end of main |
76 | 76 |
|
77 |
sub add { |
|
78 |
$lxdebug->enter_sub(); |
|
79 |
|
|
80 |
$auth->assert('part_service_assembly_edit'); |
|
81 |
|
|
82 |
my $title = 'Add ' . ucfirst $form->{part_type}; |
|
83 |
$form->{title} = $locale->text($title); |
|
84 |
$form->{callback} = "$form->{script}?action=add&part_type=$form->{part_type}" unless $form->{callback}; |
|
85 |
$form->{unit_changeable} = 1; |
|
86 |
|
|
87 |
IC->get_pricegroups(\%myconfig, \%$form); |
|
88 |
&link_part; |
|
89 |
&display_form; |
|
90 |
|
|
91 |
$lxdebug->leave_sub(); |
|
92 |
} |
|
93 |
|
|
94 | 77 |
sub search { |
95 | 78 |
$lxdebug->enter_sub(); |
96 | 79 |
|
... | ... | |
732 | 715 |
$lxdebug->leave_sub(); |
733 | 716 |
} |
734 | 717 |
|
735 |
sub edit { |
|
736 |
$lxdebug->enter_sub(); |
|
737 |
|
|
738 |
$auth->assert('part_service_assembly_details'); |
|
739 |
|
|
740 |
# show history button |
|
741 |
$form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|; |
|
742 |
#/show hhistory button |
|
743 |
IC->get_part(\%myconfig, \%$form); |
|
744 |
|
|
745 |
$form->{"original_partnumber"} = $form->{"partnumber"}; |
|
746 |
|
|
747 |
my $title = 'Edit ' . ucfirst $form->{part_type}; |
|
748 |
$form->{title} = $locale->text($title); |
|
749 |
|
|
750 |
&link_part; |
|
751 |
&display_form; |
|
752 |
|
|
753 |
$lxdebug->leave_sub(); |
|
754 |
} |
|
755 |
|
|
756 |
sub link_part { |
|
757 |
$lxdebug->enter_sub(); |
|
758 |
|
|
759 |
$auth->assert('part_service_assembly_details'); |
|
760 |
|
|
761 |
IC->create_links("IC", \%myconfig, \%$form); |
|
762 |
|
|
763 |
# currencies |
|
764 |
map({ $form->{selectcurrency} .= "<option>$_\n" } $::form->get_all_currencies()); |
|
765 |
|
|
766 |
# parts and assemblies have the same links |
|
767 |
my $item = $form->{part_type}; |
|
768 |
if ($form->{part_type} eq 'assembly') { |
|
769 |
$item = 'part'; |
|
770 |
} |
|
771 |
|
|
772 |
# build the popup menus |
|
773 |
$form->{taxaccounts} = ""; |
|
774 |
foreach my $key (keys %{ $form->{IC_links} }) { |
|
775 |
foreach my $ref (@{ $form->{IC_links}{$key} }) { |
|
776 |
|
|
777 |
# if this is a tax field |
|
778 |
if ($key =~ /IC_tax/) { |
|
779 |
if ($key =~ /\Q$item\E/) { |
|
780 |
$form->{taxaccounts} .= "$ref->{accno} "; |
|
781 |
$form->{"IC_tax_$ref->{accno}_description"} = |
|
782 |
"$ref->{accno}--$ref->{description}"; |
|
783 |
|
|
784 |
if ($form->{id}) { |
|
785 |
if ($form->{amount}{ $ref->{accno} }) { |
|
786 |
$form->{"IC_tax_$ref->{accno}"} = "checked"; |
|
787 |
} |
|
788 |
} else { |
|
789 |
$form->{"IC_tax_$ref->{accno}"} = "checked"; |
|
790 |
} |
|
791 |
} |
|
792 |
} else { |
|
793 |
|
|
794 |
$form->{"select$key"} .= |
|
795 |
"<option $ref->{selected}>$ref->{accno}--$ref->{description}\n"; |
|
796 |
if ($form->{amount}{$key} eq $ref->{accno}) { |
|
797 |
$form->{$key} = "$ref->{accno}--$ref->{description}"; |
|
798 |
} |
|
799 |
|
|
800 |
} |
|
801 |
} |
|
802 |
} |
|
803 |
chop $form->{taxaccounts}; |
|
804 |
|
|
805 |
if (($form->{part_type} eq "part") || ($form->{part_type} eq "assembly")) { |
|
806 |
$form->{selectIC_income} = $form->{selectIC_sale}; |
|
807 |
$form->{selectIC_expense} = $form->{selectIC_cogs}; |
|
808 |
$form->{IC_income} = $form->{IC_sale}; |
|
809 |
$form->{IC_expense} = $form->{IC_cogs}; |
|
810 |
} |
|
811 |
|
|
812 |
delete $form->{IC_links}; |
|
813 |
delete $form->{amount}; |
|
814 |
|
|
815 |
$form->get_partsgroup(\%myconfig, { all => 1 }); |
|
816 |
|
|
817 |
$form->{partsgroup} = "$form->{partsgroup}--$form->{partsgroup_id}"; |
|
818 |
|
|
819 |
if (@{ $form->{all_partsgroup} }) { |
|
820 |
$form->{selectpartsgroup} = qq|<option>\n|; |
|
821 |
map { $form->{selectpartsgroup} .= qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n| } @{ $form->{all_partsgroup} }; |
|
822 |
} |
|
823 |
|
|
824 |
if ($form->{part_type} eq 'assembly') { |
|
825 |
|
|
826 |
foreach my $i (1 .. $form->{assembly_rows}) { |
|
827 |
if ($form->{"partsgroup_id_$i"}) { |
|
828 |
$form->{"partsgroup_$i"} = |
|
829 |
qq|$form->{"partsgroup_$i"}--$form->{"partsgroup_id_$i"}|; |
|
830 |
} |
|
831 |
} |
|
832 |
$form->get_partsgroup(\%myconfig); |
|
833 |
|
|
834 |
if (@{ $form->{all_partsgroup} }) { |
|
835 |
$form->{selectassemblypartsgroup} = qq|<option>\n|; |
|
836 |
|
|
837 |
map { |
|
838 |
$form->{selectassemblypartsgroup} .= |
|
839 |
qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n| |
|
840 |
} @{ $form->{all_partsgroup} }; |
|
841 |
} |
|
842 |
} |
|
843 |
$lxdebug->leave_sub(); |
|
844 |
} |
|
845 |
|
|
846 |
sub form_header { |
|
847 |
$lxdebug->enter_sub(); |
|
848 |
|
|
849 |
$auth->assert('part_service_assembly_details'); |
|
850 |
|
|
851 |
$form->{pg_keys} = sub { "$_[0]->{partsgroup}--$_[0]->{id}" }; |
|
852 |
$form->{description_area} = ($form->{rows} = $form->numtextrows($form->{description}, 40)) > 1; |
|
853 |
$form->{notes_rows} = max 4, $form->numtextrows($form->{notes}, 40), $form->numtextrows($form->{formel}, 40); |
|
854 |
|
|
855 |
map { $form->{"is_$_"} = ($form->{part_type} eq $_) } qw(part service assembly); |
|
856 |
map { $form->{$_} =~ s/"/"/g; } qw(unit); |
|
857 |
|
|
858 |
$form->get_lists('price_factors' => 'ALL_PRICE_FACTORS', |
|
859 |
'partsgroup' => 'all_partsgroup', |
|
860 |
'vendors' => 'ALL_VENDORS', |
|
861 |
'warehouses' => { 'key' => 'WAREHOUSES', |
|
862 |
'bins' => 'BINS', }); |
|
863 |
# leerer wert für Lager und Lagerplatz korrekt einstellt |
|
864 |
# ID 0 sollte in Ordnung sein, da der Zähler sowieso höher ist |
|
865 |
my $no_default_bin_entry = { 'id' => '0', description => '--', 'BINS' => [ { id => '0', description => ''} ] }; |
|
866 |
push @ { $form->{WAREHOUSES} }, $no_default_bin_entry; |
|
867 |
if (my $max = scalar @{ $form->{WAREHOUSES} }) { |
|
868 |
my ($default_warehouse_id, $default_bin_id); |
|
869 |
if ($form->{action} eq 'add') { # default only for new entries |
|
870 |
$default_warehouse_id = $::instance_conf->get_warehouse_id; |
|
871 |
$default_bin_id = $::instance_conf->get_bin_id; |
|
872 |
} |
|
873 |
$form->{warehouse_id} ||= $default_warehouse_id || $form->{WAREHOUSES}->[$max -1]->{id}; |
|
874 |
$form->{bin_id} ||= $default_bin_id || $form->{WAREHOUSES}->[$max -1]->{BINS}->[0]->{id}; |
|
875 |
} |
|
876 |
|
|
877 |
$form->{LANGUAGES} = SL::DB::Manager::Language->get_all_sorted; |
|
878 |
$form->{translations_map} = { map { ($_->{language_id} => $_) } @{ $form->{translations} || [] } }; |
|
879 |
|
|
880 |
IC->retrieve_buchungsgruppen(\%myconfig, $form); |
|
881 |
@{ $form->{BUCHUNGSGRUPPEN} } = grep { $_->{id} eq $form->{buchungsgruppen_id} || ($form->{id} && $form->{orphaned}) || !$form->{id} } @{ $form->{BUCHUNGSGRUPPEN} }; |
|
882 |
|
|
883 |
if (($form->{partnumber} ne '') && !SL::TransNumber->new(number => $form->{partnumber}, type => $form->{part_type}, id => $form->{id})->is_unique) { |
|
884 |
flash('info', $::locale->text('This partnumber is not unique. You should change it.')); |
|
885 |
} |
|
886 |
|
|
887 |
my $units = AM->retrieve_units(\%myconfig, $form); |
|
888 |
$form->{ALL_UNITS} = [ map +{ name => $_ }, sort { $units->{$a}{sortkey} <=> $units->{$b}{sortkey} } keys %$units ]; |
|
889 |
|
|
890 |
$form->{defaults} = AM->get_defaults(); |
|
891 |
|
|
892 |
$form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'IC', 'trans_id' => $form->{id}); |
|
893 |
|
|
894 |
my ($null, $partsgroup_id) = split /--/, $form->{partsgroup}; |
|
895 |
|
|
896 |
CVar->render_inputs('variables' => $form->{CUSTOM_VARIABLES}, show_disabled_message => 1, partsgroup_id => $partsgroup_id) |
|
897 |
if (scalar @{ $form->{CUSTOM_VARIABLES} }); |
|
898 |
|
|
899 |
$::request->layout->use_javascript("${_}.js") for qw(ckeditor/ckeditor ckeditor/adapters/jquery kivi.PriceRule); |
|
900 |
$::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $::form->{id} * 1 ]})});") if $::form->{id}; |
|
901 |
$form->header; |
|
902 |
#print $form->parse_html_template('ic/form_header', { ALL_PRICE_FACTORS => $form->{ALL_PRICE_FACTORS}, |
|
903 |
# ALL_UNITS => $form->{ALL_UNITS}, |
|
904 |
# BUCHUNGSGRUPPEN => $form->{BUCHUNGSGRUPPEN}, |
|
905 |
# payment_terms => $form->{payment_terms}, |
|
906 |
# all_partsgroup => $form->{all_partsgroup}}); |
|
907 |
|
|
908 |
$form->{show_edit_buttons} = $main::auth->check_right($::myconfig{login}, 'part_service_assembly_edit'); |
|
909 |
|
|
910 |
print $form->parse_html_template('ic/form_header'); |
|
911 |
$lxdebug->leave_sub(); |
|
912 |
} |
|
913 |
|
|
914 |
sub form_footer { |
|
915 |
$lxdebug->enter_sub(); |
|
916 |
|
|
917 |
$auth->assert('part_service_assembly_details'); |
|
918 |
|
|
919 |
print $form->parse_html_template('ic/form_footer'); |
|
920 |
|
|
921 |
$lxdebug->leave_sub(); |
|
922 |
} |
|
923 |
|
|
924 |
sub makemodel_row { |
|
925 |
$lxdebug->enter_sub(); |
|
926 |
my ($numrows) = @_; |
|
927 |
#hli |
|
928 |
my @mm_data = grep { any { $_ ne '' } @$_{qw(make model)} } map +{ make => $form->{"make_$_"}, model => $form->{"model_$_"}, lastcost => $form->{"lastcost_$_"}, lastupdate => $form->{"lastupdate_$_"}, sortorder => $form->{"sortorder_$_"} }, 1 .. $numrows; |
|
929 |
delete @{$form}{grep { m/^make_\d+/ || m/^model_\d+/ } keys %{ $form }}; |
|
930 |
print $form->parse_html_template('ic/makemodel', { MM_DATA => [ @mm_data, {} ], mm_rows => scalar @mm_data + 1 }); |
|
931 |
|
|
932 |
$lxdebug->leave_sub(); |
|
933 |
} |
|
934 |
|
|
935 |
sub assembly_row { |
|
936 |
$lxdebug->enter_sub(); |
|
937 |
my ($numrows) = @_; |
|
938 |
my (@column_index); |
|
939 |
my ($nochange, $callback, $previousform, $linetotal, $line_purchase_price, $href); |
|
940 |
|
|
941 |
@column_index = qw(runningnumber qty unit bom partnumber description partsgroup lastcost total); |
|
942 |
|
|
943 |
if ($form->{previousform}) { |
|
944 |
$nochange = 1; |
|
945 |
@column_index = qw(qty unit bom partnumber description partsgroup total); |
|
946 |
} else { |
|
947 |
|
|
948 |
# change callback |
|
949 |
$form->{old_callback} = $form->{callback}; |
|
950 |
$callback = $form->{callback}; |
|
951 |
$form->{callback} = "$form->{script}?action=display_form"; |
|
952 |
|
|
953 |
# delete action |
|
954 |
map { delete $form->{$_} } qw(action header); |
|
955 |
|
|
956 |
# save form variables in a previousform variable |
|
957 |
my %form_to_save = map { ($_ => m/^ (?: listprice | sellprice | lastcost ) $/x ? $form->format_amount(\%myconfig, $form->{$_}) : $form->{$_}) } |
|
958 |
keys %{ $form }; |
|
959 |
$previousform = $::auth->save_form_in_session(form => \%form_to_save); |
|
960 |
|
|
961 |
$form->{callback} = $callback; |
|
962 |
$form->{assemblytotal} = 0; |
|
963 |
$form->{assembly_purchase_price_total} = 0; |
|
964 |
$form->{weight} = 0; |
|
965 |
} |
|
966 |
|
|
967 |
my %header = ( |
|
968 |
runningnumber => { text => $locale->text('No.'), nowrap => 1, width => '5%', align => 'left',}, |
|
969 |
qty => { text => $locale->text('Qty'), nowrap => 1, width => '10%', align => 'left',}, |
|
970 |
unit => { text => $locale->text('Unit'), nowrap => 1, width => '5%', align => 'left',}, |
|
971 |
partnumber => { text => $locale->text('Part Number'), nowrap => 1, width => '20%', align => 'left',}, |
|
972 |
description => { text => $locale->text('Part Description'), nowrap => 1, width => '50%', align => 'left',}, |
|
973 |
lastcost => { text => $locale->text('Purchase Prices'), nowrap => 1, width => '50%', align => 'right',}, |
|
974 |
total => { text => $locale->text('Sale Prices'), nowrap => 1, align => 'right',}, |
|
975 |
bom => { text => $locale->text('BOM'), align => 'center',}, |
|
976 |
partsgroup => { text => $locale->text('Group'), align => 'left',}, |
|
977 |
); |
|
978 |
|
|
979 |
my @ROWS; |
|
980 |
|
|
981 |
for my $i (1 .. $numrows) { |
|
982 |
my (%row, @row_hiddens); |
|
983 |
|
|
984 |
$form->{"partnumber_$i"} =~ s/\"/"/g; |
|
985 |
|
|
986 |
$linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4); |
|
987 |
$line_purchase_price = $form->round_amount($form->{"lastcost_$i"} * $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4); |
|
988 |
$form->{assemblytotal} += $linetotal; |
|
989 |
$form->{assembly_purchase_price_total} += $line_purchase_price; |
|
990 |
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); |
|
991 |
$linetotal = $form->format_amount(\%myconfig, $linetotal, 2); |
|
992 |
$line_purchase_price = $form->format_amount(\%myconfig, $line_purchase_price, 2); |
|
993 |
$href = build_std_url("action=edit", qq|id=$form->{"id_$i"}|, "rowcount=$numrows", "currow=$i", "previousform=$previousform"); |
|
994 |
map { $row{$_}{data} = "" } qw(qty unit partnumber description bom partsgroup runningnumber); |
|
995 |
|
|
996 |
# last row |
|
997 |
if (($i >= 1) && ($i == $numrows)) { |
|
998 |
if (!$form->{previousform}) { |
|
999 |
$row{partnumber}{data} = qq|<input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}">|; |
|
1000 |
$row{qty}{data} = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|; |
|
1001 |
$row{description}{data} = qq|<input name="description_$i" size=40 value="$form->{"description_$i"}">|; |
|
1002 |
$row{partsgroup}{data} = qq|<input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}">|; |
|
1003 |
} |
|
1004 |
# other rows |
|
1005 |
} else { |
|
1006 |
if ($form->{previousform}) { |
|
1007 |
push @row_hiddens, qw(qty bom); |
|
1008 |
$row{partnumber}{data} = $form->{"partnumber_$i"}; |
|
1009 |
$row{qty}{data} = $form->{"qty_$i"}; |
|
1010 |
$row{bom}{data} = $form->{"bom_$i"} ? "x" : " "; |
|
1011 |
$row{qty}{align} = 'right'; |
|
1012 |
} else { |
|
1013 |
$row{partnumber}{data} = qq|$form->{"partnumber_$i"}|; |
|
1014 |
$row{partnumber}{link} = $href; |
|
1015 |
$row{qty}{data} = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|; |
|
1016 |
$row{runningnumber}{data} = qq|<input name="runningnumber_$i" size=3 value="$i">|; |
|
1017 |
$row{bom}{data} = sprintf qq|<input name="bom_$i" type=checkbox class=checkbox value=1 %s>|, |
|
1018 |
$form->{"bom_$i"} ? 'checked' : ''; |
|
1019 |
} |
|
1020 |
push @row_hiddens, qw(unit description partnumber partsgroup); |
|
1021 |
$row{unit}{data} = $form->{"unit_$i"}; |
|
1022 |
#Bei der Artikelbeschreibung und Warengruppe können Sonderzeichen verwendet |
|
1023 |
#werden, die den HTML Code stören. Daher sollen diese im Template escaped werden |
|
1024 |
#dies geschieht, wenn die Variable escape gesetzt ist |
|
1025 |
$row{description}{data} = $form->{"description_$i"}; |
|
1026 |
$row{description}{escape} = 1; |
|
1027 |
$row{partsgroup}{data} = $form->{"partsgroup_$i"}; |
|
1028 |
$row{partsgroup}{escape} = 1; |
|
1029 |
$row{bom}{align} = 'center'; |
|
1030 |
} |
|
1031 |
|
|
1032 |
$row{lastcost}{data} = $line_purchase_price; |
|
1033 |
$row{total}{data} = $linetotal; |
|
1034 |
$row{lastcost}{align} = 'right'; |
|
1035 |
$row{total}{align} = 'right'; |
|
1036 |
$row{deliverydate}{align} = 'right'; |
|
1037 |
|
|
1038 |
push @row_hiddens, qw(id sellprice lastcost weight price_factor_id price_factor); |
|
1039 |
$row{hiddens} = [ map +{ name => "${_}_$i", value => $form->{"${_}_$i"} }, @row_hiddens ]; |
|
1040 |
|
|
1041 |
push @ROWS, \%row; |
|
1042 |
} |
|
1043 |
|
|
1044 |
print $form->parse_html_template('ic/assembly_row', { COLUMNS => \@column_index, ROWS => \@ROWS, HEADER => \%header }); |
|
1045 |
|
|
1046 |
$lxdebug->leave_sub(); |
|
1047 |
} |
|
1048 |
|
|
1049 |
sub update { |
|
1050 |
$lxdebug->enter_sub(); |
|
1051 |
|
|
1052 |
$auth->assert('part_service_assembly_edit'); |
|
1053 |
|
|
1054 |
# update checks whether pricegroups, makemodels or assembly items have been changed/added |
|
1055 |
# new items might have been added (and the original form might have been stored and restored) |
|
1056 |
# so at the end the ic form is run through check_form in io.pl |
|
1057 |
# The various combination of events can lead to problems with the order of parse_amount and format_amount |
|
1058 |
# Currently check_form parses some variables in assembly mode, but not in article or service mode |
|
1059 |
# This will only ever really be sanely resolved with a rewrite... |
|
1060 |
|
|
1061 |
# parse pricegroups. and no, don't rely on check_form for this... |
|
1062 |
map { $form->{"price_$_"} = $form->parse_amount(\%myconfig, $form->{"price_$_"}) } 1 .. $form->{price_rows}; |
|
1063 |
|
|
1064 |
unless ($form->{part_type} eq 'assembly') { |
|
1065 |
# for assemblies check_form will parse sellprice and listprice, but not for parts or services |
|
1066 |
$form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) for qw(sellprice listprice ve gv); |
|
1067 |
}; |
|
1068 |
|
|
1069 |
if ($form->{part_type} eq 'part') { |
|
1070 |
$form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) for qw(weight rop); |
|
1071 |
} |
|
1072 |
|
|
1073 |
# same for makemodel lastcosts |
|
1074 |
# but parse_amount not necessary for assembly component lastcosts |
|
1075 |
unless ($form->{part_type} eq "assembly") { |
|
1076 |
map { $form->{"lastcost_$_"} = $form->parse_amount(\%myconfig, $form->{"lastcost_$_"}) } 1 .. $form->{"makemodel_rows"}; |
|
1077 |
$form->{lastcost} = $form->parse_amount(\%myconfig, $form->{lastcost}); |
|
1078 |
} |
|
1079 |
|
|
1080 |
if ($form->{part_type} eq "assembly") { |
|
1081 |
my $i = $form->{assembly_rows}; |
|
1082 |
|
|
1083 |
# if last row is empty check the form otherwise retrieve item |
|
1084 |
if ( ($form->{"partnumber_$i"} eq "") |
|
1085 |
&& ($form->{"description_$i"} eq "") |
|
1086 |
&& ($form->{"partsgroup_$i"} eq "")) { |
|
1087 |
# no new assembly item was added |
|
1088 |
|
|
1089 |
&check_form; |
|
1090 |
|
|
1091 |
} else { |
|
1092 |
# search db for newly added assemblyitems, via partnumber or description |
|
1093 |
IC->assembly_item(\%myconfig, \%$form); |
|
1094 |
|
|
1095 |
# form->{item_list} contains the possible matches, next check whether the |
|
1096 |
# match is unique or we need to call the page to select the item |
|
1097 |
my $rows = scalar @{ $form->{item_list} }; |
|
1098 |
|
|
1099 |
if ($rows) { |
|
1100 |
$form->{"qty_$i"} = 1 unless ($form->{"qty_$i"}); |
|
1101 |
|
|
1102 |
if ($rows > 1) { |
|
1103 |
$form->{makemodel_rows}--; |
|
1104 |
select_item(mode => 'IC', pre_entered_qty => $form->parse_amount(\%myconfig, $form->{"qty_$i"})); |
|
1105 |
$::dispatcher->end_request; |
|
1106 |
} else { |
|
1107 |
map { $form->{item_list}[$i]{$_} =~ s/\"/"/g } |
|
1108 |
qw(partnumber description unit partsgroup); |
|
1109 |
map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } |
|
1110 |
keys %{ $form->{item_list}[0] }; |
|
1111 |
$form->{"runningnumber_$i"} = $form->{assembly_rows}; |
|
1112 |
$form->{assembly_rows}++; |
|
1113 |
|
|
1114 |
&check_form; |
|
1115 |
|
|
1116 |
} |
|
1117 |
|
|
1118 |
} else { |
|
1119 |
|
|
1120 |
$form->{rowcount} = $i; |
|
1121 |
$form->{assembly_rows}++; |
|
1122 |
|
|
1123 |
&new_item; |
|
1124 |
|
|
1125 |
} |
|
1126 |
} |
|
1127 |
|
|
1128 |
} elsif (($form->{part_type} eq 'part') || ($form->{part_type} eq 'service')) { |
|
1129 |
&check_form; |
|
1130 |
} |
|
1131 |
|
|
1132 |
$lxdebug->leave_sub(); |
|
1133 |
} |
|
1134 |
|
|
1135 |
sub save { |
|
1136 |
$lxdebug->enter_sub(); |
|
1137 |
|
|
1138 |
$auth->assert('part_service_assembly_edit'); |
|
1139 |
$::form->mtime_ischanged('parts'); |
|
1140 |
my ($parts_id, %newform, $amount, $callback); |
|
1141 |
|
|
1142 |
# check if there is a part number - commented out, cause there is an automatic allocation of numbers |
|
1143 |
# $form->isblank("partnumber", $locale->text(ucfirst $form->{part_type}." Part Number missing!")); |
|
1144 |
|
|
1145 |
# check if there is a description |
|
1146 |
$form->isblank("description", $locale->text("Part Description missing!")); |
|
1147 |
|
|
1148 |
$form->error($locale->text("Inventory quantity must be zero before you can set this $form->{part_type} obsolete!")) |
|
1149 |
if $form->{obsolete} && $form->{onhand} * 1 && $form->{part_type} ne 'service'; |
|
1150 |
|
|
1151 |
if (!$form->{buchungsgruppen_id}) { |
|
1152 |
$form->error($locale->text("Parts must have an entry type.") . " " . |
|
1153 |
$locale->text("If you see this message, you most likely just setup your LX-Office and haven't added any entry types. If this is the case, the option is accessible for administrators in the System menu.") |
|
1154 |
); |
|
1155 |
} |
|
1156 |
|
|
1157 |
$form->error($locale->text('Description must not be empty!')) unless $form->{description}; |
|
1158 |
$form->error($locale->text('Partnumber must not be set to empty!')) if $form->{id} && !$form->{partnumber}; |
|
1159 |
|
|
1160 |
# undef warehouse_id if the empty value is selected |
|
1161 |
if ( ($form->{warehouse_id} == 0) && ($form->{bin_id} == 0) ) { |
|
1162 |
undef $form->{warehouse_id}; |
|
1163 |
undef $form->{bin_id}; |
|
1164 |
} |
|
1165 |
# save part |
|
1166 |
if (IC->save(\%myconfig, \%$form) == 3) { |
|
1167 |
$form->error($locale->text('Partnumber not unique!')); |
|
1168 |
} |
|
1169 |
# saving the history |
|
1170 |
if(!exists $form->{addition}) { |
|
1171 |
$form->{snumbers} = qq|partnumber_| . $form->{partnumber}; |
|
1172 |
$form->{what_done} = "part"; |
|
1173 |
$form->{addition} = "SAVED"; |
|
1174 |
$form->save_history; |
|
1175 |
} |
|
1176 |
# /saving the history |
|
1177 |
$parts_id = $form->{id}; |
|
1178 |
|
|
1179 |
my $i; |
|
1180 |
# load previous variables |
|
1181 |
if ($form->{previousform}) { |
|
1182 |
|
|
1183 |
# save the new form variables before splitting previousform |
|
1184 |
map { $newform{$_} = $form->{$_} } keys %$form; |
|
1185 |
|
|
1186 |
# don't trample on previous variables |
|
1187 |
map { delete $form->{$_} } keys %newform; |
|
1188 |
|
|
1189 |
my $ic_cvar_configs = CVar->get_configs(module => 'IC'); |
|
1190 |
my @ic_cvar_fields = map { "cvar_$_->{name}" } @{ $ic_cvar_configs }; |
|
1191 |
|
|
1192 |
# restore original values |
|
1193 |
$::auth->restore_form_from_session($newform{previousform}, form => $form); |
|
1194 |
$form->{taxaccounts} = $newform{taxaccount2}; |
|
1195 |
|
|
1196 |
if ($form->{part_type} eq 'assembly') { |
|
1197 |
|
|
1198 |
# undo number formatting |
|
1199 |
map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } |
|
1200 |
qw(weight listprice sellprice rop); |
|
1201 |
|
|
1202 |
$form->{assembly_rows}--; |
|
1203 |
if ($newform{currow}) { |
|
1204 |
$i = $newform{currow}; |
|
1205 |
} else { |
|
1206 |
$i = $form->{assembly_rows}; |
|
1207 |
} |
|
1208 |
$form->{"qty_$i"} = 1 unless ($form->{"qty_$i"} > 0); |
|
1209 |
|
|
1210 |
$form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"}; |
|
1211 |
$form->{weight} -= $form->{"weight_$i"} * $form->{"qty_$i"}; |
|
1212 |
|
|
1213 |
# change/add values for assembly item |
|
1214 |
map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno price_factor_id); |
|
1215 |
map { $form->{"ic_${_}_$i"} = $newform{$_} } @ic_cvar_fields; |
|
1216 |
|
|
1217 |
# das ist __voll__ bekloppt, dass so auszurechnen jb 22.5.09 |
|
1218 |
#$form->{sellprice} += $form->{"sellprice_$i"} * $form->{"qty_$i"}; |
|
1219 |
$form->{weight} += $form->{"weight_$i"} * $form->{"qty_$i"}; |
|
1220 |
|
|
1221 |
} else { |
|
1222 |
|
|
1223 |
# set values for last invoice/order item |
|
1224 |
$i = $form->{rowcount}; |
|
1225 |
$form->{"qty_$i"} = 1 unless ($form->{"qty_$i"} > 0); |
|
1226 |
|
|
1227 |
map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit listprice inventory_accno income_accno expense_accno sellprice lastcost price_factor_id); |
|
1228 |
map { $form->{"ic_${_}_$i"} = $newform{$_} } @ic_cvar_fields; |
|
1229 |
|
|
1230 |
$form->{"longdescription_$i"} = $newform{notes}; |
|
1231 |
|
|
1232 |
$form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id}); |
|
1233 |
|
|
1234 |
if ($form->{exchangerate} != 0) { |
|
1235 |
$form->{"sellprice_$i"} /= $form->{exchangerate}; |
|
1236 |
} |
|
1237 |
|
|
1238 |
map { $form->{"taxaccounts_$i"} .= "$_ " } split / /, $newform{taxaccount}; |
|
1239 |
chop $form->{"taxaccounts_$i"}; |
|
1240 |
foreach my $item (qw(description rate taxnumber)) { |
|
1241 |
my $index = $form->{"taxaccounts_$i"} . "_$item"; |
|
1242 |
$form->{$index} = $newform{$index}; |
|
1243 |
} |
|
1244 |
|
|
1245 |
# credit remaining calculation |
|
1246 |
$amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"}; |
|
1247 |
|
|
1248 |
map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"}); |
|
1249 |
map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded}; |
|
1250 |
|
|
1251 |
$form->{creditremaining} -= $amount; |
|
1252 |
|
|
1253 |
# redo number formatting, because invoice parse them! |
|
1254 |
map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } qw(weight listprice sellprice lastcost rop); |
|
1255 |
} |
|
1256 |
|
|
1257 |
$form->{"id_$i"} = $parts_id; |
|
1258 |
|
|
1259 |
# Get the actual price factor (not just the ID) for the marge calculation. |
|
1260 |
$form->get_lists('price_factors' => 'ALL_PRICE_FACTORS'); |
|
1261 |
foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) { |
|
1262 |
next if ($pfac->{id} != $newform{price_factor_id}); |
|
1263 |
$form->{"marge_price_factor_$i"} = $pfac->{factor}; |
|
1264 |
last; |
|
1265 |
} |
|
1266 |
delete $form->{ALL_PRICE_FACTORS}; |
|
1267 |
|
|
1268 |
delete $form->{action}; |
|
1269 |
|
|
1270 |
# restore original callback |
|
1271 |
$callback = $form->unescape($form->{callback}); |
|
1272 |
$form->{callback} = $form->unescape($form->{old_callback}); |
|
1273 |
delete $form->{old_callback}; |
|
1274 |
|
|
1275 |
$form->{makemodel_rows}--; |
|
1276 |
|
|
1277 |
# put callback together |
|
1278 |
foreach my $key (keys %$form) { |
|
1279 |
|
|
1280 |
# do single escape for Apache 2.0 |
|
1281 |
my $value = $form->escape($form->{$key}, 1); |
|
1282 |
$callback .= qq|&$key=$value|; |
|
1283 |
} |
|
1284 |
$form->{callback} = $callback; |
|
1285 |
} |
|
1286 |
|
|
1287 |
# redirect |
|
1288 |
$form->redirect; |
|
1289 |
|
|
1290 |
$lxdebug->leave_sub(); |
|
1291 |
} |
|
1292 |
|
|
1293 |
sub save_as_new { |
|
1294 |
$lxdebug->enter_sub(); |
|
1295 |
|
|
1296 |
$auth->assert('part_service_assembly_edit'); |
|
1297 |
|
|
1298 |
# saving the history |
|
1299 |
if(!exists $form->{addition}) { |
|
1300 |
$form->{snumbers} = qq|partnumber_| . $form->{partnumber}; |
|
1301 |
$form->{addition} = "SAVED AS NEW"; |
|
1302 |
$form->{what_done} = "part"; |
|
1303 |
$form->save_history; |
|
1304 |
} |
|
1305 |
# /saving the history |
|
1306 |
|
|
1307 |
# deleting addition to get the history saved for the new part, too. |
|
1308 |
delete $form->{addition}; |
|
1309 |
|
|
1310 |
$form->{id} = 0; |
|
1311 |
if ($form->{"original_partnumber"} && |
|
1312 |
($form->{"partnumber"} eq $form->{"original_partnumber"})) { |
|
1313 |
$form->{partnumber} = ""; |
|
1314 |
} |
|
1315 |
&save; |
|
1316 |
$lxdebug->leave_sub(); |
|
1317 |
} |
|
1318 |
|
|
1319 |
sub delete { |
|
1320 |
$lxdebug->enter_sub(); |
|
1321 |
|
|
1322 |
$auth->assert('part_service_assembly_edit'); |
|
1323 |
|
|
1324 |
# saving the history |
|
1325 |
if(!exists $form->{addition}) { |
|
1326 |
$form->{snumbers} = qq|partnumber_| . $form->{partnumber}; |
|
1327 |
$form->{addition} = "DELETED"; |
|
1328 |
$form->{what_done} = "part"; |
|
1329 |
$form->save_history; |
|
1330 |
} |
|
1331 |
# /saving the history |
|
1332 |
my $rc = IC->delete(\%myconfig, \%$form); |
|
1333 |
|
|
1334 |
# redirect |
|
1335 |
$form->redirect($locale->text('Item deleted!')) if ($rc > 0); |
|
1336 |
$form->error($locale->text('Cannot delete item!')); |
|
1337 |
|
|
1338 |
$lxdebug->leave_sub(); |
|
1339 |
} |
|
1340 |
|
|
1341 |
sub price_row { |
|
1342 |
$lxdebug->enter_sub(); |
|
1343 |
|
|
1344 |
$auth->assert('part_service_assembly_details'); |
|
1345 |
|
|
1346 |
my ($numrows) = @_; |
|
1347 |
|
|
1348 |
my @PRICES = map +{ |
|
1349 |
pricegroup => $form->{"pricegroup_$_"}, |
|
1350 |
pricegroup_id => $form->{"pricegroup_id_$_"}, |
|
1351 |
price => $form->{"price_$_"}, |
|
1352 |
}, 1 .. $numrows; |
|
1353 |
|
|
1354 |
print $form->parse_html_template('ic/price_row', { PRICES => \@PRICES }); |
|
1355 |
|
|
1356 |
$lxdebug->leave_sub(); |
|
1357 |
} |
|
1358 |
|
|
1359 | 718 |
sub ajax_autocomplete { |
1360 | 719 |
$main::lxdebug->enter_sub(); |
1361 | 720 |
|
... | ... | |
1375 | 734 |
$main::lxdebug->leave_sub(); |
1376 | 735 |
} |
1377 | 736 |
|
1378 |
sub display_form { |
|
1379 |
$::lxdebug->enter_sub; |
|
1380 |
|
|
1381 |
$auth->assert('part_service_assembly_edit'); |
|
1382 |
|
|
1383 |
relink_accounts(); |
|
1384 |
|
|
1385 |
$::form->language_payment(\%::myconfig); |
|
1386 |
|
|
1387 |
Common::webdav_folder($::form); |
|
1388 |
|
|
1389 |
form_header(); |
|
1390 |
price_row($::form->{price_rows}); |
|
1391 |
makemodel_row(++$::form->{makemodel_rows}) if $::form->{part_type} =~ /^(part|service)$/; |
|
1392 |
assembly_row(++$::form->{assembly_rows}) if $::form->{part_type} eq 'assembly'; |
|
1393 |
|
|
1394 |
form_footer(); |
|
1395 |
|
|
1396 |
$::lxdebug->leave_sub; |
|
1397 |
} |
|
1398 |
|
|
1399 | 737 |
sub back_to_record { |
1400 | 738 |
_check_io_auth(); |
1401 | 739 |
|
Auch abrufbar als: Unified diff
Part Controller - ic.pl und IC.pm Funktionen entfernt