Revision d6cc1832
Von Sven Schöling vor fast 3 Jahren hinzugefügt
SL/Controller/DeliveryOrder.pm | ||
---|---|---|
52 | 52 |
# safety |
53 | 53 |
__PACKAGE__->run_before('check_auth'); |
54 | 54 |
|
55 |
__PACKAGE__->run_before('recalc', |
|
56 |
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_ap_transaction |
|
57 |
print send_email) ]); |
|
58 |
|
|
59 | 55 |
__PACKAGE__->run_before('get_unalterable_data', |
60 | 56 |
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_ap_transaction |
61 | 57 |
print send_email) ]); |
... | ... | |
107 | 103 |
$_->{render_second_row} = 1 for @{ $self->order->items_sorted }; |
108 | 104 |
} |
109 | 105 |
|
110 |
$self->recalc(); |
|
111 | 106 |
$self->pre_render(); |
112 | 107 |
$self->render( |
113 | 108 |
'order/form', |
... | ... | |
579 | 574 |
my ($self) = @_; |
580 | 575 |
|
581 | 576 |
setup_order_from_cv($self->order); |
582 |
$self->recalc(); |
|
583 | 577 |
|
584 | 578 |
my $cv_method = $self->cv; |
585 | 579 |
|
... | ... | |
612 | 606 |
->focus( '#order_' . $self->cv . '_id') |
613 | 607 |
->run('kivi.Order.update_exchangerate'); |
614 | 608 |
|
615 |
$self->js_redisplay_amounts_and_taxes; |
|
616 | 609 |
$self->js_redisplay_cvpartnumbers; |
617 | 610 |
$self->js->render(); |
618 | 611 |
} |
... | ... | |
661 | 654 |
my $old_unit_obj = SL::DB::Unit->new(name => $::form->{old_unit})->load; |
662 | 655 |
$item->sellprice($item->unit_obj->convert_to($item->sellprice, $old_unit_obj)); |
663 | 656 |
|
664 |
$self->recalc(); |
|
665 |
|
|
666 | 657 |
$self->js |
667 | 658 |
->run('kivi.Order.update_sellprice', $::form->{item_id}, $item->sellprice_as_number); |
668 | 659 |
$self->js_redisplay_line_values; |
669 |
$self->js_redisplay_amounts_and_taxes; |
|
670 | 660 |
$self->js->render(); |
671 | 661 |
} |
672 | 662 |
|
... | ... | |
684 | 674 |
|
685 | 675 |
$self->order->add_items($item); |
686 | 676 |
|
687 |
$self->recalc(); |
|
688 |
|
|
689 | 677 |
$self->get_item_cvpartnumber($item); |
690 | 678 |
|
691 | 679 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
... | ... | |
717 | 705 |
$item->discount(1) unless $assortment_item->charge; |
718 | 706 |
|
719 | 707 |
$self->order->add_items( $item ); |
720 |
$self->recalc(); |
|
721 | 708 |
$self->get_item_cvpartnumber($item); |
722 | 709 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
723 | 710 |
my $row_as_html = $self->p->render('order/tabs/_row', |
... | ... | |
743 | 730 |
|
744 | 731 |
$self->js->run('kivi.Order.row_table_scroll_down') if !$::form->{insert_before_item_id}; |
745 | 732 |
|
746 |
$self->js_redisplay_amounts_and_taxes; |
|
747 | 733 |
$self->js->render(); |
748 | 734 |
} |
749 | 735 |
|
... | ... | |
775 | 761 |
} |
776 | 762 |
$self->order->add_items(@items); |
777 | 763 |
|
778 |
$self->recalc(); |
|
779 |
|
|
780 | 764 |
foreach my $item (@items) { |
781 | 765 |
$self->get_item_cvpartnumber($item); |
782 | 766 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
... | ... | |
803 | 787 |
|
804 | 788 |
$self->js->run('kivi.Order.row_table_scroll_down') if !$::form->{insert_before_item_id}; |
805 | 789 |
|
806 |
$self->js_redisplay_amounts_and_taxes; |
|
807 |
$self->js->render(); |
|
808 |
} |
|
809 |
|
|
810 |
# recalculate all linetotals, amounts and taxes and redisplay them |
|
811 |
sub action_recalc_amounts_and_taxes { |
|
812 |
my ($self) = @_; |
|
813 |
|
|
814 |
$self->recalc(); |
|
815 |
|
|
816 |
$self->js_redisplay_line_values; |
|
817 |
$self->js_redisplay_amounts_and_taxes; |
|
818 | 790 |
$self->js->render(); |
819 | 791 |
} |
820 | 792 |
|
... | ... | |
912 | 884 |
$item->{new_fake_id} = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
913 | 885 |
} |
914 | 886 |
|
915 |
$self->recalc(); |
|
916 | 887 |
$self->get_unalterable_data(); |
917 | 888 |
$self->pre_render(); |
918 | 889 |
|
... | ... | |
937 | 908 |
sub action_load_second_rows { |
938 | 909 |
my ($self) = @_; |
939 | 910 |
|
940 |
$self->recalc() if $self->order->is_sales; # for margin calculation |
|
941 |
|
|
942 | 911 |
foreach my $item_id (@{ $::form->{item_ids} }) { |
943 | 912 |
my $idx = first_index { $_ eq $item_id } @{ $::form->{orderitem_ids} }; |
944 | 913 |
my $item = $self->order->items_sorted->[$idx]; |
... | ... | |
994 | 963 |
} |
995 | 964 |
} |
996 | 965 |
|
997 |
$self->recalc(); |
|
998 | 966 |
$self->js_redisplay_line_values; |
999 |
$self->js_redisplay_amounts_and_taxes; |
|
1000 | 967 |
|
1001 | 968 |
$self->js->render(); |
1002 | 969 |
} |
... | ... | |
1046 | 1013 |
->run('kivi.Order.redisplay_line_values', $is_sales, \@data); |
1047 | 1014 |
} |
1048 | 1015 |
|
1049 |
sub js_redisplay_amounts_and_taxes { |
|
1050 |
my ($self) = @_; |
|
1051 |
|
|
1052 |
if (scalar @{ $self->{taxes} }) { |
|
1053 |
$self->js->show('#taxincluded_row_id'); |
|
1054 |
} else { |
|
1055 |
$self->js->hide('#taxincluded_row_id'); |
|
1056 |
} |
|
1057 |
|
|
1058 |
if ($self->order->taxincluded) { |
|
1059 |
$self->js->hide('#subtotal_row_id'); |
|
1060 |
} else { |
|
1061 |
$self->js->show('#subtotal_row_id'); |
|
1062 |
} |
|
1063 |
|
|
1064 |
if ($self->order->is_sales) { |
|
1065 |
my $is_neg = $self->order->marge_total < 0; |
|
1066 |
$self->js |
|
1067 |
->html('#marge_total_id', $::form->format_amount(\%::myconfig, $self->order->marge_total, 2)) |
|
1068 |
->html('#marge_percent_id', $::form->format_amount(\%::myconfig, $self->order->marge_percent, 2)) |
|
1069 |
->action_if( $is_neg, 'addClass', '#marge_total_id', 'plus0') |
|
1070 |
->action_if( $is_neg, 'addClass', '#marge_percent_id', 'plus0') |
|
1071 |
->action_if( $is_neg, 'addClass', '#marge_percent_sign_id', 'plus0') |
|
1072 |
->action_if(!$is_neg, 'removeClass', '#marge_total_id', 'plus0') |
|
1073 |
->action_if(!$is_neg, 'removeClass', '#marge_percent_id', 'plus0') |
|
1074 |
->action_if(!$is_neg, 'removeClass', '#marge_percent_sign_id', 'plus0'); |
|
1075 |
} |
|
1076 |
|
|
1077 |
$self->js |
|
1078 |
->html('#netamount_id', $::form->format_amount(\%::myconfig, $self->order->netamount, -2)) |
|
1079 |
->html('#amount_id', $::form->format_amount(\%::myconfig, $self->order->amount, -2)) |
|
1080 |
->remove('.tax_row') |
|
1081 |
->insertBefore($self->build_tax_rows, '#amount_row_id'); |
|
1082 |
} |
|
1083 |
|
|
1084 | 1016 |
sub js_redisplay_cvpartnumbers { |
1085 | 1017 |
my ($self) = @_; |
1086 | 1018 |
|
... | ... | |
1243 | 1175 |
$_[0]->p->render('order/tabs/_business_info_row', SELF => $_[0]); |
1244 | 1176 |
} |
1245 | 1177 |
|
1246 |
# build the rows for displaying taxes |
|
1247 |
# |
|
1248 |
# Called if amounts where recalculated and redisplayed. |
|
1249 |
sub build_tax_rows { |
|
1250 |
my ($self) = @_; |
|
1251 |
|
|
1252 |
my $rows_as_html; |
|
1253 |
foreach my $tax (sort { $a->{tax}->rate cmp $b->{tax}->rate } @{ $self->{taxes} }) { |
|
1254 |
$rows_as_html .= $self->p->render('order/tabs/_tax_row', TAX => $tax, TAXINCLUDED => $self->order->taxincluded); |
|
1255 |
} |
|
1256 |
return $rows_as_html; |
|
1257 |
} |
|
1258 |
|
|
1259 | 1178 |
|
1260 | 1179 |
sub render_price_dialog { |
1261 | 1180 |
my ($self, $record_item) = @_; |
... | ... | |
1488 | 1407 |
} |
1489 | 1408 |
} |
1490 | 1409 |
|
1491 |
# recalculate prices and taxes |
|
1492 |
# |
|
1493 |
# Using the PriceTaxCalculator. Store linetotals in the item objects. |
|
1494 |
sub recalc { |
|
1495 |
my ($self) = @_; |
|
1496 |
|
|
1497 |
my %pat = $self->order->calculate_prices_and_taxes(); |
|
1498 |
|
|
1499 |
$self->{taxes} = []; |
|
1500 |
foreach my $tax_id (keys %{ $pat{taxes_by_tax_id} }) { |
|
1501 |
my $netamount = sum0 map { $pat{amounts}->{$_}->{amount} } grep { $pat{amounts}->{$_}->{tax_id} == $tax_id } keys %{ $pat{amounts} }; |
|
1502 |
|
|
1503 |
push(@{ $self->{taxes} }, { amount => $pat{taxes_by_tax_id}->{$tax_id}, |
|
1504 |
netamount => $netamount, |
|
1505 |
tax => SL::DB::Tax->new(id => $tax_id)->load }); |
|
1506 |
} |
|
1507 |
pairwise { $a->{linetotal} = $b->{linetotal} } @{$self->order->items_sorted}, @{$pat{items}}; |
|
1508 |
} |
|
1509 |
|
|
1510 | 1410 |
# get data for saving, printing, ..., that is not changed in the form |
1511 | 1411 |
# |
1512 | 1412 |
# Only cvars for now. |
... | ... | |
1624 | 1524 |
$self->cv ($self->init_cv); |
1625 | 1525 |
$self->check_auth; |
1626 | 1526 |
|
1627 |
$self->recalc(); |
|
1628 | 1527 |
$self->get_unalterable_data(); |
1629 | 1528 |
$self->pre_render(); |
1630 | 1529 |
|
... | ... | |
1688 | 1587 |
$self->cv ($self->init_cv); |
1689 | 1588 |
$self->check_auth; |
1690 | 1589 |
|
1691 |
$self->recalc(); |
|
1692 | 1590 |
$self->get_unalterable_data(); |
1693 | 1591 |
$self->pre_render(); |
1694 | 1592 |
|
js/kivi.DeliveryOrder.js | ||
---|---|---|
233 | 233 |
} |
234 | 234 |
}; |
235 | 235 |
|
236 |
ns.recalc_amounts_and_taxes = function() { |
|
237 |
var data = $('#order_form').serializeArray(); |
|
238 |
data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' }); |
|
239 |
|
|
240 |
$.post("controller.pl", data, kivi.eval_json_result); |
|
241 |
}; |
|
242 |
|
|
243 | 236 |
ns.unit_change = function(event) { |
244 | 237 |
var row = $(event.target).parents("tbody").first(); |
245 | 238 |
var item_id_dom = $(row).find('[name="orderitem_ids[+]"]'); |
... | ... | |
328 | 321 |
}; |
329 | 322 |
|
330 | 323 |
ns.init_row_handlers = function() { |
331 |
kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) { |
|
332 |
$(elt).change(ns.recalc_amounts_and_taxes); |
|
333 |
}); |
|
334 |
|
|
335 | 324 |
kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) { |
336 | 325 |
$(elt).change(ns.reformat_number); |
337 | 326 |
}); |
... | ... | |
489 | 478 |
$(row).remove(); |
490 | 479 |
|
491 | 480 |
ns.renumber_positions(); |
492 |
ns.recalc_amounts_and_taxes(); |
|
493 | 481 |
}; |
494 | 482 |
|
495 | 483 |
ns.row_table_scroll_down = function() { |
... | ... | |
557 | 545 |
var html_elt = $(row).find('[name="sellprice_text"]'); |
558 | 546 |
price_elt.val(price_str); |
559 | 547 |
html_elt.html(price_str); |
560 |
ns.recalc_amounts_and_taxes(); |
|
561 | 548 |
} |
562 | 549 |
|
563 | 550 |
kivi.io.close_dialog(); |
... | ... | |
592 | 579 |
var html_elt = $(row).find('[name="discount_text"]'); |
593 | 580 |
discount_elt.val(discount_str); |
594 | 581 |
html_elt.html(discount_str); |
595 |
ns.recalc_amounts_and_taxes(); |
|
596 | 582 |
} |
597 | 583 |
|
598 | 584 |
kivi.io.close_dialog(); |
templates/webpages/delivery_order/tabs/_row.html | ||
---|---|---|
71 | 71 |
[%- L.input_tag("order.orderitems[].qty_as_number", |
72 | 72 |
ITEM.qty_as_number, |
73 | 73 |
size = 5, |
74 |
class="recalc reformat_number numeric") %]
|
|
74 |
class="reformat_number numeric") %] |
|
75 | 75 |
[%- IF ITEM.part.formel -%] |
76 | 76 |
[%- L.button_tag("kivi.Order.show_calculate_qty_dialog(this)", LxERP.t8("*/")) %] |
77 | 77 |
[%- L.hidden_tag("formula[+]", ITEM.part.formel) -%] |
... | ... | |
82 | 82 |
SELF.all_price_factors, |
83 | 83 |
default = ITEM.price_factor_id, |
84 | 84 |
title_key = 'description', |
85 |
with_empty = 1, |
|
86 |
class="recalc") %] |
|
85 |
with_empty = 1) %] |
|
87 | 86 |
</td> |
88 | 87 |
<td nowrap> |
89 | 88 |
[%- L.select_tag("order.orderitems[].unit", |
... | ... | |
113 | 112 |
ITEM.sellprice_as_number, |
114 | 113 |
size = 10, |
115 | 114 |
disabled=(EDIT_PRICE? '' : 1), |
116 |
class="recalc reformat_number numeric") %]
|
|
115 |
class="reformat_number numeric") %] |
|
117 | 116 |
</div> |
118 | 117 |
<div name="not_editable_price" [%- IF EDIT_PRICE %]style="display:none"[%- END %]> |
119 | 118 |
[%- L.div_tag(ITEM.sellprice_as_number, name="sellprice_text", class="numeric") %] |
... | ... | |
130 | 129 |
ITEM.discount_as_percent, |
131 | 130 |
size = 5, |
132 | 131 |
disabled=(EDIT_DISCOUNT? '' : 1), |
133 |
class="recalc reformat_number numeric") %]
|
|
132 |
class="reformat_number numeric") %] |
|
134 | 133 |
</div> |
135 | 134 |
<div name="not_editable_discount" [%- IF EDIT_DISCOUNT %]style="display:none"[%- END %]> |
136 | 135 |
[%- L.div_tag(ITEM.discount_as_percent, name="discount_text", class="numeric") %] |
templates/webpages/delivery_order/tabs/basic_data.html | ||
---|---|---|
336 | 336 |
</table> |
337 | 337 |
</td> |
338 | 338 |
|
339 |
[%- IF (SELF.type == "sales_order" || SELF.type == "sales_quotation") -%] |
|
340 |
[%- SET marge_class = (SELF.order.marge_total < 0) ? 'plus0' : '' -%] |
|
341 |
<td> |
|
342 |
<table> |
|
343 |
<tr> |
|
344 |
<th align="left">[% 'Ertrag' | $T8 %]</th> |
|
345 |
<td align="right"> |
|
346 |
[%- L.div_tag(SELF.order.marge_total_as_number, id='marge_total_id', class=marge_class) %] |
|
347 |
</td> |
|
348 |
</tr> |
|
349 |
<tr> |
|
350 |
<th align="left">[% 'Ertrag prozentual' | $T8 %]</th> |
|
351 |
<td align="right"> |
|
352 |
[%- L.div_tag(LxERP.format_amount(SELF.order.marge_percent, 2), id='marge_percent_id', class=marge_class) %] |
|
353 |
</td> |
|
354 |
<td>[%- L.div_tag('%', id='marge_percent_sign_id', class=marge_class) %]</td> |
|
355 |
</tr> |
|
356 |
</table> |
|
357 |
</td> |
|
358 |
[%- END %] |
|
359 |
|
|
360 |
<td align="right"> |
|
361 |
<table> |
|
362 |
<tr id="taxincluded_row_id" [%- IF !SELF.taxes.size %]style="display:none"[%- END %]> |
|
363 |
<td align=right colspan="2"> |
|
364 |
<label for="order.taxincluded"><b>[% 'Tax Included' | $T8 %]</b></label> |
|
365 |
[% L.yes_no_tag('order.taxincluded', SELF.order.taxincluded, class='recalc') %] |
|
366 |
</td> |
|
367 |
</tr> |
|
368 |
|
|
369 |
<tr id="subtotal_row_id" [%- IF SELF.order.taxincluded %]style="display:none"[%- END %]> |
|
370 |
<th align="right">[%- 'Subtotal' | $T8 %]</th> |
|
371 |
<td align="right"> |
|
372 |
[%- L.div_tag(SELF.order.netamount_as_number, id='netamount_id') %] |
|
373 |
</td> |
|
374 |
</tr> |
|
375 |
[%- FOREACH tax = SELF.taxes %] |
|
376 |
[%- PROCESS order/tabs/_tax_row.html TAX=tax TAXINCLUDED=SELF.order.taxincluded %] |
|
377 |
[%- END %] |
|
378 |
<tr id="amount_row_id"> |
|
379 |
<th align="right">[%- 'Total' | $T8 %]</th> |
|
380 |
<td align="right"> |
|
381 |
[%- L.div_tag(SELF.order.amount_as_number, id='amount_id') %] |
|
382 |
</td> |
|
383 |
</tr> |
|
384 |
</table> |
|
385 |
</td> |
|
386 |
|
|
387 | 339 |
</tr> |
388 | 340 |
</table> |
389 | 341 |
</td> |
Auch abrufbar als: Unified diff
DeliveryOrder: taxes und recalc Mechanismus entfernt