Merge branch 'master' of https://github.com/kivitendo/kivitendo-erp
authorNiclas Zimmermann <niclas@kivitendo-premium.de>
Mon, 6 Jan 2014 14:15:13 +0000 (15:15 +0100)
committerNiclas Zimmermann <niclas@kivitendo-premium.de>
Mon, 6 Jan 2014 14:15:13 +0000 (15:15 +0100)
SL/Controller/Helper/ParseFilter.pm
SL/Controller/Inventory.pm
SL/DB/Manager/BackgroundJobHistory.pm
SL/DN.pm
SL/DO.pm
SL/Presenter/Record.pm
bin/mozilla/dn.pl
locale/de/all
templates/webpages/ap/form_footer.html
templates/webpages/ir/form_header.html

index afe9b7b..9b5eb51 100644 (file)
@@ -101,16 +101,31 @@ sub _parse_filter {
   my @result;
   for (my $i = 0; $i < scalar @$flattened; $i += 2) {
     my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
+    my ($type, $op)   = $key =~ m{:(.+)::(.+)};
 
     ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/,  { %filters, %{ $params{filters} || {} } });
     ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } });
     ($key, $value) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value) if $params{class};
+    ($key, $value) = _apply_value_filters($key, $value, $type, $op);
 
     push @result, $key, $value if defined $key;
   }
   return \@result;
 }
 
+sub _apply_value_filters {
+  my ($key, $value, $type, $op) = @_;
+
+  return ($key, $value) unless $key && $value && $type && $op && (ref($value) eq 'HASH');
+
+  if (($type eq 'date') && ($op eq 'le')) {
+    my $date     = delete $value->{le};
+    $value->{lt} = $date->add(days => 1);
+  }
+
+  return ($key, $value);
+}
+
 sub _dispatch_custom_filters {
   my ($class, $with_objects, $key, $value) = @_;
 
index 3f406ee..0a41f0b 100644 (file)
@@ -44,28 +44,35 @@ sub action_stock_in {
 sub action_stock {
   my ($self) = @_;
 
-  # do stock
-  WH->transfer({
-    parts         => $self->part,
-    dst_bin       => $self->bin,
-    dst_wh        => $self->warehouse,
-    qty           => $::form->parse_amount(\%::myconfig, $::form->{qty}),
-    unit          => $self->unit,
-    transfer_type => 'stock',
-    chargenumber  => $::form->{chargenumber},
-    ean           => $::form->{ean},
-    comment       => $::form->{comment},
-  });
-
-  if ($::form->{write_default_bin}) {
-    $self->part->load;   # onhand is calculated in between. don't mess that up
-    $self->part->bin($self->bin);
-    $self->part->warehouse($self->warehouse);
-    $self->part->save;
+  my $qty = $::form->parse_amount(\%::myconfig, $::form->{qty});
+  if (!$qty) {
+    flash_later('error', t8('Cannot stock without amount'));
+  } elsif ($qty < 0) {
+    flash_later('error', t8('Cannot stock negative amounts'));
+  } else {
+    # do stock
+    WH->transfer({
+      parts         => $self->part,
+      dst_bin       => $self->bin,
+      dst_wh        => $self->warehouse,
+      qty           => $qty,
+      unit          => $self->unit,
+      transfer_type => 'stock',
+      chargenumber  => $::form->{chargenumber},
+      ean           => $::form->{ean},
+      comment       => $::form->{comment},
+    });
+
+    if ($::form->{write_default_bin}) {
+      $self->part->load;   # onhand is calculated in between. don't mess that up
+      $self->part->bin($self->bin);
+      $self->part->warehouse($self->warehouse);
+      $self->part->save;
+    }
+
+    flash_later('info', t8('Transfer successful'));
   }
 
-  flash_later('info', t8('Transfer successful'));
-
   # redirect
   $self->redirect_to(
     action       => 'stock_in',
index 4f1ddd3..5d7b0d0 100644 (file)
@@ -13,7 +13,7 @@ sub object_class { 'SL::DB::BackgroundJobHistory' }
 __PACKAGE__->make_manager_methods;
 
 sub _sort_spec {
-  return ( default => [ 'run_at', 1 ],
+  return ( default => [ 'run_at', 0 ],
            columns => { SIMPLE => 'ALL' } );
 }
 
index c38733e..ebfa4f3 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -327,12 +327,13 @@ sub save_dunning {
 
   $form->{DUNNING_PDFS_EMAIL} = [];
 
+  $form->{dunning_id} = $dunning_id;
+
   $self->create_invoice_for_fees($myconfig, $form, $dbh, $dunning_id);
 
   $self->print_invoice_for_fees($myconfig, $form, $dunning_id, $dbh);
   $self->print_dunning($myconfig, $form, $dunning_id, $dbh);
 
-  $form->{dunning_id} = $dunning_id;
 
   if ($send_email) {
     $self->send_email($myconfig, $form, $dunning_id, $dbh);
index d83c49b..bc651c8 100644 (file)
--- a/SL/DO.pm
+++ b/SL/DO.pm
@@ -725,6 +725,8 @@ sub order_details {
   my @partsgroup = ();
   my $partsgroup;
   my $position = 0;
+  my $subtotal_header = 0;
+  my $subposition = 0;
 
   my (@project_ids, %projectnumbers, %projectdescriptions);
 
@@ -797,8 +799,6 @@ sub order_details {
 
     next if (!$form->{"id_$i"});
 
-    $position++;
-
     if ($item->[1] ne $sameitem) {
       push(@{ $form->{description} }, qq|$item->[1]|);
       $sameitem = $item->[1];
@@ -809,6 +809,19 @@ sub order_details {
     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
 
     # add number, description and qty to $form->{number}, ....
+    if ($form->{"subtotal_$i"} && !$subtotal_header) {
+      $subtotal_header = $i;
+      $position = int($position);
+      $subposition = 0;
+      $position++;
+    } elsif ($subtotal_header) {
+      $subposition += 1;
+      $position = int($position);
+      $position = $position.".".$subposition;
+    } else {
+      $position = int($position);
+      $position++;
+    }
 
     my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
 
@@ -826,6 +839,10 @@ sub order_details {
     push @{ $form->{TEMPLATE_ARRAYS}{projectdescription} },
       $projectdescriptions{$form->{"project_id_$i"}};
 
+    if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
+      $subtotal_header     = 0;
+    }
+
     my $lineweight = $form->{"qty_$i"} * $form->{"weight_$i"};
     $totalweight += $lineweight;
     push @{ $form->{TEMPLATE_ARRAYS}->{weight} },            $form->format_amount($myconfig, $form->{"weight_$i"}, 3);
index a00f400..4f9a518 100644 (file)
@@ -37,7 +37,7 @@ sub grouped_record_list {
   $output .= _purchase_order_list(         $self, $groups{purchase_orders},          %params) if $groups{purchase_orders};
   $output .= _purchase_delivery_order_list($self, $groups{purchase_delivery_orders}, %params) if $groups{purchase_delivery_orders};
   $output .= _purchase_invoice_list(       $self, $groups{purchase_invoices},        %params) if $groups{purchase_invoices};
-  $output .= _ar_transaction_list(         $self, $groups{ar_transactions},          %params) if $groups{ar_transactions};
+  $output .= _ap_transaction_list(         $self, $groups{ap_transactions},          %params) if $groups{ap_transactions};
 
   $output .= _sepa_collection_list(        $self, $groups{sepa_collections},         %params) if $groups{sepa_collections};
   $output .= _sepa_transfer_list(          $self, $groups{sepa_transfers},           %params) if $groups{sepa_transfers};
index 01658ab..9cac44e 100644 (file)
@@ -251,7 +251,8 @@ sub save_dunning {
 
   $form->{language_id} = $saved_language_id;
 
-  if($form->{DUNNING_PDFS}) {
+  if (scalar @{ $form->{DUNNING_PDFS} }) {
+    $form->{dunning_id} = strftime("%Y%m%d", localtime time) if scalar @{ $form->{DUNNING_PDFS}} > 1;
     DN->melt_pdfs(\%myconfig, $form, $form->{copies});
   }
 
@@ -498,6 +499,7 @@ sub print_multiple {
     if (!$form->{force_lang}) {
       $form->{language_id} = $language_ids[$i];
     }
+    $form->{dunning_id} = $dunning_id;
     DN->print_invoice_for_fees(\%myconfig, $form, $dunning_id);
     DN->print_dunning(\%myconfig, $form, $dunning_id);
     $i++;
@@ -505,7 +507,7 @@ sub print_multiple {
   $form->{language_id} = $saved_language_id;
 
   if (scalar @{ $form->{DUNNING_PDFS} }) {
-    $form->{dunning_id} = strftime("%Y%m%d", localtime time);
+    $form->{dunning_id} = strftime("%Y%m%d", localtime time) if scalar @{ $form->{DUNNING_PDFS}} > 1;
     DN->melt_pdfs(\%myconfig, $form, $form->{copies});
 
     if ($form->{media} eq 'printer') {
index 05673c9..038ed28 100755 (executable)
@@ -18,10 +18,8 @@ $self->{texts} = {
   '#1 h'                        => '#1 h',
   '#1 of #2 importable objects were imported.' => '#1 von #2 importierbaren Objekten wurden importiert.',
   '#1 prices were updated.'     => '#1 Preise wurden aktualisiert.',
-  '(recommended) Insert the used currencies in the system. You can simply change the name of the currencies by editing the textfields above. Do not use a name of a currency that is already in use.' => '(empfohlen) F&uuml;gen Sie die verwaisten Währungen in Ihr System ein. Sie können den Namen der Währung einfach ändern, indem Sie die Felder oben bearbeiten. Benutzen Sie keine Namen von Währungen, die Sie bereits benutzen.',
   '%'                           => '%',
-  '* there are restrictions for the perpetual method, look at chapter "Bemerkungen zu Bestandsmethode"  in' => ' für die Bestandsmethode gibt es Einschränkungen, siehe Kapitel "Bemerkungen zu Bestandsmethode"  in',
-  '*) Since version 2.7 these parameters ares set in the client database and not in the configuration file, details in chapter:' => '*) Seit 2.7 werden Gewinnermittlungsart, Versteuerungsart und Warenbuchungsmethode in der Mandanten-DB gesteuert und nicht mehr in der Konfigurationsdatei, Umstellungs-Details:',
+  '(recommended) Insert the used currencies in the system. You can simply change the name of the currencies by editing the textfields above. Do not use a name of a currency that is already in use.' => '(empfohlen) F&uuml;gen Sie die verwaisten Währungen in Ihr System ein. Sie können den Namen der Währung einfach ändern, indem Sie die Felder oben bearbeiten. Benutzen Sie keine Namen von Währungen, die Sie bereits benutzen.',
   '*/'                          => '*/',
   ', if set'                    => ', falls gesetzt',
   '---please select---'         => '---bitte auswählen---',
@@ -408,6 +406,8 @@ $self->{texts} = {
   'Cannot save order!'          => 'Auftrag kann nicht gespeichert werden!',
   'Cannot save preferences!'    => 'Einstellungen können nicht gespeichert werden!',
   'Cannot save quotation!'      => 'Angebot kann nicht gespeichert werden!',
+  'Cannot stock negative amounts' => 'Negative Mengen können nicht eingelagert werden!',
+  'Cannot stock without amount' => 'Kann nicht ohne Menge einlagern!',
   'Cannot storno invoice for a closed period!' => 'Das Rechnungsdatum der zu stornierenden Rechnung fällt in einen abgeschlossenen Zeitraum!',
   'Cannot storno storno invoice!' => 'Kann eine Stornorechnung nicht stornieren',
   'Cannot transfer. <br> Reason:<br>#1' => 'Kann nicht auslagern. <br>Grund:<br>#1',
@@ -420,7 +420,6 @@ $self->{texts} = {
   'Cc E-mail'                   => 'CC (E-Mail)',
   'Change default bin for this parts' => 'Standardlagerplatz für diese Waren ändern',
   'Change kivitendo installation settings (most entries in the \'System\' menu)' => 'Verändern der kivitendo-Installationseinstellungen (die meisten Menüpunkte unterhalb von \'System\')',
-  'Change representative to'    => 'Vertreter ändern in',
   'Changes in this block are only sensible if the account is NOT a summary account AND there exists one valid taxkey. To select both Receivables and Payables only make sense for Payment / Receipt (i.e. account cash).' => 'Es ist nur sinnvoll Änderungen vorzunehmen, wenn das Konto KEIN Sammelkonto ist und wenn ein gültiger Steuerschlüssel für das Konto existiert. Gleichzeitig Haken bei Forderungen und Verbindlichkeiten zu setzen, macht auch NUR für den Zahlungsein- und Ausgang (bspw. Bank oder Kasse) Sinn.',
   'Changes to Receivables and Payables are only possible if no transactions to this account are posted yet.' => 'Änderungen bei Forderungen oder Verbindlichkeiten sind nur möglich, wenn dieses Konto noch nicht bebucht wurde.',
   'Charge Number'               => 'Chargennummer',
@@ -519,7 +518,6 @@ $self->{texts} = {
   'Create a new project type'   => 'Einen neuen Projekttypen anlegen',
   'Create a new user'           => 'Einen neuen Benutzer anlegen',
   'Create a new user group'     => 'Eine neue Benutzergruppe erfassen',
-  'Create a standard group'     => 'Eine Standard-Benutzergruppe anlegen',
   'Create and edit RFQs'        => 'Lieferantenanfragen erfassen und bearbeiten',
   'Create and edit dunnings'    => 'Mahnungen erfassen und bearbeiten',
   'Create and edit invoices and credit notes' => 'Rechnungen und Gutschriften erfassen und bearbeiten',
@@ -545,8 +543,8 @@ $self->{texts} = {
   'Create new delivery term'    => 'Neue Lieferbedingungen anlegen',
   'Create new department'       => 'Neue Abteilung erfassen',
   'Create new payment term'     => 'Neue Zahlungsbedingung anlegen',
-  'Create new templates from master templates' => 'Neue Druckvorlagen aus Vorlagensatz erstellen',
   'Create new project type'     => 'Neuen Projekttypen anlegen',
+  'Create new templates from master templates' => 'Neue Druckvorlagen aus Vorlagensatz erstellen',
   'Create tables'               => 'Tabellen anlegen',
   'Created by'                  => 'Erstellt von',
   'Created for'                 => 'Erstellt f&uuml;r',
@@ -1345,7 +1343,6 @@ $self->{texts} = {
   'MwSt. inkl.'                 => 'MwSt. inkl.',
   'Name'                        => 'Name',
   'Name and Street'             => 'Name und Straße',
-  'Name missing!'               => 'Name fehlt!',
   'National Expenses'           => 'Aufwand Inland',
   'National Revenues'           => 'Erl&ouml;se Inland',
   'Net amount'                  => 'Nettobetrag',
index c518134..3363503 100644 (file)
@@ -41,7 +41,7 @@
 [%- END %]
 
 [%- IF id %]
-  <input type="submit" onclick="set_history_window([% id %]);" name="history" id="history" value="[% 'history' | $T8 %]">
+  <input type=button class=submit onclick="set_history_window([% id %]);" name="history" id="history" value="[% 'history' | $T8 %]">
   [% IF INSTANCE_CONF.get_ap_show_mark_as_paid %]
     <input type="submit" name="action" value="[% 'mark as paid' | $T8 %]">
   [% END %]
index fb9660a..f5a7daf 100644 (file)
@@ -20,6 +20,7 @@
 <input type="hidden" name="follow_up_trans_type_1" value="sales_invoice">
 <input type="hidden" name="follow_up_trans_info_1" value="[% HTML.escape(follow_up_trans_info) %]">
 <input type="hidden" name="follow_up_rowcount" value="1">
+<input type="hidden" name="show_details" value="[% show_details | html %]">
 
 <p><div class="listtop" width="100%">[% title %]</div></p>
 
      }
    //-->
   </script>
-
-  <input type="hidden" name="webdav" value="[% webdav %]">
+  <input type="hidden" name="webdav" value="[% webdav | html %]">