Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
authorJan Büren <jan@lx-office-hosting.de>
Tue, 10 Jan 2012 14:59:30 +0000 (15:59 +0100)
committerJan Büren <jan@lx-office-hosting.de>
Tue, 10 Jan 2012 14:59:30 +0000 (15:59 +0100)
30 files changed:
SL/DN.pm
SL/DO.pm
SL/Form.pm
SL/IC.pm
SL/Template.pm
SL/Template/ShellCommand.pm [new file with mode: 0644]
SL/User.pm
bin/mozilla/ar.pl
bin/mozilla/dn.pl
bin/mozilla/do.pl
bin/mozilla/ic.pl
bin/mozilla/io.pl
bin/mozilla/oe.pl
doc/COPYING
doc/changelog
doc/copyright
doc/dbschema.dia [deleted file]
doc/dokumentenvorlagen-und-variablen.html
js/checkbox_utils.js [deleted file]
locale/de/all
locale/de_DE/all
sql/Pg-upgrade2/delivery_order_items_add_pricegroup_id.sql [new file with mode: 0644]
sql/Pg-upgrade2/employee_deleted.sql [new file with mode: 0644]
templates/webpages/admin/create_dataset.html
templates/webpages/admin/list_users.html
templates/webpages/do/form_footer.html
templates/webpages/do/set_stock_in_out.html
templates/webpages/dunning/show_invoices.html
templates/webpages/ic/search.html
templates/webpages/oe/search.html

index b00a83b..797588a 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -718,6 +718,7 @@ sub print_dunning {
          ar.transdate,       ar.duedate,      ar.customer_id,
          ar.invnumber,       ar.ordnumber,    ar.cp_id,
          ar.amount,          ar.netamount,    ar.paid,
+         ar.curr,
          ar.amount - ar.paid AS open_amount,
          ar.amount - ar.paid + da.fee + da.interest AS linetotal
 
@@ -746,11 +747,13 @@ sub print_dunning {
          c.country,           c.department_1, c.department_2, c.email,     c.customernumber,
          c.greeting,          c.contact,      c.phone,        c.fax,       c.homepage,
          c.email,             c.taxincluded,  c.business_id,  c.taxnumber, c.iban,
+         c,ustid,             e.name as salesman_name,
          co.*
        FROM dunning d
        LEFT JOIN ar          ON (d.trans_id = ar.id)
        LEFT JOIN customer c  ON (ar.customer_id = c.id)
        LEFT JOIN contacts co ON (ar.cp_id = co.cp_id)
+       LEFT JOIN employee e  ON (ar.salesman_id = e.id)
        WHERE (d.dunning_id = ?)
        LIMIT 1|;
   my $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id);
index 8e12694..8d61b0f 100644 (file)
--- a/SL/DO.pm
+++ b/SL/DO.pm
@@ -251,9 +251,9 @@ sub save {
          id, delivery_order_id, parts_id, description, longdescription, qty, base_qty,
          sellprice, discount, unit, reqdate, project_id, serialnumber,
          ordnumber, transdate, cusordnumber,
-         lastcost, price_factor_id, price_factor, marge_price_factor)
+         lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
-         (SELECT factor FROM price_factors WHERE id = ?), ?)|;
+         (SELECT factor FROM price_factors WHERE id = ?), ?, ?)|;
   my $h_item = prepare_query($form, $dbh, $q_item);
 
   my $q_item_stock =
@@ -300,7 +300,8 @@ sub save {
                $form->{"cusordnumber_$i"},
                $form->{"lastcost_$i"},
                conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
-               conv_i($form->{"marge_price_factor_$i"}));
+               conv_i($form->{"marge_price_factor_$i"}),
+               conv_i($form->{"pricegroup_id_$i"}));
     do_statement($form, $h_item, $q_item, @values);
 
     my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
@@ -668,7 +669,7 @@ sub retrieve {
          doi.sellprice, doi.parts_id AS id, doi.unit, doi.discount, p.bin, p.notes AS partnotes,
          doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost,
          doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription,
-         doi.price_factor_id, doi.price_factor, doi.marge_price_factor,
+         doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id,
          pr.projectnumber, dord.transdate AS dord_transdate,
          pg.partsgroup
        FROM delivery_order_items doi
index 6852236..d537d28 100644 (file)
@@ -1106,15 +1106,20 @@ sub parse_template {
   close $temp_fh;
 
   if ($template->uses_temp_file() || $self->{media} eq 'email') {
-    $out = $self->{OUT};
-    $out_mode = $self->{OUT_MODE} || '>';
-    $self->{OUT} = "$self->{tmpfile}";
+    $out              = $self->{OUT};
+    $out_mode         = $self->{OUT_MODE} || '>';
+    $self->{OUT}      = "$self->{tmpfile}";
     $self->{OUT_MODE} = '>';
   }
 
   my $result;
+  my $command_formatter = sub {
+    my ($out_mode, $out) = @_;
+    return $out_mode eq '|-' ? SL::Template::create(type => 'ShellCommand', form => $self)->parse($out) : $out;
+  };
 
   if ($self->{OUT}) {
+    $self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT});
     open(OUT, $self->{OUT_MODE}, $self->{OUT}) or $self->error("error on opening $self->{OUT} with mode $self->{OUT_MODE} : $!");
   } else {
     *OUT = ($::dispatcher->get_standard_filehandles)[1];
@@ -1154,19 +1159,15 @@ sub parse_template {
 
       # if we send html or plain text inline
       if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) {
-        $mail->{contenttype} = "text/html";
-
-        $mail->{message}       =~ s/\r//g;
-        $mail->{message}       =~ s/\n/<br>\n/g;
-        $myconfig->{signature} =~ s/\n/<br>\n/g;
-        $mail->{message} .= "<br>\n-- <br>\n$myconfig->{signature}\n<br>";
+        $mail->{contenttype}    =  "text/html";
+        $mail->{message}        =~ s/\r//g;
+        $mail->{message}        =~ s/\n/<br>\n/g;
+        $myconfig->{signature}  =~ s/\n/<br>\n/g;
+        $mail->{message}       .=  "<br>\n-- <br>\n$myconfig->{signature}\n<br>";
 
         open(IN, "<", $self->{tmpfile})
           or $self->error($self->cleanup . "$self->{tmpfile} : $!");
-        while (<IN>) {
-          $mail->{message} .= $_;
-        }
-
+        $mail->{message} .= $_ while <IN>;
         close(IN);
 
       } else {
@@ -1203,10 +1204,12 @@ sub parse_template {
       #print(STDERR "OUT $self->{OUT}\n");
       for my $i (1 .. $self->{copies}) {
         if ($self->{OUT}) {
-          open OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!");
+          $self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT});
+
+          open  OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!");
           print OUT $_ while <IN>;
           close OUT;
-          seek IN, 0, 0;
+          seek  IN, 0, 0;
 
         } else {
           $self->{attachment_filename} = ($self->{attachment_filename})
index 5396c7a..9b224d6 100644 (file)
--- a/SL/IC.pm
+++ b/SL/IC.pm
@@ -1007,12 +1007,6 @@ sub all_parts {
   $joins_needed{apoe}        = 1 if $joins_needed{cv}   || grep { $form->{$_} || $form->{"l_$_"} } @apoe_filters;
   $joins_needed{invoice_oi}  = 1 if $joins_needed{apoe} || grep { $form->{$_} || $form->{"l_$_"} } @invoice_oi_filters;
 
-  # in bsoorq, use qtys instead of onhand
-  if ($joins_needed{invoice_oi}) {
-    $renamed_columns{onhand} = 'onhand_before_bsooqr';
-    $renamed_columns{qty}    = 'onhand';
-  }
-
   # special case for description search.
   # up in the simple filter section the description filter got interpreted as something like: WHERE description ILIKE '%$form->{description}%'
   # now we'd like to search also for the masked description entered in orderitems and invoice, so...
@@ -1083,6 +1077,13 @@ sub all_parts {
 
   map { $_->{onhand} *= 1 } @{ $form->{parts} };
 
+  # fix qty sign in ap. those are saved negative
+  if ($bsooqr && $form->{bought}) {
+    for my $row (@{ $form->{parts} }) {
+      $row->{qty} *= -1 if $row->{module} eq 'ir';
+    }
+  }
+
   # post processing for assembly parts lists (bom)
   # for each part get the assembly parts and add them into the partlist.
   my @assemblies;
index df18e70..ab499e9 100644 (file)
@@ -16,6 +16,7 @@ use SL::Template::HTML;
 use SL::Template::LaTeX;
 use SL::Template::OpenDocument;
 use SL::Template::PlainText;
+use SL::Template::ShellCommand;
 use SL::Template::XML;
 
 sub create {
diff --git a/SL/Template/ShellCommand.pm b/SL/Template/ShellCommand.pm
new file mode 100644 (file)
index 0000000..0824129
--- /dev/null
@@ -0,0 +1,51 @@
+package SL::Template::ShellCommand;
+
+use parent qw(SL::Template::LaTeX);
+
+use strict;
+
+use String::ShellQuote;
+
+sub new {
+  my $type = shift;
+
+  return $type->SUPER::new(@_);
+}
+
+sub substitute_vars {
+  my ($self, $text, @indices) = @_;
+
+  my $form = $self->{"form"};
+
+  while ($text =~ /$self->{substitute_vars_re}/) {
+    my ($tag_pos, $tag_len) = ($-[0], $+[0] - $-[0]);
+    my ($var, @option_list) = split(/\s+/, $1);
+    my %options             = map { ($_ => 1) } @option_list;
+
+    my $value               = $self->_get_loop_variable($var, 0, @indices);
+    $value                  = $form->parse_amount({ numberformat => $::myconfig{output_numberformat} || $::myconfig{numberformat} }, $value) if $options{NOFORMAT};
+    $value                  = $self->format_string($value); # Don't allow NOESCAPE for arguments passed to shell commands.
+
+    substr($text, $tag_pos, $tag_len, $value);
+  }
+
+  return $text;
+}
+
+sub format_string {
+  my ($self, $variable) = @_;
+
+  return shell_quote_best_effort($variable);
+}
+
+sub get_mime_type {
+  return "text/plain";
+}
+
+sub parse {
+  my ($self, $text) = @_;
+
+  return $self->parse_block($text);
+}
+
+1;
index 49ba339..5d58b5d 100644 (file)
@@ -738,7 +738,7 @@ sub create_employee_entry {
     do_query($form, $dbh, $query, ($self->{login}, $myconfig->{name}, $myconfig->{tel}, "user"));
 
   } elsif ($update_existing) {
-    my $query = qq|UPDATE employee SET name = ?, workphone = ?, role = 'user' WHERE id = ?|;
+    my $query = qq|UPDATE employee SET name = ?, workphone = ?, role = 'user', deleted = 'f' WHERE id = ?|;
     do_query($form, $dbh, $query, $myconfig->{name}, $myconfig->{tel}, $id);
   }
 
index 1522339..a6e1220 100644 (file)
@@ -1046,13 +1046,12 @@ sub update {
 
   $form->{invdate} = $form->{transdate};
 
-  my %saved_variables = map +( $_ => $form->{$_} ), qw(AR AR_amount_1 taxchart_1 oldcustomer);
+  my %saved_variables = map +( $_ => $form->{$_} ), qw(AR AR_amount_1 taxchart_1 customer_id);
 
   &check_name("customer");
 
-  # check_name ruft get_customer auf, oldcustomer wird überschrieben, daher wird dies vorher gemerkt
-  # get_customer holt Bemerkungen als intnotes, für Debitorenbuchungen gibt es aber nur das Feld notes
-  $form->{notes} = $form->{intnotes} if $saved_variables{oldcustomer} ne $form->{customer};
+  # check_name loads customer notes into notes, but ar only knows intnotes, so copy them
+  $form->{notes} = $form->{intnotes} if $saved_variables{customer_id} != $form->{customer_id};
 
   $form->{AR} = $saved_variables{AR};
   if ($saved_variables{AR_amount_1} =~ m/.--./) {
index 132286f..6c3492b 100644 (file)
@@ -368,7 +368,7 @@ sub show_dunning {
                                duedate amount dunning_date dunning_duedate fee interest salesman));
   $report->set_sort_indicator($form->{sort}, $form->{sortdir});
 
-  my $edit_url  = build_std_url('script=is.pl', 'action=edit', 'callback') . '&id=';
+  my $edit_url  = sub { build_std_url('script=' . ($_[0]->{invoice} ? 'is' : 'ar') . '.pl', 'action=edit', 'callback') . '&id=' . $::form->escape($_[0]->{id}) };
   my $print_url = build_std_url('action=print_dunning', 'format=pdf', 'media=screen') . '&dunning_id=';
   my $sort_url  = build_std_url('action=show_dunning', grep { $form->{$_} } @filter_field_list);
 
@@ -403,8 +403,9 @@ sub show_dunning {
 
         'align' => $alignment{$column},
 
-        'link'  => ($column eq 'invnumber'           ? $edit_url  . E($ref->{id})         :
-                    $column eq 'dunning_description' ? $print_url . E($ref->{dunning_id}) : ''),
+        'link'  => (  $column eq 'invnumber'           ? $edit_url->($ref)
+                    : $column eq 'dunning_description' ? $print_url . E($ref->{dunning_id})
+                    :                                    ''),
       };
     }
 
index 4011c5e..17b9fcc 100644 (file)
@@ -173,7 +173,7 @@ sub order_links {
   DO->retrieve('vc'  => $form->{vc},
                'ids' => $form->{id});
 
-  $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes));
+  $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes currency));
   $form->{shipto} = 1 if $form->{id};
 
   # get customer / vendor
@@ -186,6 +186,7 @@ sub order_links {
   }
 
   $form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id));
+  $form->restore_vars(qw(currency)) if ($form->{id} || $form->{convert_from_oe_ids});
   $form->restore_vars(qw(taxincluded)) if $form->{id};
   $form->restore_vars(qw(salesman_id)) if $editing;
 
@@ -826,6 +827,13 @@ sub invoice {
 
   }
 
+  #  show pricegroup in newly loaded invoice when creating invoice from delivery order
+  for my $i (1 .. $form->{rowcount}) {
+    $form->{"sellprice_pg_$i"} = join /--/, $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"};
+  }
+  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
+  set_pricegroup($_) for 1 .. $form->{rowcount};
+
   display_form();
 
   $main::lxdebug->leave_sub();
@@ -924,6 +932,14 @@ sub invoice_multi {
 
   invoice_links();
   prepare_invoice();
+
+  #  show pricegroup in newly loaded invoice when creating invoice from delivery order
+  for my $i (1 .. $form->{rowcount}) {
+    $form->{"sellprice_pg_$i"} = join /--/, $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"};
+  }
+  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
+  set_pricegroup($_) for 1 .. $form->{rowcount};
+
   display_form();
 
   $main::lxdebug->leave_sub();
@@ -992,14 +1008,16 @@ sub calculate_stock_in_out {
   my $in_out   = $form->{type} =~ /^sales/ ? 'out' : 'in';
   my $sinfo    = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_${i}"});
 
+  my $do_qty   = AM->sum_with_unit($::form->{"qty_$i"}, $::form->{"unit_$i"});
   my $sum      = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $sinfo });
+  my $matches  = $do_qty == $sum;
 
   my $content  = $form->format_amount_units('amount'      => $sum * 1,
                                             'part_unit'   => $form->{"partunit_$i"},
                                             'amount_unit' => $all_units->{$form->{"partunit_$i"}}->{base_unit},
                                             'conv_units'  => 'convertible_not_smaller',
                                             'max_places'  => 2);
-  $content     = qq|<span id="stock_in_out_qty_display_${i}">${content}</span> <input type="button" onclick="open_stock_in_out_window('${in_out}', $i);" value="?">|;
+  $content     = qq|<span id="stock_in_out_qty_display_${i}">${content}</span><input type=hidden id='stock_in_out_qty_matches_$i' value='$matches'> <input type="button" onclick="open_stock_in_out_window('${in_out}', $i);" value="?">|;
 
   $main::lxdebug->leave_sub();
 
@@ -1154,8 +1172,13 @@ sub set_stock_in {
 
   _stock_in_out_set_qty_display($stock_info);
 
+  my $do_qty       = AM->sum_with_unit($::form->parse_amount(\%::myconfig, $::form->{do_qty}), $::form->{do_unit});
+  my $transfer_qty = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $stock_info });
+
   $form->header();
-  print $form->parse_html_template('do/set_stock_in_out');
+  print $form->parse_html_template('do/set_stock_in_out', {
+    qty_matches => $do_qty == $transfer_qty,
+  });
 
   $main::lxdebug->leave_sub();
 }
@@ -1249,8 +1272,13 @@ sub set_stock_out {
   } else {
     _stock_in_out_set_qty_display($stock_info);
 
+    my $do_qty       = AM->sum_with_unit($::form->parse_amount(\%::myconfig, $::form->{do_qty}), $::form->{do_unit});
+    my $transfer_qty = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $stock_info });
+
     $form->header();
-    print $form->parse_html_template('do/set_stock_in_out');
+    print $form->parse_html_template('do/set_stock_in_out', {
+      qty_matches => $do_qty == $transfer_qty,
+    });
   }
 
   $main::lxdebug->leave_sub();
index c6714e6..b02e19d 100644 (file)
@@ -1043,7 +1043,7 @@ sub generate_report {
     'listprice'          => { 'text' => $locale->text('List Price'), },
     'microfiche'         => { 'text' => $locale->text('Microfiche'), },
     'name'               => { 'text' => $locale->text('Name'), },
-    'onhand'             => { 'text' => $locale->text('Qty'), },
+    'onhand'             => { 'text' => $locale->text('Stocked Qty'), },
     'ordnumber'          => { 'text' => $locale->text('Order Number'), },
     'partnumber'         => { 'text' => $locale->text('Part Number'), },
     'partsgroup'         => { 'text' => $locale->text('Group'), },
@@ -1052,7 +1052,7 @@ sub generate_report {
     'rop'                => { 'text' => $locale->text('ROP'), },
     'sellprice'          => { 'text' => $locale->text('Sell Price'), },
     'serialnumber'       => { 'text' => $locale->text('Serial Number'), },
-    'soldtotal'          => { 'text' => $locale->text('soldtotal'), },
+    'soldtotal'          => { 'text' => $locale->text('Qty in Selected Records'), },
     'transdate'          => { 'text' => $locale->text('Transdate'), },
     'unit'               => { 'text' => $locale->text('Unit'), },
     'weight'             => { 'text' => $locale->text('Weight'), },
@@ -1136,7 +1136,7 @@ sub generate_report {
     model         => $locale->text('Model')            . ": '$form->{model}'",
     drawing       => $locale->text('Drawing')          . ": '$form->{drawing}'",
     microfiche    => $locale->text('Microfiche')       . ": '$form->{microfiche}'",
-    l_soldtotal   => $locale->text('soldtotal'),
+    l_soldtotal   => $locale->text('Qty in Selected Records'),
     ean           => $locale->text('EAN')              . ": '$form->{ean}'",
   );
 
@@ -1171,7 +1171,7 @@ sub generate_report {
   }
 
   if ($form->{l_linetotal}) {
-    $form->{l_onhand} = "Y";
+    $form->{l_qty} = "Y";
     $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
     $form->{l_linetotallastcost}  = $form->{searchitems} eq 'assembly' && !$form->{bom} ? "" : 'Y' if  $form->{l_lastcost};
     $form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
@@ -1191,20 +1191,31 @@ sub generate_report {
         || $form->{ordered}
         || $form->{rfq}
         || $form->{quoted}) {
-      $form->{l_onhand} = "Y";
+#      $form->{l_onhand} = "Y";
     } else {
       $form->{l_linetotalsellprice} = "";
       $form->{l_linetotallastcost}  = "";
     }
   }
 
+  # soldtotal doesn't make sense with more than one bsooqr option.
+  # so reset it to sold (the most common option), and issue a warning
+  my @bsooqr = qw(sold bought onorder ordered rfq quoted);
+  if ($form->{l_subtotal} && 1 < grep { $form->{$_} } @bsooqr) {
+    my $enabled       = first { $form->{$_} } @bsooqr;
+    $form->{$_}       = ''   for @bsooqr;
+    $form->{$enabled} = 'Y';
+
+    push @options, $::locale->text('Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1', $optiontexts{$enabled});
+  }
+
   IC->all_parts(\%myconfig, \%$form);
 
   my @columns = qw(
-    partnumber description partsgroup bin onhand rop unit listprice
+    partnumber description partsgroup bin onhand rop soldtotal unit listprice
     linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost
     priceupdate weight image drawing microfiche invnumber ordnumber quonumber
-    transdate name serialnumber soldtotal deliverydate ean
+    transdate name serialnumber deliverydate ean
   );
 
   my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs };
@@ -1290,12 +1301,12 @@ sub generate_report {
     $ref->{lastcost}      *= $ref->{exchangerate} / $ref->{price_factor};
 
     # use this for assemblies
-    my $onhand = $ref->{onhand};
+    my $soldtotal = $ref->{soldtotal};
 
     if ($ref->{assemblyitem}) {
       $row->{partnumber}{align}   = 'right';
-      $row->{onhand}{data}        = 0;
-      $onhand                     = 0 if ($form->{sold});
+      $row->{soldtotal}{data}     = 0;
+      $soldtotal                  = 0 if ($form->{sold});
     }
 
     my $edit_link               = build_std_url('action=edit', 'id=' . E($ref->{id}), 'callback');
@@ -1313,11 +1324,11 @@ sub generate_report {
 
     if (!$ref->{assemblyitem}) {
       foreach my $col (@subtotal_columns) {
-        $totals{$col}    += $onhand * $ref->{$col};
-        $subtotals{$col} += $onhand * $ref->{$col};
+        $totals{$col}    += $soldtotal * $ref->{$col};
+        $subtotals{$col} += $soldtotal * $ref->{$col};
       }
 
-      $subtotals{onhand} += $onhand;
+      $subtotals{soldtotal} += $soldtotal;
     }
 
     # set module stuff
@@ -1348,11 +1359,11 @@ sub generate_report {
       my $row = { map { $_ => { 'class' => 'listsubtotal', } } @columns };
 
       if (($form->{searchitems} ne 'assembly') || !$form->{bom}) {
-        $row->{onhand}->{data} = $form->format_amount(\%myconfig, $subtotals{onhand});
+        $row->{soldtotal}->{data} = $form->format_amount(\%myconfig, $subtotals{soldtotal});
       }
 
       map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $subtotals{$_}, 2) } @subtotal_columns;
-      map { $subtotals{$_} = 0 } ('onhand', @subtotal_columns);
+      map { $subtotals{$_} = 0 } ('soldtotal', @subtotal_columns);
 
       $report->add_data($row);
 
index 1805843..dbefff3 100644 (file)
@@ -400,7 +400,7 @@ sub display_row {
 
     if ($is_delivery_order) {
       map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
-      push @hidden_vars, qw(sellprice discount not_discountable price_factor_id lastcost);
+      push @hidden_vars, qw(sellprice discount not_discountable price_factor_id lastcost pricegroup_id);
       push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}";
     }
 
@@ -1517,7 +1517,6 @@ sub print_form {
   delete $form->{OUT};
 
   if ($form->{media} eq 'printer') {
-    #$form->{OUT} = "| $form->{printer_command} &>/dev/null";
     $form->{OUT}      = $form->{printer_command};
     $form->{OUT_MODE} = '|-';
     $form->{printed} .= " $form->{formname}";
index 5947993..dd1d8e2 100644 (file)
@@ -318,7 +318,7 @@ sub form_header {
   # openclosed checkboxes
   my @tmp;
   push @tmp, sprintf qq|<input name="delivered" id="delivered" type="checkbox" class="checkbox" value="1" %s><label for="delivered">%s</label>|,
-                        $form->{"delivered"} ? "checked" : "",  $locale->text('Delivered') if $form->{"type"} =~ /_order$/;
+                        $form->{"delivered"} ? "checked" : "",  $locale->text('Delivery Order created') if $form->{"type"} =~ /_order$/;
   push @tmp, sprintf qq|<input name="closed" id="closed" type="checkbox" class="checkbox" value="1" %s><label for="closed">%s</label>|,
                         $form->{"closed"}    ? "checked" : "",  $locale->text('Closed')    if $form->{id};
   $TMPL_VAR{openclosed} = sprintf qq|<tr><td colspan=%d align=center>%s</td></tr>\n|, 2 * scalar @tmp, join "\n", @tmp if @tmp;
@@ -833,7 +833,7 @@ sub orders {
     'globalprojectnumber'     => { 'text' => $locale->text('Project Number'), },
     'transaction_description' => { 'text' => $locale->text('Transaction description'), },
     'open'                    => { 'text' => $locale->text('Open'), },
-    'delivered'               => { 'text' => $locale->text('Delivered'), },
+    'delivered'               => { 'text' => $locale->text('Delivery Order created'), },
     'marge_total'             => { 'text' => $locale->text('Ertrag'), },
     'marge_percent'           => { 'text' => $locale->text('Ertrag prozentual'), },
     'vcnumber'                => { 'text' => $form->{vc} eq 'customer' ? $locale->text('Customer Number') : $locale->text('Vendor Number'), },
@@ -879,7 +879,7 @@ sub orders {
   };
   push @options, $locale->text('Open')                                                                    if $form->{open};
   push @options, $locale->text('Closed')                                                                  if $form->{closed};
-  push @options, $locale->text('Delivered')                                                               if $form->{delivered};
+  push @options, $locale->text('Delivery Order created')                                                               if $form->{delivered};
   push @options, $locale->text('Not delivered')                                                           if $form->{notdelivered};
   push @options, $locale->text('Periodic invoices active')                                                if $form->{periodic_invoices_actibe};
 
@@ -1849,6 +1849,9 @@ sub delivery_order {
 
   map { $form->{$_} = $old_values{$_} if ($old_values{$_}) } keys %old_values;
 
+  for my $i (1 .. $form->{rowcount}) {
+    (my $dummy, $form->{"pricegroup_id_$i"}) = split /--/, $form->{"sellprice_pg_$i"};
+  }
   update();
 
   $main::lxdebug->leave_sub();
index 083bb41..7edebd1 100644 (file)
@@ -1,13 +1,3 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<TITLE>GNU General Public License</TITLE>
-</HEAD>
-
-<BODY BGCOLOR=ffffff>
-
-
-<pre>
                     GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 
@@ -301,8 +291,8 @@ to attach them to the start of each source file to most effectively
 convey the exclusion of warranty; and each file should have at least
 the "copyright" line and a pointer to where the full notice is found.
 
-    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) 19yy  &lt;name of author&gt;
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -340,7 +330,7 @@ necessary.  Here is a sample; alter the names:
   Yoyodyne, Inc., hereby disclaims all copyright interest in the program
   `Gnomovision' (which makes passes at compilers) written by James Hacker.
 
-  &lt;signature of Ty Coon&gt;, 1 April 1989
+  <signature of Ty Coon>, 1 April 1989
   Ty Coon, President of Vice
 
 This General Public License does not permit incorporating your program into
@@ -348,8 +338,3 @@ proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
-
-
-</BODY>
-</HTML>
-
index 43f6a01..479c59e 100644 (file)
   - Bugfix 1738:  Entwürfe können nicht gelöscht werden
   - Bugfix 1759: Währung bei Kunden / Lieferanten vorbelegen
   - Bugfix 1770: Währung / currency überlebt Workflow über Lieferschein nicht
+  - Bugfix 1770: (zweiter Teil) Preisgruppen überleben Workflow nicht
   - Bugfix 1773: SQL Fehler bei Anzeige von Angeboten
+  - Bugfix 1725: In Mahnungen steht currency nicht als Variable zur Verfügung?
   - Bugfix 1771: Zahlungsausgang: Lieferant wird nicht ausgewählt, wenn Name 2 Leerzeichen hintereinander enthält
+  - Bugfix 1566: Variablen für Verkäufer und USTID in Mahnungsdruck hinzugefügt
+  - Bugfix 1588: Einzelteile eines Erzeugnisses von Verkaufsbericht ausnehmen
+  - Bugfix 1756: Ertrag in Bruttorechnungen korrekt berechnen
+
+
 
 
 2011-06-15 - Release 2.6.3
index 70cdbab..3b87ce7 100644 (file)
@@ -1,6 +1,6 @@
 ######################################################################
-# Lx-Office ERP                                                  
-# distributed from Linet Services GbR - Braunschweig
+# Lx-Office ERP
+# distributed from Linet Services GmbH - Braunschweig
 #
 # based von SQL-Ledger - Author: Dieter Simander
 #
diff --git a/doc/dbschema.dia b/doc/dbschema.dia
deleted file mode 100644 (file)
index 7d6eb07..0000000
Binary files a/doc/dbschema.dia and /dev/null differ
index 1e05032..e1dac11 100644 (file)
@@ -51,6 +51,9 @@ td {
   <li><a href="#variablen_ausgeben">Variablen ausgeben</a>
   </li>
 
+  <li><a href="#verwendung_in_druckbefehlen">Verwendung in Druckbefehlen</a>
+  </li>
+
   <li><a href="dokumentenvorlagen-und-variablen.html#tag_style">
     Anfang und Ende der Tags ver&auml;ndern</a></li>
 
@@ -229,6 +232,31 @@ td {
    zum Inhaltsverzeichnis</a></small><br>
  <hr>
 
+ <h2><a name="verwendung_in_druckbefehlen">Verwendung in Druckbefehlen</a></h2>
+
+ <p>
+  In der Admininstration können Drucker definiert werden. Auch im dort
+  eingebbaren Druckbefehl können die hier aufgelisteten Variablen und
+  Kontrollstrukturen verwendet werden. Ihr Inhalt wird dabei nach den
+  Regeln der gängigen Shells formatiert, sodass Sonderzeichen
+  wie <code>`...`</code> nicht zu unerwünschtem Verhalten führen.
+ </p>
+
+ <p>
+  Dies erlaubt z.B. die Definition eines Faxes als Druckerbefehl, für
+  das die Telefonnummer eines Ansprechpartners als Teil der
+  Kommandozeile verwendet wird. Für ein fiktives Kommando könnte das
+  z.B. wie folgt aussehen:
+ </p>
+
+ <p>
+  <code>send_fax --number &lt;%if cp_phone2%&gt;&lt;%cp_phone2%&gt;&lt;%else%&gt;&lt;%cp_phone1%&gt;&lt;%end%&gt;</code>
+ </p>
+
+ <small><a href="dokumentenvorlagen-und-variablen.html#inhaltsverzeichnis">
+   zum Inhaltsverzeichnis</a></small><br>
+ <hr>
+
  <h2><a name="tag_style">
    Anfang und Ende der Tags ver&auml;ndern</a></h2>
 
@@ -598,7 +626,7 @@ td {
    </tr>
    <tr>
     <td><code>ustid</code></td>
-    <td>Usatzsteuer-Identifikationsnummer</td>
+    <td>Umsatzsteuer-Identifikationsnummer</td>
    </tr>
    <tr>
    <tr>
@@ -1196,6 +1224,11 @@ td {
     <td><code>dn_transdate</code></td>
     <td>Rechnungsdatum</td>
    </tr>
+   <tr>
+    <td><code>dn_curr</code></td>
+    <td>W&auml;hrung, in der die Rechnung erstellt wurde. (Die Rechnungsbetr&auml;ge
+      sind aber immer in der Hauptw&auml;hrung)</td>
+   </tr>
   </table>
  </p>
 
diff --git a/js/checkbox_utils.js b/js/checkbox_utils.js
deleted file mode 100644 (file)
index b5d4e61..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-function checkbox_check_all(cb_name, prefix, start, end) {
-  var i;
-
-  var control = document.getElementsByName(cb_name)[0];
-  if (!control)
-    return;
-
-  var checked = control.checked;
-
-  for (i = start; i <= end; i++) {
-    control = document.getElementsByName(prefix + i)[0];
-    if (control)
-      control.checked = checked;
-  }
-}
index 971c2ac..ebc2f84 100644 (file)
@@ -347,7 +347,7 @@ $self->{texts} = {
   'Cannot delete quotation!'    => 'Angebot kann nicht gelöscht werden!',
   'Cannot delete transaction!'  => 'Buchung kann nicht gelöscht werden!',
   'Cannot delete vendor!'       => 'Lieferant kann nicht gelöscht werden!',
-  'Cannot find matching template for this print request. Please contact your template maintainer. I tried these: #1.' => '',
+  'Cannot find matching template for this print request. Please contact your template maintainer. I tried these: #1.' => 'Konnte keine passende Vorlage für diesen Druckauftrag finden. Bitte benachrichtigen Sie Ihren Vorlagenadministrator. Die folgenden Pfade wurden durchsucht: #1 ',
   'Cannot have a value in both Debit and Credit!' => 'Es kann nicht gleichzeitig Soll und Haben gebucht werden!',
   'Cannot post Payment!'        => 'Zahlung kann nicht gebucht werden!',
   'Cannot post Receipt!'        => 'Beleg kann nicht gebucht werden!',
@@ -577,6 +577,7 @@ $self->{texts} = {
   'Delivery Order Date'         => 'Lieferscheindatum',
   'Delivery Order Date missing!' => 'Lieferscheindatum fehlt!',
   'Delivery Order Number'       => 'Lieferscheinnummer',
+  'Delivery Order created'      => 'Lieferschein erstellt',
   'Delivery Order deleted!'     => 'Lieferschein gel&ouml;scht!',
   'Delivery Orders'             => 'Lieferscheine',
   'Department'                  => 'Abteilung',
@@ -1428,6 +1429,7 @@ $self->{texts} = {
   'Purpose'                     => 'Verwendungszweck',
   'Qty'                         => 'Menge',
   'Qty according to delivery order' => 'Menge laut Lieferschein',
+  'Qty in Selected Records'     => 'Menge in gewählten Belegen',
   'Qty in stock'                => 'Lagerbestand',
   'Quantity'                    => 'Menge',
   'Quantity missing.'           => 'Die Mengenangabe fehlt.',
@@ -1652,6 +1654,7 @@ $self->{texts} = {
   'Steuersatz'                  => 'Steuersatz',
   'Stock'                       => 'Einlagern',
   'Stock value'                 => 'Bestandswert',
+  'Stocked Qty'                 => 'Lagermenge',
   'Storno'                      => 'Storno',
   'Storno (one letter abbreviation)' => 'S',
   'Storno Invoice'              => 'Stornorechnung',
@@ -1660,6 +1663,7 @@ $self->{texts} = {
   'Subject'                     => 'Betreff',
   'Subject:'                    => 'Betreff:',
   'Subtotal'                    => 'Zwischensumme',
+  'Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1' => 'Zwischensummen können nicht zwischen den einzelnen Belegen unterscheiden, es wird nur "#1" angezeigt',
   'Such entries cannot be exported into the DATEV format and have to be fixed as well.' => 'Solche Einträge sind aber nicht DATEV-exportiertbar und müssen ebenfalls korrigiert werden.',
   'Sum Credit'                  => 'Summe Haben',
   'Sum Debit'                   => 'Summe Soll',
@@ -1878,6 +1882,7 @@ $self->{texts} = {
   'There are no items in stock.' => 'Dieser Artikel ist nicht eingelagert.',
   'There are no items on your TODO list at the moment.' => 'Ihre Aufgabenliste enth&auml;lt momentan keine Eintr&auml;ge.',
   'There are still entries in the database for which no unit has been assigned.' => 'Es gibt noch Eintr&auml;ge in der Datenbank, f&uuml;r die keine Einheit zugeordnet ist.',
+  'There are still transfers not matching the qty of the delivery order. Stock operations can not be changed later. Do you really want to proceed?' => 'Einige der Lagerbewegungen sind nicht vollständig und Lagerbewegungen können nachträglich nicht mehr verändert werden. Wollen Sie wirklich fortfahren?',
   'There are usually three ways to install Perl modules.' => 'Es gibt normalerweise drei Arten, ein Perlmodul zu installieren.',
   'There is at least one sales or purchase invoice for which Lx-Office recorded an inventory transaction with taxkeys even though no tax was recorded.' => 'Es gibt mindestens eine Einkaufs- oder Verkaufsrechnung, für die Lx-Office einen Steuerschlüssel ungleich 0 verzeichnet hat, obwohl für Warenbestandsbuchugen bei Rechnungen nie Steuern gebucht werden.',
   'There is at least one transaction for which the user has chosen a logically wrong taxkey.' => 'Es gibt mindestens eine Buchung, bei der ein logisch nicht passender Steuerschlüssel ausgewählt wurde.',
index 3657999..6ab32d5 100644 (file)
@@ -539,6 +539,7 @@ $self->{texts} = {
   'Delivered'                   => 'Geliefert',
   'Delivery Date'               => 'Lieferdatum',
   'Delivery Order'              => 'Lieferschein',
+  'Delivery Order created'      => 'Lieferschein erstellt',
   'Delivery Order Date'         => 'Lieferscheindatum',
   'Delivery Order Date missing!' => 'Lieferscheindatum fehlt!',
   'Delivery Order Number'       => 'Lieferscheinnummer',
diff --git a/sql/Pg-upgrade2/delivery_order_items_add_pricegroup_id.sql b/sql/Pg-upgrade2/delivery_order_items_add_pricegroup_id.sql
new file mode 100644 (file)
index 0000000..4d896d1
--- /dev/null
@@ -0,0 +1,5 @@
+-- @tag: delivery_order_items_add_pricegroup_id
+-- @description: Spalten für Preisgruppen-Id für Lieferscheine
+-- @depends: release_2_6_3
+-- @charset: utf-8
+ALTER TABLE delivery_order_items ADD COLUMN pricegroup_id integer;
diff --git a/sql/Pg-upgrade2/employee_deleted.sql b/sql/Pg-upgrade2/employee_deleted.sql
new file mode 100644 (file)
index 0000000..939580e
--- /dev/null
@@ -0,0 +1,5 @@
+-- @tag: employee_deleted
+-- @description: Benutzer löschbar machen
+-- @depends: release_2_6_3
+
+ALTER TABLE employee ADD COLUMN deleted BOOLEAN DEFAULT 'f';
index 00768f1..ba2d724 100644 (file)
@@ -58,7 +58,9 @@
       <select name="inventory_system">
        [% FOREACH row = INVENTORY_SYSTEMS %]<option value=[% HTML.escape(row.name) %] [% IF row.selected %]selected[% END %]>[% HTML.escape(row.name) | $T8 %]</option>[% END %]
       </select>
+     * f&uuml;r die Bestandsmethode gibt es Einschr&auml;nkungen, siehe Bemerkungen in <a href="doc/umstellung_eur.txt">EUR Umstellung in Mandant</a>.
      </td>
+
     </tr>
 
     <tr>
index eb55dc5..2e6228f 100644 (file)
@@ -40,8 +40,8 @@
 
   <input type="submit" class="submit" name="action" value="[% 'Add User' | $T8 %]">
   <input type="submit" class="submit" name="action" value="[% 'Edit groups' | $T8 %]">
-  <input type="submit" class="submit" name="action" value="[% 'Printer Management' | $T8 %]">
   <input type="submit" class="submit" name="action" value="[% 'Pg Database Administration' | $T8 %]">
+  <input type="submit" class="submit" name="action" value="[% 'Printer Management' | $T8 %]">
   [% IF LOCKED %]
    <input type="submit" class="submit" name="action" value="[% 'Unlock System' | $T8 %]">
    [% ELSE %]
index b81ce8c..a6a5129 100644 (file)
@@ -68,9 +68,9 @@
    [%- UNLESS delivered %]
    <input class="submit" type="submit" name="action_save" value="[% 'Save' | $T8 %]">
    [%- IF vc == 'customer' %]
-   <input class="submit" type="submit" name="action_transfer_out" value="[% 'Transfer out' | $T8 %]">
+   <input class="submit" type="submit" name="action_transfer_out" onclick="return check_transfer_qty()" value="[% 'Transfer out' | $T8 %]">
    [%- ELSE %]
-   <input class="submit" type="submit" name="action_transfer_in" value="[% 'Transfer in' | $T8 %]">
+   <input class="submit" type="submit" name="action_transfer_in"  onclick="return check_transfer_qty()" value="[% 'Transfer in' | $T8 %]">
    [%- END %]
    [%- END %]
    [%- IF id %]
   <input name="callback" type="hidden" value="[% HTML.escape(callback) %]">
 
  </form>
-
+<script type='text/javascript'>
+  function check_transfer_qty() {
+    var all_match = true;
+    var rowcount = $('input[name=rowcount]').val();
+    for (var i = 1; i < rowcount; i++) {
+      if ($('#stock_in_out_qty_matches_' + i).val() != 1) {
+        all_match = false;
+      }
+    }
+
+    if (all_match) {
+      return true;
+    } else {
+      return confirm("[% 'There are still transfers not matching the qty of the delivery order. Stock operations can not be changed later. Do you really want to proceed?' | $T8 %]");
+    }
+  }
+</script>
 </body>
 </html>
index 07e084d..8110594 100644 (file)
@@ -9,6 +9,7 @@
         var row = $('#row').attr('value');
         window.opener.document.getElementsByName("stock_" + $('#in_out').attr('value') + "_" + row)[0].value = $('#stock').attr('value');
         $(window.opener.document.getElementById("stock_in_out_qty_display_" + row)).html($('#qty_display').attr('value'));
+        $(window.opener.document.getElementById("stock_in_out_qty_matches_" + row)).val([% qty_matches %]);
 
         window.close();
       }
index db6b1ad..cd8c434 100644 (file)
@@ -1,6 +1,10 @@
 [%- USE T8 %]
-[% USE HTML %]<body>
- <script type="text/javascript" src="js/checkbox_utils.js"></script>
+[% USE HTML %]
+[% USE L %]
+[% L.javascript_tag('jquery.checkall') %]
+[% SET all_active = 1 %][% FOREACH row = DUNNINGS %][% IF !row.active %][% SET all_active = 0 %][% LAST %][% END %][% END %]
+[% SET all_email = 1 %][% FOREACH row = DUNNINGS %][% IF !row.email %][% SET all_email = 0 %][% LAST %][% END %][% END %]
+<body>
  <script type="text/javascript" src="js/common.js"></script>
  <script type="text/javascript" src="js/dunning.js"></script>
 
    <th class="listheading" colspan="2">[% 'Current / Next Level' | $T8 %]</th>
 
    <th class="listheading">
-    <input type="checkbox" name="selectall_active" id="selectall_active" onclick="checkbox_check_all('selectall_active', 'active_', 1, [% rowcount %]);">
+    [% L.checkbox_tag('selectall_active', checkall='INPUT[name*=active_]', checked=all_active) %]
     <label for="selectall_active">[% 'Active?' | $T8 %]</label>
    </th>
 
    <th class="listheading">
-    <input type="checkbox" name="selectall_email" id="selectall_email" onclick="checkbox_check_all('selectall_email', 'email_', 1, [% rowcount %]);">
+    [% L.checkbox_tag('selectall_email', checkall='INPUT[name*=email_]', checked=all_email) %]
     <label for="selectall_email">[% 'eMail?' | $T8 %]</label>
    </th>
 
index 1d94fe8..18ef3d2 100644 (file)
           </td>
           <td>
            <input name="l_soldtotal" id="l_soldtotal" class="checkbox" type="checkbox" value="Y">
-           <label for="l_soldtotal">[% 'soldtotal' | $T8 %]</label>
+           <label for="l_soldtotal">[% 'Qty in Selected Records' | $T8 %]</label>
           </td>
           <td>
            <input name="l_ean" id="l_ean" class="checkbox" type="checkbox" value="Y">
           </td>
          </tr>
 
+         <tr>
+          <td>
+           <input name="l_onhand" id="l_onhand" class="checkbox" type="checkbox" value="Y">
+           <label for="l_onhand">[% 'Stocked Qty' | $T8 %]</label>
+          </td>
+         </tr>
+
          [% CUSTOM_VARIABLES_INCLUSION_CODE %]
         </table>
        </td>
index 788a1a2..22d83b0 100644 (file)
         </td>
         <td>
          <input name="delivered" id="delivered" class="checkbox" type="checkbox" value="1" checked>
-         <label for="delivered">[% 'Delivered' | $T8 %]</label>
+         <label for="delivered">[% 'Delivery Order created' | $T8 %]</label>
         </td>
        </tr>
 [%- END %]