Zusätzliche Rechnungsadressen: in Kundenstammdaten bearbeiten
authorMoritz Bunkus <m.bunkus@linet.de>
Mon, 25 Oct 2021 12:52:09 +0000 (14:52 +0200)
committerMoritz Bunkus <m.bunkus@linet.de>
Wed, 10 Nov 2021 15:06:56 +0000 (16:06 +0100)
SL/Controller/CustomerVendor.pm
js/kivi.CustomerVendor.js
locale/de/all
templates/webpages/customer_vendor/form.html
templates/webpages/customer_vendor/tabs/additional_billing_addresses.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/shipto.html

index 5470284..f2efeb0 100644 (file)
@@ -61,6 +61,7 @@ __PACKAGE__->run_before(
     'delete',
     'delete_contact',
     'delete_shipto',
+    'delete_additional_billing_address',
   ]
 );
 
@@ -71,6 +72,7 @@ __PACKAGE__->run_before(
     'show',
     'update',
     'ajaj_get_shipto',
+    'ajaj_get_additional_billing_address',
     'ajaj_get_contact',
     'ajax_list_prices',
   ]
@@ -88,6 +90,7 @@ __PACKAGE__->run_before(
 
 __PACKAGE__->run_before('normalize_name');
 
+my @ADDITIONAL_BILLING_ADDRESS_COLUMNS = qw(name department_1 department_2 contact street zipcode city country gln email phone fax default_address);
 
 sub action_add {
   my ($self) = @_;
@@ -280,6 +283,21 @@ sub _save {
       $self->{shipto}->save(cascade => 1);
     }
 
+    if ($self->is_customer && any { $self->{additional_billing_address}->$_ ne '' } @ADDITIONAL_BILLING_ADDRESS_COLUMNS) {
+      $self->{additional_billing_address}->customer_id($self->{cv}->id);
+      $self->{additional_billing_address}->save(cascade => 1);
+
+      # Make sure only one address per customer has "default address" set.
+      if ($self->{additional_billing_address}->default_address) {
+        SL::DB::Manager::AdditionalBillingAddress->update_all(
+          set   => { default_address => 0, },
+          where => [
+            customer_id => $self->{cv}->id,
+            '!id'       => $self->{additional_billing_address}->id,
+          ]);
+      }
+    }
+
     my $snumbers = $self->is_vendor() ? 'vendornumber_'. $self->{cv}->vendornumber : 'customernumber_'. $self->{cv}->customernumber;
     SL::DB::History->new(
       trans_id => $self->{cv}->id,
@@ -325,6 +343,10 @@ sub action_save {
     push(@redirect_params, shipto_id => $self->{shipto}->shipto_id);
   }
 
+  if ( $self->is_customer && $self->{additional_billing_address}->id ) {
+    push(@redirect_params, additional_billing_address_id => $self->{additional_billing_address}->id);
+  }
+
   $self->redirect_to(@redirect_params);
 }
 
@@ -512,6 +534,32 @@ sub action_delete_shipto {
   $self->action_edit();
 }
 
+sub action_delete_additional_billing_address {
+  my ($self) = @_;
+
+  my $db = $self->{additional_billing_address}->db;
+
+  if ( !$self->{additional_billing_address}->id ) {
+    SL::Helper::Flash::flash('error', $::locale->text('No address selected to delete'));
+  } else {
+    $db->with_transaction(sub {
+      if ( $self->{additional_billing_address}->used ) {
+        $self->{additional_billing_address}->detach;
+        $self->{additional_billing_address}->save(cascade => 1);
+        SL::Helper::Flash::flash('info', $::locale->text('Address is in use and was flagged invalid.'));
+      } else {
+        $self->{additional_billing_address}->delete(cascade => 1);
+        SL::Helper::Flash::flash('info', $::locale->text('Address deleted.'));
+      }
+
+      1;
+    }) || die($db->error);
+
+    $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new;
+  }
+
+  $self->action_edit;
+}
 
 sub action_search {
   my ($self) = @_;
@@ -637,6 +685,18 @@ sub action_ajaj_get_shipto {
   $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
 }
 
+sub action_ajaj_get_additional_billing_address {
+  my ($self) = @_;
+
+  my $data = {
+    additional_billing_address => {
+      map { ($_ => $self->{additional_billing_address}->$_) } ('id', @ADDITIONAL_BILLING_ADDRESS_COLUMNS)
+    },
+  };
+
+  $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
+}
+
 sub action_ajaj_get_contact {
   my ($self) = @_;
 
@@ -899,6 +959,15 @@ sub _instantiate_args {
   $self->{shipto}->assign_attributes(%{$::form->{shipto}});
   $self->{shipto}->module('CT');
 
+  if ($self->is_customer) {
+    if ( $::form->{additional_billing_address}->{id} ) {
+      $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new(id => $::form->{additional_billing_address}->{id})->load;
+    } else {
+      $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new;
+    }
+    $self->{additional_billing_address}->assign_attributes(%{ $::form->{additional_billing_address} });
+  }
+
   if ( $::form->{contact}->{cp_id} ) {
     $self->{contact} = SL::DB::Contact->new(cp_id => $::form->{contact}->{cp_id})->load();
   } else {
@@ -940,6 +1009,16 @@ sub _load_customer_vendor {
     $self->{shipto} = SL::DB::Shipto->new();
   }
 
+  if ($self->is_customer) {
+    if ( $::form->{additional_billing_address_id} ) {
+      $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new(id => $::form->{additional_billing_address_id})->load;
+      die($::locale->text('Error')) if $self->{additional_billing_address}->customer_id != $self->{cv}->id;
+
+    } else {
+      $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new;
+    }
+  }
+
   if ( $::form->{contact_id} ) {
     $self->{contact} = SL::DB::Contact->new(cp_id => $::form->{contact_id})->load();
 
@@ -988,6 +1067,7 @@ sub _create_customer_vendor {
   $self->{note_followup} = SL::DB::FollowUp->new();
 
   $self->{shipto} = SL::DB::Shipto->new();
+  $self->{additional_billing_address} = SL::DB::AdditionalBillingAddress->new if $self->is_customer;
 
   $self->{contact} = $self->_new_contact_object;
 }
@@ -1064,6 +1144,11 @@ sub _pre_render {
   $self->{shiptos} = $self->{cv}->shipto;
   $self->{shiptos} ||= [];
 
+  if ($self->is_customer) {
+    $self->{additional_billing_addresses} = $self->{cv}->additional_billing_addresses;
+    $self->{additional_billing_addresses} ||= [];
+  }
+
   $self->{notes} = SL::DB::Manager::Note->get_all(
     query => [
       trans_id => $self->{cv}->id,
@@ -1311,11 +1396,15 @@ sub _new_customer_vendor_object {
   my ($self) = @_;
 
   my $class  = 'SL::DB::' . ($self->is_vendor ? 'Vendor' : 'Customer');
-  return $class->new(
+  my $object = $class->new(
     contacts         => [],
     shipto           => [],
     custom_variables => [],
   );
+
+  $object->additional_billing_addresses([]) if $self->is_customer;
+
+  return $object;
 }
 
 sub _new_contact_object {
index e8cd923..02a2c2e 100644 (file)
@@ -21,6 +21,25 @@ namespace('kivi.CustomerVendor', function(ns) {
     });
   };
 
+  this.selectAdditionalBillingAddress = function(params) {
+    var additionalBillingAddressId = $('#additional_billing_address_id').val();
+    var url                        = 'controller.pl?action=CustomerVendor/ajaj_get_additional_billing_address&id='+ $('#cv_id').val() +'&db='+ $('#db').val() +'&additional_billing_address_id='+ additionalBillingAddressId;
+
+    $.getJSON(url, function(data) {
+      var additional_billing_address = data.additional_billing_address;
+      for (var key in additional_billing_address)
+        $('#additional_billing_address_'+ key).val(additional_billing_address[key])
+
+      if ( additionalBillingAddressId )
+        $('#action_delete_additional_billing_address').show();
+      else
+        $('#action_delete_additional_billing_address').hide();
+
+      if ( params.onFormSet )
+        params.onFormSet();
+    });
+  };
+
   this.selectDelivery = function(fromDate, toDate) {
     var deliveryId = $('#delivery_id').val();
 
@@ -449,7 +468,7 @@ namespace('kivi.CustomerVendor', function(ns) {
         $(elt).data('customer_vendor_picker', new kivi.CustomerVendor.Picker($(elt)));
     });
 
-    $('#cv_phone,#shipto_shiptophone,#contact_cp_phone1,#contact_cp_phone2,#contact_cp_mobile1,#contact_cp_mobile2').each(function(idx, elt) {
+    $('#cv_phone,#shipto_shiptophone,#additional_billing_address_phone,#contact_cp_phone1,#contact_cp_phone2,#contact_cp_mobile1,#contact_cp_mobile2').each(function(idx, elt) {
       kivi.CustomerVendor.init_dial_action($(elt));
     });
   }
index 12aa6bb..9bfe339 100755 (executable)
@@ -254,11 +254,14 @@ $self->{texts} = {
   'Added sections and function blocks: #1' => 'Hinzugefügte Abschnitte und Funktionsblöcke: #1',
   'Added text blocks: #1'       => 'Hinzugefügte Textblöcke: #1',
   'Addition'                    => 'Zusatz',
+  'Additional Billing Addresses' => 'Zusätzliche Rechnungsadressen',
   'Additional articles'         => 'Zusätzliche Artikel',
   'Additional articles actions' => 'Aktionen zu zusätzlichen Artikeln',
   'Additionally the invoice is marked for direct debit and would have been checked automatically had the bank information been entered.' => 'Weiterhin ist die Rechnung für Lastschrifteinzug vorgesehen und wäre standardmäßig ausgewählt, wenn die Bankinformationen eingetragen wären.',
   'Additionally the invoice is not marked for direct debit and would have been checked automatically had the bank information been entered.' => 'Weiterhin ist die Rechnung nicht für Lastschrifteinzug vorgesehen und wäre standardmäßig ausgewählt, wenn die Bankinformationen eingetragen wären.',
   'Address'                     => 'Adresse',
+  'Address deleted.'            => 'Adresse gelöscht',
+  'Address is in use and was flagged invalid.' => 'Adresse wurde benutzt und wird nur als ungültig markiert',
   'Administration'              => 'Administration',
   'Administration area'         => 'Administration',
   'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
@@ -978,6 +981,7 @@ $self->{texts} = {
   'Decrease'                    => 'Verringern',
   'Default (no language selected)' => 'Standard (keine Sprache ausgewählt)',
   'Default Accounts'            => 'Standardkonten',
+  'Default Billing Address'     => 'Standard-Rechnungsadresse',
   'Default Bin'                 => 'Standard-Lagerplatz',
   'Default Bin with ignoring onhand' => 'Standard-Lagerplatz für Auslagern ohne Prüfung auf Bestand',
   'Default Client (unconfigured)' => 'Standardmandant (unkonfiguriert)',
@@ -1015,6 +1019,7 @@ $self->{texts} = {
   'Delete Documents'            => 'Dokumente löschen',
   'Delete Images'               => 'Bilder löschen',
   'Delete Shipto'               => 'Lieferadresse löschen',
+  'Delete address'              => 'Adresse löschen',
   'Delete all'                  => 'Alle Löschen',
   'Delete for Customers'        => 'Bei Kunden löschen',
   'Delete links'                => 'Verknüpfungen löschen',
@@ -2110,6 +2115,7 @@ $self->{texts} = {
   'New Password'                => 'Neues Passwort',
   'New Purchase Price Rule'     => 'Neue Einkaufspreisregel',
   'New Sales Price Rule'        => 'Neue Verkaufspreisregel',
+  'New address'                 => 'Neue Adresse',
   'New client #1: The database configuration fields "host", "port", "name" and "user" must not be empty.' => 'Neuer Mandant #1: Die Datenbankkonfigurationsfelder "Host", "Port" und "Name" dürfen nicht leer sein.',
   'New client #1: The name must be unique and not empty.' => 'Neuer Mandant #1: Der Name darf nicht leer und muss eindeutig sein.',
   'New contact'                 => 'Neue Ansprechperson',
@@ -2140,6 +2146,7 @@ $self->{texts} = {
   'No VAT Info for this Factur-X/ZUGFeRD invoice, please ask your vendor to add this for his Factur-X/ZUGFeRD data.' => 'Konnte keine UST-ID für diese Factur-X-/ZUGFeRD-Rechnungen finden, bitte fragen Sie bei Ihren Lieferanten nach, ob dieses Feld im Factur-X-/ZUGFeRD-Datensatz gesetzt wird.',
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No action defined.'          => 'Keine Aktion definiert.',
+  'No address selected to delete' => 'Keine Adresse zum Löschen ausgewählt',
   'No article has been selected yet.' => 'Es wurde noch kein Artikel ausgewählt.',
   'No articles have been added yet.' => 'Es wurden noch keine Artikel hinzugefügt.',
   'No assembly has been selected yet.' => 'Es wurde noch kein Erzeugnis ausgewahlt.',
index 4fdc8a3..b726c1b 100644 (file)
@@ -20,6 +20,7 @@
   <div class="tabwidget" id="customer_vendor_tabs">
     <ul>
       <li><a href="#billing">[% 'Billing Address' | $T8 %]</a></li>
+      <li><a href="#additional_billing_addresses">[% 'Additional Billing Addresses' | $T8 %]</a></li>
       <li><a href="#bank">[% 'Bank account' | $T8 %]</a></li>
       <li><a href="#shipto">[% 'Shipping Address' | $T8 %]</a></li>
       <li><a href="#contacts">[% 'Contacts' | $T8 %]</a></li>
@@ -61,6 +62,7 @@
     </ul>
 
     [% PROCESS "customer_vendor/tabs/billing.html" %]
+    [% PROCESS "customer_vendor/tabs/additional_billing_addresses.html" %]
     [% PROCESS "customer_vendor/tabs/bank.html" %]
     [% PROCESS "customer_vendor/tabs/shipto.html" %]
     [% PROCESS "customer_vendor/tabs/contacts.html" %]
diff --git a/templates/webpages/customer_vendor/tabs/additional_billing_addresses.html b/templates/webpages/customer_vendor/tabs/additional_billing_addresses.html
new file mode 100644 (file)
index 0000000..d8a284c
--- /dev/null
@@ -0,0 +1,127 @@
+[%- USE T8 %]
+[%- USE LxERP %]
+[%- USE L %]
+
+<div id="additional_billing_addresses">
+  <table id="additional_billing_address_table">
+    <tr>
+      <th align="right">[% 'Billing Address' | $T8 %]</th>
+
+      <td>
+        [% L.select_tag(
+             'additional_billing_address.id',
+             SELF.additional_billing_addresses,
+             default     = SELF.additional_billing_address.id,
+             value_key   = 'id',
+             title_key   = 'displayable_id',
+             with_empty  = 1,
+             empty_title = LxERP.t8('New address'),
+             onchange    = "kivi.CustomerVendor.selectAdditionalBillingAddress({onFormSet: function(){ additionalBillingAddressMapWidget.testInputs(); kivi.reinit_widgets(); }});",
+           )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Default Billing Address' | $T8 %]</th>
+      <td>[% L.yes_no_tag('additional_billing_address.default_address', SELF.additional_billing_address.default_address) %]</td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Name' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.name', SELF.additional_billing_address.name,  size = 35) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Department' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.department_1', SELF.additional_billing_address.department_1,  size = 16) %]
+        [% L.input_tag('additional_billing_address.department_2', SELF.additional_billing_address.department_2,  size = 16) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Street' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.street', SELF.additional_billing_address.street,  size = 35) %]
+
+        <span id="additional_billing_address_map"></span>
+        <script type="text/javascript">
+          additionalBillingAddressMapWidget = new kivi.CustomerVendor.MapWidget('additional_billing_address_');
+          $(function() {
+            additionalBillingAddressMapWidget.render($('#additional_billing_address_map'));
+          });
+        </script>
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Zipcode' | $T8 %]/[% 'City' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.zipcode', SELF.additional_billing_address.zipcode,  size = 5) %]
+        [% L.input_tag('additional_billing_address.city', SELF.additional_billing_address.city,  size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Country' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.country', SELF.additional_billing_address.country,  size = 35) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'GLN' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.gln', SELF.additional_billing_address.gln,  size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Contact' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.contact', SELF.additional_billing_address.contact,  size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Phone' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.phone', SELF.additional_billing_address.phone,  size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Fax' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.fax', SELF.additional_billing_address.fax,  size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('additional_billing_address.email', SELF.additional_billing_address.email,  size = 45) %]
+      </td>
+    </tr>
+  </table>
+
+  [% L.button_tag('submitInputButton("delete_additional_billing_address");', LxERP.t8('Delete address'), class = 'submit') %]
+  [% IF ( !SELF.additional_billing_address.id ) %]
+    <script type="text/javascript">
+      $('#action_delete_additional_billing_address').hide();
+    </script>
+  [% END %]
+</div>
index 6e61072..c47d272 100644 (file)
@@ -3,7 +3,7 @@
 [%- USE L %]
 
 <div id="shipto">
-  <table width="100%" id="shipto_table">
+  <table id="shipto_table">
     <tr>
       <th align="right">[% 'Shipping Address' | $T8 %]</th>