epic-s6ts
[kivitendo-erp.git] / SL / DB / Helper / PriceUpdater.pm
1 package SL::DB::Helper::PriceUpdater;
2
3 use strict;
4
5 use parent qw(Exporter);
6 our @EXPORT = qw(update_prices);
7
8 use Carp;
9
10 sub update_prices {
11   my $self   = shift;
12   my %params = @_;
13
14   croak('Missing parameters amount/percent') unless $params{amount} || $params{percent};
15
16   my @prices = ref $params{prices} eq 'ARRAY' ? @{ $params{prices} } : ( $params{prices} || 'sellprice' );
17
18   foreach my $field (@prices) {
19     my $rounding_error = 0;
20
21     foreach my $item (@{ $self->items }) {
22       my $new_price;
23       if ($params{amount}) {
24         $new_price = $item->$field + $params{amount}        + $rounding_error;
25       } else {
26         $new_price = $item->$field * $params{percent} / 100 + $rounding_error;
27       }
28
29       $item->$field($::form->round_amount($new_price, 2));
30       $rounding_error += $new_price - $item->$field;
31
32       _dbg("new_price $new_price new_price_no_err " . ($new_price - $rounding_error) . " rounded " . $item->$field .
33            " error_old " . ($rounding_error - $new_price + $item->$field) . " error_new $rounding_error");
34     }
35   }
36
37   return $self->calculate_prices_and_taxes if $params{calculate};
38   return $self;
39 }
40
41 sub _dbg {
42   # $::lxdebug->message(0, __PACKAGE__ . ': ' . join(' ', @_));
43 }
44
45 1;
46
47 __END__
48
49 =encoding utf8
50
51 =head1 NAME
52
53 SL::DB::Helper::PriceUpdater - Mixin for updating all prices by a fixed amount or by a percentage
54
55 =head1 FUNCTIONS
56
57 =over 4
58
59 =item C<update_prices %params>
60
61 Updates the prices of all items as returned by the function C<items>
62 provided by the mixing class.
63
64 Supported arguments via C<%params> are:
65
66 =over 2
67
68 =item C<amount>
69
70 Absolute amount to add or subtract. Either C<amount> or C<percent>
71 must be given. Resulting prices are rounded to two significant places.
72
73 =item C<percent>
74
75 Percentage to set the prices to (with 100 meaning "no
76 change"). Resulting prices are rounded to two significant
77 places. Rounding errors are carried over to the next item.
78
79 Either C<amount> or C<percent> must be given.
80
81 =item C<prices>
82
83 A string or an array of strings naming the prices to update. If
84 missing only the C<sellprice> field will be updated.
85
86 =item C<calculate>
87
88 If trueish the all prices, taxes and amounts are re-calculated by
89 calling
90 L<SL::DB::Helper::PriceTaxCalculator::calculate_prices_and_taxes>.
91 Returns that function's result.
92
93 =back
94
95 Returns C<$self> unless C<$params{calculate}> is trueish.
96
97 =back
98
99 =head1 EXPORTS
100
101 This mixin exports the function L</update_prices>.
102
103 =head1 BUGS
104
105 Nothing here yet.
106
107 =head1 AUTHOR
108
109 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
110
111 =cut