Merge branch 'master' of github.com:kivitendo/kivitendo-erp
authorJan Büren <jan@kivitendo-premium.de>
Wed, 1 Oct 2014 09:16:25 +0000 (11:16 +0200)
committerJan Büren <jan@kivitendo-premium.de>
Wed, 1 Oct 2014 09:16:25 +0000 (11:16 +0200)
12 files changed:
SL/DB/MetaSetup/Default.pm
SL/Form.pm
SL/OE.pm
bin/mozilla/oe.pl
doc/changelog
locale/de/all
sql/Pg-upgrade2/defaults_reqdate_interval.pl [new file with mode: 0644]
sql/Pg-upgrade2/defaults_transport_cost_reminder.pl [new file with mode: 0644]
templates/webpages/client_config/_features.html
templates/webpages/client_config/_posting_configuration.html
templates/webpages/oe/form_footer.html
templates/webpages/oe/search.html

index 2822b86..8ddda02 100644 (file)
@@ -72,6 +72,7 @@ __PACKAGE__->meta->columns(
   profit_determination                     => { type => 'text' },
   purchase_delivery_order_show_delete      => { type => 'boolean', default => 'true' },
   purchase_order_show_delete               => { type => 'boolean', default => 'true' },
+  reqdate_interval                         => { type => 'integer', default => '0' },
   require_transaction_description_ps       => { type => 'boolean', default => 'false', not_null => 1 },
   requirement_spec_section_order_part_id   => { type => 'integer' },
   revtrans                                 => { type => 'boolean', default => 'false' },
@@ -93,6 +94,7 @@ __PACKAGE__->meta->columns(
   transfer_default_ignore_onhand           => { type => 'boolean', default => 'false' },
   transfer_default_services                => { type => 'boolean', default => 'true' },
   transfer_default_use_master_default_bin  => { type => 'boolean', default => 'false' },
+  transport_cost_reminder_article_number   => { type => 'text' },
   vendornumber                             => { type => 'text' },
   version                                  => { type => 'varchar', length => 8 },
   vertreter                                => { type => 'boolean', default => 'false' },
index 441ba76..9d032bf 100644 (file)
@@ -2153,7 +2153,7 @@ sub _get_taxzones {
 
   $key = "all_taxzones" unless ($key);
   my $tzfilter = "";
-  $tzfilter = "WHERE obsolete is FALSE" if $key eq 'ALL_ACTIVE_TAXZONES'; 
+  $tzfilter = "WHERE obsolete is FALSE" if $key eq 'ALL_ACTIVE_TAXZONES';
 
   my $query = qq|SELECT * FROM tax_zones $tzfilter ORDER BY sortkey|;
 
index 52a5a61..8e746f4 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -795,6 +795,11 @@ sub retrieve {
   if (!$form->{id}) {
     my $wday         = (localtime(time))[6];
     my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1;
+
+    # if we have a client configured interval for sales quotation, we add this
+    $next_workday   += $::instance_conf->get_reqdate_interval if ($::instance_conf->get_reqdate_interval &&
+                                                                    $form->{type} eq 'sales_quotation' );
+
     $query_add       = qq|, current_date AS transdate, date(current_date + interval '${next_workday} days') AS reqdate|;
   }
 
index 8c5598d..1d32138 100644 (file)
@@ -240,7 +240,7 @@ sub order_links {
   # get customer/vendor
   $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
 
-  # retrieve order/quotation
+  # retrieve order/quotation and webdav config
   $form->{webdav}   = $::instance_conf->get_webdav;
 
   my $editing = $form->{id};
@@ -343,7 +343,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('Delivery Order created') if $form->{"type"} =~ /_order$/;
+                        $form->{"delivered"} ? "checked" : "",  $locale->text('Delivery Order(s) for full qty 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;
@@ -564,9 +564,11 @@ sub form_footer {
 
   $TMPL_VAR{ALL_DELIVERY_TERMS} = SL::DB::Manager::DeliveryTerm->get_all_sorted();
 
+  my $tpca_reminder = check_transport_cost_reminder_article_number() if $::instance_conf->get_transport_cost_reminder_article_number;
   print $form->parse_html_template("oe/form_footer", {
      %TMPL_VAR,
      webdav          => $::instance_conf->get_webdav,
+     tpca_reminder   => $tpca_reminder,
      print_options   => print_options(inline => 1),
      label_edit      => $locale->text("Edit the $form->{type}"),
      label_workflow  => $locale->text("Workflow $form->{type}"),
@@ -1629,6 +1631,10 @@ sub save_as_new {
       my $wday         = (localtime(time))[6];
       my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1;
 
+      # if we have a client configured interval for sales quotation, we add this
+      $next_workday   += $::instance_conf->get_reqdate_interval if ($::instance_conf->get_reqdate_interval &&
+                                                                    $form->{type} eq 'sales_quotation'       );
+
       my $query = 'SELECT
                      date(current_date + interval \''. $next_workday .' days\') AS reqdate,
                      date(current_date) AS transdate';
@@ -2074,6 +2080,23 @@ sub _oe_remove_delivered_or_billed_rows {
   _remove_billed_or_delivered_rows(quantities => \%handled_base_qtys);
 }
 
+# iterate all positions and match articlenumber
+sub check_transport_cost_reminder_article_number {
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+
+  check_oe_access();
+
+  my $transport_article = $::instance_conf->get_transport_cost_reminder_article_number;
+  for my $i (1 .. $form->{rowcount}) {
+    return undef if $form->{"partnumber_${i}"} eq $transport_article;
+  }
+
+  return $transport_article;
+
+  $main::lxdebug->leave_sub();
+}
 sub dispatcher {
   foreach my $action (qw(delete delivery_order e_mail invoice print purchase_order purchase_order quotation
                          request_for_quotation sales_order sales_order save save_and_close save_as_new ship_to update)) {
index e657af0..cff28e4 100644 (file)
@@ -70,6 +70,11 @@ Größere neue Features:
   dann erscheint die Variablen nur in den Stammdaten und den Beleg-Masken bei
   Artikeln, die zu einer der ausgewählten Warengruppen gehören.
 
+Kleinere neue Features und Detailverbesserungen:
+
+- Versand- oder Transportkostenerinnerung in Aufträgen / Angeboten implementiert (einstellbar in Mandantenkonfiguration)
+
+- Verkaufsangebotsgültigkeit konfigurierbar per Intervall (nächster Werktag + x Tage)
 
 2014-02-28 - Release 3.1.0
 
index 693b9f5..1ea9613 100755 (executable)
@@ -334,6 +334,7 @@ $self->{texts} = {
   'Bcc'                         => 'Bcc',
   'Bcc E-mail'                  => 'BCC (E-Mail)',
   'Because the useability gets worse if one partnumber is used for several parts (for example if you are searching a position for an invoice), partnumbers should be unique.' => 'Da die Benutzerfreundlichkeit durch doppelte Artikelnummern erheblich verschlechtert wird (zum Beispiel, wenn man einen Artikel für eine Rechnung sucht), sollten Artikelnummern eindeutig vergeben sein.',
+  'Before saving a sales order, this article will be checked and a warning is generated.' => 'Vor dem Speichern eines Angebots oder Auftrags wird überprüft, ob die hier definierte Artikelnnumer vorhanden ist (Versandkosten01, etc.) und eine entsprechende Hinweiswarnung angezeigt',
   'Belegnummer'                 => 'Buchungsnummer',
   'Beratername'                 => 'Beratername',
   'Beraternummer'               => 'Beraternummer',
@@ -756,6 +757,7 @@ $self->{texts} = {
   'Default output medium'       => 'Standardausgabekanal',
   'Default printer'             => 'Standarddrucker',
   'Default template format'     => 'Standardvorlagenformat',
+  'Default transport article number' => 'Standard Versand / Transport-Erinnerungs-Artikel',
   'Default unit'                => 'Standardeinheit',
   'Default value'               => 'Standardwert',
   'Delete'                      => 'Löschen',
@@ -782,6 +784,7 @@ $self->{texts} = {
   'Delivery Order Number'       => 'Lieferscheinnummer',
   'Delivery Order created'      => 'Lieferschein erstellt',
   'Delivery Order deleted!'     => 'Lieferschein gelöscht!',
+  'Delivery Order(s) for full qty created' => 'Lieferschein(e) mit kompletter Menge erstellt',
   'Delivery Orders'             => 'Lieferscheine',
   'Delivery Plan'               => 'Lieferplan',
   'Delivery Plan for currently outstanding sales orders' => 'Lieferplan für offene Verkaufsaufträge',
@@ -1473,6 +1476,7 @@ $self->{texts} = {
   'Missing parameter (at least one of #1) in call to sub #2.' => 'Fehlernder Parameter (mindestens einer aus \'#1\') in Funktionsaufruf \'#2\'.',
   'Missing parameter for WebDAV file copy' => 'Fehlender Parameter für WebDAV Datei kopieren',
   'Missing taxkeys in invoices with taxes.' => 'Fehlende Steuerschl&uuml;ssel in Rechnungen mit Steuern',
+  'Missing transport cost: #1  Are you sure?' => 'Fehlender Transportkosten-Artikel #1 Trotzdem speichern?',
   'Mitarbeiter'                 => 'Mitarbeiter',
   'Mixed (requires column "type")' => 'Gemischt (erfordert Spalte "type")',
   'Mobile'                      => 'Mobiltelefon',
@@ -2032,6 +2036,7 @@ $self->{texts} = {
   'Sales Orders'                => 'Aufträge',
   'Sales Orders deleteable'     => 'Kundenaufträge löschbar',
   'Sales Price information'     => 'Verkaufspreisinformation',
+  'Sales Quotation valid interval' => 'Angebotsgültigkeitsintervall',
   'Sales Quotations'            => 'Angebote',
   'Sales Report'                => 'Verkaufsbericht',
   'Sales and purchase invoices with inventory transactions with taxkeys' => 'Einkaufs- und Verkaufsrechnungen mit Warenbestandsbuchungen mit Steuerschlüsseln',
@@ -2067,7 +2072,7 @@ $self->{texts} = {
   'Save and Order'              => 'Speichern und Auftrag erfassen',
   'Save and Quotation'          => 'Speichern und Angebot',
   'Save and RFQ'                => 'Speichern und Lieferantenanfrage',
-  'Save and close'              => 'Speichern und schlie&szlig;en',
+  'Save and close'              => 'Speichern und schließen',
   'Save and execute'            => 'Speichern und ausführen',
   'Save and keep open'          => 'Speichern und geöffnet lassen',
   'Save as new'                 => 'als neu speichern',
@@ -2706,6 +2711,7 @@ $self->{texts} = {
   'Transfer successful'         => 'Lagervorgang erfolgreich',
   'Translation'                 => 'Übersetzung',
   'Translations'                => 'Übersetzungen',
+  'Transport and service costs reminder' => 'Transport- und Versandkosten-Erinnerung',
   'Trial Balance'               => 'Summen- und Saldenliste',
   'Trial balance between %s and %s' => 'Summen- und Saldenlisten vom %s bis zum %s',
   'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
@@ -2762,6 +2768,7 @@ $self->{texts} = {
   'Updating the client fields in the database "#1" on host "#2:#3" failed.' => 'Die Aktualisierung der Mandantenfelder in der Datenbank "#1" auf Host "#2:#3" schlug fehl.',
   'Uploaded at'                 => 'Hochgeladen um',
   'Uploaded on #1, size #2 kB'  => 'Am #1 hochgeladen, Größe #2 kB',
+  'Usally the sales quotation is valid until the next working day. This entry will be added to this date (i.e. 14, 28).' => 'Standardmässig ist ein Verkaufsangebot bis zum nächsten Werktag gültig. Dieses Intervall wird dann noch hinzugerechnet, bspw. nächster Werktag plus 14, 28 etc.',
   'Use As New'                  => 'Als neu verwenden',
   'Use WebDAV Repository'       => 'WebDAV-Ablage verwenden',
   'Use existing templates'      => 'Vorhandene Druckvorlagen verwenden',
diff --git a/sql/Pg-upgrade2/defaults_reqdate_interval.pl b/sql/Pg-upgrade2/defaults_reqdate_interval.pl
new file mode 100644 (file)
index 0000000..05335c6
--- /dev/null
@@ -0,0 +1,19 @@
+# @tag: defaults_reqdate_interval
+# @description: Einstellen der Angebotsgültigkeit per Intervall (z.B.: +28 Tage)
+# @depends: release_3_1_0
+package SL::DBUpgrade2::defaults_reqdate_interval;
+
+use utf8;
+
+use parent qw(SL::DBUpgrade2::Base);
+use strict;
+
+sub run {
+  my ($self) = @_;
+
+  # this query will fail if column already exist (new database)
+  $self->db_query(qq|ALTER TABLE defaults ADD COLUMN reqdate_interval integer DEFAULT 0|);
+  return 1;
+}
+
+1;
diff --git a/sql/Pg-upgrade2/defaults_transport_cost_reminder.pl b/sql/Pg-upgrade2/defaults_transport_cost_reminder.pl
new file mode 100644 (file)
index 0000000..9a2173b
--- /dev/null
@@ -0,0 +1,19 @@
+# @tag: defaults_transport_cost_reminder
+# @description: Artikelname der beim Auftrag auf Vorhandensein überprüft wird (Versandkostenerinnerung).
+# @depends: release_3_1_0
+package SL::DBUpgrade2::defaults_transport_cost_reminder;
+
+use utf8;
+
+use parent qw(SL::DBUpgrade2::Base);
+use strict;
+
+sub run {
+  my ($self) = @_;
+
+  # this query will fail if column already exist (new database)
+  $self->db_query(qq|ALTER TABLE defaults ADD COLUMN transport_cost_reminder_article_number text|);
+  return 1;
+}
+
+1;
index 416eb81..bc817b0 100644 (file)
    </td>
    <td>[% LxERP.t8('When converting a requirement spec into a quotation or an oder each section gets converted into a line position in the new record. This is the article used by default for this conversion.') %]</td>
   </tr>
+  <tr><td class="listheading" colspan="4">[% LxERP.t8('Transport and service costs reminder') %]</td></tr>
+ <tr>
+  <td align="right">[% LxERP.t8('Default transport article number') %]</td>
+  <td>[% L.input_tag('defaults.transport_cost_reminder_article_number', SELF.defaults.transport_cost_reminder_article_number, style=style) %]</td>
+   <td>[% LxERP.t8('Before saving a sales order, this article will be checked and a warning is generated.') %]</td>
+ </tr>
  </table>
 </div>
index 8096c87..2d4733d 100644 (file)
    <td>[% L.select_tag('defaults.balance_startdate_method', SELF.balance_startdate_method_options, value_key = 'value', title_key = 'title', default = SELF.defaults.balance_startdate_method) %]</td>
    <td>[% LxERP.t8('This option controls the method used for determining the startdate for the balance report.') %]</td>
   </tr>
+  <tr>
+   <td align="right">[% LxERP.t8('Sales Quotation valid interval') %]</td>
+   <td>[% L.input_tag('defaults.reqdate_interval', LxERP.format_amount(SELF.defaults.reqdate_interval, 0), style=style) %]</td>
+   <td>[% LxERP.t8('Usally the sales quotation is valid until the next working day. This entry will be added to this date (i.e. 14, 28).') %]</td>
+  </tr>
  </table>
 </div>
index 9dd893e..8a8dd08 100644 (file)
 <input class="submit" type="submit" name="action_ship_to" value="[% 'Ship to' | $T8 %]">
 <input class="submit" type="submit" name="action_print" value="[% 'Print' | $T8 %]" data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
 <input class="submit" type="submit" name="action_e_mail" value="[% 'E-mail' | $T8 %]" data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
-<input class="submit" type="submit" name="action_save" value="[% 'Save' | $T8 %]"[% IF warn_save_active_periodic_invoice %] data-warn-save-active-periodic-invoice="1"[% END %] data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
-<input class="submit" type="submit" name="action_save_and_close" value="[% 'Save and Close' | $T8 %]"[% IF warn_save_active_periodic_invoice %] data-warn-save-active-periodic-invoice="1"[% END %] data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
+
+[% IF not tpca_reminder %]
+  <input class="submit" type="submit" name="action_save" value="[% 'Save' | $T8 %]"[% IF warn_save_active_periodic_invoice %] data-warn-save-active-periodic-invoice="1"[% END %] data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
+  <input class="submit" type="submit" name="action_save_and_close" value="[% 'Save and Close' | $T8 %]"[% IF warn_save_active_periodic_invoice %] data-warn-save-active-periodic-invoice="1"[% END %] data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
+[% ELSE %]
+  [% IF warn_save_active_periodic_invoice  %] [% warn_save_active_periodic_invoice=1 %] [% END %]
+    [% L.submit_tag('action_save', LxERP.t8('Save'), confirm=LxERP.t8('Missing transport cost: #1  Are you sure?', tpca_reminder), 'data-require-transaction-description'=INSTANCE_CONF.get_require_transaction_description_ps, 'data-warn-save-active-periodic-invoice'=warn_save_active_periodic_invoice) %]
+    [% L.submit_tag('action_save_and_close', LxERP.t8('Save and close'), confirm=LxERP.t8('Missing transport cost: #1  Are you sure?', tpca_reminder), 'data-require-transaction-description'=INSTANCE_CONF.get_require_transaction_description_ps, 'data-warn-save-active-periodic-invoice'=warn_save_active_periodic_invoice) %]
+[% END %]
 
 [%- IF id %]
   <input type="button" class="submit" onclick="follow_up_window()" value="[% 'Follow-Up' | $T8 %]">
index b651bf0..4fdcbda 100644 (file)
         </td>
         <td>
          <input name="delivered" id="delivered" class="checkbox" type="checkbox" value="1" checked>
-         <label for="delivered">[% 'Delivery Order created' | $T8 %]</label>
+         <label for="delivered">[% 'Delivery Order(s) for full qty created' | $T8 %]</label>
         </td>
        </tr>
 [%- END %]