Whitespace.
[kivitendo-erp.git] / bin / mozilla / ic.pl
index 547acf7..0639731 100644 (file)
@@ -33,7 +33,9 @@
 
 use POSIX qw(strftime);
 use List::Util qw(max);
+use List::MoreUtils qw(any);
 
+use SL::AM;
 use SL::IC;
 use SL::ReportGenerator;
 
@@ -99,7 +101,7 @@ sub search {
 
   $form->{title} = (ucfirst $form->{searchitems}) . "s";
   $form->{title} = $locale->text($form->{title});
-  $form->{title} = $locale->text('Assemblies') if ($is_xyz{assembly});
+  $form->{title} = $locale->text('Assemblies') if ($is_xyz{is_assembly});
 
   $form->{jsscript} = 1;
 
@@ -130,12 +132,42 @@ sub confirm_price_update {
 
   $auth->assert('part_service_assembly_edit');
 
+  my @errors      = ();
+  my $value_found = false;
+
+  foreach my $idx (qw(sellprice listprice), (1..$form->{price_rows})) {
+    my $name      = $idx =~ m/\d/ ? $form->{"pricegroup_${idx}"}      : $idx eq 'sellprice' ? $locale->text('Sell Price') : $locale->text('List Price');
+    my $type      = $idx =~ m/\d/ ? $form->{"pricegroup_type_${idx}"} : $form->{"${idx}_type"};
+    my $value_idx = $idx =~ m/\d/ ? "price_${idx}" : $idx;
+    my $value     = $form->parse_amount(\%myconfig, $form->{$value_idx});
+
+    if ((0 > $value) && ($type eq 'percent')) {
+      push @errors, $locale->text('You cannot adjust the price for pricegroup "#1" by a negative percentage.', $name);
+
+    } elsif (!$value && ($form->{$value_idx} ne '')) {
+      push @errors, $locale->text('No valid number entered for pricegroup "#1".', $name);
+
+    } elsif (0 < $value) {
+      $value_found = 1;
+    }
+  }
+
+  push @errors, $locale->text('No prices will be updated because no prices have been entered.') if (!$value_found);
+
+  my $num_matches = IC->get_num_matches_for_priceupdate();
+
+  $form->header();
+
+  if (@errors) {
+    $form->show_generic_error(join('<br>', @errors), 'back_button' => 1);
+  }
+
   $form->{nextsub} = "update_prices";
-  $form->header;
 
   map { delete $form->{$_} } qw(action header);
 
-  print $form->parse_html_template('ic/confirm_price_update', { HIDDENS => [ map { name => $_, value => $form->{$_} }, keys %$form ] });
+  print $form->parse_html_template('ic/confirm_price_update', { HIDDENS     => [ map { name => $_, value => $form->{$_} }, keys %$form ],
+                                                                num_matches => $num_matches });
 
   $lxdebug->leave_sub();
 }
@@ -145,8 +177,10 @@ sub update_prices {
 
   $auth->assert('part_service_assembly_edit');
 
-  if (IC->update_prices(\%myconfig, \%$form)) {
-    $form->redirect($form->{update_count} . $locale->text('prices updated!'));
+  my $num_updated = IC->update_prices(\%myconfig, \%$form);
+
+  if (-1 != $num_updated) {
+    $form->redirect($locale->text('#1 prices were updated.', $num_updated));
   } else {
     $form->error($locale->text('Could not update prices!'));
   }
@@ -574,9 +608,6 @@ sub addtop100 {
     }
   }
 
-  $form->{l_lastcost} = ""
-    if ($form->{searchitems} eq 'assembly' && !$form->{bom});
-
   foreach my $item (@columns) {
     if ($form->{"l_$item"} eq "Y") {
       push @column_index, $item;
@@ -1114,8 +1145,6 @@ sub generate_report {
     }
   }
 
-  $form->{l_lastcost} = "" if ($form->{searchitems} eq 'assembly' && !$form->{bom});
-
   IC->all_parts(\%myconfig, \%$form);
 
   my @columns =
@@ -1196,6 +1225,8 @@ sub generate_report {
   my $idx       = 0;
   my $same_item = $form->{parts}[0]{ $form->{sort} } if (scalar @{ $form->{parts} });
 
+  my $defaults  = AM->get_defaults();
+
   # postprocess parts
   foreach my $ref (@{ $form->{parts} }) {
 
@@ -1228,6 +1259,8 @@ sub generate_report {
 
     map { $row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{$_}); } qw(onhand rop weight soldtotal);
 
+    $row->{weight}->{data} .= ' ' . $defaults->{weightunit};
+
     if (!$ref->{assemblyitem}) {
       foreach my $col (@subtotal_columns) {
         $totals{$col}    += $onhand * $ref->{$col};
@@ -1464,7 +1497,9 @@ sub form_header {
   map { $form->{$_}       =~ s/"/&quot;/g;        } qw(unit);
 
   $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
-                   'partsgroup'    => 'all_partsgroup');
+                   'partsgroup'    => 'all_partsgroup',
+                   'vendors'       => 'ALL_VENDORS',);
+
 
   IC->retrieve_buchungsgruppen(\%myconfig, $form);
   @{ $form->{BUCHUNGSGRUPPEN} } = grep { $_->{id} eq $form->{buchungsgruppen_id} || ($form->{id} && $form->{orphaned}) || !$form->{id} } @{ $form->{BUCHUNGSGRUPPEN} };
@@ -1475,14 +1510,17 @@ sub form_header {
   $units = AM->retrieve_units(\%myconfig, $form);
   $form->{ALL_UNITS} = [ map +{ name => $_ }, sort { $units->{$a}{sortkey} <=> $units->{$b}{sortkey} } keys %$units ];
 
+  $form->{defaults} = AM->get_defaults();
+
   $form->{fokus} = "ic.partnumber";
 
   $form->header;
-  print $form->parse_html_template('ic/form_header', { ALL_PRICE_FACTORS => $form->{ALL_PRICE_FACTORS},
-                                                       ALL_UNITS         => $form->{ALL_UNITS},
-                                                       BUCHUNGSGRUPPEN   => $form->{BUCHUNGSGRUPPEN},
-                                                       payment_terms     => $form->{payment_terms},
-                                                       all_partsgroup    => $form->{all_partsgroup}});
+  #print $form->parse_html_template('ic/form_header', { ALL_PRICE_FACTORS => $form->{ALL_PRICE_FACTORS},
+  #                                                     ALL_UNITS         => $form->{ALL_UNITS},
+  #                                                     BUCHUNGSGRUPPEN   => $form->{BUCHUNGSGRUPPEN},
+  #                                                     payment_terms     => $form->{payment_terms},
+  #                                                     all_partsgroup    => $form->{all_partsgroup}});
+  print $form->parse_html_template('ic/form_header');
   $lxdebug->leave_sub();
 }
 
@@ -1501,6 +1539,7 @@ sub makemodel_row {
   my ($numrows) = @_;
 
   my @mm_data = grep { any { $_ ne '' } @$_{qw(make model)} } map +{ make => $form->{"make_$_"}, model => $form->{"model_$_"} }, 1 .. $numrows;
+  delete @{$form}{grep { m/^make_\d+/ || m/^model_\d+/ } keys %{ $form }};
   print $form->parse_html_template('ic/makemodel', { MM_DATA => [ @mm_data, {} ], mm_rows => scalar @mm_data + 1 });
 
   $lxdebug->leave_sub();
@@ -1509,13 +1548,12 @@ sub makemodel_row {
 sub assembly_row {
   $lxdebug->enter_sub();
   my ($numrows) = @_;
-  my (@column_index, %column_data, %column_header);
-  my ($nochange, $callback, $previousform, $linetotal, $href);
+  my (@column_index);
+  my ($nochange, $callback, $previousform, $linetotal, $line_purchase_price, $href);
 
   our ($deliverydate); # ToDO: cjeck if this indeed comes from global context
 
-  @column_index =
-    qw(runningnumber qty unit bom partnumber description partsgroup lastcost total);
+  @column_index = qw(runningnumber qty unit bom partnumber description partsgroup lastcost total);
 
   if ($form->{previousform}) {
     $nochange     = 1;
@@ -1530,157 +1568,90 @@ sub assembly_row {
     # delete action
     map { delete $form->{$_} } qw(action header);
 
-    $previousform = "";
-
     # save form variables in a previousform variable
-    foreach my $key (sort keys %$form) {
+    $previousform = $form->escape($form->escape(join '&', map {
+      sprintf "%s=%s", Q($_), /^listprice|lastcost|sellprice$/ ? $form->format_amount(\%myconfig, $form->{$key}) : $form->{$key}
+    } grep { ref $form->{$_} eq '' && $form->{$_} } grep { !/^select/ } sort keys %$form ));
 
-      # escape ampersands
-      $form->{$key} =~ s/&/%26/g;
-      $previousform .= qq|$key=$form->{$key}&|;
-    }
-    chop $previousform;
-    $previousform = $form->escape($form->escape($previousform, 1));
     $form->{callback} = $callback;
-
     $form->{assemblytotal} = 0;
     $form->{assembly_purchase_price_total} = 0;
     $form->{weight}        = 0;
-
   }
-  $column_header{runningnumber} =
-    qq|<th nowrap width=5%>| . $locale->text('No.') . qq|</th>|;
-  $column_header{qty} =
-    qq|<th align=left nowrap width=10%>| . $locale->text('Qty') . qq|</th>|;
-  $column_header{unit} =
-    qq|<th align=left nowrap width=5%>| . $locale->text('Unit') . qq|</th>|;
-  $column_header{partnumber} =
-      qq|<th align=left nowrap width=20%>|
-    . $locale->text('Part Number')
-    . qq|</th>|;
-  $column_header{description} =
-    qq|<th nowrap width=50%>| . $locale->text('Part Description') . qq|</th>|;
-  $column_header{lastcost} =
-    qq|<th nowrap width=50%>| . $locale->text('Purchase Price') . qq|</th>|;
-  $column_header{total} =
-    qq|<th align=right nowrap>| . $locale->text('Extended') . qq|</th>|;
-  $column_header{bom}        = qq|<th>| . $locale->text('BOM') . qq|</th>|;
-  $column_header{partsgroup} = qq|<th>| . $locale->text('Group') . qq|</th>|;
 
-  print qq|
-  <tr class=listheading>
-    <th class=listheading>| . $locale->text('Individual Items') . qq|</th>
-  </tr>
-  <tr>
-    <td>
-      <table width=100%>
-        <tr>
-|;
-
-  map { print "\n$column_header{$_}" } @column_index;
+  my %header = (
+   runningnumber => { text =>  $locale->text('No.'),              nowrap => 1, width => '5%'  },
+   qty           => { text =>  $locale->text('Qty'),              nowrap => 1, width => '10%' },
+   unit          => { text =>  $locale->text('Unit'),             nowrap => 1, width => '5%'  },
+   partnumber    => { text =>  $locale->text('Part Number'),      nowrap => 1, width => '20%' },
+   description   => { text =>  $locale->text('Part Description'), nowrap => 1, width => '50%' },
+   lastcost      => { text =>  $locale->text('Purchase Prices'),  nowrap => 1, width => '50%' },
+   total         => { text =>  $locale->text('Sale Prices'),      nowrap => 1,                },
+   bom           => { text =>  $locale->text('BOM'),                                          },
+   partsgroup    => { text =>  $locale->text('Group'),                                        },
+  );
 
-  print qq|
-        </tr>
-|;
+  my @ROWS;
 
   for my $i (1 .. $numrows) {
+    my (%row, @row_hiddens);
+
     $form->{"partnumber_$i"} =~ s/\"/&quot;/g;
 
-    $linetotal =
-      $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
-    $line_purchase_price  = 
-      $form->round_amount($form->{"lastcost_$i"} * $form->{"qty_$i"}, 2); #lastcost == purchase_price | ungenaue datenbankfeld-übersetzung
-    $form->{assemblytotal} += $linetotal;
+    $linetotal           = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4);
+    $line_purchase_price = $form->round_amount($form->{"lastcost_$i"} *  $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4);
+    $form->{assemblytotal}                  += $linetotal;
     $form->{assembly_purchase_price_total}  += $line_purchase_price;
-
-    $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
-
-    $linetotal = $form->format_amount(\%myconfig, $linetotal, 2);
+    $form->{"qty_$i"}    = $form->format_amount(\%myconfig, $form->{"qty_$i"});
+    $linetotal           = $form->format_amount(\%myconfig, $linetotal, 2);
     $line_purchase_price = $form->format_amount(\%myconfig, $line_purchase_price, 2);
+    $href                = qq|$form->{script}?action=edit&id=$form->{"id_$i"}&rowcount=$i&previousform=$previousform|;
+    map { $row{$_}{data} = "" } qw(qty unit partnumber description bom partsgroup runningnumber);
 
+    # last row
     if (($i >= 1) && ($i == $numrows)) {
-
-      if ($nochange) {
-        map { $column_data{$_} = qq|<td></td>| }
-          qw(qty unit partnumber description bom partsgroup);
-      } else {
-
-        map { $column_data{$_} = qq|<td></td>| } qw(runningnumber unit bom);
-
-        $column_data{qty} =
-          qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
-        $column_data{partnumber} =
-          qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}"></td>|;
-        $column_data{description} =
-          qq|<td><input name="description_$i" size=40 value="$form->{"description_$i"}"></td>|;
-        $column_data{partsgroup} =
-          qq|<td><input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}"></td>|;
-
+      if (!$form->{previousform}) {
+        $row{partnumber}{data}  = qq|<input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}">|;
+        $row{qty}{data}         = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|;
+        $row{description}{data} = qq|<input name="description_$i" size=40 value="$form->{"description_$i"}">|;
+        $row{partsgroup}{data}  = qq|<input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}">|;
       }
-
+    # other rows
     } else {
-
       if ($form->{previousform}) {
-        $column_data{partnumber} =
-          qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}">$form->{"partnumber_$i"}</td>|;
-        $column_data{qty} =
-          qq|<td align=right><input type=hidden name="qty_$i" value="$form->{"qty_$i"}">$form->{"qty_$i"}</td>|;
-
-        $column_data{bom} =
-          qq|<td align=center><input type=hidden name="bom_$i" value=$form->{"bom_$i"}>|;
-        $column_data{bom} .= ($form->{"bom_$i"}) ? "x" : "&nbsp;";
-        $column_data{bom} .= qq|</td>|;
-
-        $column_data{partsgroup} =
-          qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
-
+        push @row_hiddens,          qw(qty bom);
+        $row{partnumber}{data}    = $form->{"partnumber_$i"};
+        $row{qty}{data}           = $form->{"qty_$i"};
+        $row{bom}{data}           = $form->{"bom_$i"} ? "x" : "&nbsp;";
+        $row{qty}{align}          = 'right';
       } else {
-        $href =
-          qq|$form->{script}?action=edit&id=$form->{"id_$i"}&rowcount=$i&previousform=$previousform|;
-        $column_data{partnumber} =
-          qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}"><a href=$href>$form->{"partnumber_$i"}</a></td>|;
-        $column_data{runningnumber} =
-          qq|<td><input name="runningnumber_$i" size=3 value="$i"></td>|;
-        $column_data{qty} =
-          qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
-
-        $form->{"bom_$i"} = ($form->{"bom_$i"}) ? "checked" : "";
-        $column_data{bom} =
-          qq|<td align=center><input name="bom_$i" type=checkbox class=checkbox value=1 $form->{"bom_$i"}></td>|;
-
-        $column_data{partsgroup} =
-          qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
+        $row{partnumber}{data}    = qq|<a href=$href>$form->{"partnumber_$i"}</a>|;
+        $row{qty}{data}           = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|;
+        $row{runningnumber}{data} = qq|<input name="runningnumber_$i" size=3 value="$i">|;
+        $row{bom}{data}   = sprintf qq|<input name="bom_$i" type=checkbox class=checkbox value=1 %s>|,
+                                       $form->{"bom_$i"} ? 'checked' : '';
       }
-
-      $column_data{unit} =
-        qq|<td><input type=hidden name="unit_$i" value="$form->{"unit_$i"}">$form->{"unit_$i"}</td>|;
-      $column_data{description} =
-        qq|<td><input type=hidden name="description_$i" value="$form->{"description_$i"}">$form->{"description_$i"}</td>|;
+      push @row_hiddens,        qw(unit description partnumber partsgroup);
+      $row{unit}{data}        = $form->{"unit_$i"};
+      $row{description}{data} = $form->{"description_$i"};
+      $row{partsgroup}{data}  = $form->{"partsgroup_$i"};
+      $row{bom}{align}        = 'center';
     }
 
-    $column_data{lastcost} = qq|<td align=right>$line_purchase_price</td>|;
-    $column_data{total} = qq|<td align=right>$linetotal</td>|;
-
-    $column_data{deliverydate} = qq|<td align=right>$deliverydate</td>|;
-
-    print qq|
-        <tr>|;
+    $row{lastcost}{data}      = $line_purchase_price;
+    $row{total}{data}         = $linetotal;
+    $row{deliverydate}{data}  = $deliverydate;
+    $row{lastcost}{align}     = 'right';
+    $row{total}{align}        = 'right';
+    $row{deliverydate}{align} = 'right';
 
-    map { print "\n$column_data{$_}" } @column_index;
+    push @row_hiddens, qw(id sellprice lastcost weight price_factor_id price_factor);
+    $row{hiddens} = [ map +{ name => "${_}_$i", value => $form->{"${_}_$i"} }, @row_hiddens ];
 
-    print qq|
-        </tr>
-  <input type=hidden name="id_$i" value=$form->{"id_$i"}>
-  <input type=hidden name="sellprice_$i" value=$form->{"sellprice_$i"}>
-  <input type=hidden name="weight_$i" value=$form->{"weight_$i"}>
-|;
+    push @ROWS, \%row;
   }
 
-  print qq|
-      </table>
-    </td>
-  </tr>
-|;
+  print $form->parse_html_template('ic/assembly_row', { COLUMNS => \@column_index, ROWS => \@ROWS, HEADER => \%header });
 
   $lxdebug->leave_sub();
 }
@@ -1688,6 +1659,9 @@ sub assembly_row {
 sub update {
   $lxdebug->enter_sub();
 
+  # parse pricegroups. and no, don't rely on check_form for this...
+  map { $form->{"price_$_"} = $form->parse_amount(\%myconfig, $form->{"price_$_"}) } 1 .. $form->{price_rows};
+
   if ($form->{item} eq "assembly") {
     my $i = $form->{assembly_rows};
 
@@ -1820,7 +1794,8 @@ sub save {
       # change/add values for assembly item
       map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno price_factor_id);
 
-      $form->{sellprice} += $form->{"sellprice_$i"} * $form->{"qty_$i"};
+      # das ist __voll__ bekloppt, dass so auszurechnen jb 22.5.09
+      #$form->{sellprice} += $form->{"sellprice_$i"} * $form->{"qty_$i"};
       $form->{weight}    += $form->{"weight_$i"} * $form->{"qty_$i"};
 
     } else {