Revision eebe8e90
Von Sven Schöling vor etwa 10 Jahren hinzugefügt
SL/DB/Helper/PriceTaxCalculator.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use parent qw(Exporter); |
6 |
our @EXPORT = qw(calculate_prices_and_taxes); |
|
6 |
our @EXPORT = qw(calculate_prices_and_taxes _calculate_item);
|
|
7 | 7 |
|
8 | 8 |
use Carp; |
9 | 9 |
use List::Util qw(sum min max); |
... | ... | |
75 | 75 |
my ($self, $item, $idx, $data, %params) = @_; |
76 | 76 |
|
77 | 77 |
my $part = SL::DB::Part->load_cached($item->parts_id); |
78 |
return unless $item->part; |
|
79 |
|
|
78 | 80 |
my $part_unit = $data->{units_by_name}->{ $part->unit }; |
79 | 81 |
my $item_unit = $data->{units_by_name}->{ $item->unit }; |
80 | 82 |
|
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 }, |
|
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 }, |
|
35 | 36 |
); |
36 | 37 |
|
37 | 38 |
__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 }, |
|
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 }, |
|
42 | 43 |
); |
43 | 44 |
|
44 | 45 |
__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 }, |
|
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 }, |
|
39 | 40 |
); |
40 | 41 |
|
41 | 42 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
SL/DO.pm | ||
---|---|---|
284 | 284 |
id, delivery_order_id, parts_id, description, longdescription, qty, base_qty, |
285 | 285 |
sellprice, discount, unit, reqdate, project_id, serialnumber, |
286 | 286 |
ordnumber, transdate, cusordnumber, |
287 |
lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id) |
|
287 |
lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id, |
|
288 |
active_price_source) |
|
288 | 289 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, |
289 |
(SELECT factor FROM price_factors WHERE id = ?), ?, ?)|; |
|
290 |
(SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?)|;
|
|
290 | 291 |
my $h_item = prepare_query($form, $dbh, $q_item); |
291 | 292 |
|
292 | 293 |
my $q_item_stock = |
... | ... | |
341 | 342 |
$form->{"lastcost_$i"}, |
342 | 343 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), |
343 | 344 |
conv_i($form->{"marge_price_factor_$i"}), |
344 |
$pricegroup_id); |
|
345 |
$pricegroup_id, |
|
346 |
$form->{"active_price_source_$i"}); |
|
345 | 347 |
do_statement($form, $h_item, $q_item, @values); |
346 | 348 |
|
347 | 349 |
my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"}); |
... | ... | |
688 | 690 |
doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost, |
689 | 691 |
doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription, |
690 | 692 |
doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id, |
693 |
doi.active_price_source, |
|
691 | 694 |
pr.projectnumber, dord.transdate AS dord_transdate, dord.donumber, |
692 | 695 |
pg.partsgroup |
693 | 696 |
FROM delivery_order_items doi |
SL/IS.pm | ||
---|---|---|
2131 | 2131 |
$main::lxdebug->leave_sub(); |
2132 | 2132 |
} |
2133 | 2133 |
|
2134 |
########################## |
|
2135 |
# get pricegroups from database |
|
2136 |
# build up selected pricegroup |
|
2137 |
# if an exchange rate - change price |
|
2138 |
# for each part |
|
2139 |
# |
|
2140 |
sub get_pricegroups_for_parts { |
|
2141 |
|
|
2142 |
$main::lxdebug->enter_sub(); |
|
2143 |
|
|
2144 |
my ($self, $myconfig, $form) = @_; |
|
2145 |
|
|
2146 |
my $dbh = $form->get_standard_dbh; |
|
2147 |
|
|
2148 |
$form->{"PRICES"} = {}; |
|
2149 |
|
|
2150 |
my $i = 1; |
|
2151 |
my $id = 0; |
|
2152 |
my $all_units = AM->retrieve_units($myconfig, $form); |
|
2153 |
while (($form->{"id_$i"}) or ($form->{"new_id_$i"})) { |
|
2154 |
$form->{"PRICES"}{$i} = []; |
|
2155 |
|
|
2156 |
$id = $form->{"id_$i"}; |
|
2157 |
|
|
2158 |
if (!($form->{"id_$i"}) and $form->{"new_id_$i"}) { |
|
2159 |
$id = $form->{"new_id_$i"}; |
|
2160 |
} |
|
2161 |
|
|
2162 |
my ($price, $selectedpricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"}); |
|
2163 |
|
|
2164 |
my $pricegroup_old = $form->{"pricegroup_old_$i"}; |
|
2165 |
|
|
2166 |
# sellprice has format 13,0000 or 0,00000, can't check for 0 numerically |
|
2167 |
my $sellprice = $form->{"sellprice_$i"}; |
|
2168 |
my $pricegroup_id = $form->{"pricegroup_id_$i"}; |
|
2169 |
$form->{"new_pricegroup_$i"} = $selectedpricegroup_id; |
|
2170 |
$form->{"old_pricegroup_$i"} = $pricegroup_old; |
|
2171 |
|
|
2172 |
my $price_new = $form->{"price_new_$i"}; |
|
2173 |
my $price_old = $form->{"price_old_$i"}; |
|
2174 |
|
|
2175 |
if (!$form->{"unit_old_$i"}) { |
|
2176 |
# Neue Ware aus der Datenbank. In diesem Fall ist unit_$i die |
|
2177 |
# Einheit, wie sie in den Stammdaten hinterlegt wurde. |
|
2178 |
# Es sollte also angenommen werden, dass diese ausgewaehlt war. |
|
2179 |
$form->{"unit_old_$i"} = $form->{"unit_$i"}; |
|
2180 |
} |
|
2181 |
|
|
2182 |
# Die zuletzt ausgewaehlte mit der aktuell ausgewaehlten Einheit |
|
2183 |
# vergleichen und bei Unterschied den Preis entsprechend umrechnen. |
|
2184 |
$form->{"selected_unit_$i"} = $form->{"unit_$i"} unless ($form->{"selected_unit_$i"}); |
|
2185 |
|
|
2186 |
if (!$all_units->{$form->{"selected_unit_$i"}} || |
|
2187 |
($all_units->{$form->{"selected_unit_$i"}}->{"base_unit"} ne |
|
2188 |
$all_units->{$form->{"unit_old_$i"}}->{"base_unit"})) { |
|
2189 |
# Die ausgewaehlte Einheit ist fuer diesen Artikel nicht gueltig |
|
2190 |
# (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber |
|
2191 |
# um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen. |
|
2192 |
$form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"}; |
|
2193 |
} |
|
2194 |
|
|
2195 |
my $basefactor = 1; |
|
2196 |
|
|
2197 |
if ($form->{"unit_old_$i"} ne $form->{"selected_unit_$i"}) { |
|
2198 |
if (defined($all_units->{$form->{"unit_old_$i"}}->{"factor"}) && |
|
2199 |
$all_units->{$form->{"unit_old_$i"}}->{"factor"}) { |
|
2200 |
$basefactor = $all_units->{$form->{"selected_unit_$i"}}->{"factor"} / |
|
2201 |
$all_units->{$form->{"unit_old_$i"}}->{"factor"}; |
|
2202 |
} |
|
2203 |
} |
|
2204 |
|
|
2205 |
if (!$form->{"basefactor_$i"}) { |
|
2206 |
$form->{"basefactor_$i"} = 1; |
|
2207 |
} |
|
2208 |
|
|
2209 |
my $query = |
|
2210 |
qq|SELECT |
|
2211 |
0 as pricegroup_id, |
|
2212 |
sellprice AS default_sellprice, |
|
2213 |
'' AS pricegroup, |
|
2214 |
sellprice AS price, |
|
2215 |
'selected' AS selected |
|
2216 |
FROM parts |
|
2217 |
WHERE id = ? |
|
2218 |
UNION ALL |
|
2219 |
SELECT |
|
2220 |
pricegroup_id, |
|
2221 |
parts.sellprice AS default_sellprice, |
|
2222 |
pricegroup.pricegroup, |
|
2223 |
price, |
|
2224 |
'' AS selected |
|
2225 |
FROM prices |
|
2226 |
LEFT JOIN parts ON parts.id = parts_id |
|
2227 |
LEFT JOIN pricegroup ON pricegroup.id = pricegroup_id |
|
2228 |
WHERE parts_id = ? |
|
2229 |
ORDER BY pricegroup|; |
|
2230 |
my @values = (conv_i($id), conv_i($id)); |
|
2231 |
my $pkq = prepare_execute_query($form, $dbh, $query, @values); |
|
2232 |
|
|
2233 |
while (my $pkr = $pkq->fetchrow_hashref('NAME_lc')) { |
|
2234 |
$pkr->{id} = $id; |
|
2235 |
$pkr->{selected} = ''; |
|
2236 |
|
|
2237 |
# if there is an exchange rate change price |
|
2238 |
if (($form->{exchangerate} * 1) != 0) { |
|
2239 |
$pkr->{price} /= $form->{exchangerate}; |
|
2240 |
} |
|
2241 |
|
|
2242 |
$pkr->{price} *= $form->{"basefactor_$i"}; |
|
2243 |
$pkr->{price} *= $basefactor; |
|
2244 |
$pkr->{price_ufmt} = $pkr->{price}; |
|
2245 |
$pkr->{price} = $form->format_amount($myconfig, $pkr->{price}, 5); |
|
2246 |
|
|
2247 |
if (!defined $selectedpricegroup_id) { |
|
2248 |
# new entries in article list, either old invoice was loaded (edit) or a new article was added |
|
2249 |
# Case A: open old invoice, no pricegroup selected |
|
2250 |
# Case B: add new article to invoice, no pricegroup selected |
|
2251 |
|
|
2252 |
# to distinguish case A and B the variable pricegroup_id_$i is used |
|
2253 |
# for new articles this variable isn't defined, for loaded articles it is |
|
2254 |
# sellprice can't be used, as it already has 0,00 set |
|
2255 |
|
|
2256 |
if ($pkr->{pricegroup_id} eq $form->{"pricegroup_id_$i"} and defined $form->{"pricegroup_id_$i"}) { |
|
2257 |
# Case A |
|
2258 |
$pkr->{selected} = ' selected'; |
|
2259 |
} elsif ($pkr->{pricegroup_id} eq $form->{customer_klass} |
|
2260 |
and not defined $form->{"pricegroup_id_$i"} |
|
2261 |
and $pkr->{price_ufmt} != 0 # only use customer pricegroup price if it has a value, else use default_sellprice |
|
2262 |
# for the case where pricegroup prices haven't been set |
|
2263 |
) { |
|
2264 |
# Case B: use default pricegroup of customer |
|
2265 |
|
|
2266 |
$pkr->{selected} = ' selected'; # unless $form->{selected}; |
|
2267 |
# no customer pricesgroup set |
|
2268 |
if ($pkr->{price_ufmt} == $pkr->{default_sellprice}) { |
|
2269 |
|
|
2270 |
$pkr->{price} = $form->{"sellprice_$i"}; |
|
2271 |
|
|
2272 |
} else { |
|
2273 |
|
|
2274 |
# this sub should not set anything and only return. --sschoeling, 20090506 |
|
2275 |
# is this correct? put in again... -- grichardson 20110119 |
|
2276 |
$form->{"sellprice_$i"} = $pkr->{price}; |
|
2277 |
} |
|
2278 |
|
|
2279 |
} elsif ($pkr->{price_ufmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) { |
|
2280 |
$pkr->{price} = $form->{"sellprice_$i"}; |
|
2281 |
$pkr->{selected} = ' selected'; |
|
2282 |
} |
|
2283 |
} |
|
2284 |
|
|
2285 |
# existing article: pricegroup or price changed |
|
2286 |
if ($selectedpricegroup_id or $selectedpricegroup_id == 0) { |
|
2287 |
if ($selectedpricegroup_id ne $pricegroup_old) { |
|
2288 |
# pricegroup has changed |
|
2289 |
if ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { |
|
2290 |
$pkr->{selected} = ' selected'; |
|
2291 |
} |
|
2292 |
} elsif ( ($form->parse_amount($myconfig, $price_new) |
|
2293 |
!= $form->parse_amount($myconfig, $form->{"sellprice_$i"})) |
|
2294 |
and ($price_new ne 0) and defined $price_new) { |
|
2295 |
# sellprice has changed |
|
2296 |
# when loading existing invoices $price_new is NULL |
|
2297 |
if ($pkr->{pricegroup_id} == 0) { |
|
2298 |
$pkr->{price} = $form->{"sellprice_$i"}; |
|
2299 |
$pkr->{selected} = ' selected'; |
|
2300 |
} |
|
2301 |
} elsif ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { |
|
2302 |
# neither sellprice nor pricegroup changed |
|
2303 |
$pkr->{selected} = ' selected'; |
|
2304 |
if ( ($pkr->{pricegroup_id} == 0) and ($pkr->{price} == $form->{"sellprice_$i"})) { |
|
2305 |
# $pkr->{price} = $form->{"sellprice_$i"}; |
|
2306 |
} else { |
|
2307 |
$pkr->{price} = $form->{"sellprice_$i"}; |
|
2308 |
} |
|
2309 |
} |
|
2310 |
} |
|
2311 |
push @{ $form->{PRICES}{$i} }, $pkr; |
|
2312 |
|
|
2313 |
} |
|
2314 |
$form->{"basefactor_$i"} *= $basefactor; |
|
2315 |
|
|
2316 |
$i++; |
|
2317 |
|
|
2318 |
$pkq->finish; |
|
2319 |
} |
|
2320 |
|
|
2321 |
$main::lxdebug->leave_sub(); |
|
2322 |
} |
|
2323 |
|
|
2324 | 2134 |
sub has_storno { |
2325 | 2135 |
$main::lxdebug->enter_sub(); |
2326 | 2136 |
|
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 | 536 |
price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ? |
536 | 537 |
WHERE id = ? |
537 | 538 |
SQL |
... | ... | |
546 | 547 |
$form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f', |
547 | 548 |
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"}, |
548 | 549 |
$form->{"lastcost_$i"}, |
550 |
$form->{"active_price_source_$i"}, |
|
549 | 551 |
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), |
550 | 552 |
conv_i($form->{"marge_price_factor_$i"}), |
551 | 553 |
conv_i($orderitems_id), |
... | ... | |
945 | 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, |
946 | 948 |
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost, |
947 | 949 |
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription, |
948 |
o.price_factor_id, o.price_factor, o.marge_price_factor, |
|
950 |
o.price_factor_id, o.price_factor, o.marge_price_factor, o.active_price_source,
|
|
949 | 951 |
pr.projectnumber, p.formel, |
950 | 952 |
pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup |
951 | 953 |
FROM orderitems o |
SL/PriceSource.pm | ||
---|---|---|
1 |
package SL::PriceSource; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent 'SL::DB::Object'; |
|
5 |
use Rose::Object::MakeMethods::Generic ( |
|
6 |
scalar => [ qw(record_item) ], |
|
7 |
); |
|
8 |
|
|
9 |
use List::UtilsBy qw(min_by); |
|
10 |
use SL::PriceSource::ALL; |
|
11 |
use SL::PriceSource::Price; |
|
12 |
use SL::Locale::String; |
|
13 |
|
|
14 |
sub all_price_sources { |
|
15 |
my ($self) = @_; |
|
16 |
|
|
17 |
return map { |
|
18 |
$_->new(record_item => $self->record_item) |
|
19 |
} SL::PriceSource::ALL->all_price_sources |
|
20 |
} |
|
21 |
|
|
22 |
sub price_from_source { |
|
23 |
my ($self, $source) = @_; |
|
24 |
my ($source_name, $spec) = split m{/}, $source, 2; |
|
25 |
|
|
26 |
my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name); |
|
27 |
|
|
28 |
return $class |
|
29 |
? $class->new(record_item => $self->record_item)->price_from_source($source, $spec) |
|
30 |
: empty_price(); |
|
31 |
} |
|
32 |
|
|
33 |
sub available_prices { |
|
34 |
map { $_->available_prices } $_[0]->all_price_sources; |
|
35 |
} |
|
36 |
|
|
37 |
sub best_price { |
|
38 |
min_by { $_->price } map { $_->best_price } $_[0]->all_price_sources; |
|
39 |
} |
|
40 |
|
|
41 |
sub empty_price { |
|
42 |
SL::PriceSource::Price->new( |
|
43 |
source => '', |
|
44 |
description => t8('None (PriceSource)'), |
|
45 |
); |
|
46 |
} |
|
47 |
|
|
48 |
1; |
|
49 |
|
|
50 |
__END__ |
|
51 |
|
|
52 |
=encoding utf-8 |
|
53 |
|
|
54 |
=head1 NAME |
|
55 |
|
|
56 |
SL::PriceSource - mixin for price_sources in record items |
|
57 |
|
|
58 |
=head1 SYNOPSIS |
|
59 |
|
|
60 |
# in record item class |
|
61 |
|
|
62 |
use SL::PriceSource; |
|
63 |
|
|
64 |
# later on: |
|
65 |
|
|
66 |
$record_item->all_price_sources |
|
67 |
$record_item->price_source # get |
|
68 |
$record_item->price_source($c) # set |
|
69 |
|
|
70 |
$record_item->update_price_source # set price to calculated |
|
71 |
|
|
72 |
=head1 DESCRIPTION |
|
73 |
|
|
74 |
This mixin provides a way to use price_source objects from within a record item. |
|
75 |
Record items in this contest mean OrderItems, InvoiceItems and |
|
76 |
DeliveryOrderItems. |
|
77 |
|
|
78 |
=head1 FUNCTIONS |
|
79 |
|
|
80 |
price_sources |
|
81 |
|
|
82 |
returns a list of price_source objects which are created with the current record |
|
83 |
item. |
|
84 |
|
|
85 |
active_price_source |
|
86 |
|
|
87 |
returns the object representing the currently chosen price_source method or |
|
88 |
undef if custom price is chosen. Note that this must not necessarily be the |
|
89 |
active price, if something affecting the price_source has changed, the price |
|
90 |
calculated can differ from the price in the record. It is the responsibility of |
|
91 |
the implementing code to decide what to do in this case. |
|
92 |
|
|
93 |
=head1 BUGS |
|
94 |
|
|
95 |
None yet. :) |
|
96 |
|
|
97 |
=head1 AUTHOR |
|
98 |
|
|
99 |
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt> |
|
100 |
|
|
101 |
=cut |
SL/PriceSource/ALL.pm | ||
---|---|---|
1 |
package SL::PriceSource::ALL; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use SL::PriceSource::Pricegroup; |
|
5 |
use SL::PriceSource::MasterData; |
|
6 |
|
|
7 |
my %price_sources_by_name = ( |
|
8 |
master_data => 'SL::PriceSource::MasterData', |
|
9 |
pricegroup => 'SL::PriceSource::Pricegroup', |
|
10 |
); |
|
11 |
|
|
12 |
my @price_sources_order = qw( |
|
13 |
master_data |
|
14 |
pricegroup |
|
15 |
); |
|
16 |
|
|
17 |
sub all_price_sources { |
|
18 |
map { $price_sources_by_name{$_} } @price_sources_order; |
|
19 |
} |
|
20 |
|
|
21 |
sub price_source_class_by_name { |
|
22 |
$price_sources_by_name{$_[1]}; |
|
23 |
} |
|
24 |
|
|
25 |
1; |
SL/PriceSource/Base.pm | ||
---|---|---|
1 |
package SL::PriceSource::Base; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(SL::DB::Object); |
|
6 |
use Rose::Object::MakeMethods::Generic ( |
|
7 |
scalar => [ qw(record_item record) ], |
|
8 |
); |
|
9 |
|
|
10 |
sub name { die 'name needs to be implemented' } |
|
11 |
|
|
12 |
sub description { die 'description needs to be implemented' } |
|
13 |
|
|
14 |
sub available_prices { die 'available_prices needs to be implemented' } |
|
15 |
|
|
16 |
sub best_price { die 'best_price needs to be implemented' } |
|
17 |
|
|
18 |
sub price_from_source { die 'price_from_source needs to be implemented:' . "@_" } |
|
19 |
|
|
20 |
sub part { |
|
21 |
$_[0]->record_item->part; |
|
22 |
} |
|
23 |
|
|
24 |
1; |
|
25 |
|
|
26 |
__END__ |
|
27 |
|
|
28 |
=encoding utf-8 |
|
29 |
|
|
30 |
=head1 NAME |
|
31 |
|
|
32 |
SL::PriceSource::Base - <oneliner description> |
|
33 |
|
|
34 |
=head1 SYNOPSIS |
|
35 |
|
|
36 |
# in consuming module |
|
37 |
# TODO: thats bullshit, theres no need to have this pollute the namespace |
|
38 |
# make a manager that handles this |
|
39 |
|
|
40 |
my @list_of_price_sources = $record_item->price_sources; |
|
41 |
for (@list_of_price_sources) { |
|
42 |
my $internal_name = $_->name; |
|
43 |
my $translated_name = $_->description; |
|
44 |
my $price = $_->price; |
|
45 |
} |
|
46 |
|
|
47 |
$record_item->set_active_price_source($price_source) # equivalent to: |
|
48 |
$record_item->active_price_source($price_source->name); |
|
49 |
$record_item->sellprice($price_source->price); |
|
50 |
|
|
51 |
# for finer control |
|
52 |
$price_source->needed_params |
|
53 |
$price_source->supported_params |
|
54 |
|
|
55 |
=head1 DESCRIPTION |
|
56 |
|
|
57 |
PriceSource is an interface that allows generic algorithms to be used, to |
|
58 |
calculate a price for a position in a record. |
|
59 |
|
|
60 |
If any such price_source algorithm is known to the system, a user can chose |
|
61 |
which of them should be used to claculate the price displayed in the record. |
|
62 |
|
|
63 |
The algorithm is saved togetherwith the target price, so that changes in the |
|
64 |
record can recalculate the price accordingly, and otherwise manual changes to |
|
65 |
the price can reset the price_source used to custom (aka no price_source). |
|
66 |
|
|
67 |
=head1 INTERFACE METHODS |
|
68 |
|
|
69 |
=over 4 |
|
70 |
|
|
71 |
=item C<name> |
|
72 |
|
|
73 |
Should return a unique internal name. Should be entered in |
|
74 |
L<SL::PriceSource::ALL> so that a name_to_class lookup works. |
|
75 |
|
|
76 |
=item C<description> |
|
77 |
|
|
78 |
Should return a translated name. |
|
79 |
|
|
80 |
=item C<needed_params> |
|
81 |
|
|
82 |
Should return a list of elements that a record_item NEEDS to be used with this calulation. |
|
83 |
|
|
84 |
Both C<needed_params> nad C<supported_params> are purely informational at this point. |
|
85 |
|
|
86 |
=item C<supported_params> |
|
87 |
|
|
88 |
Should return a list of elements that a record_item MAY HAVE to be used with this calulation. |
|
89 |
|
|
90 |
Both C<needed_params> nad C<supported_params> are purely informational at this point. |
|
91 |
|
|
92 |
=item C<price> |
|
93 |
|
|
94 |
Calculate a price and return. Do not mutate the record_item. Should will return |
|
95 |
undef if price is not applicable to the current record_item. |
|
96 |
|
|
97 |
=back |
|
98 |
|
|
99 |
=head1 BUGS |
|
100 |
|
|
101 |
None yet. :) |
|
102 |
|
|
103 |
=head1 AUTHOR |
|
104 |
|
|
105 |
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt> |
|
106 |
|
|
107 |
=cut |
SL/PriceSource/MasterData.pm | ||
---|---|---|
1 |
package SL::PriceSource::MasterData; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::PriceSource::Base); |
|
5 |
|
|
6 |
use SL::PriceSource::Price; |
|
7 |
use SL::Locale::String; |
|
8 |
|
|
9 |
sub name { 'master_data' } |
|
10 |
|
|
11 |
sub description { t8('Master Data') } |
|
12 |
|
|
13 |
sub available_prices { |
|
14 |
my ($self, %params) = @_; |
|
15 |
|
|
16 |
my $part = $self->part; |
|
17 |
|
|
18 |
return () unless $part; |
|
19 |
|
|
20 |
# TODO: sellprice only in sales, lastcost in purchase |
|
21 |
return $self->make_sellprice($part); |
|
22 |
} |
|
23 |
|
|
24 |
sub price_from_source { |
|
25 |
my ($self, $source, $spec) = @_; |
|
26 |
|
|
27 |
if ($spec eq 'sellprice') { |
|
28 |
return $self->make_sellprice($self->part); |
|
29 |
} |
|
30 |
} |
|
31 |
|
|
32 |
sub make_sellprice { |
|
33 |
my ($self, $part) = @_; |
|
34 |
|
|
35 |
return SL::PriceSource::Price->new( |
|
36 |
price => $part->sellprice, |
|
37 |
source => 'master_data/sellprice', |
|
38 |
description => t8('Sellprice'), |
|
39 |
price_source => $self, |
|
40 |
); |
|
41 |
} |
|
42 |
|
|
43 |
1; |
SL/PriceSource/Price.pm | ||
---|---|---|
1 |
package SL::PriceSource::Price; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent 'SL::DB::Object'; |
|
6 |
use Rose::Object::MakeMethods::Generic ( |
|
7 |
scalar => [ qw(price description source price_source) ], |
|
8 |
array => [ qw(depends_on) ] |
|
9 |
); |
|
10 |
|
|
11 |
sub full_description { |
|
12 |
my ($self) = @_; |
|
13 |
|
|
14 |
$self->price_source |
|
15 |
? $self->price_source->description . ': ' . $self->description |
|
16 |
: $self->description |
|
17 |
} |
|
18 |
|
|
19 |
1; |
SL/PriceSource/Pricegroup.pm | ||
---|---|---|
1 |
package SL::PriceSource::Pricegroup; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::PriceSource::Base); |
|
5 |
|
|
6 |
use SL::PriceSource::Price; |
|
7 |
use SL::Locale::String; |
|
8 |
|
|
9 |
sub name { 'pricegroup' } |
|
10 |
|
|
11 |
sub description { t8('Pricegroup') } |
|
12 |
|
|
13 |
sub available_prices { |
|
14 |
my ($self, %params) = @_; |
|
15 |
|
|
16 |
my $item = $self->record_item; |
|
17 |
|
|
18 |
my $prices = SL::DB::Manager::Price->get_all( |
|
19 |
query => [ parts_id => $item->parts_id, price => { gt => 0 } ], |
|
20 |
with_objects => 'pricegroup', |
|
21 |
order_by => 'pricegroun.id', |
|
22 |
); |
|
23 |
|
|
24 |
return () unless @$prices; |
|
25 |
|
|
26 |
return map { |
|
27 |
$self->make_price($_); |
|
28 |
} @$prices; |
|
29 |
} |
|
30 |
|
|
31 |
sub price_from_source { |
|
32 |
my ($self, $source, $spec) = @_; |
|
33 |
|
|
34 |
my $price = SL::DB::Manager::Price->find_by(id => $spec); |
|
35 |
|
|
36 |
return $self->make_price($price); |
|
37 |
} |
|
38 |
|
|
39 |
sub make_price { |
|
40 |
my ($self, $price_obj) = @_; |
|
41 |
|
|
42 |
SL::PriceSource::Price->new( |
|
43 |
price => $price_obj->price, |
|
44 |
source => 'pricegroup/' . $price_obj->id, |
|
45 |
description => $price_obj->pricegroup->pricegroup, |
|
46 |
price_source => $self, |
|
47 |
) |
|
48 |
} |
|
49 |
|
|
50 |
1; |
bin/mozilla/do.pl | ||
---|---|---|
390 | 390 |
# Kunde mit Rabatt 20 -> Rabatt 5,5 i.O. |
391 | 391 |
$form->{payment_id} = $payment_id if $form->{payment_id} eq ""; |
392 | 392 |
|
393 |
# for pricegroups |
|
394 | 393 |
my $i = $form->{rowcount}; |
395 | 394 |
|
396 | 395 |
if ( ($form->{"partnumber_$i"} eq "") |
... | ... | |
431 | 430 |
$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"} * (1 - $form->{tradediscount})); |
432 | 431 |
$form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}); |
433 | 432 |
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); |
434 |
|
|
435 |
# get pricegroups for parts |
|
436 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
437 |
|
|
438 |
# build up html code for prices_$i |
|
439 |
&set_pricegroup($i); |
|
440 | 433 |
} |
441 | 434 |
|
442 | 435 |
display_form(); |
... | ... | |
849 | 842 |
|
850 | 843 |
} |
851 | 844 |
|
852 |
# show pricegroup in newly loaded invoice when creating invoice from delivery order |
|
853 |
for my $i (1 .. $form->{rowcount}) { |
|
854 |
$form->{"sellprice_pg_$i"} = join '--', $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"}; |
|
855 |
} |
|
856 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
857 |
set_pricegroup($form->{rowcount}); |
|
858 |
|
|
859 | 845 |
display_form(); |
860 | 846 |
|
861 | 847 |
$main::lxdebug->leave_sub(); |
... | ... | |
957 | 943 |
invoice_links(); |
958 | 944 |
prepare_invoice(); |
959 | 945 |
|
960 |
# show pricegroup in newly loaded invoice when creating invoice from delivery order |
|
961 |
for my $i (1 .. $form->{rowcount}) { |
|
962 |
$form->{"sellprice_pg_$i"} = join '--', $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"}; |
|
963 |
} |
|
964 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
965 |
set_pricegroup($_) for 1 .. $form->{rowcount}; |
|
966 |
|
|
967 | 946 |
display_form(); |
968 | 947 |
|
969 | 948 |
$main::lxdebug->leave_sub(); |
bin/mozilla/invoice_io.pl | ||
---|---|---|
88 | 88 |
use SL::AM; |
89 | 89 |
use Data::Dumper; |
90 | 90 |
|
91 |
sub set_pricegroup { |
|
92 |
$main::lxdebug->enter_sub(); |
|
93 |
|
|
94 |
my $form = $main::form; |
|
95 |
my %myconfig = %main::myconfig; |
|
96 |
my $locale = $main::locale; |
|
97 |
|
|
98 |
my $rowcount = shift; |
|
99 |
for my $j (1 .. $rowcount) { |
|
100 |
my $pricegroup_old = $form->{"pricegroup_old_$j"}; |
|
101 |
if ($form->{PRICES}{$j}) { |
|
102 |
my $len = 0; |
|
103 |
my $prices = '<option value="--">' . $locale->text("none (pricegroup)") . '</option>'; |
|
104 |
my $price = 0; |
|
105 |
foreach my $item (@{ $form->{PRICES}{$j} }) { |
|
106 |
|
|
107 |
#$price = $form->round_amount($myconfig, $item->{price}, 5); |
|
108 |
#$price = $form->format_amount($myconfig, $item->{price}, 2); |
|
109 |
my $price = $item->{price}; |
|
110 |
my $pricegroup_id = $item->{pricegroup_id}; |
|
111 |
my $pricegroup = $item->{pricegroup}; |
|
112 |
|
|
113 |
# build drop down list for pricegroups |
|
114 |
$prices .= |
|
115 |
qq|<option value="$price--$pricegroup_id"$item->{selected}>$pricegroup</option>\n|; |
|
116 |
|
|
117 |
$len += 1; |
|
118 |
|
|
119 |
# map { |
|
120 |
# $form->{"${_}_$j"} = |
|
121 |
# $form->format_amount(\%myconfig, $form->{"${_}_$j"}) |
|
122 |
# } qw(sellprice price_new price_old); |
|
123 |
|
|
124 |
# set new selectedpricegroup_id and prices for "Preis" |
|
125 |
if ($item->{selected} && ($pricegroup_id != 0)) { |
|
126 |
$form->{"pricegroup_old_$j"} = $pricegroup_id; |
|
127 |
$form->{"price_new_$j"} = $price; |
|
128 |
# edit: don't change the sellprice here |
|
129 |
# $form->{"sellprice_$j"} = $price; # this must only be updated for existing articles, not new ones |
|
130 |
} |
|
131 |
if ($pricegroup_id == 0) { |
|
132 |
$form->{"price_new_$j"} = $form->{"sellprice_$j"}; |
|
133 |
} |
|
134 |
} |
|
135 |
$form->{"prices_$j"} = $prices; |
|
136 |
} |
|
137 |
} |
|
138 |
$main::lxdebug->leave_sub(); |
|
139 |
} |
|
140 |
|
|
141 | 91 |
sub display_form { |
142 | 92 |
$main::lxdebug->enter_sub(); |
143 | 93 |
|
... | ... | |
188 | 138 |
# $form->{rowcount}--; |
189 | 139 |
# my $rowcount = $form->{rowcount}; |
190 | 140 |
# |
191 |
# # get pricegroups for parts |
|
192 |
# IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
193 |
# |
|
194 |
# # build up html code for prices_$i |
|
195 |
# set_pricegroup($rowcount); |
|
196 |
# |
|
197 | 141 |
# $form->{resubmit} = 1; |
198 | 142 |
# |
199 | 143 |
# } |
bin/mozilla/io.pl | ||
---|---|---|
38 | 38 |
|
39 | 39 |
use Carp; |
40 | 40 |
use CGI; |
41 |
use List::MoreUtils qw(any uniq); |
|
41 |
use List::MoreUtils qw(any uniq apply);
|
|
42 | 42 |
use List::Util qw(min max first); |
43 | 43 |
|
44 | 44 |
use SL::CVar; |
... | ... | |
46 | 46 |
use SL::CT; |
47 | 47 |
use SL::IC; |
48 | 48 |
use SL::IO; |
49 |
use SL::PriceSource; |
|
49 | 50 |
|
50 | 51 |
use SL::DB::Customer; |
51 | 52 |
use SL::DB::Default; |
... | ... | |
149 | 150 |
} |
150 | 151 |
|
151 | 152 |
# column_index |
152 |
my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice_pg sellprice discount linetotal);
|
|
153 |
my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice discount linetotal); |
|
153 | 154 |
my @HEADER = ( |
154 | 155 |
{ id => 'runningnumber', width => 5, value => $locale->text('No.'), display => 1, }, |
155 | 156 |
{ id => 'partnumber', width => 8, value => $locale->text('Number'), display => 1, }, |
... | ... | |
162 | 163 |
{ id => 'serialnr', width => 10, value => $locale->text('Serial No.'), display => 0, }, |
163 | 164 |
{ id => 'projectnr', width => 10, value => $locale->text('Project'), display => 0, }, |
164 | 165 |
{ id => 'sellprice', width => 15, value => $locale->text('Price'), display => !$is_delivery_order, }, |
165 |
{ id => 'sellprice_pg', width => 8, value => $locale->text('Pricegroup'), display => !$is_delivery_order && !$is_purchase, },
|
|
166 |
{ id => 'price_source', width => 5, value => $locale->text('Price Source'), display => !$is_delivery_order, },
|
|
166 | 167 |
{ id => 'discount', width => 5, value => $locale->text('Discount'), display => !$is_delivery_order, }, |
167 | 168 |
{ id => 'linetotal', width => 10, value => $locale->text('Extended'), display => !$is_delivery_order, }, |
168 | 169 |
{ id => 'bin', width => 10, value => $locale->text('Bin'), display => 0, }, |
... | ... | |
196 | 197 |
my $deliverydate = $locale->text('Required by'); |
197 | 198 |
|
198 | 199 |
# special alignings |
199 |
my %align = map { $_ => 'right' } qw(qty ship right sellprice_pg discount linetotal stock_in_out weight);
|
|
200 |
my %align = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight); |
|
200 | 201 |
my %nowrap = map { $_ => 1 } qw(description unit); |
201 | 202 |
|
202 | 203 |
$form->{marge_total} = 0; |
... | ... | |
232 | 233 |
$form->{"sellprice_$i"} = $form->{"price_new_$i"}; |
233 | 234 |
} |
234 | 235 |
|
236 |
my $record_item = _make_record_item($i); |
|
237 |
|
|
235 | 238 |
# unit begin |
236 | 239 |
$form->{"unit_old_$i"} ||= $form->{"unit_$i"}; |
237 | 240 |
$form->{"selected_unit_$i"} ||= $form->{"unit_$i"}; |
... | ... | |
240 | 243 |
|| !AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units)) { # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber |
241 | 244 |
$form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"}; # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen. |
242 | 245 |
} |
243 |
# adjust prices by unit, ignore if pricegroup changed |
|
244 |
if ((!$form->{"prices_$i"}) || ($form->{"new_pricegroup_$i"} == $form->{"old_pricegroup_$i"})) { |
|
245 |
$form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1; |
|
246 |
$form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1; |
|
247 |
$form->{"unit_old_$i"} = $form->{"selected_unit_$i"}; |
|
248 |
} |
|
246 |
|
|
247 |
$form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1; |
|
248 |
$form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1; |
|
249 |
$form->{"unit_old_$i"} = $form->{"selected_unit_$i"}; |
|
250 |
|
|
249 | 251 |
my $this_unit = $form->{"unit_$i"}; |
250 | 252 |
$this_unit = $form->{"selected_unit_$i"} if AM->convert_unit($this_unit, $form->{"selected_unit_$i"}, $all_units); |
251 | 253 |
|
... | ... | |
305 | 307 |
$column_data{ship} = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"}; |
306 | 308 |
} |
307 | 309 |
|
308 |
# build in drop down list for pricesgroups |
|
309 |
# $sellprice_value setzt den Wert etwas unabhängiger von der Darstellung. |
|
310 |
# Hintergrund: Preisgruppen werden hier überprüft und neu berechnet. |
|
311 |
# Vorher wurde der ganze cgi->textfield Block zweimal identisch eingebaut, dass passiert |
|
312 |
# jetzt nach der Abfrage. |
|
313 |
my $sellprice_value; |
|
314 |
if ($form->{"prices_$i"}) { |
|
315 |
$column_data{sellprice_pg} = qq|<select name="sellprice_pg_$i" style="width: 8em">$form->{"prices_$i"}</select>|; |
|
316 |
$sellprice_value =($form->{"new_pricegroup_$i"} != $form->{"old_pricegroup_$i"}) |
|
317 |
? $form->format_amount(\%myconfig, $form->{"price_new_$i"}, $decimalplaces) |
|
318 |
: $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); |
|
319 |
} else { |
|
320 |
# for last row and report |
|
321 |
# set pricegroup drop down list from report menu |
|
322 |
if ($form->{"sellprice_$i"} != 0) { |
|
323 |
# remember the pricegroup_id in pricegroup_old |
|
324 |
# but don't overwrite it |
|
325 |
$form->{"pricegroup_old_$i"} = $form->{"pricegroup_id_$i"}; |
|
326 |
my $default_option = $form->{"sellprice_$i"}.'--'.$form->{"pricegroup_id_$i"}; |
|
327 |
$column_data{sellprice_pg} = NTI($cgi->popup_menu("sellprice_pg_$i", [ $default_option ], $default_option, { $default_option => $form->{"pricegroup_$i"} || '' })); |
|
328 |
} else { |
|
329 |
$column_data{sellprice_pg} = qq| |; |
|
330 |
} |
|
331 |
$sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); |
|
332 |
|
|
333 |
} |
|
334 |
# Falls der Benutzer die Preise nicht anpassen sollte, wird das entsprechende |
|
335 |
# Textfield auf readonly gesetzt. Anm. von Sven: Manipulation der Preise ist |
|
336 |
# immer noch möglich, konsequenterweise sollten diese NUR aus der Datenbank |
|
337 |
# geholt werden. |
|
338 |
my $edit_prices = $main::auth->assert('edit_prices', 1); |
|
339 |
$column_data{sellprice} = (!$edit_prices) |
|
340 |
? $cgi->textfield(-readonly => "readonly", |
|
341 |
-name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value) |
|
342 |
: $cgi->textfield(-name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value); |
|
310 |
my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); |
|
311 |
my $edit_prices = $main::auth->assert('edit_prices', 1) && !$::form->{"active_price_source_$i"}; |
|
312 |
$column_data{sellprice} = (!$edit_prices) |
|
313 |
? $cgi->hidden( -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value |
|
314 |
: $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value); |
|
343 | 315 |
$column_data{discount} = (!$edit_prices) |
344 | 316 |
? $cgi->textfield(-readonly => "readonly", |
345 | 317 |
-name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"})) |
... | ... | |
349 | 321 |
|
350 | 322 |
$column_data{weight} = $form->format_amount(\%myconfig, $form->{"qty_$i"} * $form->{"weight_$i"}, 3) . ' ' . $defaults->{weightunit} if $defaults->{show_weight}; |
351 | 323 |
|
324 |
if ($form->{"id_${i}"}) { |
|
325 |
my $price_source = SL::PriceSource->new(record_item => $record_item); |
|
326 |
my $price = $price_source->price_from_source($::form->{"active_price_source_$i"}); |
|
327 |
$::form->{price_sources}[$i] = $price_source; |
|
328 |
$column_data{price_source} .= $cgi->button(-value => $price->full_description, -onClick => "toggle_price_source($i)"); |
|
329 |
} |
|
330 |
|
|
352 | 331 |
if ($is_delivery_order) { |
353 | 332 |
$column_data{stock_in_out} = calculate_stock_in_out($i); |
354 | 333 |
} |
... | ... | |
433 | 412 |
|
434 | 413 |
if ($is_delivery_order) { |
435 | 414 |
map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost); |
436 |
$form->{"pricegroup_id_$i"} = $form->{"pricegroup_old_$i"} if $form->{"pricegroup_old_$i"}; |
|
437 |
$form->{"sellprice_pg_$i"} = $form->{"hidden_prices_$i"} if $form->{"hidden_prices_$i"}; |
|
438 |
push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost pricegroup_id sellprice_pg); |
|
415 |
push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost); |
|
439 | 416 |
push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}"; |
440 | 417 |
} |
441 | 418 |
|
... | ... | |
443 | 420 |
$cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}), |
444 | 421 |
$cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})), |
445 | 422 |
map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" } |
446 |
(qw(orderitems_id bo pricegroup_old price_old id inventory_accno bin partsgroup partnotes
|
|
423 |
(qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source
|
|
447 | 424 |
income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber |
448 | 425 |
longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars) |
449 | 426 |
); |
... | ... | |
455 | 432 |
# Benutzerdefinierte Variablen für Waren/Dienstleistungen/Erzeugnisse |
456 | 433 |
_render_custom_variables_inputs(ROW2 => \@ROW2, row => $i, part_id => $form->{"id_$i"}); |
457 | 434 |
|
458 |
push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, }; |
|
435 |
push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, obj => $record_item };
|
|
459 | 436 |
} |
460 | 437 |
|
461 | 438 |
$form->{totalweight} = $totalweight; |
... | ... | |
471 | 448 |
$main::lxdebug->leave_sub(); |
472 | 449 |
} |
473 | 450 |
|
474 |
################################################## |
|
475 |
# build html-code for pricegroups in variable $form->{prices_$j} |
|
476 |
|
|
477 |
sub set_pricegroup { |
|
478 |
$main::lxdebug->enter_sub(); |
|
479 |
|
|
480 |
my $form = $main::form; |
|
481 |
my $locale = $main::locale; |
|
482 |
my $cgi = $::request->{cgi}; |
|
483 |
|
|
484 |
_check_io_auth(); |
|
485 |
|
|
486 |
my $rowcount = shift; |
|
487 |
for my $j (1 .. $rowcount) { |
|
488 |
next unless $form->{PRICES}{$j}; |
|
489 |
# build drop down list for pricegroups |
|
490 |
my $option_tmpl = qq|<option value="%s--%s" %s>%s</option>|; |
|
491 |
$form->{"prices_$j"} = join '', map { sprintf $option_tmpl, @$_{qw(price pricegroup_id selected pricegroup)} } |
|
492 |
(+{ pricegroup => $locale->text("none (pricegroup)") }, @{ $form->{PRICES}{$j} }); |
|
493 |
|
|
494 |
foreach my $item (@{ $form->{PRICES}{$j} }) { |
|
495 |
# set new selectedpricegroup_id and prices for "Preis" |
|
496 |
$form->{"pricegroup_old_$j"} = $item->{pricegroup_id} if $item->{selected} && $item->{pricegroup_id}; |
|
497 |
$form->{"sellprice_$j"} = $item->{price} if $item->{selected} && $item->{pricegroup_id}; |
|
498 |
$form->{"price_new_$j"} = $form->{"sellprice_$j"} if $item->{selected} || !$item->{pricegroup_id}; |
|
499 |
} |
|
500 |
|
|
501 |
# save hidden pricegroups for delivery_orders |
|
502 |
next unless my @selected_prices = grep { $_->{selected} } @{ $form->{PRICES}{$j} }; |
|
503 |
$form->{"hidden_prices_$j"} = $selected_prices[-1]{price} . "--" . $selected_prices[-1]{pricegroup_id}; |
|
504 |
} |
|
505 |
$main::lxdebug->leave_sub(); |
|
506 |
} |
|
507 |
|
|
508 | 451 |
sub select_item { |
509 | 452 |
$main::lxdebug->enter_sub(); |
510 | 453 |
|
... | ... | |
633 | 576 |
$form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) |
634 | 577 |
} qw(sellprice listprice lastcost) if $form->{item} ne 'assembly'; |
635 | 578 |
|
636 |
# get pricegroups for parts |
|
637 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
638 |
|
|
639 |
# build up html code for prices_$i |
|
640 |
set_pricegroup($form->{rowcount}); |
|
641 |
|
|
642 | 579 |
&display_form; |
643 | 580 |
|
644 | 581 |
$main::lxdebug->leave_sub(); |
... | ... | |
733 | 670 |
or (($form->{level} eq undef) and ($form->{type} =~ /invoice/)) |
734 | 671 |
or ($form->{type} =~ /sales_order/)) { |
735 | 672 |
|
736 |
# get pricegroups for parts |
|
737 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
738 |
|
|
739 |
# build up html code for prices_$i |
|
740 |
set_pricegroup($form->{rowcount}); |
|
741 |
|
|
742 | 673 |
} |
743 | 674 |
|
744 | 675 |
&display_form; |
... | ... | |
757 | 688 |
taxaccounts bin assembly weight projectnumber project_id |
758 | 689 |
oldprojectnumber runningnumber serialnumber partsgroup payment_id |
759 | 690 |
not_discountable shop ve gv buchungsgruppen_id language_values |
760 |
sellprice_pg pricegroup_old price_old price_new unit_old ordnumber donumber
|
|
691 |
price_old price_new unit_old ordnumber donumber |
|
761 | 692 |
transdate longdescription basefactor marge_total marge_percent |
762 | 693 |
marge_price_factor lastcost price_factor_id partnotes |
763 | 694 |
stock_out stock_in has_sernumber reqdate orderitems_id); |
... | ... | |
1714 | 1645 |
# get details for customer/vendor |
1715 | 1646 |
call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number"); |
1716 | 1647 |
|
1717 |
# get pricegroups for parts |
|
1718 |
IS->get_pricegroups_for_parts(\%::myconfig, \%$::form); |
|
1719 |
|
|
1720 |
# build up html code for prices_$i |
|
1721 |
set_pricegroup($::form->{rowcount}); |
|
1722 |
|
|
1723 | 1648 |
$::form->{rowcount}--; |
1724 | 1649 |
|
1725 | 1650 |
my @shipto_vars = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry |
... | ... | |
1964 | 1889 |
$::form->redo_rows(\@fields, \@new_rows, scalar(@new_rows), $::form->{rowcount}); |
1965 | 1890 |
$::form->{rowcount} -= $removed_rows; |
1966 | 1891 |
} |
1892 |
|
|
1893 |
sub _make_record_item { |
|
1894 |
my ($row) = @_; |
|
1895 |
|
|
1896 |
my $class = { |
|
1897 |
sales_order => 'OrderItem', |
|
1898 |
purchase_oder => 'OrderItem', |
|
1899 |
sales_quotation => 'OrderItem', |
|
1900 |
request_quotation => 'OrderItem', |
|
1901 |
invoice => 'InvoiceItem', |
|
1902 |
purchase_invoice => 'InvoiceItem', |
|
1903 |
purchase_delivery_order => 'DeliveryOrderItem', |
|
1904 |
sales_delivery_order => 'DeliveryOrderItem', |
|
1905 |
}->{$::form->{type}}; |
|
1906 |
|
|
1907 |
return unless $class; |
|
1908 |
|
|
1909 |
$class = 'SL::DB::' . $class; |
|
1910 |
|
|
1911 |
eval "require $class"; |
|
1912 |
|
|
1913 |
my $obj = $::form->{"orderitems_id_$row"} |
|
1914 |
? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"}) |
|
1915 |
: $class->new; |
|
1916 |
|
|
1917 |
for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) { |
|
1918 |
next unless $obj->meta->column($method); |
|
1919 |
if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { |
|
1920 |
$obj->${\"$method\_as_date"}($::form->{"$method\_$row"}); |
|
1921 |
} else { |
|
1922 |
$obj->$method($::form->{"$method\_$row"}); |
|
1923 |
} |
|
1924 |
} |
|
1925 |
|
|
1926 |
if ($::form->{"id_$row"}) { |
|
1927 |
$obj->part(SL::DB::Part->load_cached($::form->{"id_$row"})); |
|
1928 |
} |
|
1929 |
|
|
1930 |
return $obj; |
|
1931 |
} |
bin/mozilla/is.pl | ||
---|---|---|
273 | 273 |
$form->{rowcount} = $i; |
274 | 274 |
|
275 | 275 |
} |
276 |
|
|
277 |
# get pricegroups for parts |
|
278 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
279 |
|
|
280 |
# Problem: set_pricegroup resets the sellprice of old invoices to the price |
|
281 |
# currently defined in the pricegroup, which is a problem if the price has |
|
282 |
# changed, as the old invoice gets the new price |
|
283 |
# set_pricegroup must never be called, when an old invoice is initially loaded |
|
284 |
|
|
285 |
# set_pricegroup($_) for 1 .. $form->{rowcount}; |
|
286 | 276 |
} |
287 | 277 |
$main::lxdebug->leave_sub(); |
288 | 278 |
} |
... | ... | |
614 | 604 |
map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice lastcost); |
615 | 605 |
|
616 | 606 |
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); |
617 |
|
|
618 |
# get pricegroups for parts |
|
619 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
620 |
|
|
621 |
# build up html code for prices_$i |
|
622 |
&set_pricegroup($i); |
|
623 | 607 |
} |
624 | 608 |
|
625 | 609 |
&display_form; |
... | ... | |
837 | 821 |
$form->{forex} = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy'); |
838 | 822 |
$form->{exchangerate} = $form->{forex} if $form->{forex}; |
839 | 823 |
|
840 |
# remember pricegroups for "use as new" |
|
841 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
842 |
set_pricegroup($_) for 1 .. $form->{rowcount}; |
|
843 |
|
|
844 | 824 |
&display_form; |
845 | 825 |
|
846 | 826 |
$main::lxdebug->leave_sub(); |
bin/mozilla/oe.pl | ||
---|---|---|
594 | 594 |
|
595 | 595 |
check_oe_access(); |
596 | 596 |
|
597 |
my $order = _make_record(); |
|
598 |
|
|
597 | 599 |
set_headings($form->{"id"} ? "edit" : "add"); |
598 | 600 |
|
599 | 601 |
$form->{update} = 1; |
... | ... | |
692 | 694 |
$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces); |
693 | 695 |
$form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces); |
694 | 696 |
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty); |
695 |
|
|
696 |
# get pricegroups for parts |
|
697 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
698 |
|
|
699 |
# build up html code for prices_$i |
|
700 |
&set_pricegroup($i); |
|
701 | 697 |
} |
702 | 698 |
|
703 | 699 |
display_form(); |
... | ... | |
1510 | 1506 |
$form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty); |
1511 | 1507 |
} |
1512 | 1508 |
|
1513 |
# show pricegroup in newly loaded invoice when creating invoice from quotation/order |
|
1514 |
IS->get_pricegroups_for_parts(\%myconfig, \%$form); |
|
1515 |
set_pricegroup($_) for 1 .. $form->{rowcount}; |
|
1516 |
|
|
1517 | 1509 |
&display_form; |
1518 | 1510 |
|
1519 | 1511 |
$main::lxdebug->leave_sub(); |
... | ... | |
2118 | 2110 |
|
2119 | 2111 |
$::form->error($::locale->text('No action defined.')); |
2120 | 2112 |
} |
2113 |
|
|
2114 |
sub _make_record { |
|
2115 |
my $obj = SL::DB::Order->new; |
|
2116 |
|
|
2117 |
for my $method (keys %$::form) { |
|
2118 |
next unless $obj->can($method); |
|
2119 |
next unless $obj->meta->column($method); |
|
2120 |
|
|
2121 |
if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { |
|
2122 |
$obj->${\"$method\_as_date"}($::form->{$method}); |
|
2123 |
} elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Integer|Numeric|Float|DoublePrecsion)$/) { |
|
2124 |
$obj->$method($::form->{$method}); |
|
2125 |
} |
|
2126 |
} |
|
2127 |
|
|
2128 |
my @items; |
|
2129 |
for my $i (1 .. $::form->{rowcount}) { |
|
2130 |
next unless $::form->{"id_$i"}; |
|
2131 |
push @items, _make_record_item($i) |
|
2132 |
} |
|
2133 |
|
|
2134 |
$obj->orderitems(@items); |
|
2135 |
|
|
2136 |
return $obj; |
|
2137 |
} |
|
2138 |
|
locale/de/all | ||
---|---|---|
1596 | 1596 |
'No.' => 'Position', |
1597 | 1597 |
'No/individual shipping address' => 'Keine/individuelle Lieferadresse', |
1598 | 1598 |
'None' => 'Kein', |
1599 |
'None (PriceSource)' => 'Freier Preis', |
|
1599 | 1600 |
'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.', |
1600 | 1601 |
'Normalize Customer / Vendor names' => 'Normalisierung Kunden- / Lieferantennamen', |
1601 | 1602 |
'Normalize part description and part notes' => 'Normalisierung Artikelbeschreibung und Artikellangtext (Bemerkung)', |
... | ... | |
1832 | 1833 |
'Price' => 'Preis', |
1833 | 1834 |
'Price Factor' => 'Preisfaktor', |
1834 | 1835 |
'Price Factors' => 'Preisfaktoren', |
1836 |
'Price Source' => 'Preisquelle', |
|
1835 | 1837 |
'Price factor (database ID)' => 'Preisfaktor (Datenbank-ID)', |
1836 | 1838 |
'Price factor (name)' => 'Preisfaktor (Name)', |
1837 | 1839 |
'Price factor deleted!' => 'Preisfaktor gelöscht.', |
... | ... | |
3051 | 3053 |
'no article assigned yet' => 'noch kein Artikel zugewiesen', |
3052 | 3054 |
'no bestbefore' => 'keine Mindesthaltbarkeit', |
3053 | 3055 |
'no chargenumber' => 'keine Chargennummer', |
3054 |
'none (pricegroup)' => 'keine', |
|
3055 | 3056 |
'not configured' => 'nicht konfiguriert', |
3056 | 3057 |
'not delivered' => 'nicht geliefert', |
3057 | 3058 |
'not executed' => 'nicht ausgeführt', |
sql/Pg-upgrade2/recorditem_active_price_source.sql | ||
---|---|---|
1 |
-- @tag: recorditem_active_price_source |
|
2 |
-- @description: Preisquelle in Belegpositionen |
|
3 |
-- @depends: release_2_6_2 |
|
4 |
-- @encoding: utf-8 |
|
5 |
|
|
6 |
ALTER TABLE orderitems ADD COLUMN active_price_source TEXT NOT NULL DEFAULT ''; |
|
7 |
ALTER TABLE delivery_order_items ADD COLUMN active_price_source TEXT NOT NULL DEFAULT ''; |
|
8 |
ALTER TABLE invoice ADD COLUMN active_price_source TEXT NOT NULL DEFAULT ''; |
templates/webpages/oe/_price_sources_row.html | ||
---|---|---|
1 |
[%- USE T8 %] |
|
2 |
[%- USE HTML %] |
|
3 |
[%- USE L %] |
|
4 |
[%- USE LxERP %] |
|
5 |
<tr class="listrow[% i % 2 %]" id="row[% i %]_3" style='display:none'> |
|
6 |
<td colspan="[% row.colspan %]"> |
|
7 |
<span class="[% IF !row.obj.active_price_source %]bold[% END %]"> |
|
8 |
[% L.radio_button_tag('active_price_source_' _ i, label=LxERP.t8('None (PriceSource)'), checked=!row.obj.active_price_source, value='', onChange='update_price_source(' _ i _ ', \'\')') %] |
|
9 |
</span> |
|
10 |
[%- FOREACH price IN price_sources.$i.available_prices %] |
|
11 |
<div class="[% IF price.source == row.obj.active_price_source %]bold[% END %]"> |
|
12 |
[% L.radio_button_tag('active_price_source_' _ i, value=price.source, checked=price.source == row.obj.active_price_source, label=LxERP.format_amount(price.price, 2) _ ' (' _ price.full_description _ ')', onChange='update_price_source(' _ i _ ', \'' _ price.source _ '\', \'' _ LxERP.format_amount(price.price, -2) _ '\')' ) %] |
|
13 |
</div> |
|
14 |
[%- END %] |
|
15 |
</td> |
|
16 |
</tr> |
templates/webpages/oe/sales_order.html | ||
---|---|---|
1 | 1 |
[%- USE T8 %] |
2 | 2 |
[%- USE HTML %] |
3 |
|
|
3 |
[%- USE L %] |
|
4 |
[%- USE LxERP %] |
|
4 | 5 |
[%- PROCESS 'amcvar/render_inputs_block.html' %] |
5 | 6 |
<tr> |
6 | 7 |
<td> |
... | ... | |
74 | 75 |
|
75 | 76 |
</td> |
76 | 77 |
</tr> |
Auch abrufbar als: Unified diff
PriceSource: Erste Version
- Preisgruppen und Stammdaten sind implementiert
- Persistenz in allen Belegen funktioniert
- Rudimentäre Visualisierung funktioniert
- Klassen sind alle da
- Doku fehlt
- Verkauf/Einkaufweiche fehlt
- best_price ungetestet
- Preisgruppen hängen noch nicht von Verkäufer ab
- dependancy system fehlt
- verhalten bei fehlerhaften sources
- pricegroup -> active_source migration