Merge branch 'master' of github.com:kivitendo/kivitendo-erp
authorSven Schöling <s.schoeling@linet-services.de>
Thu, 7 Aug 2014 10:11:34 +0000 (12:11 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Thu, 7 Aug 2014 10:11:34 +0000 (12:11 +0200)
21 files changed:
SL/CVar.pm
SL/Controller/CustomVariableConfig.pm
SL/Controller/CustomerVendor.pm
SL/DB/AuthUser.pm
SL/DB/MetaSetup/Customer.pm
SL/DB/MetaSetup/Vendor.pm
bin/mozilla/io.pl
css/kivitendo/main.css
css/lx-office-erp/main.css
locale/de/all
locale/en/all
sql/Pg-upgrade2/change_taxzone_id_0.pl
sql/Pg-upgrade2/convert_taxzone.pl
t/db_helper/price_tax_calculator.t
t/db_helper/record_links.t
templates/webpages/am/config.html
templates/webpages/buchungsgruppen/form.html
templates/webpages/buchungsgruppen/list.html
templates/webpages/custom_variable_config/form.html
templates/webpages/custom_variable_config/list.html
templates/webpages/oe/sales_order.html

index b15f82b..99e4672 100644 (file)
@@ -132,6 +132,8 @@ sub get_custom_variables {
       $act_var = $h_var->fetchrow_hashref();
 
       $valid = $self->get_custom_variables_validity(config_id => $cvar->{id}, trans_id => $params{trans_id});
+    } else {
+      $valid = !$cvar->{flag_defaults_to_invalid};
     }
 
     if ($act_var) {
@@ -145,7 +147,7 @@ sub get_custom_variables {
                      :                                $act_var->{text_value};
       $cvar->{valid} = $valid;
     } else {
-      $cvar->{valid}  =  1;
+      $cvar->{valid} = $valid // 1;
 
       if ($cvar->{type} eq 'date') {
         if ($cvar->{default_value} eq 'NOW') {
index 28ed179..a56740b 100644 (file)
@@ -7,6 +7,7 @@ use parent qw(SL::Controller::Base);
 use List::Util qw(first);
 
 use SL::DB::CustomVariableConfig;
+use SL::DB::CustomVariableValidity;
 use SL::Helper::Flash;
 use SL::Locale::String;
 use Data::Dumper;
@@ -103,7 +104,7 @@ sub action_reorder {
 
   SL::DB::CustomVariableConfig->reorder_list(@{ $::form->{cvarcfg_id} || [] });
 
-  $self->render(\'', { type => 'json' });
+  $self->render(\'', { type => 'json' }); # ' make emacs happy
 }
 
 #
@@ -179,10 +180,33 @@ sub create_or_update {
     return;
   }
 
+  my $dbh = $self->config->db;
+  $dbh->begin_work;
+
   $self->config->save;
+  $self->_set_cvar_validity() if $is_new;
+
+  $dbh->commit;
 
   flash_later('info', $is_new ? t8('The custom variable has been created.') : t8('The custom variable has been saved.'));
   $self->redirect_to(action => 'list', module => $self->module);
 }
 
+sub _set_cvar_validity {
+  my ($self) = @_;
+
+  my $flags = {
+    map { split m/=/, $_, 2 }
+    split m/:/, ($self->config->flags || '')
+  };
+
+  # nothing to do to set valid
+  return if !$flags->{defaults_to_invalid};
+
+  my $all_parts  = SL::DB::Manager::Part->get_all(where => [ or => [ obsolete => 0, obsolete => undef ] ]);
+  foreach my $part (@{ $all_parts }) {
+    SL::DB::CustomVariableValidity->new(config_id => $self->config->id, trans_id => $part->id)->save;
+  }
+}
+
 1;
index 91994a1..d472be7 100644 (file)
@@ -806,7 +806,7 @@ sub _pre_render {
 
   $self->{all_languages} = SL::DB::Manager::Language->get_all();
 
-  $self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all();
+  $self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all_sorted();
 
   if ( $::instance_conf->get_vertreter() ) {
     $query =
index a127966..1eac6f9 100644 (file)
@@ -11,7 +11,7 @@ use SL::DB::Helper::Util;
 use constant CONFIG_VARS => qw(copies countrycode dateformat timeformat default_media default_printer_id
                                email favorites fax hide_cvar_search_options mandatory_departments menustyle name
                                numberformat show_form_details signature stylesheet taxincluded_checked tel
-                               template_format vclimit focus_position);
+                               template_format vclimit focus_position form_cvars_nr_cols);
 
 __PACKAGE__->meta->add_relationship(
   groups => {
index b802119..deab35b 100644 (file)
@@ -53,7 +53,7 @@ __PACKAGE__->meta->columns(
   taxincluded               => { type => 'boolean' },
   taxincluded_checked       => { type => 'boolean' },
   taxnumber                 => { type => 'text' },
-  taxzone_id                => { type => 'integer', default => '0', not_null => 1 },
+  taxzone_id                => { type => 'integer', not_null => 1 },
   terms                     => { type => 'integer', default => '0' },
   user_password             => { type => 'text' },
   username                  => { type => 'text' },
@@ -90,6 +90,11 @@ __PACKAGE__->meta->foreign_keys(
     class       => 'SL::DB::PaymentTerm',
     key_columns => { payment_id => 'id' },
   },
+
+  taxzone => {
+    class       => 'SL::DB::TaxZone',
+    key_columns => { taxzone_id => 'id' },
+  },
 );
 
 1;
index 8367137..0b57e83 100644 (file)
@@ -46,7 +46,7 @@ __PACKAGE__->meta->columns(
   street           => { type => 'text' },
   taxincluded      => { type => 'boolean' },
   taxnumber        => { type => 'text' },
-  taxzone_id       => { type => 'integer', default => '0', not_null => 1 },
+  taxzone_id       => { type => 'integer', not_null => 1 },
   terms            => { type => 'integer', default => '0' },
   user_password    => { type => 'text' },
   username         => { type => 'text' },
@@ -85,6 +85,11 @@ __PACKAGE__->meta->foreign_keys(
     class       => 'SL::DB::PaymentTerm',
     key_columns => { payment_id => 'id' },
   },
+
+  taxzone => {
+    class       => 'SL::DB::TaxZone',
+    key_columns => { taxzone_id => 'id' },
+  },
 );
 
 1;
index 4cd8822..3c6c087 100644 (file)
@@ -1865,16 +1865,18 @@ sub _render_custom_variables_inputs {
   foreach my $cvar (@{ $form->{CVAR_CONFIGS}->{IC} }) {
     $cvar->{valid} = $params{part_id} && $valid->($cvar->{id});
 
+    my $show = 0;
     my $description = '';
     if ($cvar->{flag_editable} && $cvar->{valid}) {
       $num_visible_cvars++;
       $description = $cvar->{description} . ' ';
+      $show = 1;
     }
 
     my $form_key = "ic_cvar_" . $cvar->{name} . "_$params{row}";
 
     push @{ $params{ROW2} }, {
-      line_break     => $num_visible_cvars == 1,
+      line_break     => $show && !(($num_visible_cvars - 1) % ($::myconfig{form_cvars_nr_cols}*1 || 3)),
       description    => $description,
       cvar           => 1,
       render_options => {
index 6fa432d..0b701b4 100644 (file)
@@ -455,3 +455,8 @@ a.cti_call_action {
   background-image: url(../../image/icons/16x16/phone.png);
   background-repeat: no-repeat;
 }
+
+/* the cvars table in the 2. row */
+.row2-cvars-table tr {vertical-align: top;}
+.row2-cvars-table th {text-align: right; padding-left: 15px; padding-right: 0;}
+.row2-cvars-table td, .row2-cvars-table th {padding-top: 10px;}
index ab71226..a4773ab 100644 (file)
@@ -506,3 +506,8 @@ a.cti_call_action {
   background-image: url(../../image/icons/16x16/phone.png);
   background-repeat: no-repeat;
 }
+
+/* the cvars table in the 2. row */
+.row2-cvars-table tr {vertical-align: top;}
+.row2-cvars-table th {text-align: right; padding-left: 15px; padding-right: 0;}
+.row2-cvars-table td, .row2-cvars-table th {padding-top: 10px;}
index 1e27fb6..e17a78c 100755 (executable)
@@ -52,7 +52,8 @@ $self->{texts} = {
   'A transaction description is required.' => 'Die Vorgangsbezeichnung muss eingegeben werden.',
   'A unit with this name does already exist.' => 'Eine Einheit mit diesem Namen existiert bereits.',
   'A valid taxkey is missing!'  => 'Einen gültiger Steuerschlüssel fehlt!',
-  'A variable marked as \'editable\' can be changed in each quotation, order, invoice etc.' => 'Eine als \'editierbar\' markierte Variable kann in jedem Angebot, Auftrag, jeder Rechnung etc für jede Position geändert werden.',
+  'A variable marked as \'Deactivate by default\' isn\'t automatically added to all articles, and has to be explicitly added for each desired article in its master data tab. Only then can the variable be used for that article in the records.' => 'Eine als \'Deaktiviert als Voreinstellung\' markierte Variable wird nicht automatisch bei allen Artikeln hinzugefügt, sondern muß explizit für jeden gewünschten Artikel in den Stammdaten aktiviert werden. Erst danach ist die Variable für den Artikel in Belegen bearbeitbar.',
+  'A variable marked as \'editable\' can be changed in each quotation, order, invoice etc.' => 'Eine als \'Bearbeitbar\' markierte Variable kann in jedem Angebot, Auftrag, jeder Rechnung etc für jede Position geändert werden.',
   'ADDED'                       => 'Hinzugefügt',
   'AP'                          => 'Einkauf',
   'AP Aging'                    => 'Offene Verbindlichkeiten',
@@ -115,8 +116,6 @@ $self->{texts} = {
   'Account number'              => 'Kontonummer',
   'Account number not unique!'  => 'Kontonummer bereits vorhanden!',
   'Account saved!'              => 'Konto gespeichert!',
-  'Accounting Group deleted!'   => 'Buchungsgruppe gel&ouml;scht!',
-  'Accounting Group saved!'     => 'Buchungsgruppe gespeichert!',
   'Accounting method'           => 'Versteuerungsart',
   'Accrual'                     => 'Soll-Versteuerung',
   'Accrual accounting'          => 'Soll-Versteuerung',
@@ -126,7 +125,6 @@ $self->{texts} = {
   'Add AP Transaction'          => 'Kreditorenbuchung',
   'Add AR Transaction'          => 'Debitorenbuchung',
   'Add Account'                 => 'Konto erfassen',
-  'Add Accounting Group'        => 'Buchungsgruppe erfassen',
   'Add Accounts Payables Transaction' => 'Kreditorenbuchung erfassen',
   'Add Accounts Receivables Transaction' => 'Debitorenbuchung erfassen',
   'Add Assembly'                => 'Erzeugnis erfassen',
@@ -335,7 +333,6 @@ $self->{texts} = {
   'Beratername'                 => 'Beratername',
   'Beraternummer'               => 'Beraternummer',
   'Best Before'                 => 'Mindesthaltbarkeit',
-  'Bestandskonto'               => 'Bestandskonto',
   'Bilanz'                      => 'Bilanz',
   'Billable amount'             => 'Abrechenbarer Betrag',
   'Billed amount'               => 'Abgerechneter Betrag',
@@ -720,6 +717,7 @@ $self->{texts} = {
   'Date the payment is due with discount' => 'Das Datum, bis die Rechnung unter Abzug von Skonto bezahlt werden kann',
   'Datevautomatik'              => 'Datev-Automatik',
   'Datum von'                   => 'Datum von',
+  'Deactivate by default'       => 'Deaktiviert als Voreinstellung',
   'Debit'                       => 'Soll',
   'Debit (one letter abbreviation)' => 'S',
   'Debit Account'               => 'Sollkonto',
@@ -895,7 +893,6 @@ $self->{texts} = {
   'Edit Access Rights'          => 'Zugriffsrechte bearbeiten',
   'Edit Access Rights for Follow-Ups' => 'Zugriff auf meine Wiedervorlagen regeln',
   'Edit Account'                => 'Kontodaten bearbeiten',
-  'Edit Accounting Group'       => 'Buchungsgruppe bearbeiten',
   'Edit Accounts Payables Transaction' => 'Kreditorenbuchung bearbeiten',
   'Edit Accounts Receivables Transaction' => 'Debitorenbuchung bearbeiten',
   'Edit Assembly'               => 'Erzeugnis bearbeiten',
@@ -1064,8 +1061,6 @@ $self->{texts} = {
   'Expense'                     => 'Aufwandskonto',
   'Expense Account'             => 'Aufwandskonto',
   'Expense/Asset'               => 'Aufwand/Anlagen',
-  'Expenses EU with UStId'      => 'Aufwand EU m. UStId',
-  'Expenses EU without UStId'   => 'Aufwand EU o. UStId',
   'Export Buchungsdaten'        => 'Export Buchungsdaten',
   'Export Number'               => 'Exportnummer',
   'Export Stammdaten'           => 'Export Stammdaten',
@@ -1122,8 +1117,6 @@ $self->{texts} = {
   'For type "customer" the perl module JSON is required. Please check this on system level: $ ./scripts/installation_check.pl' => 'Für den Typ "Kunde" wird das Perl Module JSON benötigt. Überprüfbar im Installationspfad mit: $ ./scripts/installation_check.pl',
   'Foreign Exchange Gain'       => 'Wechselkurserträge',
   'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
-  'Foreign Expenses'            => 'Aufwand Ausland',
-  'Foreign Revenues'            => 'Erl&ouml;se Ausland',
   'Form details (second row)'   => 'Formulardetails (zweite Positionszeile)',
   'Formula'                     => 'Formel',
   'Found #1 errors.'            => '#1 Fehler gefunden.',
@@ -1288,6 +1281,7 @@ $self->{texts} = {
   'Invdate from'                => 'Rechnungen von',
   'Inventory'                   => 'Inventar',
   'Inventory Account'           => 'Warenbestand',
+  'Inventory account'           => '',
   'Inventory quantity must be zero before you can set this assembly obsolete!' => 'Bevor dieses Erzeugnis als ungültig markiert werden kann, muß das Inventar auf Null sein!',
   'Inventory quantity must be zero before you can set this part obsolete!' => 'Bevor diese Ware als ungültig markiert werden kann, muß das Inventar Null sein!',
   'Inventory system'            => 'Warenbuchungsmethode',
@@ -1492,8 +1486,6 @@ $self->{texts} = {
   'MwSt. inkl.'                 => 'MwSt. inkl.',
   'Name'                        => 'Name',
   'Name and Street'             => 'Name und Straße',
-  'National Expenses'           => 'Aufwand Inland',
-  'National Revenues'           => 'Erl&ouml;se Inland',
   'Neither sections nor function blocks have been created yet.' => 'Es wurden bisher weder Abschnitte noch Funktionsblöcke angelegt.',
   'Net Income Statement'        => 'Einnahmenüberschußrechnung',
   'Net amount'                  => 'Nettobetrag',
@@ -1607,6 +1599,7 @@ $self->{texts} = {
   'Number Format'               => 'Zahlenformat',
   'Number missing in Row'       => 'Nummer fehlt in Zeile',
   'Number of bins'              => 'Anzahl Lagerpl&auml;tze',
+  'Number of columns of custom variables in form details (second row)' => 'Anzahl der Spalten für benutzerdef. Variablen in den Formulardetails (zweite Positionszeile)',
   'Number of copies'            => 'Anzahl Kopien',
   'Number of entries changed: #1' => 'Anzahl geänderter Einträge: #1',
   'Number of months'            => 'Anzahl Monate',
@@ -1993,8 +1986,6 @@ $self->{texts} = {
   'Result'                      => 'Ergebnis',
   'Revenue'                     => 'Erlöskonto',
   'Revenue Account'             => 'Erlöskonto',
-  'Revenues EU with UStId'      => 'Erl&ouml;se EU m. UStId',
-  'Revenues EU without UStId'   => 'Erl&ouml;se EU o. UStId',
   'Revert to version'           => 'Auf Version zurücksetzen',
   'Review of Aging list'        => 'Altersstrukturliste',
   'Right'                       => 'Rechts',
@@ -2334,6 +2325,8 @@ $self->{texts} = {
   'The AR transaction #1 has been deleted.' => 'Die Debitorenbuchung #1 wurde gelöscht.',
   'The Bins in Inventory were only a information text field.' => 'Die Lagerplätze unter Stammdaten/Waren sind nur ein informatives Textfeld.',
   'The Bins in master data were only a information text field.' => 'Die Lagerplätze unter Stammdaten/Waren sind nur ein informatives Textfeld.',
+  'The Buchungsgruppe has been created.' => '',
+  'The Buchungsgruppe has been saved.' => '',
   'The GL transaction #1 has been deleted.' => 'Die Dialogbuchung #1 wurde gelöscht.',
   'The LDAP server "#1:#2" is unreachable. Please check config/kivitendo.conf.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/kivitendo.conf.',
   'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt',
@@ -2366,6 +2359,8 @@ $self->{texts} = {
   'The base unit does not exist.' => 'Die Basiseinheit existiert nicht.',
   'The base unit relations must not contain loops (e.g. by saying that unit A\'s base unit is B, B\'s base unit is C and C\'s base unit is A) in row %d.' => 'Die Beziehungen der Einheiten d&uuml;rfen keine Schleifen beinhalten (z.B. wenn gesagt wird, dass Einheit As Basiseinheit B, Bs Basiseinheit C und Cs Basiseinheit A ist) in Zeile %d.',
   'The basic client tables have not been created for this client\'s database yet.' => 'Die grundlegenden Mandantentabellen wurden in der für diesen Mandanten konfigurierten Datenbank noch nicht angelegt.',
+  'The buchungsgruppe has been deleted.' => '',
+  'The buchungsgruppe is in use and cannot be deleted.' => '',
   'The business has been created.' => 'Der Kunden-/Lieferantentyp wurde erfasst.',
   'The business has been deleted.' => 'Der Kunden-/Lieferantentyp wurde gelöscht.',
   'The business has been saved.' => 'Der Kunden-/Lieferantentyp wurde gespeichert.',
@@ -2394,8 +2389,8 @@ $self->{texts} = {
   'The connection was established successfully.' => 'Die Verbindung zur Datenbank wurde erfolgreich hergestellt.',
   'The contact person attribute "birthday" is converted from a free-form text field into a date field.' => 'Das Kontaktpersonenfeld "Geburtstag" wird von einem freien Textfeld auf ein Datumsfeld umgestellt.',
   'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
-  'The custom variable has been created.' => 'Die benutzerdefinierte Varieble wurde erfasst.',
-  'The custom variable has been deleted.' => 'Die benutzerdefinierte Variable wurde gel&ouml;scht.',
+  'The custom variable has been created.' => 'Die benutzerdefinierte Variable wurde erfasst.',
+  'The custom variable has been deleted.' => 'Die benutzerdefinierte Variable wurde gelöscht.',
   'The custom variable has been saved.' => 'Die benutzerdefinierte Variable wurde gespeichert.',
   'The custom variable is in use and cannot be deleted.' => 'Die benutzerdefinierte Variable ist in Benutzung und kann nicht gelöscht werden.',
   'The database for user management and authentication does not exist. You can create let kivitendo create it with the following parameters:' => 'Die Datenbank für die Benutzeranmeldung existiert nicht. Sie können Sie von kivitendo automatisch mit den folgenden Parametern anlegen lassen:',
@@ -2956,7 +2951,6 @@ $self->{texts} = {
   'disposed'                    => 'Entsorgung',
   'do not include'              => 'Nicht aufnehmen',
   'done'                        => 'erledigt',
-  'down'                        => 'runter',
   'dunning_list'                => 'mahnungsliste',
   'eBayImporter'                => 'eBay-Importierer',
   'eMail Send?'                 => 'E-Mail-Versand?',
@@ -3103,7 +3097,6 @@ $self->{texts} = {
   'trial_balance'               => 'susa',
   'unconfigured'                => 'unkonfiguriert',
   'uncorrect partnumber '       => 'Unbekannte Teilenummer ',
-  'up'                          => 'hoch',
   'use program settings'        => 'benutze Programmeinstellungen',
   'use user config'             => 'Verwende Benutzereinstellung',
   'used'                        => 'Verbraucht',
index 30a729a..70e8314 100644 (file)
@@ -45,6 +45,7 @@ $self->{texts} = {
   'A special character is required (valid characters: #1).' => '',
   'A unit with this name does already exist.' => '',
   'A valid taxkey is missing!'  => '',
+  'A variable marked as \'Deactivate by default\' isn\'t automatically added to all articles, and has to be explicitly added for each desired article in its master data tab. Only then can the variable be used for that article in the records.' => '',
   'A variable marked as \'editable\' can be changed in each quotation, order, invoice etc.' => '',
   'ADDED'                       => '',
   'AP'                          => 'Purchases',
@@ -633,6 +634,7 @@ $self->{texts} = {
   'Date the payment is due with discount' => '',
   'Datevautomatik'              => '',
   'Datum von'                   => '',
+  'Deactivate by default'       => '',
   'Debit'                       => '',
   'Debit (one letter abbreviation)' => '',
   'Debit Account'               => '',
@@ -1414,6 +1416,7 @@ $self->{texts} = {
   'Number Format'               => '',
   'Number missing in Row'       => '',
   'Number of bins'              => '',
+  'Number of columns of custom variables in form details (second row)' => '',
   'Number of copies'            => '',
   'Number of entries changed: #1' => '',
   'Number of new bins'          => '',
index 23b2023..3a36f3d 100644 (file)
@@ -30,14 +30,27 @@ sub run {
     $query = qq|DELETE FROM tax_zones WHERE id=0|;
     $self->db_query($query);
 
-    #Adapt other tables to the new id:
+    #Adapt ar/ap and customer/vendor tables to the new taxzone_id
     $query = qq|UPDATE ar SET taxzone_id=$id WHERE taxzone_id=0|;
     $self->db_query($query);
 
     $query = qq|UPDATE ap SET taxzone_id=$id WHERE taxzone_id=0|;
     $self->db_query($query);
+
+    $query = qq|UPDATE customer SET taxzone_id=$id WHERE taxzone_id=0|;
+    $self->db_query($query);
+
+    $query = qq|UPDATE vendor SET taxzone_id=$id WHERE taxzone_id=0|;
+    $self->db_query($query);
   }
 
+  # Remove default 0 for taxzone_id
+  $query = qq|ALTER TABLE customer ALTER COLUMN taxzone_id DROP default|;
+  $self->db_query($query);
+
+  $query = qq|ALTER TABLE vendor ALTER COLUMN taxzone_id DROP default|;
+  $self->db_query($query);
+
   #Set Constraints:
   $query = qq|ALTER TABLE ar ADD FOREIGN KEY (taxzone_id) REFERENCES tax_zones (id)|;
   $self->db_query($query);
@@ -45,6 +58,12 @@ sub run {
   $query = qq|ALTER TABLE ap ADD FOREIGN KEY (taxzone_id) REFERENCES tax_zones (id)|;
   $self->db_query($query);
 
+  $query = qq|ALTER TABLE customer ADD FOREIGN KEY (taxzone_id) REFERENCES tax_zones (id)|;
+  $self->db_query($query);
+
+  $query = qq|ALTER TABLE vendor ADD FOREIGN KEY (taxzone_id) REFERENCES tax_zones (id)|;
+  $self->db_query($query);
+
   $sth->finish;
 
   return 1;
index 413d772..b1e1a0b 100644 (file)
@@ -39,17 +39,21 @@ SQL
     }
     $sth->finish;
 
-    my $taxzone_charts_update_query;
-    foreach my $taxzone (  @{$::form->{taxzones}} ) {
-        foreach my $buchungsgruppe (  @{$::form->{buchungsgruppen}} ) {
-            my $id = $taxzone->{id};
-            my $income_accno_id = $buchungsgruppe->{"income_accno_id_$id"};
-            my $expense_accno_id = $buchungsgruppe->{"expense_accno_id_$id"};
-            # TODO: check if the variables have a value
-            $taxzone_charts_update_query .= "INSERT INTO taxzone_charts (taxzone_id, buchungsgruppen_id, income_accno_id, expense_accno_id) VALUES ('$taxzone->{id}', '$buchungsgruppe->{id}', $income_accno_id, $expense_accno_id);\n";
+    # convert Buchungsgruppen to taxzone_charts if any exist
+    # the default swiss COA doesn't have any, for example
+    if ( scalar @{ $::form->{buchungsgruppen} } > 0 ) { 
+        my $taxzone_charts_update_query;
+        foreach my $taxzone (  @{$::form->{taxzones}} ) {
+            foreach my $buchungsgruppe (  @{$::form->{buchungsgruppen}} ) {
+                my $id = $taxzone->{id};
+                my $income_accno_id = $buchungsgruppe->{"income_accno_id_$id"};
+                my $expense_accno_id = $buchungsgruppe->{"expense_accno_id_$id"};
+                # TODO: check if the variables have a value
+                $taxzone_charts_update_query .= "INSERT INTO taxzone_charts (taxzone_id, buchungsgruppen_id, income_accno_id, expense_accno_id) VALUES ('$taxzone->{id}', '$buchungsgruppe->{id}', $income_accno_id, $expense_accno_id);\n";
+            };
         };
+        $self->db_query($taxzone_charts_update_query) if $taxzone_charts_update_query;
     };
-    $self->db_query($taxzone_charts_update_query);
 
     my $clean_buchungsgruppen_query = <<SQL;
 alter table buchungsgruppen drop column income_accno_id_0;
index b374f5e..4bf9ab8 100644 (file)
@@ -129,21 +129,21 @@ sub test_default_invoice_one_item_19_tax_not_included() {
   is($invoice->marge_percent,   17.4358974358974, "${title}: marge_percent");
 
   is_deeply(\%data, {
-    allocated                            => {},
-    amounts                              => {
-      $buchungsgruppe->income_accno_id_0 => {
-        amount                           => 5.85,
-        tax_id                           => $tax->id,
-        taxkey                           => 3,
+    allocated                                    => {},
+    amounts                                      => {
+      $buchungsgruppe->income_accno_id($taxzone) => {
+        amount                                   => 5.85,
+        tax_id                                   => $tax->id,
+        taxkey                                   => 3,
       },
     },
-    amounts_cogs                         => {},
-    assembly_items                       => [
+    amounts_cogs                                 => {},
+    assembly_items                               => [
       [],
     ],
-    exchangerate                         => 1,
-    taxes                                => {
-      $tax->chart_id                     => 1.11,
+    exchangerate                                 => 1,
+    taxes                                        => {
+      $tax->chart_id                             => 1.11,
     },
   }, "${title}: calculated data");
 }
@@ -193,27 +193,27 @@ sub test_default_invoice_two_items_19_7_tax_not_included() {
   is($invoice->marge_percent,    34.8943460879497, "${title}: marge_percent");
 
   is_deeply(\%data, {
-    allocated                             => {},
-    amounts                               => {
-      $buchungsgruppe->income_accno_id_0  => {
-        amount                            => 5.85,
-        tax_id                            => $tax->id,
-        taxkey                            => 3,
+    allocated                                     => {},
+    amounts                                       => {
+      $buchungsgruppe->income_accno_id($taxzone)  => {
+        amount                                    => 5.85,
+        tax_id                                    => $tax->id,
+        taxkey                                    => 3,
       },
-      $buchungsgruppe7->income_accno_id_0 => {
-        amount                            => 11.66,
-        tax_id                            => $tax7->id,
-        taxkey                            => 2,
+      $buchungsgruppe7->income_accno_id($taxzone) => {
+        amount                                    => 11.66,
+        tax_id                                    => $tax7->id,
+        taxkey                                    => 2,
       },
     },
-    amounts_cogs                          => {},
-    assembly_items                        => [
+    amounts_cogs                                  => {},
+    assembly_items                                => [
       [], [],
     ],
-    exchangerate                          => 1,
-    taxes                                 => {
-      $tax->chart_id                      => 1.11,
-      $tax7->chart_id                     => 0.82,
+    exchangerate                                  => 1,
+    taxes                                         => {
+      $tax->chart_id                              => 1.11,
+      $tax7->chart_id                             => 0.82,
     },
   }, "${title}: calculated data");
 }
@@ -295,21 +295,21 @@ sub test_default_invoice_three_items_sellprice_rounding_discount() {
   is($invoice->marge_percent,    62.007874015748,    "${title}: marge_percent");
 
   is_deeply(\%data, {
-    allocated                             => {},
-    amounts                               => {
-      $buchungsgruppe->income_accno_id_0  => {
-        amount                            => 15.24,
-        tax_id                            => $tax->id,
-        taxkey                            => 3,
+    allocated                                    => {},
+    amounts                                      => {
+      $buchungsgruppe->income_accno_id($taxzone) => {
+        amount                                   => 15.24,
+        tax_id                                   => $tax->id,
+        taxkey                                   => 3,
       },
     },
-    amounts_cogs                          => {},
-    assembly_items                        => [
+    amounts_cogs                                 => {},
+    assembly_items                               => [
       [], [], [],
     ],
-    exchangerate                          => 1,
-    taxes                                 => {
-      $tax->chart_id                      => 2.9,
+    exchangerate                                 => 1,
+    taxes                                        => {
+      $tax->chart_id                             => 2.9,
     },
   }, "${title}: calculated data");
 }
index e063b33..e7dd31b 100644 (file)
@@ -20,8 +20,9 @@ use SL::DB::Order;
 use SL::DB::DeliveryOrder;
 use SL::DB::Part;
 use SL::DB::Unit;
+use SL::DB::TaxZone;
 
-my ($customer, $currency_id, $buchungsgruppe, $employee, $vendor);
+my ($customer, $currency_id, $buchungsgruppe, $employee, $vendor, $taxzone);
 my ($link, $links, $o1, $o2, $d, $i);
 
 sub reset_state {
@@ -37,6 +38,7 @@ sub reset_state {
 
   $buchungsgruppe  = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group";
   $employee        = SL::DB::Manager::Employee->current                                                                    || croak "No employee";
+  $taxzone         = SL::DB::Manager::TaxZone->find_by( description => 'Inland')                                           || croak "No taxzone";
 
   $currency_id     = $::instance_conf->get_currency_id;
 
@@ -61,7 +63,7 @@ sub new_order {
     currency_id => $currency_id,
     employee_id => $employee->id,
     salesman_id => $employee->id,
-    taxzone_id  => 0,
+    taxzone_id  => $taxzone->id,
     quotation   => 0,
     %params,
   )->save;
@@ -75,7 +77,7 @@ sub new_delivery_order {
     currency_id => $currency_id,
     employee_id => $employee->id,
     salesman_id => $employee->id,
-    taxzone_id  => 0,
+    taxzone_id  => $taxzone->id,
     %params,
   )->save;
 }
@@ -89,8 +91,8 @@ sub new_invoice {
     employee_id => $employee->id,
     salesman_id => $employee->id,
     gldate      => DateTime->today_local->to_kivitendo,
-    taxzone_id  => 0,
     invoice     => 1,
+    taxzone_id  => $taxzone->id,
     type        => 'invoice',
     %params,
   )->save;
index 27a91ad..257f6a7 100644 (file)
        </select>
       </td>
      </tr>
+
+     <tr>
+      <th align="right">[% 'Number of columns of custom variables in form details (second row)' | $T8 %]</th>
+      <td>
+        [% L.input_tag('form_cvars_nr_cols',  myconfig_form_cvars_nr_cols || 3,  size = 5) %]
+      </td>
+     </tr>
+
     </table>
    </div>
 
index b520197..4141570 100644 (file)
@@ -11,7 +11,7 @@
     <td>[%- L.input_tag("config.description", SELF.config.description) %]</td>
   </tr>
   <tr>
-    <th align="right">[% 'Inventory account' | $T8 %]</th>
+    <th align="right">[% 'Inventory Account' | $T8 %]</th>
     [%- IF NOT SELF.config.id %]
       <td>[%- L.select_tag("config.inventory_accno_id", ACCOUNTS.ic, title_sub=\account_label, default=SELF.defaults.inventory_accno_id) %]</td>
     [%- ELSIF SELF.config.id AND SELF.config.orphaned %]
index ba80499..8621e85 100644 (file)
@@ -8,7 +8,7 @@
    <tr class="listheading">
     <th align="center" width="1%"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></th>
     <th width="20%">[% 'Description' | $T8 %]</th>
-    <th width="20%">[% 'Inventory account' | $T8 %]</th>
+    <th width="20%">[% 'Inventory Account' | $T8 %]</th>
      [%- FOREACH tz = TAXZONES %]
         <th width="20%">[% 'Revenue' | $T8 %] [% HTML.escape(tz.description) %]</th>
         <th width="20%">[% 'Expense' | $T8 %] [% HTML.escape(tz.description) %]</th>
index 2703cdc..a34dd5d 100644 (file)
      [% L.radio_button_tag('config.flag_editable', value='0', id='config.flag_editable_0', label=LxERP.t8('No'),  checked=(SELF.flags.editable ? '' :  1)) %]
     </td>
    </tr>
+   <tr data-show-for="IC"[% UNLESS SELF.module == 'IC' %] style="display: none;"[% END %]>
+    <td align="right">[% 'Deactivate by default' | $T8 %]<sup><span class="small-text">(7)</span></sup></td>
+    <td>
+     [% L.radio_button_tag('config.flag_defaults_to_invalid', value='1', id='config.flag_defaults_to_invalid_1', label=LxERP.t8('Yes'), checked=(SELF.flags.defaults_to_invalid ?  1 : '')) %]
+     [% L.radio_button_tag('config.flag_defaults_to_invalid', value='0', id='config.flag_defaults_to_invalid_0', label=LxERP.t8('No'),  checked=(SELF.flags.defaults_to_invalid ? '' :  1)) %]
+    </td>
+   </tr>
   </table>
  </p>
 
   [% 'Otherwise the variable is only available for printing.' | $T8 %]
  </p>
 
+ <p data-show-for="IC"[% UNLESS SELF.module == 'IC' %] style="display: none;"[% END %]>
+  (7)
+
+  [%- 'A variable marked as \'Deactivate by default\' isn\'t automatically added to all articles, and has to be explicitly added for each desired article in its master data tab. Only then can the variable be used for that article in the records.' | $T8 %]
+ </p>
+
 </form>
 
 <script type="text/javascript">
index 1f26429..349674b 100644 (file)
@@ -19,6 +19,7 @@
     <th width="20%">[% 'Includeable in reports' | $T8 %]</th>
     [%- IF SELF.module == 'IC' %]
      <th width="20%">[% 'Editable' | $T8 %]</th>
+     <th width="20%">[% 'Deactivate by default' | $T8 %]</th>
     [%- END %]
    </tr>
   </thead>
@@ -39,6 +40,7 @@
 
      [%- IF SELF.module == 'IC' %]
       <td>[%- IF cfg.flags.match('editable=1') %][% 'Yes' | $T8 %][%- ELSE %][% 'No' | $T8 %][%- END %]</td>
+      <td>[%- IF cfg.flags.match('defaults_to_invalid=1') %][% 'Yes' | $T8 %][%- ELSE %][% 'No' | $T8 %][%- END %]</td>
      [%- END %]
     </tr>
     [%- END %]
index d96740a..6c131c7 100644 (file)
      <tr class="listrow[% loop.count % 2 %]" id="row2.[% loop.count %]" [% UNLESS show_details %]style="display:none;"[% END %]>
       <td colspan="[% row.colspan %]">
  [%- FOREACH row2 = row.ROW2 %]
-   [%- IF row2.line_break %]<br>[%- END %]
-   [%- IF row2.cvar %]
-     [% row2.description %]
-     [% PROCESS cvar_inputs cvar = row2.render_options %]
-   [%- ELSE %]
+   [%- IF !row2.cvar %]
      [% row2.value %]
    [%- END %]
  [%- END %]
+
+ <table class='row2-cvars-table'>
+   <tr>
+   [%- FOREACH row2 = row.ROW2 %]
+     [%- IF row2.cvar && row2.render_options.valid %]
+       [%- IF row2.line_break %]
+         </tr><tr>
+       [%- END %]
+     <th>
+       [% row2.description %]
+     </th>
+     <td>
+       [% PROCESS cvar_inputs cvar = row2.render_options %]
+     </td>
+     [%- END %]
+   [%- END %]
+   </tr>
+ </table>
+
       </td>
      </tr>
 [%- END %]