Revision 89b26688
Von Sven Schöling vor etwa 10 Jahren hinzugefügt
SL/DB/MetaSetup/DeliveryOrderItem.pm | ||
---|---|---|
9 | 9 |
__PACKAGE__->meta->table('delivery_order_items'); |
10 | 10 |
|
11 | 11 |
__PACKAGE__->meta->columns( |
12 |
base_qty => { type => 'float', scale => 4 }, |
|
13 |
cusordnumber => { type => 'text' }, |
|
14 |
delivery_order_id => { type => 'integer', not_null => 1 }, |
|
15 |
description => { type => 'text' }, |
|
16 |
discount => { type => 'float', scale => 4 }, |
|
17 |
id => { type => 'integer', not_null => 1, sequence => 'delivery_order_items_id' }, |
|
18 |
itime => { type => 'timestamp', default => 'now()' }, |
|
19 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
20 |
longdescription => { type => 'text' }, |
|
21 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
22 |
mtime => { type => 'timestamp' }, |
|
23 |
ordnumber => { type => 'text' }, |
|
24 |
parts_id => { type => 'integer', not_null => 1 }, |
|
25 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
26 |
price_factor_id => { type => 'integer' }, |
|
27 |
pricegroup_id => { type => 'integer' }, |
|
28 |
project_id => { type => 'integer' }, |
|
29 |
qty => { type => 'numeric', precision => 25, scale => 5 }, |
|
30 |
reqdate => { type => 'date' }, |
|
31 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
32 |
serialnumber => { type => 'text' }, |
|
33 |
transdate => { type => 'text' }, |
|
34 |
unit => { type => 'varchar', length => 20 }, |
|
35 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
12 |
active_discount_source => { type => 'text', default => '', not_null => 1 }, |
|
13 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
14 |
base_qty => { type => 'float', scale => 4 }, |
|
15 |
cusordnumber => { type => 'text' }, |
|
16 |
delivery_order_id => { type => 'integer', not_null => 1 }, |
|
17 |
description => { type => 'text' }, |
|
18 |
discount => { type => 'float', scale => 4 }, |
|
19 |
id => { type => 'integer', not_null => 1, sequence => 'delivery_order_items_id' }, |
|
20 |
itime => { type => 'timestamp', default => 'now()' }, |
|
21 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
22 |
longdescription => { type => 'text' }, |
|
23 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
24 |
mtime => { type => 'timestamp' }, |
|
25 |
ordnumber => { type => 'text' }, |
|
26 |
parts_id => { type => 'integer', not_null => 1 }, |
|
27 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
28 |
price_factor_id => { type => 'integer' }, |
|
29 |
pricegroup_id => { type => 'integer' }, |
|
30 |
project_id => { type => 'integer' }, |
|
31 |
qty => { type => 'numeric', precision => 25, scale => 5 }, |
|
32 |
reqdate => { type => 'date' }, |
|
33 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
34 |
serialnumber => { type => 'text' }, |
|
35 |
transdate => { type => 'text' }, |
|
36 |
unit => { type => 'varchar', length => 20 }, |
|
36 | 37 |
); |
37 | 38 |
|
38 | 39 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
SL/DB/MetaSetup/InvoiceItem.pm | ||
---|---|---|
9 | 9 |
__PACKAGE__->meta->table('invoice'); |
10 | 10 |
|
11 | 11 |
__PACKAGE__->meta->columns( |
12 |
allocated => { type => 'float', scale => 4 }, |
|
13 |
assemblyitem => { type => 'boolean', default => 'false' }, |
|
14 |
base_qty => { type => 'float', scale => 4 }, |
|
15 |
cusordnumber => { type => 'text' }, |
|
16 |
deliverydate => { type => 'date' }, |
|
17 |
description => { type => 'text' }, |
|
18 |
discount => { type => 'float', scale => 4 }, |
|
19 |
donumber => { type => 'text' }, |
|
20 |
fxsellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
21 |
id => { type => 'integer', not_null => 1, sequence => 'invoiceid' }, |
|
22 |
itime => { type => 'timestamp', default => 'now()' }, |
|
23 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
24 |
longdescription => { type => 'text' }, |
|
25 |
marge_percent => { type => 'numeric', precision => 15, scale => 5 }, |
|
26 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
27 |
marge_total => { type => 'numeric', precision => 15, scale => 5 }, |
|
28 |
mtime => { type => 'timestamp' }, |
|
29 |
ordnumber => { type => 'text' }, |
|
30 |
parts_id => { type => 'integer' }, |
|
31 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
32 |
price_factor_id => { type => 'integer' }, |
|
33 |
pricegroup_id => { type => 'integer' }, |
|
34 |
project_id => { type => 'integer' }, |
|
35 |
qty => { type => 'float', scale => 4 }, |
|
36 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
37 |
serialnumber => { type => 'text' }, |
|
38 |
subtotal => { type => 'boolean', default => 'false' }, |
|
39 |
trans_id => { type => 'integer' }, |
|
40 |
transdate => { type => 'text' }, |
|
41 |
unit => { type => 'varchar', length => 20 }, |
|
42 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
12 |
active_discount_source => { type => 'text', default => '', not_null => 1 }, |
|
13 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
14 |
allocated => { type => 'float', scale => 4 }, |
|
15 |
assemblyitem => { type => 'boolean', default => 'false' }, |
|
16 |
base_qty => { type => 'float', scale => 4 }, |
|
17 |
cusordnumber => { type => 'text' }, |
|
18 |
deliverydate => { type => 'date' }, |
|
19 |
description => { type => 'text' }, |
|
20 |
discount => { type => 'float', scale => 4 }, |
|
21 |
donumber => { type => 'text' }, |
|
22 |
fxsellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
23 |
id => { type => 'integer', not_null => 1, sequence => 'invoiceid' }, |
|
24 |
itime => { type => 'timestamp', default => 'now()' }, |
|
25 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
26 |
longdescription => { type => 'text' }, |
|
27 |
marge_percent => { type => 'numeric', precision => 15, scale => 5 }, |
|
28 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
29 |
marge_total => { type => 'numeric', precision => 15, scale => 5 }, |
|
30 |
mtime => { type => 'timestamp' }, |
|
31 |
ordnumber => { type => 'text' }, |
|
32 |
parts_id => { type => 'integer' }, |
|
33 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
34 |
price_factor_id => { type => 'integer' }, |
|
35 |
pricegroup_id => { type => 'integer' }, |
|
36 |
project_id => { type => 'integer' }, |
|
37 |
qty => { type => 'float', scale => 4 }, |
|
38 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
39 |
serialnumber => { type => 'text' }, |
|
40 |
subtotal => { type => 'boolean', default => 'false' }, |
|
41 |
trans_id => { type => 'integer' }, |
|
42 |
transdate => { type => 'text' }, |
|
43 |
unit => { type => 'varchar', length => 20 }, |
|
43 | 44 |
); |
44 | 45 |
|
45 | 46 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
SL/DB/MetaSetup/OrderItem.pm | ||
---|---|---|
9 | 9 |
__PACKAGE__->meta->table('orderitems'); |
10 | 10 |
|
11 | 11 |
__PACKAGE__->meta->columns( |
12 |
base_qty => { type => 'float', scale => 4 }, |
|
13 |
cusordnumber => { type => 'text' }, |
|
14 |
description => { type => 'text' }, |
|
15 |
discount => { type => 'float', scale => 4 }, |
|
16 |
id => { type => 'integer', not_null => 1, sequence => 'orderitemsid' }, |
|
17 |
itime => { type => 'timestamp', default => 'now()' }, |
|
18 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
19 |
longdescription => { type => 'text' }, |
|
20 |
marge_percent => { type => 'numeric', precision => 15, scale => 5 }, |
|
21 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
22 |
marge_total => { type => 'numeric', precision => 15, scale => 5 }, |
|
23 |
mtime => { type => 'timestamp' }, |
|
24 |
ordnumber => { type => 'text' }, |
|
25 |
parts_id => { type => 'integer' }, |
|
26 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
27 |
price_factor_id => { type => 'integer' }, |
|
28 |
pricegroup_id => { type => 'integer' }, |
|
29 |
project_id => { type => 'integer' }, |
|
30 |
qty => { type => 'float', scale => 4 }, |
|
31 |
reqdate => { type => 'date' }, |
|
32 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
33 |
serialnumber => { type => 'text' }, |
|
34 |
ship => { type => 'float', scale => 4 }, |
|
35 |
subtotal => { type => 'boolean', default => 'false' }, |
|
36 |
trans_id => { type => 'integer' }, |
|
37 |
transdate => { type => 'text' }, |
|
38 |
unit => { type => 'varchar', length => 20 }, |
|
39 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
12 |
active_discount_source => { type => 'text', default => '', not_null => 1 }, |
|
13 |
active_price_source => { type => 'text', default => '', not_null => 1 }, |
|
14 |
base_qty => { type => 'float', scale => 4 }, |
|
15 |
cusordnumber => { type => 'text' }, |
|
16 |
description => { type => 'text' }, |
|
17 |
discount => { type => 'float', scale => 4 }, |
|
18 |
id => { type => 'integer', not_null => 1, sequence => 'orderitemsid' }, |
|
19 |
itime => { type => 'timestamp', default => 'now()' }, |
|
20 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
|
21 |
longdescription => { type => 'text' }, |
|
22 |
marge_percent => { type => 'numeric', precision => 15, scale => 5 }, |
|
23 |
marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
24 |
marge_total => { type => 'numeric', precision => 15, scale => 5 }, |
|
25 |
mtime => { type => 'timestamp' }, |
|
26 |
ordnumber => { type => 'text' }, |
|
27 |
parts_id => { type => 'integer' }, |
|
28 |
price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 }, |
|
29 |
price_factor_id => { type => 'integer' }, |
|
30 |
pricegroup_id => { type => 'integer' }, |
|
31 |
project_id => { type => 'integer' }, |
|
32 |
qty => { type => 'float', scale => 4 }, |
|
33 |
reqdate => { type => 'date' }, |
|
34 |
sellprice => { type => 'numeric', precision => 15, scale => 5 }, |
|
35 |
serialnumber => { type => 'text' }, |
|
36 |
ship => { type => 'float', scale => 4 }, |
|
37 |
subtotal => { type => 'boolean', default => 'false' }, |
|
38 |
trans_id => { type => 'integer' }, |
|
39 |
transdate => { type => 'text' }, |
|
40 |
unit => { type => 'varchar', length => 20 }, |
|
40 | 41 |
); |
41 | 42 |
|
42 | 43 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
SL/DO.pm | ||
---|---|---|
285 | 285 |
sellprice, discount, unit, reqdate, project_id, serialnumber, |
286 | 286 |
ordnumber, transdate, cusordnumber, |
287 | 287 |
lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id, |
288 |
active_price_source) |
|
288 |
active_price_source, active_discount_source)
|
|
289 | 289 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, |
290 |
(SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?)|; |
|
290 |
(SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?, ?)|;
|
|
291 | 291 |
my $h_item = prepare_query($form, $dbh, $q_item); |
292 | 292 |
|
293 | 293 |
my $q_item_stock = |
... | ... | |
343 | 343 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), |
344 | 344 |
conv_i($form->{"marge_price_factor_$i"}), |
345 | 345 |
$pricegroup_id, |
346 |
$form->{"active_price_source_$i"}); |
|
346 |
$form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"});
|
|
347 | 347 |
do_statement($form, $h_item, $q_item, @values); |
348 | 348 |
|
349 | 349 |
my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"}); |
... | ... | |
690 | 690 |
doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost, |
691 | 691 |
doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription, |
692 | 692 |
doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id, |
693 |
doi.active_price_source, |
|
693 |
doi.active_price_source, doi.active_discount_source,
|
|
694 | 694 |
pr.projectnumber, dord.transdate AS dord_transdate, dord.donumber, |
695 | 695 |
pg.partsgroup |
696 | 696 |
FROM delivery_order_items doi |
SL/IR.pm | ||
---|---|---|
381 | 381 |
$query = |
382 | 382 |
qq|INSERT INTO invoice (id, trans_id, parts_id, description, longdescription, qty, base_qty, |
383 | 383 |
sellprice, fxsellprice, discount, allocated, unit, deliverydate, |
384 |
project_id, serialnumber, price_factor_id, price_factor, marge_price_factor) |
|
385 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT factor FROM price_factors WHERE id = ?), ?, ?)|; |
|
384 |
project_id, serialnumber, price_factor_id, price_factor, marge_price_factor, |
|
385 |
active_price_source, active_discount_source) |
|
386 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?)|; |
|
386 | 387 |
@values = ($invoice_id, conv_i($form->{id}), conv_i($form->{"id_$i"}), |
387 | 388 |
$form->{"description_$i"}, $restricter->process($form->{"longdescription_$i"}), $form->{"qty_$i"} * -1, |
388 | 389 |
$baseqty * -1, $form->{"sellprice_$i"}, $fxsellprice, $form->{"discount_$i"}, $allocated, |
389 | 390 |
$form->{"unit_$i"}, conv_date($form->{deliverydate}), |
390 | 391 |
conv_i($form->{"project_id_$i"}), $form->{"serialnumber_$i"}, |
391 | 392 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"marge_price_factor_$i"}), |
392 |
conv_i($form->{"active_price_source_$i"}), |
|
393 |
conv_i($form->{"active_price_source_$i"}), conv_i($form->{"active_discount_source_$i"}),
|
|
393 | 394 |
); |
394 | 395 |
do_query($form, $dbh, $query, @values); |
395 | 396 |
|
... | ... | |
978 | 979 |
|
979 | 980 |
i.id AS invoice_id, |
980 | 981 |
i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.parts_id AS id, i.unit, i.deliverydate, i.project_id, i.serialnumber, |
981 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.discount, i.active_price_source, |
|
982 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.discount, i.active_price_source, i.active_discount_source,
|
|
982 | 983 |
p.partnumber, p.inventory_accno_id AS part_inventory_accno_id, pr.projectnumber, pg.partsgroup |
983 | 984 |
|
984 | 985 |
FROM invoice i |
SL/IS.pm | ||
---|---|---|
761 | 761 |
sellprice, fxsellprice, discount, allocated, assemblyitem, |
762 | 762 |
unit, deliverydate, project_id, serialnumber, pricegroup_id, |
763 | 763 |
ordnumber, donumber, transdate, cusordnumber, base_qty, subtotal, |
764 |
marge_percent, marge_total, lastcost, active_price_source, |
|
764 |
marge_percent, marge_total, lastcost, active_price_source, active_discount_source, |
|
765 |
|
|
765 | 766 |
price_factor_id, price_factor, marge_price_factor) |
766 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, |
|
767 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
|
767 | 768 |
(SELECT factor FROM price_factors WHERE id = ?), ?)|; |
768 | 769 |
|
769 | 770 |
@values = ($invoice_id, conv_i($form->{id}), conv_i($form->{"id_$i"}), |
... | ... | |
776 | 777 |
$form->{"cusordnumber_$i"}, $baseqty, $form->{"subtotal_$i"} ? 't' : 'f', |
777 | 778 |
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"}, |
778 | 779 |
$form->{"lastcost_$i"}, |
779 |
$form->{"active_price_source_$i"}, |
|
780 |
$form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"},
|
|
780 | 781 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), |
781 | 782 |
conv_i($form->{"marge_price_factor_$i"})); |
782 | 783 |
do_query($form, $dbh, $query, @values); |
... | ... | |
1678 | 1679 |
i.id AS invoice_id, |
1679 | 1680 |
i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.discount, i.parts_id AS id, i.unit, i.deliverydate AS reqdate, |
1680 | 1681 |
i.project_id, i.serialnumber, i.id AS invoice_pos, i.pricegroup_id, i.ordnumber, i.donumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost, |
1681 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.active_price_source, |
|
1682 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.active_price_source, i.active_discount_source,
|
|
1682 | 1683 |
p.partnumber, p.assembly, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, p.formel, p.listprice, |
1683 | 1684 |
pr.projectnumber, pg.partsgroup, prg.pricegroup |
1684 | 1685 |
|
SL/OE.pm | ||
---|---|---|
532 | 532 |
sellprice = ?, discount = ?, unit = ?, reqdate = ?, project_id = ?, serialnumber = ?, ship = ?, |
533 | 533 |
pricegroup_id = ?, ordnumber = ?, transdate = ?, cusordnumber = ?, subtotal = ?, |
534 | 534 |
marge_percent = ?, marge_total = ?, lastcost = ?, price_factor_id = ?, |
535 |
active_price_source = ?, |
|
535 |
active_price_source = ?, active_discount_source = ?,
|
|
536 | 536 |
price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ? |
537 | 537 |
WHERE id = ? |
538 | 538 |
SQL |
... | ... | |
547 | 547 |
$form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f', |
548 | 548 |
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"}, |
549 | 549 |
$form->{"lastcost_$i"}, |
550 |
$form->{"active_price_source_$i"}, |
|
550 |
$form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"},
|
|
551 | 551 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), |
552 | 552 |
conv_i($form->{"marge_price_factor_$i"}), |
553 | 553 |
conv_i($orderitems_id), |
... | ... | |
947 | 947 |
o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, |
948 | 948 |
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost, |
949 | 949 |
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription, |
950 |
o.price_factor_id, o.price_factor, o.marge_price_factor, o.active_price_source, |
|
950 |
o.price_factor_id, o.price_factor, o.marge_price_factor, o.active_price_source, o.active_discount_source,
|
|
951 | 951 |
pr.projectnumber, p.formel, |
952 | 952 |
pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup |
953 | 953 |
FROM orderitems o |
SL/PriceSource.pm | ||
---|---|---|
6 | 6 |
scalar => [ qw(record_item record) ], |
7 | 7 |
); |
8 | 8 |
|
9 |
use List::UtilsBy qw(min_by); |
|
9 |
use List::UtilsBy qw(min_by max_by);
|
|
10 | 10 |
use SL::PriceSource::ALL; |
11 | 11 |
use SL::PriceSource::Price; |
12 | 12 |
use SL::Locale::String; |
... | ... | |
14 | 14 |
sub all_price_sources { |
15 | 15 |
my ($self) = @_; |
16 | 16 |
|
17 |
return map {
|
|
17 |
map { |
|
18 | 18 |
$_->new(record_item => $self->record_item, record => $self->record) |
19 | 19 |
} SL::PriceSource::ALL->all_enabled_price_sources |
20 | 20 |
} |
... | ... | |
26 | 26 |
my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); |
27 | 27 |
|
28 | 28 |
return $class |
29 |
? $class->new(record_item => $self->record_item)->price_from_source($source, $spec) |
|
29 |
? $class->new(record_item => $self->record_item, record => $self->record)->price_from_source($source, $spec)
|
|
30 | 30 |
: empty_price(); |
31 | 31 |
} |
32 | 32 |
|
... | ... | |
34 | 34 |
map { $_->available_prices } $_[0]->all_price_sources; |
35 | 35 |
} |
36 | 36 |
|
37 |
sub available_discounts { |
|
38 |
map { $_->available_discounts } $_[0]->all_price_sources; |
|
39 |
} |
|
40 |
|
|
37 | 41 |
sub best_price { |
38 |
min_by { $_->price } grep { $_->price > 0 } map { $_->best_price } $_[0]->all_price_sources; |
|
42 |
min_by { $_->price } grep { $_->price > 0 } grep { $_ } map { $_->best_price } $_[0]->all_price_sources; |
|
43 |
} |
|
44 |
|
|
45 |
sub best_discount { |
|
46 |
max_by { $_->discount } grep { $_->discount } grep { $_ } map { $_->best_discount } $_[0]->all_price_sources; |
|
39 | 47 |
} |
40 | 48 |
|
41 | 49 |
sub empty_price { |
SL/PriceSource/ALL.pm | ||
---|---|---|
4 | 4 |
use SL::PriceSource::Pricegroup; |
5 | 5 |
use SL::PriceSource::MasterData; |
6 | 6 |
use SL::PriceSource::Makemodel; |
7 |
use SL::PriceSource::Customer; |
|
8 |
use SL::PriceSource::Vendor; |
|
9 |
use SL::PriceSource::Business; |
|
7 | 10 |
|
8 | 11 |
my %price_sources_by_name = ( |
9 | 12 |
master_data => 'SL::PriceSource::MasterData', |
13 |
customer => 'SL::PriceSource::Customer', |
|
14 |
vendor => 'SL::PriceSource::Vendor', |
|
10 | 15 |
pricegroup => 'SL::PriceSource::Pricegroup', |
11 | 16 |
makemodel => 'SL::PriceSource::Makemodel', |
17 |
business => 'SL::PriceSource::Business', |
|
12 | 18 |
); |
13 | 19 |
|
14 | 20 |
my @price_sources_order = qw( |
15 | 21 |
master_data |
22 |
customer |
|
23 |
vendor |
|
16 | 24 |
pricegroup |
17 | 25 |
makemodel |
26 |
business |
|
18 | 27 |
); |
19 | 28 |
|
20 | 29 |
sub all_enabled_price_sources { |
SL/PriceSource/Base.pm | ||
---|---|---|
13 | 13 |
|
14 | 14 |
sub available_prices { die 'available_prices needs to be implemented' } |
15 | 15 |
|
16 |
sub available_discounts { die 'available_discounts needs to be implemented' } |
|
17 |
|
|
16 | 18 |
sub best_price { die 'best_price needs to be implemented' } |
17 | 19 |
|
20 |
sub best_discounts { die 'best_discounts needs to be implemented' } |
|
21 |
|
|
18 | 22 |
sub price_from_source { die 'price_from_source needs to be implemented:' . "@_" } |
19 | 23 |
|
20 | 24 |
sub part { |
21 | 25 |
$_[0]->record_item->part; |
22 | 26 |
} |
23 | 27 |
|
28 |
sub customer_vendor { |
|
29 |
$_[0]->record->is_sales ? $_[0]->record->customer : $_[0]->record->vendor; |
|
30 |
} |
|
31 |
|
|
24 | 32 |
1; |
25 | 33 |
|
26 | 34 |
__END__ |
... | ... | |
98 | 106 |
|
99 | 107 |
Shortcut to C<< record_item->part >> |
100 | 108 |
|
109 |
=item C<customer_vendor> |
|
110 |
|
|
111 |
Shortcut to C<< record->is_sales ? record->customer : record->vendor >> |
|
112 |
|
|
101 | 113 |
=back |
102 | 114 |
|
103 | 115 |
=head1 INTERFACE METHODS |
... | ... | |
121 | 133 |
to recreate it later. Try to be brief, no one needs 20 different price |
122 | 134 |
suggestions. |
123 | 135 |
|
136 |
=item C<available_discounts> |
|
137 |
|
|
138 |
Must return a list of all prices that you algorithm can recommend the user |
|
139 |
for the current situation. Each discount must have a unique spec that can be |
|
140 |
used to recreate it later. Try to be brief, no one needs 20 different discount |
|
141 |
suggestions. |
|
142 |
|
|
124 | 143 |
=item C<best_price> |
125 | 144 |
|
126 | 145 |
Must return what you think of as the best matching price in your |
127 | 146 |
C<available_prices>. This does not have to be the lowest price, but it will be |
128 | 147 |
compared later to other price sources, and the lowest will be set. |
129 | 148 |
|
149 |
=item C<best_discount> |
|
150 |
|
|
151 |
Must return what you think of as the best matching discount in your |
|
152 |
C<available_discounts>. This does not have to be the highest discount, but it |
|
153 |
will be compared later to other price sources, and the highest will be set. |
|
154 |
|
|
130 | 155 |
=item C<price_from_source SOURCE, SPEC> |
131 | 156 |
|
132 |
Must recreate the price from C<SPEC> and return. For reference, the complete |
|
133 |
C<SOURCE> entry from C<record_item.active_price_source> is included. |
|
157 |
Must recreate the price or discount from C<SPEC> and return. For reference, the |
|
158 |
complete C<SOURCE> entry from C<record_item.active_price_source> or |
|
159 |
C<record_item.active_discount_source> is included. |
|
134 | 160 |
|
135 | 161 |
Note that constraints from the rest of the C<record> do not apply anymore. If |
136 | 162 |
information needed for the retrieval can be deleted elsewhere, then you must |
SL/PriceSource/Business.pm | ||
---|---|---|
1 |
package SL::PriceSource::Business; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::PriceSource::Base); |
|
5 |
|
|
6 |
use SL::DB::Business; |
|
7 |
use SL::PriceSource::Discount; |
|
8 |
use SL::Locale::String; |
|
9 |
|
|
10 |
sub name { 'business' } |
|
11 |
|
|
12 |
sub description { t8('Business') } |
|
13 |
|
|
14 |
sub available_prices { } |
|
15 |
|
|
16 |
sub available_discounts { |
|
17 |
my ($self, %params) = @_; |
|
18 |
|
|
19 |
return unless $self->customer_vendor; |
|
20 |
return unless $self->customer_vendor->business; |
|
21 |
return unless $self->customer_vendor->business->discount != 0; |
|
22 |
|
|
23 |
SL::PriceSource::Discount->new( |
|
24 |
discount => $self->customer_vendor->business->discount, |
|
25 |
spec => $self->customer_vendor->business->id, |
|
26 |
description => t8('Business Discount'), |
|
27 |
price_source => $self, |
|
28 |
); |
|
29 |
} |
|
30 |
|
|
31 |
sub price_from_source { |
|
32 |
my ($self, $source, $spec) = @_; |
|
33 |
|
|
34 |
my $business = SL::DB::Business->load_cached($spec); |
|
35 |
|
|
36 |
if (!$business) { |
|
37 |
return SL::PriceSource::Discount->new( |
|
38 |
missing => t8('Could not load this business'), |
|
39 |
price_source => $self, |
|
40 |
) |
|
41 |
} |
|
42 |
|
|
43 |
if (!$self->customer_vendor) { |
|
44 |
return SL::PriceSource::Discount->new( |
|
45 |
discount => $business->discount, |
|
46 |
spec => $business->id, |
|
47 |
description => t8('Business Discount'), |
|
48 |
price_source => $self, |
|
49 |
invalid => t8('This discount is only valid in records with customer or vendor'), |
|
50 |
) |
|
51 |
} |
|
52 |
|
|
53 |
if ($business->id != $self->customer_vendor->business->id) { |
|
54 |
return SL::PriceSource::Discount->new( |
|
55 |
discount => $business->discount, |
|
56 |
spec => $business->id, |
|
57 |
description => t8('Business Discount'), |
|
58 |
price_source => $self, |
|
59 |
invalid => t8('This discount is only valid for business #1', $business->full_description), |
|
60 |
) |
|
61 |
} |
|
62 |
|
|
63 |
return SL::PriceSource::Discount->new( |
|
64 |
discount => $business->discount, |
|
65 |
spec => $business->id, |
|
66 |
description => t8('Business Discount'), |
|
67 |
price_source => $self, |
|
68 |
); |
|
69 |
} |
|
70 |
|
|
71 |
sub best_price { } |
|
72 |
|
|
73 |
sub best_discount { |
|
74 |
&available_discounts; |
|
75 |
} |
|
76 |
|
|
77 |
1; |
|
78 |
|
SL/PriceSource/Customer.pm | ||
---|---|---|
1 |
package SL::PriceSource::Customer; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::PriceSource::Base); |
|
5 |
|
|
6 |
use SL::DB::Customer; |
|
7 |
use SL::PriceSource::Discount; |
|
8 |
use SL::Locale::String; |
|
9 |
|
|
10 |
sub name { 'customer_discount' } |
|
11 |
|
|
12 |
sub description { t8('Customer Discount') } |
|
13 |
|
|
14 |
sub available_prices { } |
|
15 |
|
|
16 |
sub available_discounts { |
|
17 |
my ($self, %params) = @_; |
|
18 |
|
|
19 |
return unless $self->record->is_sales; |
|
20 |
return unless $self->record->customer; |
|
21 |
return unless $self->record->customer->discount != 0; |
|
22 |
|
|
23 |
SL::PriceSource::Discount->new( |
|
24 |
discount => $self->record->customer->discount, |
|
25 |
spec => $self->record->customer->id, |
|
26 |
description => t8('Customer Discount'), |
|
27 |
price_source => $self, |
|
28 |
); |
|
29 |
} |
|
30 |
|
|
31 |
sub price_from_source { |
|
32 |
my ($self, $source, $spec) = @_; |
|
33 |
|
|
34 |
my $customer = SL::DB::Customer->load_cached($spec); |
|
35 |
|
|
36 |
if (!$customer) { |
|
37 |
return SL::PriceSource::Discount->new( |
|
38 |
missing => t8('Could not load this customer'), |
|
39 |
price_source => $self, |
|
40 |
) |
|
41 |
} |
|
42 |
|
|
43 |
if (!$self->record->customer) { |
|
44 |
return SL::PriceSource::Discount->new( |
|
45 |
discount => $customer->discount, |
|
46 |
spec => $customer->id, |
|
47 |
description => t8('Customer Discount'), |
|
48 |
price_source => $self, |
|
49 |
invalid => t8('This discount is only valid in sales documents'), |
|
50 |
) |
|
51 |
} |
|
52 |
|
|
53 |
if ($customer->id != $self->record->customer->id) { |
|
54 |
return SL::PriceSource::Discount->new( |
|
55 |
discount => $customer->discount, |
|
56 |
spec => $customer->id, |
|
57 |
description => t8('Customer Discount'), |
|
58 |
price_source => $self, |
|
59 |
invalid => t8('This discount is only valid for customer #1', $customer->full_description), |
|
60 |
) |
|
61 |
} |
|
62 |
|
|
63 |
return SL::PriceSource::Discount->new( |
|
64 |
discount => $customer->discount, |
|
65 |
spec => $customer->id, |
|
66 |
description => t8('Customer Discount'), |
|
67 |
price_source => $self, |
|
68 |
); |
|
69 |
} |
|
70 |
|
|
71 |
sub best_price { } |
|
72 |
|
|
73 |
sub best_discount { |
|
74 |
&available_discounts; |
|
75 |
} |
|
76 |
|
|
77 |
1; |
|
78 |
|
SL/PriceSource/Discount.pm | ||
---|---|---|
1 |
package SL::PriceSource::Discount; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent 'SL::DB::Object'; |
|
6 |
use Rose::Object::MakeMethods::Generic ( |
|
7 |
scalar => [ qw(discount description spec price_source invalid missing) ], |
|
8 |
); |
|
9 |
|
|
10 |
require SL::DB::Helper::Attr; |
|
11 |
SL::DB::Helper::Attr::make(__PACKAGE__, |
|
12 |
discount => 'numeric(15,5)', |
|
13 |
); |
|
14 |
|
|
15 |
sub source { |
|
16 |
$_[0]->price_source |
|
17 |
? $_[0]->price_source->name . '/' . $_[0]->spec |
|
18 |
: ''; |
|
19 |
} |
|
20 |
|
|
21 |
sub full_description { |
|
22 |
my ($self) = @_; |
|
23 |
|
|
24 |
$self->price_source |
|
25 |
? $self->price_source->description . ': ' . $self->description |
|
26 |
: $self->description |
|
27 |
} |
|
28 |
|
|
29 |
sub source_description { |
|
30 |
my ($self) = @_; |
|
31 |
|
|
32 |
$self->price_source |
|
33 |
? $self->price_source->description |
|
34 |
: $self->description |
|
35 |
} |
|
36 |
|
|
37 |
sub to_str { |
|
38 |
"source: @{[ $_[0]->source ]}, discount: @{[ $_[0]->discount ]}, description: @{[ $_[0]->description ]}" |
|
39 |
} |
|
40 |
|
|
41 |
1; |
|
42 |
|
|
43 |
__END__ |
|
44 |
|
|
45 |
=encoding utf-8 |
|
46 |
|
|
47 |
=head1 NAME |
|
48 |
|
|
49 |
SL::PriceSource::Price - contrainer to pass calculated prices around |
|
50 |
|
|
51 |
=head1 SYNOPSIS |
|
52 |
|
|
53 |
# in PriceSource::Base implementation |
|
54 |
$price = SL::PriceSource::Price->new( |
|
55 |
discount => 10, |
|
56 |
spec => 'summersale2014', # something you can easily parse later |
|
57 |
description => t8('10% discount during summer sale 2014'), |
|
58 |
price_source => $self, |
|
59 |
) |
|
60 |
|
|
61 |
# special empty price in SL::PriceSource, for internal use. |
|
62 |
SL::PriceSource::Price->new( |
|
63 |
description => t8('None (PriceSource)'), |
|
64 |
); |
|
65 |
|
|
66 |
# price can't be restored |
|
67 |
SL::PriceSource::Price->new( |
|
68 |
missing => t8('Um, sorry, cannot find that one'), |
|
69 |
price_source => $self, |
|
70 |
); |
|
71 |
|
|
72 |
# invalid price |
|
73 |
SL::PriceSource::Price->new( |
|
74 |
price => $original_price, |
|
75 |
spec => $original_spec, |
|
76 |
description => $original_description, |
|
77 |
invalid => t8('Offer expired #1 weeks ago', $dt->delta_weeks), |
|
78 |
price_source => $self, |
|
79 |
); |
|
80 |
|
|
81 |
=head1 DESCRIPTION |
|
82 |
|
|
83 |
See L<SL::PriceSource> for information about the mechanism. |
|
84 |
|
|
85 |
This is a container for prices that are generated by L<SL::PriceSource::Base> |
|
86 |
implementations. |
|
87 |
|
|
88 |
=head1 CONSTRUCTOR FIELDS |
|
89 |
|
|
90 |
=over 4 |
|
91 |
|
|
92 |
=item C<discount> |
|
93 |
|
|
94 |
The discount in percent. A discount of 0 will be ignored. If passed as |
|
95 |
part of C<available_prices> it will be filtered out. If returned as |
|
96 |
C<best_price> or C<price_from_source> it will trigger a warning. |
|
97 |
|
|
98 |
=item C<spec> |
|
99 |
|
|
100 |
A unique string that can later be understood by the creating implementation. |
|
101 |
Can be empty if the implementation only supports one price for a given |
|
102 |
record_item. |
|
103 |
|
|
104 |
=item C<description> |
|
105 |
|
|
106 |
A localized short description of the origins of this price. |
|
107 |
|
|
108 |
=item C<price_source> |
|
109 |
|
|
110 |
A ref to the creating algorithm. |
|
111 |
|
|
112 |
=item C<missing> |
|
113 |
|
|
114 |
OPTIONAL. Both indicator and localized message that the price with this spec |
|
115 |
could not be reproduced and should be changed. |
|
116 |
|
|
117 |
If price is missing, you do not need to supply anything except C<source>. |
|
118 |
|
|
119 |
=item C<invalid> |
|
120 |
|
|
121 |
OPTIONAL. Both indicator and localized message that the conditions for this |
|
122 |
price are no longer valid, and that the price should be changed. |
|
123 |
|
|
124 |
If price is missing, you do not need to supply anything except C<source>. |
|
125 |
|
|
126 |
=back |
|
127 |
|
|
128 |
=head1 SEE ALSO |
|
129 |
|
|
130 |
L<SL::PriceSource>, |
|
131 |
L<SL::PriceSource::Base>, |
|
132 |
L<SL::PriceSource::ALL> |
|
133 |
|
|
134 |
=head1 BUGS |
|
135 |
|
|
136 |
None yet. :) |
|
137 |
|
|
138 |
=head1 AUTHOR |
|
139 |
|
|
140 |
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt> |
|
141 |
|
|
142 |
=cut |
SL/PriceSource/Makemodel.pm | ||
---|---|---|
23 | 23 |
$self->part->makemodels; |
24 | 24 |
} |
25 | 25 |
|
26 |
sub available_discounts { } |
|
27 |
|
|
26 | 28 |
sub price_from_source { |
27 | 29 |
my ($self, $source, $spec) = @_; |
28 | 30 |
|
... | ... | |
42 | 44 |
|
43 | 45 |
} |
44 | 46 |
|
47 |
sub best_discount { } |
|
48 |
|
|
45 | 49 |
sub make_price_from_makemodel { |
46 | 50 |
my ($self, $makemodel) = @_; |
47 | 51 |
|
SL/PriceSource/MasterData.pm | ||
---|---|---|
20 | 20 |
: ($self->make_lastcost, $self->make_listprice); |
21 | 21 |
} |
22 | 22 |
|
23 |
sub available_discounts { } |
|
24 |
|
|
23 | 25 |
sub price_from_source { |
24 | 26 |
my ($self, $source, $spec) = @_; |
25 | 27 |
|
... | ... | |
35 | 37 |
: $_[0]->make_lastcost |
36 | 38 |
} |
37 | 39 |
|
40 |
sub best_discount { } |
|
41 |
|
|
38 | 42 |
sub make_sellprice { |
39 | 43 |
my ($self) = @_; |
40 | 44 |
|
SL/PriceSource/Price.pm | ||
---|---|---|
7 | 7 |
scalar => [ qw(price description spec price_source invalid missing) ], |
8 | 8 |
); |
9 | 9 |
|
10 |
use SL::DB::Helper::Attr;
|
|
10 |
require SL::DB::Helper::Attr;
|
|
11 | 11 |
SL::DB::Helper::Attr::make(__PACKAGE__, |
12 | 12 |
price => 'numeric(15,5)', |
13 | 13 |
); |
14 | 14 |
|
15 | 15 |
sub source { |
16 | 16 |
$_[0]->price_source |
17 |
? $_[0]->price_source->name . '/' . $_[0]->spec
|
|
17 |
? $_[0]->price_source->name . '/' . $_[0]->spec |
|
18 | 18 |
: ''; |
19 | 19 |
} |
20 | 20 |
|
... | ... | |
31 | 31 |
|
32 | 32 |
$self->price_source |
33 | 33 |
? $self->price_source->description |
34 |
: $self->description
|
|
34 |
: $self->description |
|
35 | 35 |
} |
36 | 36 |
|
37 | 37 |
sub to_str { |
38 |
"source: @{[ $_[0]->source ]}, price: @{[ $_[0]->price]}, description: @{[ $_[0]->description ]}" |
|
38 |
"source: @{[ $_[0]->source ]}, price: @{[ $_[0]->price ]}, description: @{[ $_[0]->description ]}"
|
|
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
1; |
... | ... | |
53 | 53 |
# in PriceSource::Base implementation |
54 | 54 |
$price = SL::PriceSource::Price->new( |
55 | 55 |
price => 10.3, |
56 |
spec => '10.3', # something you can easily parse later
|
|
57 |
description => t8('Fix price 10.3'), |
|
56 |
spec => '3', # something you can easily parse later |
|
57 |
description => t8('Fix price 10.3 for customer 3'),
|
|
58 | 58 |
price_source => $self, |
59 | 59 |
) |
60 | 60 |
|
61 |
# special empty price in SL::PriceSource |
|
61 |
# special empty price in SL::PriceSource, for internal use.
|
|
62 | 62 |
SL::PriceSource::Price->new( |
63 | 63 |
description => t8('None (PriceSource)'), |
64 | 64 |
); |
65 | 65 |
|
66 |
# invalid price
|
|
66 |
# price can't be restored
|
|
67 | 67 |
SL::PriceSource::Price->new( |
68 |
price => $original_price, |
|
69 |
spec => $original_spec, |
|
70 |
description => $original_description, |
|
71 |
invalid => t8('Offer expired #1 weeks ago', $dt->delta_weeks), |
|
68 |
missing => t8('Um, sorry, cannot find that one'), |
|
72 | 69 |
price_source => $self, |
73 | 70 |
); |
74 | 71 |
|
75 |
# missing price
|
|
72 |
# invalid price
|
|
76 | 73 |
SL::PriceSource::Price->new( |
77 |
price => $original_price, # will keep last entered price
|
|
74 |
price => $original_price, |
|
78 | 75 |
spec => $original_spec, |
79 |
description => '',
|
|
80 |
missing => t8('Um, sorry, cannot find that one'),
|
|
76 |
description => $original_description,
|
|
77 |
invalid => t8('Offer expired #1 weeks ago', $dt->delta_weeks),
|
|
81 | 78 |
price_source => $self, |
82 | 79 |
); |
83 | 80 |
|
84 |
|
|
85 | 81 |
=head1 DESCRIPTION |
86 | 82 |
|
87 | 83 |
See L<SL::PriceSource> for information about the mechanism. |
... | ... | |
97 | 93 |
|
98 | 94 |
The price. A price of 0 is special and is considered undesirable. If passed as |
99 | 95 |
part of C<available_prices> it will be filtered out. If returned as |
100 |
C<best_price> or C<price_from_source> it will be warned about.
|
|
96 |
C<best_price> or C<price_from_source> it will trigger a warning.
|
|
101 | 97 |
|
102 | 98 |
=item C<spec> |
103 | 99 |
|
... | ... | |
118 | 114 |
OPTIONAL. Both indicator and localized message that the price with this spec |
119 | 115 |
could not be reproduced and should be changed. |
120 | 116 |
|
117 |
If price is missing, you do not need to supply anything except C<source>. |
|
118 |
|
|
121 | 119 |
=item C<invalid> |
122 | 120 |
|
123 | 121 |
OPTIONAL. Both indicator and localized message that the conditions for this |
124 | 122 |
price are no longer valid, and that the price should be changed. |
125 | 123 |
|
124 |
If price is missing, you do not need to supply anything except C<source>. |
|
125 |
|
|
126 | 126 |
=back |
127 | 127 |
|
128 | 128 |
=head1 SEE ALSO |
SL/PriceSource/Pricegroup.pm | ||
---|---|---|
33 | 33 |
} @$prices; |
34 | 34 |
} |
35 | 35 |
|
36 |
sub available_discounts { } |
|
37 |
|
|
36 | 38 |
sub price_from_source { |
37 | 39 |
my ($self, $source, $spec) = @_; |
38 | 40 |
|
... | ... | |
57 | 59 |
return $best_price || (); |
58 | 60 |
} |
59 | 61 |
|
62 |
sub best_discount { } |
|
63 |
|
|
60 | 64 |
sub make_price { |
61 | 65 |
my ($self, $price_obj) = @_; |
62 | 66 |
|
SL/PriceSource/Vendor.pm | ||
---|---|---|
1 |
package SL::PriceSource::Vendor; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::PriceSource::Base); |
|
5 |
|
|
6 |
use SL::DB::Vendor; |
|
7 |
use SL::PriceSource::Price; |
|
8 |
use SL::Locale::String; |
|
9 |
|
|
10 |
sub name { 'vendor_discount' } |
|
11 |
|
|
12 |
sub description { t8('Vendor Discount') } |
|
13 |
|
|
14 |
sub available_prices { } |
|
15 |
|
|
16 |
sub available_discounts { |
|
17 |
my ($self, %params) = @_; |
|
18 |
|
|
19 |
return if $self->record->is_sales; |
|
20 |
return unless $self->record->vendor; |
|
21 |
return unless $self->record->vendor->discount != 0; |
|
22 |
|
|
23 |
SL::PriceSource::Vendor->new( |
|
24 |
discount => $self->record->vendor->discount, |
|
25 |
spec => $self->record->vendor->id, |
|
26 |
description => t8('Vendor Discount'), |
|
27 |
price_source => $self, |
|
28 |
); |
|
29 |
} |
|
30 |
|
|
31 |
sub price_from_source { |
|
32 |
my ($self, $source, $spec) = @_; |
|
33 |
|
|
34 |
my $vendor = SL::DB::Vendor->load_cached($spec); |
|
35 |
|
|
36 |
if (!$vendor) { |
|
37 |
return SL::PriceSource::Discount->new( |
|
38 |
missing => t8('Could not load this vendor'), |
|
39 |
price_source => $self, |
|
40 |
) |
|
41 |
} |
|
42 |
|
|
43 |
if (!$self->record->vendor) { |
|
44 |
return SL::PriceSource::Discount->new( |
|
45 |
discount => $vendor->discount, |
|
46 |
spec => $vendor->id, |
|
47 |
description => t8('Vendor Discount'), |
|
48 |
price_source => $self, |
|
49 |
invalid => t8('This discount is only valid in purchase documents'), |
|
50 |
) |
|
51 |
} |
|
52 |
|
|
53 |
if ($vendor->id != $self->record->vendor->id) { |
|
54 |
return SL::PriceSource::Discount->new( |
|
55 |
discount => $vendor->discount, |
|
56 |
spec => $vendor->id, |
|
57 |
description => t8('Vendor Discount'), |
|
58 |
price_source => $self, |
|
59 |
invalid => t8('This discount is only valid for vendor #1', $vendor->full_description), |
|
60 |
) |
|
61 |
} |
|
62 |
|
|
63 |
return SL::PriceSource::Discount->new( |
|
64 |
discount => $vendor->discount, |
|
65 |
spec => $vendor->id, |
|
66 |
description => t8('Vendor Discount'), |
|
67 |
price_source => $self, |
|
68 |
); |
|
69 |
} |
|
70 |
|
|
71 |
|
|
72 |
sub best_price { } |
|
73 |
|
|
74 |
sub best_discount { |
|
75 |
&available_discounts; |
|
76 |
} |
|
77 |
|
|
78 |
1; |
|
79 |
|
bin/mozilla/do.pl | ||
---|---|---|
427 | 427 |
map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] }; |
428 | 428 |
|
429 | 429 |
$form->{"marge_price_factor_$i"} = $form->{item_list}->[0]->{price_factor}; |
430 |
$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"} * (1 - $form->{tradediscount}));
|
|
430 |
$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}); |
|
431 | 431 |
$form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}); |
432 | 432 |
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); |
433 | 433 |
} |
bin/mozilla/io.pl | ||
---|---|---|
226 | 226 |
for my $i (1 .. $numrows) { |
227 | 227 |
my %column_data = (); |
228 | 228 |
|
229 |
my $record_item = $record->id && $record->items ? $record->items->[$i-1] : _make_record_item($i); |
|
230 |
|
|
229 | 231 |
# undo formatting |
230 | 232 |
map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } |
231 | 233 |
qw(qty discount sellprice lastcost price_new price_old) |
... | ... | |
235 | 237 |
$form->{"sellprice_$i"} = $form->{"price_new_$i"}; |
236 | 238 |
} |
237 | 239 |
|
238 |
my $record_item = $record->id && $record->items ? $record->items->[$i-1] : _make_record_item($i); |
|
239 |
|
|
240 | 240 |
# unit begin |
241 | 241 |
$form->{"unit_old_$i"} ||= $form->{"unit_$i"}; |
242 | 242 |
$form->{"selected_unit_$i"} ||= $form->{"unit_$i"}; |
... | ... | |
310 | 310 |
} |
311 | 311 |
|
312 | 312 |
my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); |
313 |
my $discount_value = $form->format_amount(\%myconfig, $form->{"discount_$i"}); |
|
313 | 314 |
my $edit_prices = $main::auth->assert('edit_prices', 1) && !$::form->{"active_price_source_$i"}; |
315 |
my $edit_discounts = $main::auth->assert('edit_prices', 1) && !$::form->{"active_discount_source_$i"}; |
|
314 | 316 |
$column_data{sellprice} = (!$edit_prices) |
315 | 317 |
? $cgi->hidden( -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value |
316 | 318 |
: $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value); |
317 |
$column_data{discount} = (!$edit_prices) |
|
318 |
? $cgi->textfield(-readonly => "readonly", |
|
319 |
-name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"})) |
|
320 |
: $cgi->textfield(-name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"})); |
|
319 |
$column_data{discount} = (!$edit_discounts) |
|
320 |
? $cgi->hidden( -name => "discount_$i", -id => "discount_$i", -value => $discount_value) . $discount_value . ' %' |
|
321 |
: $cgi->textfield(-name => "discount_$i", -id => "discount_$i", -size => 3, -value => $discount_value); |
|
321 | 322 |
$column_data{linetotal} = $form->format_amount(\%myconfig, $linetotal, 2); |
322 | 323 |
$column_data{bin} = $form->{"bin_$i"}; |
323 | 324 |
|
... | ... | |
325 | 326 |
|
326 | 327 |
if ($form->{"id_${i}"} && !$is_delivery_order) { |
327 | 328 |
my $price_source = SL::PriceSource->new(record_item => $record_item, record => $record); |
328 |
my $price = $price_source->price_from_source($::form->{"active_price_source_$i"}); |
|
329 |
my $price = $price_source->price_from_source($::form->{"active_price_source_$i"}); |
|
330 |
my $discount = $price_source->price_from_source($::form->{"active_discount_source_$i"}); |
|
329 | 331 |
$column_data{price_source} .= $cgi->button(-value => $price->source_description, -onClick => "kivi.io.price_chooser($i)"); |
330 | 332 |
if ($price->source) { |
331 | 333 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $price->invalid, title => $price->invalid }) if $price->invalid; |
332 | 334 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $price->missing, title => $price->missing }) if $price->missing; |
333 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This price has since gone up'), title => t8('This price has since gone up' ) }) if $price->price > $record_item->sellprice; |
|
334 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This price has since gone down'), title => t8('This price has since gone down') }) if $price->price < $record_item->sellprice; |
|
335 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/ok.png', alt => t8('There is a better price available'), title => t8('There is a better price available') }) if $price->source ne $price_source->best_price->source; |
|
335 |
if (!$price->missing && !$price->invalid) { |
|
336 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This price has since gone up'), title => t8('This price has since gone up' ) }) if $price->price > $record_item->sellprice; |
|
337 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This price has since gone down'), title => t8('This price has since gone down') }) if $price->price < $record_item->sellprice; |
|
338 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/ok.png', alt => t8('There is a better price available'), title => t8('There is a better price available') }) if $price->source ne $price_source->best_price->source; |
|
339 |
} |
|
340 |
} |
|
341 |
if ($discount->source) { |
|
342 |
$column_data{discount_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $discount->invalid, title => $discount->invalid }) if $discount->invalid; |
|
343 |
$column_data{discount_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $discount->missing, title => $discount->missing }) if $discount->missing; |
|
344 |
if (!$discount->missing && !$discount->invalid) { |
|
345 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This discount has since gone up'), title => t8('This discount has since gone up') }) if $discount->discount * 100 > $record_item->discount; |
|
346 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This discount has since gone down'), title => t8('This discount has since gone down') }) if $discount->discount * 100 < $record_item->discount; |
|
347 |
$column_data{price_source} .= ' ' . $cgi->img({src => 'image/ok.png', alt => t8('There is a better discount available'), title => t8('There is a better discount available') }) if $discount->source ne $price_source->best_discount->source; |
|
348 |
} |
|
336 | 349 |
} |
337 | 350 |
} |
338 | 351 |
|
... | ... | |
428 | 441 |
$cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}), |
429 | 442 |
$cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})), |
430 | 443 |
map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" } |
431 |
(qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source |
|
444 |
(qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source active_discount_source
|
|
432 | 445 |
income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber |
433 | 446 |
longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars) |
434 | 447 |
); |
... | ... | |
469 | 482 |
$::form->header; |
470 | 483 |
|
471 | 484 |
my @item_list = map { |
472 |
$_->{display_sellprice} = $_->{sellprice} * (1 - $::form->{tradediscount}); |
|
473 | 485 |
$_->{display_sellprice} /= $_->{price_factor} if ($_->{price_factor}); |
474 | 486 |
$_; |
475 | 487 |
} @{ $::form->{item_list} }; |
... | ... | |
536 | 548 |
$::form->{"active_price_source_$i"} = $best_price->source; |
537 | 549 |
} |
538 | 550 |
|
551 |
my $best_discount = $price_source->best_discount; |
|
552 |
|
|
553 |
if ($best_discount) { |
|
554 |
$::form->{"discount_$i"} = $best_discount->discount; |
|
555 |
$::form->{"active_discount_source_$i"} = $best_discount->source; |
|
556 |
} |
|
557 |
|
|
539 | 558 |
|
540 | 559 |
$form->{"marge_price_factor_$i"} = $new_item->{price_factor}; |
541 | 560 |
|
... | ... | |
557 | 576 |
$form->{"sellprice_$i"} = |
558 | 577 |
$form->round_amount($form->{"sellprice_$i"}, $decimalplaces); |
559 | 578 |
} |
560 |
|
|
561 |
# tradediscount |
|
562 |
if ($::form->{tradediscount}) { |
|
563 |
$::form->{"sellprice_$i"} *= 1 - $::form->{tradediscount}; |
|
564 |
} |
|
565 | 579 |
} |
566 | 580 |
|
567 | 581 |
map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } |
... | ... | |
710 | 724 |
transdate longdescription basefactor marge_total marge_percent |
711 | 725 |
marge_price_factor lastcost price_factor_id partnotes |
712 | 726 |
stock_out stock_in has_sernumber reqdate orderitems_id |
713 |
active_price_source); |
|
727 |
active_price_source active_discount_source);
|
|
714 | 728 |
|
715 | 729 |
my $ic_cvar_configs = CVar->get_configs(module => 'IC'); |
716 | 730 |
push @flds, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs }; |
bin/mozilla/ir.pl | ||
---|---|---|
511 | 511 |
if ($sellprice) { |
512 | 512 |
$form->{"sellprice_$i"} = $sellprice; |
513 | 513 |
} else { |
514 |
my $record = _make_record(); |
|
515 |
my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); |
|
516 |
my $best_price = $price_source->best_price; |
|
517 |
my $best_discount = $price_source->best_discount; |
|
518 |
|
|
519 |
if ($best_price) { |
|
520 |
$::form->{"sellprice_$i"} = $best_price->price; |
|
521 |
$::form->{"active_price_source_$i"} = $best_price->source; |
|
522 |
} |
|
523 |
if ($best_discount) { |
|
524 |
$::form->{"discount_$i"} = $best_discount->discount; |
|
525 |
$::form->{"active_discount_source_$i"} = $best_discount->source; |
|
526 |
} |
|
527 |
|
|
514 | 528 |
# if there is an exchange rate adjust sellprice |
515 | 529 |
$form->{"sellprice_$i"} /= $exchangerate; |
516 | 530 |
} |
bin/mozilla/is.pl | ||
---|---|---|
587 | 587 |
if ($sellprice) { |
588 | 588 |
$form->{"sellprice_$i"} = $sellprice; |
589 | 589 |
} else { |
590 |
my $record = _make_record(); |
|
591 |
my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); |
|
592 |
my $best_price = $price_source->best_price; |
|
593 |
my $best_discount = $price_source->best_discount; |
|
594 |
|
|
595 |
if ($best_price) { |
|
596 |
$::form->{"sellprice_$i"} = $best_price->price; |
|
597 |
$::form->{"active_price_source_$i"} = $best_price->source; |
|
598 |
} |
|
599 |
if ($best_discount) { |
|
600 |
$::form->{"discount_$i"} = $best_discount->discount; |
|
601 |
$::form->{"active_discount_source_$i"} = $best_discount->source; |
|
602 |
} |
|
603 |
|
|
590 | 604 |
# if there is an exchange rate adjust sellprice |
591 |
$form->{"sellprice_$i"} *= (1 - $form->{tradediscount}); |
|
592 | 605 |
$form->{"sellprice_$i"} /= $exchangerate; |
593 | 606 |
} |
594 | 607 |
|
bin/mozilla/oe.pl | ||
---|---|---|
678 | 678 |
if ($sellprice) { |
679 | 679 |
$form->{"sellprice_$i"} = $sellprice; |
680 | 680 |
} else { |
681 |
my $record = _make_record(); |
|
682 |
my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); |
|
683 |
my $best_price = $price_source->best_price; |
|
681 |
my $record = _make_record(); |
|
682 |
my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); |
|
683 |
my $best_price = $price_source->best_price; |
|
684 |
my $best_discount = $price_source->best_discount; |
|
684 | 685 |
|
685 | 686 |
if ($best_price) { |
686 | 687 |
$::form->{"sellprice_$i"} = $best_price->price; |
687 | 688 |
$::form->{"active_price_source_$i"} = $best_price->source; |
688 | 689 |
} |
690 |
if ($best_discount) { |
|
691 |
$::form->{"discount_$i"} = $best_discount->discount; |
|
692 |
$::form->{"active_discount_source_$i"} = $best_discount->source; |
|
693 |
} |
|
689 | 694 |
|
690 |
$form->{"sellprice_$i"} *= (1 - $form->{tradediscount}); |
|
691 | 695 |
$form->{"sellprice_$i"} /= $exchangerate; # if there is an exchange rate adjust sellprice |
692 | 696 |
} |
693 | 697 |
|
js/kivi.io.js | ||
---|---|---|
43 | 43 |
if (price_str) $('#sellprice_' + row).val(price_str); |
44 | 44 |
$('#update_button').click(); |
45 | 45 |
} |
46 |
|
|
47 |
ns.update_discount_source = function(row, source, discount_str) { |
|
48 |
$('#active_discount_source_' + row).val(source); |
|
49 |
if (discount_str) $('#discount_' + row).val(discount_str); |
|
50 |
$('#update_button').click(); |
|
51 |
} |
|
46 | 52 |
}); |
locale/de/all | ||
---|---|---|
342 | 342 |
'Beratername' => 'Beratername', |
343 | 343 |
'Beraternummer' => 'Beraternummer', |
344 | 344 |
'Best Before' => 'Mindesthaltbarkeit', |
345 |
'Best Discount' => 'Bester Rabatt', |
|
345 | 346 |
'Best Price' => 'Bester Preis', |
346 | 347 |
'Bilanz' => 'Bilanz', |
347 | 348 |
'Billable amount' => 'Abrechenbarer Betrag', |
... | ... | |
383 | 384 |
'Buchungsgruppen' => 'Buchungsgruppen', |
384 | 385 |
'Buchungskonto' => 'Buchungskonto', |
385 | 386 |
'Buchungsnummer' => 'Buchungsnummer', |
387 |
'Business' => 'Kunden-/Lieferantentyp', |
|
388 |
'Business Discount' => 'Kunden-/Lieferantentyp-Rabatt', |
|
386 | 389 |
'Business Number' => 'Firmennummer', |
387 | 390 |
'Business Volume' => 'Geschäftsvolumen', |
388 | 391 |
'Business evaluation' => 'Betriebswirtschaftliche Auswertung', |
... | ... | |
561 | 564 |
'Could not load class #1 (#2): "#3"' => 'Konnte Klasse #1 (#2) nicht laden: "#3"', |
562 | 565 |
'Could not load class #1, #2' => 'Konnte Klasse #1 nicht laden: "#2"', |
563 | 566 |
'Could not load employee' => 'Konnte Benutzer nicht laden', |
567 |
'Could not load this business' => 'Konnte diesen Kunden-/Lieferantentyp nicht laden', |
|
568 |
'Could not load this customer' => 'Konnte diesen Kunden nicht laden', |
|
569 |
'Could not load this vendor' => 'Konnte diesen Lieferanten nicht laden', |
|
564 | 570 |
'Could not print dunning.' => 'Die Mahnungen konnten nicht gedruckt werden.', |
565 | 571 |
'Could not spawn ghostscript.' => 'Die Anwendung "ghostscript" konnte nicht gestartet werden.', |
566 | 572 |
'Could not spawn the printer command.' => 'Die Druckanwendung konnte nicht gestartet werden.', |
... | ... | |
669 | 675 |
'Customer' => 'Kunde', |
670 | 676 |
'Customer (database ID)' => 'Kunde (Datenbank-ID)', |
671 | 677 |
'Customer (name)' => 'Kunde (Name)', |
678 |
'Customer Discount' => 'Kundenrabatt', |
|
672 | 679 |
'Customer Master Data' => 'Kundenstammdaten', |
673 | 680 |
'Customer Name' => 'Kundenname', |
674 | 681 |
'Customer Number' => 'Kundennummer', |
... | ... | |
825 | 832 |
'Destination warehouse' => 'Ziellager', |
826 | 833 |
'Destination warehouse and bin' => 'Ziellager und -lagerplatz', |
827 | 834 |
'Detail view' => 'Detailanzeige', |
835 |
'Details' => 'Details', |
|
828 | 836 |
'Details (one letter abbreviation)' => 'D', |
829 | 837 |
'Dial command missing in kivitendo configuration\'s [cti] section' => 'Wählbefehl fehlt im Abschnitt [cti] der kivitendo-Konfiguration', |
830 | 838 |
'Difference' => 'Differenz', |
... | ... | |
834 | 842 |
'Discard duplicate entries in CSV file' => 'Doppelte Einträge in CSV-Datei verwerfen', |
835 | 843 |
'Discard entries with duplicates in database or CSV file' => 'Einträge aus CSV-Datei verwerfen, die es bereits in der Datenbank oder der CSV-Datei gibt', |
836 | 844 |
'Discount' => 'Rabatt', |
845 |
'Discounts' => 'Rabatte', |
|
837 | 846 |
'Display' => 'Anzeigen', |
838 | 847 |
'Display file' => 'Datei anzeigen', |
839 | 848 |
'Display options' => 'Anzeigeoptionen', |
... | ... | |
1601 | 1610 |
'No.' => 'Position', |
1602 | 1611 |
'No/individual shipping address' => 'Keine/individuelle Lieferadresse', |
1603 | 1612 |
'None' => 'Kein', |
1613 |
'None (PriceSource Discount)' => 'Freier Rabatt', |
|
1604 | 1614 |
'None (PriceSource)' => 'Freier Preis', |
1605 | 1615 |
'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.', |
1606 | 1616 |
'Normalize Customer / Vendor names' => 'Normalisierung Kunden- / Lieferantennamen', |
... | ... | |
1853 | 1863 |
'Pricegroup missing!' => 'Preisgruppe fehlt!', |
1854 | 1864 |
'Pricegroup saved!' => 'Preisgruppe gespeichert!', |
1855 | 1865 |
'Pricegroups' => 'Preisgruppen', |
1866 |
'Prices' => 'Preise', |
|
1856 | 1867 |
'Print' => 'Drucken', |
1857 | 1868 |
'Print and Post' => 'Drucken und Buchen', |
1858 | 1869 |
'Print automatically' => 'Automatisch ausdrucken', |
... | ... | |
2634 | 2645 |
'There are still transfers not matching the qty of the delivery order. Stock operations can not be changed later. Do you really want to proceed?' => 'Einige der Lagerbewegungen sind nicht vollständig und Lagerbewegungen können nachträglich nicht mehr verändert werden. Wollen Sie wirklich fortfahren?', |
2635 | 2646 |
'There are undefined currencies in your system.' => 'In Ihrer Datenbank wurden Währungen benutzt, die nicht ordnungsgemäß in den Währungen eingetragen wurden.', |
2636 | 2647 |
'There are usually three ways to install Perl modules.' => 'Es gibt normalerweise drei Arten, ein Perlmodul zu installieren.', |
2648 |
'There is a better discount available' => 'Es is ein besserer Rabatt verfügbar', |
|
2637 | 2649 |
'There is a better price available' => 'Es ist ein besserer Preis verfügbar', |
2638 | 2650 |
'There is already a taxkey 0 with tax rate not 0.' => 'Es existiert bereits ein Steuerschlüssel mit Steuersatz ungleich 0%.', |
2639 | 2651 |
'There is an inconsistancy in your database.' => 'In Ihrer Datenbank sind Unstimmigkeiten vorhanden.', |
... | ... | |
2653 | 2665 |
'This can be done with the following query:' => 'Dies kann mit der folgenden Datenbankabfrage erreicht werden:', |
2654 | 2666 |
'This could have happened for two reasons:' => 'Dies kann aus zwei Gründen geschehen sein:', |
2655 | 2667 |
'This customer number is already in use.' => 'Diese Kundennummer wird bereits verwendet.', |
2668 |
'This discount has since gone down' => 'Dieser Rabatt ist mittlerweile niedriger', |
|
2669 |
'This discount has since gone up' => 'Dieser Rabatt ist mittlerweile höher', |
|
2670 |
'This discount is only valid for business #1' => 'Dieser Rabatt ist nur für Kunden-/Lieferantentyp #1 gültig', |
|
2671 |
'This discount is only valid for customer #1' => 'Dieser Rabatt ist nur für Kunde #1 gültig', |
|
2672 |
'This discount is only valid for vendor #1' => 'Dieser Rabatt ist nur für Lieferant #1 gültig', |
|
2673 |
'This discount is only valid in purchase documents' => 'Dieser Rabatt ist nur in Einkaufsdokumenten gültig', |
|
2674 |
'This discount is only valid in records with customer or vendor' => 'Dieser Rabatt ist nur in Dokumenten mit Kunde oder Lieferant gültig', |
|
2675 |
'This discount is only valid in sales documents' => 'Dieser Rabatt ist nur in Verkaufsdokumenten gültig', |
|
2656 | 2676 |
'This feature especially prevents mistakes by mixing up prior tax and sales tax.' => 'Dieses Feature vermeidet insbesondere Verwechslungen von Umsatz- und Vorsteuer.', |
2657 | 2677 |
'This function requires the presence of articles with a time-based unit such as "h" or "min".' => 'Für diese Funktion mussen Artikel mit einer Zeit-basierten Einheit wie "Std" oder "min" existieren.', |
2658 | 2678 |
'This group is valid for the following clients' => 'Diese Gruppe ist für die folgenden Mandanten gültig', |
... | ... | |
2779 | 2799 |
'Unsupported image type (supported types: #1)' => 'Nicht unterstützter Bildtyp (unterstützte Typen: #1)', |
2780 | 2800 |
'Until' => 'Bis', |
2781 | 2801 |
'Update' => 'Erneuern', |
2802 |
'Update Discount' => 'Rabatt übernehmen', |
|
2782 | 2803 |
'Update Price' => 'Preis übernehmen', |
2783 | 2804 |
'Update Prices' => 'Preise aktualisieren', |
2784 | 2805 |
'Update SKR04: new tax account 3804 (19%)' => 'Update SKR04: neues Steuerkonto 3804 (19%) für innergemeinschaftlichen Erwerb', |
... | ... | |
2830 | 2851 |
'Vendor' => 'Lieferant', |
2831 | 2852 |
'Vendor (database ID)' => '(Datenbank-ID)', |
2832 | 2853 |
'Vendor (name)' => 'Lieferant (Name)', |
2854 |
'Vendor Discount' => 'Lieferantenrabatt', |
|
2833 | 2855 |
'Vendor Invoice' => 'Einkaufsrechnung', |
2834 | 2856 |
'Vendor Invoices & AP Transactions' => 'Einkaufsrechnungen & Kreditorenbuchungen', |
2835 | 2857 |
'Vendor Name' => 'Lieferantenname', |
sql/Pg-upgrade2/recorditem_active_dicount_source.sql | ||
---|---|---|
1 |
-- @tag: recorditem_active_record_source |
|
2 |
-- @description: Preisquellen: Rabatte |
|
3 |
-- @depends: release_3_1_0 recorditem_active_price_source |
|
4 |
-- @encoding: utf-8 |
|
5 |
|
|
6 |
ALTER TABLE orderitems ADD COLUMN active_discount_source TEXT NOT NULL DEFAULT ''; |
|
7 |
ALTER TABLE delivery_order_items ADD COLUMN active_discount_source TEXT NOT NULL DEFAULT ''; |
|
8 |
ALTER TABLE invoice ADD COLUMN active_discount_source TEXT NOT NULL DEFAULT ''; |
templates/webpages/oe/price_sources_dialog.html | ||
---|---|---|
3 | 3 |
[%- USE L %] |
4 | 4 |
[%- USE LxERP %] |
5 | 5 |
[% SET best_price = price_source.best_price %] |
6 |
[% SET best_discount = price_source.best_discount %] |
|
7 |
<h2>[% 'Prices' | $T8 %]</h2> |
|
8 |
|
|
6 | 9 |
<table> |
7 | 10 |
<tr class='listheading'> |
8 | 11 |
<th></th> |
9 | 12 |
<th>[% 'Price Source' | $T8 %]</th> |
10 | 13 |
<th>[% 'Price' | $T8 %]</th> |
11 | 14 |
<th>[% 'Best Price' | $T8 %]</th> |
15 |
<th>[% 'Details' | $T8 %]</th> |
|
12 | 16 |
</tr> |
13 | 17 |
<tr class='listrow'> |
14 | 18 |
[%- IF price_source.record_item.active_price_source %] |
... | ... | |
19 | 23 |
<td>[% 'None (PriceSource)' | $T8 %]</td> |
20 | 24 |
<td>-</td> |
21 | 25 |
<td></td> |
26 |
<td></td> |
|
22 | 27 |
</tr> |
23 | 28 |
[%- FOREACH price IN price_source.available_prices %] |
24 | 29 |
<tr class='listrow'> |
25 | 30 |
[%- IF price_source.record_item.active_price_source != price.source %] |
26 | 31 |
<td>[% L.button_tag('kivi.io.update_price_source(' _ FORM.row _ ', \'' _ price.source _ '\', \'' _ LxERP.format_amount(price.price, -2) _ '\')', LxERP.t8('Select')) %]</td> |
27 |
[%- ELSIF price_source.record_item.sellprice_as_number != price.price_as_number %]
|
|
32 |
[%- ELSIF price_source.record_item.sellprice != price.price %]
|
|
28 | 33 |
<td>[% L.button_tag('kivi.io.update_price_source(' _ FORM.row _ ', \'' _ price.source _ '\', \'' _ LxERP.format_amount(price.price, -2) _ '\')', LxERP.t8('Update Price')) %]</td> |
29 | 34 |
[%- ELSE %] |
30 | 35 |
<td><b>[% 'Selected' | $T8 %]</b></td> |
31 | 36 |
[% END %] |
32 |
<td>[% price.full_description | html %]</td>
|
|
37 |
<td>[% price.source_description | html %]</td>
|
|
33 | 38 |
<td>[% price.price_as_number %]</td> |
34 | 39 |
[% IF price.source == best_price.source %] |
35 | 40 |
<td align='center'>•</td> |
36 | 41 |
[% ELSE %] |
37 | 42 |
<td></td> |
38 | 43 |
[% END %] |
44 |
<td>[% price.description | html %]</td> |
|
45 |
</tr> |
|
46 |
[%- END %] |
|
47 |
</table> |
|
48 |
|
|
49 |
<h2>[% 'Discounts' | $T8 %]</h2> |
|
50 |
|
|
51 |
<table> |
|
52 |
<tr class='listheading'> |
|
53 |
<th></th> |
|
54 |
<th>[% 'Price Source' | $T8 %]</th> |
|
55 |
<th>[% 'Discount' | $T8 %]</th> |
|
56 |
<th>[% 'Best Discount' | $T8 %]</th> |
|
57 |
<th>[% 'Details' | $T8 %]</th> |
|
58 |
</tr> |
|
59 |
<tr class='listrow'> |
|
60 |
[%- IF price_source.record_item.active_discount_source %] |
|
61 |
<td>[% L.button_tag('kivi.io.update_discount_source(' _ FORM.row _ ', \'\')', LxERP.t8('Select')) %]</td> |
|
62 |
[%- ELSE %] |
|
63 |
<td><b>[% 'Selected' | $T8 %]</b></td> |
|
64 |
[%- END %] |
|
65 |
<td>[% 'None (PriceSource Discount)' | $T8 %]</td> |
|
66 |
<td>-</td> |
|
67 |
<td></td> |
|
68 |
<td></td> |
|
69 |
</tr> |
|
70 |
[%- FOREACH price IN price_source.available_discounts %] |
|
71 |
<tr class='listrow'> |
|
72 |
[%- IF price_source.record_item.active_discount_source != price.source %] |
|
73 |
<td>[% L.button_tag('kivi.io.update_discount_source(' _ FORM.row _ ', \'' _ price.source _ '\', \'' _ price.discount_as_percent _ '\')', LxERP.t8('Select')) %]</td> |
|
74 |
[%- ELSIF price_source.record_item.discount != price.discount * 100 %] |
|
75 |
<td>[% L.button_tag('kivi.io.update_discount_source(' _ FORM.row _ ', \'' _ price.source _ '\', \'' _ price.discount_as_percent _ '\')', LxERP.t8('Update Discount')) %]</td> |
|
76 |
[%- ELSE %] |
|
77 |
<td><b>[% 'Selected' | $T8 %]</b></td> |
Auch abrufbar als: Unified diff
PriceSource: Rabattbehandlung