use SL::DB::Default;
use SL::Helper::Flash;
+use SL::Locale::String qw(t8);
__PACKAGE__->run_before('check_auth');
+use Rose::Object::MakeMethods::Generic (
+ 'scalar --get_set_init' => [ qw(defaults all_warehouses posting_options payment_options accounting_options inventory_options profit_options) ],
+);
sub action_edit {
my ($self, %params) = @_;
-
- $self->{posting_options} = [ { title => $::locale->text("never"), value => 0 },
- { title => $::locale->text("every time"), value => 1 },
- { title => $::locale->text("on the same day"), value => 2 }, ];
- $self->{payment_options} = [ { title => $::locale->text("never"), value => 0 },
- { title => $::locale->text("every time"), value => 1 },
- { title => $::locale->text("on the same day"), value => 2 }, ];
- $self->{accounting_options} = [ { title => $::locale->text("Accrual"), value => "accrual" },
- { title => $::locale->text("cash"), value => "cash" }, ];
- $self->{inventory_options} = [ { title => $::locale->text("perpetual"), value => "perpetual" },
- { title => $::locale->text("periodic"), value => "periodic" }, ];
- $self->{profit_options} = [ { title => $::locale->text("balance"), value => "balance" },
- { title => $::locale->text("income"), value => "income" }, ];
-
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(is_changeable ir_changeable ar_changeable ap_changeable gl_changeable);
-
- $self->{payments_changeable} = SL::DB::Default->get->payments_changeable;
-
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(is_show_mark_as_paid ir_show_mark_as_paid ar_show_mark_as_paid ap_show_mark_as_paid);
-
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(accounting_method inventory_system profit_determination);
-
- $self->{show_bestbefore} = SL::DB::Default->get->show_bestbefore;
-
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(datev_check_on_sales_invoice datev_check_on_purchase_invoice datev_check_on_ar_transaction datev_check_on_ap_transaction datev_check_on_gl_transaction);
- # datev check: not implemented yet:
- #check_on_cash_and_receipt = 0
- #check_on_dunning = 0
- #check_on_sepa_import = 0
-
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(sales_order_show_delete purchase_order_show_delete sales_delivery_order_show_delete purchase_delivery_order_show_delete);
-
- # All warehouse / transfer default values
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(transfer_default transfer_default_use_master_default_bin transfer_default_ignore_onhand
- warehouse_id_ignore_onhand bin_id_ignore_onhand warehouse_id bin_id);
-
- # for the default warehouse and bin we get the list and
- # set a empty value with warehouse_id and bin_id = 0
- map { $self->{$_} = SL::DB::Default->get->$_ } qw(warehouse_id bin_id);
- $::form->get_lists('warehouses' => { 'key' => 'WAREHOUSES',
- 'bins' => 'BINS', });
- $self->{WAREHOUSES} = $::form->{WAREHOUSES};
- # leerer lagerplatz mit id 0
- my $no_default_bin_entry = { 'id' => '0', description => '--', 'BINS' => [ { id => '0', description => ''} ] };
- push @ { $self->{WAREHOUSES} }, $no_default_bin_entry;
-
- # set defaults to empty
- if (my $max = scalar @{ $self->{WAREHOUSES} }) {
- $self->{warehouse_id} ||= $self->{WAREHOUSES}->[$max -1]->{id};
- $self->{bin_id} ||= $self->{WAREHOUSES}->[$max -1]->{BINS}->[0]->{id};
- $self->{warehouse_id_ignore_onhand} ||= $self->{WAREHOUSES}->[$max -1]->{id};
- $self->{bin_id_ignore_onhand} ||= $self->{WAREHOUSES}->[$max -1]->{BINS}->[0]->{id};
- }
-
- $self->{show_weight} = SL::DB::Default->get->show_weight;
-
- $self->render('client_config/form', title => $::locale->text('Client Configuration'));
+ $self->edit_form;
}
-
sub action_save {
my ($self, %params) = @_;
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(is_changeable ir_changeable ar_changeable ap_changeable gl_changeable);
+ my $defaults = delete($::form->{defaults}) || {};
- SL::DB::Default->get->update_attributes('payments_changeable' => $::form->{payments_changeable});
+ # undef several fields if an empty value has been selected.
+ foreach (qw(warehouse_id bin_id warehouse_id_ignore_onhand bin_id_ignore_onhand)) {
+ undef $defaults->{$_} if !$defaults->{$_};
+ }
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(is_show_mark_as_paid ir_show_mark_as_paid ar_show_mark_as_paid ap_show_mark_as_paid);
+ $self->defaults->update_attributes(%{ $defaults });
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(accounting_method inventory_system profit_determination);
+ flash_later('info', t8('Client Configuration saved!'));
- SL::DB::Default->get->update_attributes('show_bestbefore' => $::form->{show_bestbefore});
+ $self->redirect_to(action => 'edit');
+}
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(datev_check_on_sales_invoice datev_check_on_purchase_invoice datev_check_on_ar_transaction datev_check_on_ap_transaction datev_check_on_gl_transaction);
+#
+# initializers
+#
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(sales_order_show_delete purchase_order_show_delete sales_delivery_order_show_delete purchase_delivery_order_show_delete);
+sub init_defaults { SL::DB::Default->get }
+sub init_all_warehouses { SL::DB::Manager::Warehouse->get_all_sorted }
- # undef warehouse_id if the empty value is selected
- if ( ($::form->{warehouse_id} == 0) && ($::form->{bin_id} == 0) ) {
- undef $::form->{warehouse_id};
- undef $::form->{bin_id};
- }
- # undef warehouse_id_ignore_onhand if the empty value is selected
- if ( ($::form->{warehouse_id_ignore_onhand} == 0) && ($::form->{bin_id_ignore_onhand} == 0) ) {
- undef $::form->{warehouse_id_ignore_onhand};
- undef $::form->{bin_id_ignore_onhand};
- }
-
- # All warehouse / transfer default values
- map { SL::DB::Default->get->update_attributes($_ => $::form->{$_}); } qw(transfer_default transfer_default_use_master_default_bin transfer_default_ignore_onhand
- warehouse_id_ignore_onhand bin_id_ignore_onhand warehouse_id bin_id);
+sub init_posting_options {
+ [ { title => t8("never"), value => 0 },
+ { title => t8("every time"), value => 1 },
+ { title => t8("on the same day"), value => 2 }, ]
+}
- SL::DB::Default->get->update_attributes('show_weight' => $::form->{show_weight});
+sub init_payment_options {
+ [ { title => t8("never"), value => 0 },
+ { title => t8("every time"), value => 1 },
+ { title => t8("on the same day"), value => 2 }, ]
+}
- flash_later('info', $::locale->text('Client Configuration saved!'));
+sub init_accounting_options {
+ [ { title => t8("Accrual"), value => "accrual" },
+ { title => t8("cash"), value => "cash" }, ]
+}
- $self->redirect_to(action => 'edit');
+sub init_inventory_options {
+ [ { title => t8("perpetual"), value => "perpetual" },
+ { title => t8("periodic"), value => "periodic" }, ]
}
+sub init_profit_options {
+ [ { title => t8("balance"), value => "balance" },
+ { title => t8("income"), value => "income" }, ]
+}
-#################### private stuff ##########################
+#
+# filters
+#
sub check_auth {
$::auth->assert('admin');
}
+#
+# helpers
+#
+
+sub edit_form {
+ my ($self) = @_;
+ $self->render('client_config/form', title => t8('Client Configuration'));
+}
+
1;
--- /dev/null
+[%- USE LxERP -%][%- USE L -%]
+<div id="datev_check_configuration">
+ <div class='listheading'>[% LxERP.t8('DATEV check configuration') %]</div>
+
+ <table>
+ <tr>
+ <td colspan="3">[% LxERP.t8('It is possible to make a quick DATEV export everytime you post a record to ensure things work nicely with their data requirements. This will result in a slight overhead though you can enable this for each type of record independantly.') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Check on sales invoice') %]</td>
+ <td>[% L.yes_no_tag('defaults.datev_check_on_sales_invoice', SELF.defaults.datev_check_on_sales_invoice) %]</td>
+ <td>[% LxERP.t8('Perform check when a sales invoice or a payment for a sales invoice is posted?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Check on purchase invoice') %]</td>
+ <td>[% L.yes_no_tag('defaults.datev_check_on_purchase_invoice', SELF.defaults.datev_check_on_purchase_invoice) %]</td>
+ <td>[% LxERP.t8('Perform check when a purchase invoice or a payment for a purchase invoice is posted?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Check on ar transaction') %]</td>
+ <td>[% L.yes_no_tag('defaults.datev_check_on_ar_transaction', SELF.defaults.datev_check_on_ar_transaction) %]</td>
+ <td>[% LxERP.t8('Perform check when an ar transaction is posted?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Check on ap transaction') %]</td>
+ <td>[% L.yes_no_tag('defaults.datev_check_on_ap_transaction', SELF.defaults.datev_check_on_ap_transaction) %]</td>
+ <td>[% LxERP.t8('Perform check when an ap transaction is posted?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Check on gl transaction') %]</td>
+ <td>[% L.yes_no_tag('defaults.datev_check_on_gl_transaction', SELF.defaults.datev_check_on_gl_transaction) %]</td>
+ <td>[% LxERP.t8('Perform check when a gl transaction is posted?') %]</td>
+ </tr>
+ </table>
+</div>
--- /dev/null
+[%- USE LxERP -%][%- USE L -%]
+<div id="miscellaneous">
+ <div class='listheading'>[% LxERP.t8('Weight') %]</div>
+
+ <table>
+ <tr>
+ <td align="right">[% LxERP.t8('Show weights') %]</td>
+ <td>
+ [% L.yes_no_tag('defaults.show_weight', SELF.defaults.show_weight) %]
+ </td>
+ <td>
+ [% LxERP.t8('Show the weights of articles and the total weight in orders, invoices and delivery notes?') %]<br>
+ </td>
+ </tr>
+ </table>
+</div>
+</div>
--- /dev/null
+[%- USE LxERP -%][%- USE L -%]
+<div id="orders_deleteable">
+ <div class='listheading'>[% LxERP.t8('Orders / Delivery Orders deleteable') %]</div>
+
+ <table>
+ <tr>
+ <td align="right">[% LxERP.t8('Sales Orders deleteable') %]</td>
+ <td>[% L.yes_no_tag('defaults.sales_order_show_delete', SELF.defaults.sales_order_show_delete) %]</td>
+ <td>[% LxERP.t8('Show delete button in sales orders?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Purchase Orders deleteable') %]</td>
+ <td>[% L.yes_no_tag('defaults.purchase_order_show_delete', SELF.defaults.purchase_order_show_delete) %]</td>
+ <td>[% LxERP.t8('Show delete button in purchase orders?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Sales Delivery Orders deleteable') %]</td>
+ <td>[% L.yes_no_tag('defaults.sales_delivery_order_show_delete', SELF.defaults.sales_delivery_order_show_delete) %]</td>
+ <td>[% LxERP.t8('Show delete button in sales delivery orders?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Purchase Delivery Orders deleteable') %]</td>
+ <td>[% L.yes_no_tag('defaults.purchase_delivery_order_show_delete', SELF.defaults.purchase_delivery_order_show_delete) %]</td>
+ <td>[% LxERP.t8('Show delete button in purchase delivery orders?') %]</td>
+ </tr>
+ </table>
+</div>
--- /dev/null
+[%- USE L -%][%- USE LxERP -%]
+<div id="posting_configuration">
+ <div class="listheading">[% LxERP.t8('Posting Configuration') %]</div>
+
+ <table>
+ <tr>
+ <td align="right">[% LxERP.t8('Sales invoices changeable') %]</td>
+ <td>[% L.select_tag('defaults.is_changeable', SELF.posting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.is_changeable) %]</td>
+ <td>[% LxERP.t8('Should sales invoices be and when should they be changeable or deleteable after posting?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Purchase invoices changeable') %]</td>
+ <td>[% L.select_tag('defaults.ir_changeable', SELF.posting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.ir_changeable) %]</td>
+ <td>[% LxERP.t8('Should purchase invoices be and when should they be deleteable after posting?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('AR transactions changeable') %]</td>
+ <td>[% L.select_tag('defaults.ar_changeable', SELF.posting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.ar_changeable) %]</td>
+ <td>[% LxERP.t8('Should ar transactions be and when should they be changeable or deleteable after posting?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('AP transactions changeable') %]</td>
+ <td>[% L.select_tag('defaults.ap_changeable', SELF.posting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.ap_changeable) %]</td>
+ <td>[% LxERP.t8('Should ap transactions be and when should they be changeable or deleteable after posting?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('GL transactions changeable') %]</td>
+ <td>[% L.select_tag('defaults.gl_changeable', SELF.posting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.gl_changeable) %]</td>
+ <td>[% LxERP.t8('Should gl transactions be and when should they be changeable or deleteable after posting?') %]</td>
+ </tr>
+
+ <tr> </tr>
+ <tr> </tr>
+
+ <tr>
+ <td align="right">[% LxERP.t8('Payments Changeable') %]</td>
+ <td>[% L.select_tag('defaults.payments_changeable', SELF.payment_options, value_key = 'value', title_key = 'title', default = SELF.defaults.payments_changeable) %]</td>
+ <td>[% LxERP.t8('Should payments be and when should they be changeable after posting?') %]</td>
+ </tr>
+
+ <tr> </tr>
+ <tr> </tr>
+
+ <tr>
+ <td align="right">[% LxERP.t8('Show "mark as paid" in sales invoices') %]</td>
+ <td>[% L.yes_no_tag('defaults.is_show_mark_as_paid', SELF.defaults.is_show_mark_as_paid) %]</td>
+ <td>[% LxERP.t8('Should the "mark as paid" button showed on sales invoices?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Show "mark as paid" in purchase invoices') %]</td>
+ <td>[% L.yes_no_tag('defaults.ir_show_mark_as_paid', SELF.defaults.ir_show_mark_as_paid) %]</td>
+ <td>[% LxERP.t8('Should the "mark as paid" button showed in purchase invoices?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Show "mark as paid" in ar transactions') %]</td>
+ <td>[% L.yes_no_tag('defaults.ar_show_mark_as_paid', SELF.defaults.ar_show_mark_as_paid) %]</td>
+ <td>[% LxERP.t8('Should the "mark as paid" button showed in ar transactions?') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Show "mark as paid" in ap transactions') %]</td>
+ <td>[% L.yes_no_tag('defaults.ap_show_mark_as_paid', SELF.defaults.ap_show_mark_as_paid) %]</td>
+ <td>[% LxERP.t8('Should the "mark as paid" button showed in ap transactions?') %]</td>
+ </tr>
+
+ <tr> </tr>
+ <tr> </tr>
+
+ <tr>
+ <td align="right">[% LxERP.t8('Accounting method') %]</td>
+ <td>[% L.select_tag('defaults.accounting_method', SELF.accounting_options, value_key = 'value', title_key = 'title', default = SELF.defaults.accounting_method) %]</td>
+ <td>[% LxERP.t8('This option controls the posting and calculation behavior for the accounting method.') %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Inventory system') %]</td>
+ <td>[% L.select_tag('defaults.inventory_system', SELF.inventory_options, value_key = 'value', title_key = 'title', default = SELF.defaults.inventory_system) %]</td>
+ <td>
+ [% LxERP.t8('This option controls the inventory system.') %]<br>
+ [% LxERP.t8('ATTENTION! You can not simply change it from periodic to perpetual once you started posting.') %]
+ </td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Profit determination') %]</td>
+ <td>[% L.select_tag('defaults.profit_determination', SELF.profit_options, value_key = 'value', title_key = 'title', default = SELF.defaults.profit_determination) %]</td>
+ <td>[% LxERP.t8('This option controls the method used for profit determination.') %]</td>
+ </tr>
+ </table>
+</div>
--- /dev/null
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%]
+<div id="warehouse">
+ <div class='listheading'>[% LxERP.t8('Warehouse') %]</div>
+
+ <table>
+ <tr>
+ <td align="right">[% LxERP.t8('Default Transfer') %]</td>
+ <td>
+ [% L.yes_no_tag('defaults.transfer_default', SELF.defaults.transfer_default) %]
+ </td>
+ <td>
+ [% LxERP.t8('Show Transfer via default') %]<br>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Default Transfer with Master Bin') %]</td>
+ <td>
+ [% L.yes_no_tag('defaults.transfer_default_use_master_default_bin', SELF.defaults.transfer_default_use_master_default_bin) %]
+ </td>
+ <td>
+ [% LxERP.t8('Use master default bin for Default Transfer, if no default bin for the part is configured') %]<br>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Default Transfer Out with negative inventory') %]</td>
+ <td>
+ [% L.yes_no_tag('defaults.transfer_default_ignore_onhand', SELF.defaults.transfer_default_ignore_onhand) %]
+ </td>
+ <td>
+ [% LxERP.t8('Default Transfer Out always succeed. The current part onhand is ignored and the inventory can have negative stocks (not recommended).') %]<br>
+ </td>
+ </tr>
+
+ <tr> </tr>
+ <tr>
+ <td align="right" nowrap="true">[% LxERP.t8('Default Warehouse') %]</td>
+ <td>
+ [% L.select_tag('defaults.warehouse_id', SELF.all_warehouses, id='warehouse_id', with_empty=1, default=SELF.defaults.warehouse_id, title_key='description',
+ onchange="warehouse_selected(this.selectedIndex == 0 ? -1 : warehouses[this.selectedIndex - 1].id, -1)") %]
+ </td>
+ <td>
+ [% LxERP.t8('This is the default bin for parts') %]<br>
+ [% LxERP.t8('If configured this bin will be preselected for all new parts. Also this bin will be used as the master default bin, if default transfer out with master bin is activated.') %]<br>
+ </td>
+ </tr>
+ <tr>
+ <td align="right" nowrap="true">[% LxERP.t8('Default Bin') %]</td>
+ <td>[% L.select_tag('defaults.bin_id', [], id='bin_id', with_empty=1) %]</td>
+ </tr>
+ <tr>
+ <td align="right" nowrap="true">[% LxERP.t8('Default Warehouse with ignoring on hand') %]</td>
+ <td>
+ [% L.select_tag('defaults.warehouse_id_ignore_onhand', SELF.all_warehouses, id='warehouse_id_ignore_onhand', with_empty=1, default=SELF.defaults.warehouse_id_ignore_onhand, title_key='description',
+ onchange="warehouse_selected(this.selectedIndex == 0 ? -1 : warehouses[this.selectedIndex - 1].id, -1, 'bin_id_ignore_onhand')") %]
+ </td>
+ <td>
+ [% LxERP.t8('This is the default bin for ignoring onhand') %]<br>
+ [% LxERP.t8('If the default transfer out always succeed use this bin for negative stock quantity.') %]<br>
+ </td>
+ </tr>
+ <tr>
+ <td align="right" nowrap="true">[% LxERP.t8('Default Bin with ignoring onhand') %]</td>
+ <td>[% L.select_tag('defaults.bin_id_ignore_onhand', [], id='bin_id_ignore_onhand', with_empty=1) %]</td>
+ </tr>
+ <tr>
+ <td align="right">[% LxERP.t8('Show Bestbefore') %]</td>
+ <td>
+ [% L.yes_no_tag('defaults.show_bestbefore', SELF.defaults.show_bestbefore) %]
+ </td>
+ <td>
+ [% LxERP.t8('Show fields used for the best before date?') %]<br>
+ [% LxERP.t8('ATTENTION! If you enabled this feature you can not simply turn it off again without taking care that best_before fields are emptied in the database.') %]<br>
+ [% LxERP.t8('This can be done with the following query:') %]<br>
+ <br>
+ UPDATE inventory SET bestbefore = NULL; <br>
+ <br>
+ [% LxERP.t8('Any stock contents containing a best before date will be impossible to stock out otherwise.') %]
+ </td>
+ </tr>
+ </table>
+</div>
<script type="text/javascript" src="js/parts_language_selection.js"></script>
<script type="text/javascript">
<!--
- warehouses = new Array();
- [%- USE WAREHOUSES_it = Iterator(SELF.WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
- warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
- warehouses[[% WAREHOUSES_it.count - 1 %]]['id'] = [% warehouse.id %];
- warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'] = new Array();
- [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
- warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count - 1 %]] = new Array();
- warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count - 1 %]]['description'] = "[% JavaScript.escape(bin.description) %]";
- warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count - 1 %]]['id'] = [% bin.id %];
- [% END %]
- [% END %]
-
- function warehouse_selected(warehouse_id, bin_id, bin_id_name) {
-
- // bin_id_name is optional and only used in client_config.html
- var bin_id_name = bin_id_name || 'bin_id';
-
- var control = document.getElementById(bin_id_name);
-
- for (var i = control.options.length - 1; i >= 0; i--) {
- control.options[i] = null;
- }
-
- var warehouse_index = 0;
-
- for (i = 0; i < warehouses.length; i++)
- if (warehouses[i]['id'] == warehouse_id) {
- warehouse_index = i;
- break;
- }
-
- var warehouse = warehouses[warehouse_index];
- var bin_index = 0;
-
- for (i = 0; i < warehouse['bins'].length; i++)
- if (warehouse['bins'][i]['id'] == bin_id) {
- bin_index = i;
- break;
- }
-
- for (i = 0; i < warehouse['bins'].length; i++) {
- control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
- }
-
-
- control.options[bin_index].selected = true;
- }
-
- $(function() {
- warehouse_selected([% SELF.warehouse_id %], [% SELF.bin_id %], 'bin_id');
- warehouse_selected([% SELF.warehouse_id_ignore_onhand %], [% SELF.bin_id_ignore_onhand %], 'bin_id_ignore_onhand');
- })
+var warehouses = [
+ [%- USE warehouses_it = Iterator(SELF.all_warehouses) %][%- FOREACH warehouse = warehouses_it %]
+ { id: [% warehouse.id %],
+ bins: [
+ [% USE bins_it = Iterator(warehouse.bins_sorted) %][% FOREACH bin = bins_it %]
+ { id: [% bin.id %], description: "[% JavaScript.escape(bin.description) %]" }[% UNLESS bins_it.last %],[% END %]
+ [% END %]
+ ] }[% UNLESS warehouses_it.last %],[% END %]
+ [% END %]
+];
+
+function warehouse_selected(warehouse_id, bin_id, bin_id_name) {
+ // bin_id_name is optional and only used in client_config.html
+ bin_id_name = bin_id_name || 'bin_id';
+
+ // Remove all bins safe for the empty entry
+ var bin_select = $('#' + bin_id_name);
+ bin_select.find('option').filter('[value!=""]').remove();
+
+ // Find selected warehouse
+ var warehouse = warehouses.filter(function(elt) { return elt.id == warehouse_id; })[0];
+ if (!warehouse)
+ return;
+
+ // Add bins as options to select.
+ $(warehouse.bins).each(function(idx, bin) {
+ bin_select.append($('<option>', { value: bin.id, selected: bin.id == bin_id }).text(bin.description));
+ });
+}
+
+$(function() {
+ warehouse_selected([% SELF.defaults.warehouse_id || -1 %], [% SELF.defaults.bin_id || -1 %], 'bin_id');
+ warehouse_selected([% SELF.defaults.warehouse_id_ignore_onhand || -1 %], [% SELF.defaults.bin_id_ignore_onhand || -1 %], 'bin_id_ignore_onhand');
+})
-->
</script>
<h1>[% title | html %]</h1>
[% PROCESS 'common/flash.html' %]
<form action='controller.pl' method='POST'>
-
-<table>
-
- <tr class='listheading'>
- <th colspan="3">[% 'Posting Configuration' | $T8 %]</th>
- </tr>
-
- <tr>
- <td align="right">[% 'Sales invoices changeable' | $T8 %]</td>
- <td>[% L.select_tag('is_changeable', SELF.posting_options, value_key => 'value', title_key => 'title', default => SELF.is_changeable) %]</td>
- <td>[% 'Should sales invoices be and when should they be changeable or deleteable after posting?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Purchase invoices changeable' | $T8 %]</td>
- <td>[% L.select_tag('ir_changeable', SELF.posting_options, value_key => 'value', title_key => 'title', default => SELF.ir_changeable) %]</td>
- <td>[% 'Should purchase invoices be and when should they be deleteable after posting?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'AR transactions changeable' | $T8 %]</td>
- <td>[% L.select_tag('ar_changeable', SELF.posting_options, value_key => 'value', title_key => 'title', default => SELF.ar_changeable) %]</td>
- <td>[% 'Should ar transactions be and when should they be changeable or deleteable after posting?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'AP transactions changeable' | $T8 %]</td>
- <td>[% L.select_tag('ap_changeable', SELF.posting_options, value_key => 'value', title_key => 'title', default => SELF.ap_changeable) %]</td>
- <td>[% 'Should ap transactions be and when should they be changeable or deleteable after posting?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'GL transactions changeable' | $T8 %]</td>
- <td>[% L.select_tag('gl_changeable', SELF.posting_options, value_key => 'value', title_key => 'title', default => SELF.gl_changeable) %]</td>
- <td>[% 'Should gl transactions be and when should they be changeable or deleteable after posting?' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr>
- <td align="right">[% 'Payments Changeable' | $T8 %]</td>
- <td>[% L.select_tag('payments_changeable', SELF.payment_options, value_key => 'value', title_key => 'title', default => SELF.payments_changeable) %]</td>
- <td>[% 'Should payments be and when should they be changeable after posting?' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr>
- <td align="right">[% 'Show "mark as paid" in sales invoices' | $T8 %]</td>
- <td>[% L.yes_no_tag('is_show_mark_as_paid', SELF.is_show_mark_as_paid) %]</td>
- <td>[% 'Should the "mark as paid" button showed on sales invoices?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Show "mark as paid" in purchase invoices' | $T8 %]</td>
- <td>[% L.yes_no_tag('ir_show_mark_as_paid', SELF.ir_show_mark_as_paid) %]</td>
- <td>[% 'Should the "mark as paid" button showed in purchase invoices?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Show "mark as paid" in ar transactions' | $T8 %]</td>
- <td>[% L.yes_no_tag('ar_show_mark_as_paid', SELF.ar_show_mark_as_paid) %]</td>
- <td>[% 'Should the "mark as paid" button showed in ar transactions?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Show "mark as paid" in ap transactions' | $T8 %]</td>
- <td>[% L.yes_no_tag('ap_show_mark_as_paid', SELF.ap_show_mark_as_paid) %]</td>
- <td>[% 'Should the "mark as paid" button showed in ap transactions?' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr>
- <td align="right">[% 'Accounting method' | $T8 %]</td>
- <td>[% L.select_tag('accounting_method', SELF.accounting_options, value_key => 'value', title_key => 'title', default => SELF.accounting_method) %]</td>
- <td>[% 'This option controls the posting and calculation behavior for the accounting method.' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Inventory system' | $T8 %]</td>
- <td>[% L.select_tag('inventory_system', SELF.inventory_options, value_key => 'value', title_key => 'title', default => SELF.inventory_system) %]</td>
- <td>
- [% 'This option controls the inventory system.' | $T8 %]<br>
- [% 'ATTENTION! You can not simply change it from periodic to perpetual once you started posting.' | $T8 %]
- </td>
- </tr>
- <tr>
- <td align="right">[% 'Profit determination' | $T8 %]</td>
- <td>[% L.select_tag('profit_determination', SELF.profit_options, value_key => 'value', title_key => 'title', default => SELF.profit_determination) %]</td>
- <td>[% 'This option controls the method used for profit determination.' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr class='listheading'>
- <th colspan="3">[% 'DATEV check configuration' | $T8 %]</th>
- </tr>
- <tr>
- <td colspan="3">[% 'It is possible to make a quick DATEV export everytime you post a record to ensure things work nicely with their data requirements. This will result in a slight overhead though you can enable this for each type of record independantly.' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Check on sales invoice' | $T8 %]</td>
- <td>[% L.yes_no_tag('datev_check_on_sales_invoice', SELF.datev_check_on_sales_invoice) %]</td>
- <td>[% 'Perform check when a sales invoice or a payment for a sales invoice is posted?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Check on purchase invoice' | $T8 %]</td>
- <td>[% L.yes_no_tag('datev_check_on_purchase_invoice', SELF.datev_check_on_purchase_invoice) %]</td>
- <td>[% 'Perform check when a purchase invoice or a payment for a purchase invoice is posted?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Check on ar transaction' | $T8 %]</td>
- <td>[% L.yes_no_tag('datev_check_on_ar_transaction', SELF.datev_check_on_ar_transaction) %]</td>
- <td>[% 'Perform check when an ar transaction is posted?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Check on ap transaction' | $T8 %]</td>
- <td>[% L.yes_no_tag('datev_check_on_ap_transaction', SELF.datev_check_on_ap_transaction) %]</td>
- <td>[% 'Perform check when an ap transaction is posted?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Check on gl transaction' | $T8 %]</td>
- <td>[% L.yes_no_tag('datev_check_on_gl_transaction', SELF.datev_check_on_gl_transaction) %]</td>
- <td>[% 'Perform check when a gl transaction is posted?' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr class='listheading'>
- <th colspan="3">[% 'Orders / Delivery Orders deleteable' | $T8 %]</th>
- </tr>
- <tr>
- <td align="right">[% 'Sales Orders deleteable' | $T8 %]</td>
- <td>[% L.yes_no_tag('sales_order_show_delete', SELF.sales_order_show_delete) %]</td>
- <td>[% 'Show delete button in sales orders?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Purchase Orders deleteable' | $T8 %]</td>
- <td>[% L.yes_no_tag('purchase_order_show_delete', SELF.purchase_order_show_delete) %]</td>
- <td>[% 'Show delete button in purchase orders?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Sales Delivery Orders deleteable' | $T8 %]</td>
- <td>[% L.yes_no_tag('sales_delivery_order_show_delete', SELF.sales_delivery_order_show_delete) %]</td>
- <td>[% 'Show delete button in sales delivery orders?' | $T8 %]</td>
- </tr>
- <tr>
- <td align="right">[% 'Purchase Delivery Orders deleteable' | $T8 %]</td>
- <td>[% L.yes_no_tag('purchase_delivery_order_show_delete', SELF.purchase_delivery_order_show_delete) %]</td>
- <td>[% 'Show delete button in purchase delivery orders?' | $T8 %]</td>
- </tr>
-
- <tr> </tr>
- <tr> </tr>
-
- <tr class='listheading'>
- <th colspan="3">[% 'Warehouse' | $T8 %]</th>
- </tr>
- <tr>
- <td align="right">[% 'Default Transfer' | $T8 %]</td>
- <td>
- [% L.yes_no_tag('transfer_default', SELF.transfer_default) %]
- </td>
- <td>
- [% 'Show Transfer via default' | $T8 %]<br>
- </td>
- </tr>
- <tr>
- <td align="right">[% 'Default Transfer with Master Bin' | $T8 %]</td>
- <td>
- [% L.yes_no_tag('transfer_default_use_master_default_bin', SELF.transfer_default_use_master_default_bin) %]
- </td>
- <td>
- [% 'Use master default bin for Default Transfer, if no default bin for the part is configured' | $T8 %]<br>
- </td>
- </tr>
- <tr>
- <td align="right">[% 'Default Transfer Out with negative inventory' | $T8 %]</td>
- <td>
- [% L.yes_no_tag('transfer_default_ignore_onhand', SELF.transfer_default_ignore_onhand) %]
- </td>
- <td>
- [% 'Default Transfer Out always succeed. The current part onhand is ignored and the inventory can have negative stocks (not recommended).' | $T8 %]<br>
- </td>
- </tr>
-
- <tr> </tr>
-<tr>
-<th align="right" nowrap="true">[% 'Default Warehouse' | $T8 %]</th>
-<td>
- <select name="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
- [%- FOREACH warehouse = SELF.WAREHOUSES %]
- <option value="[% HTML.escape(warehouse.id) %]"[% IF SELF.warehouse_id == warehouse.id %] selected[% END %]>[% warehouse.description %]</option>
- [%- END %]
- </select>
-</td>
-<td>
- [% 'This is the default bin for parts' | $T8 %]<br>
- [% 'If configured this bin will be preselected for all new parts. Also this bin will be used as the master default bin, if default transfer out with master bin is activated.' | $T8 %]<br>
-</td>
-</tr>
-<tr>
-<th align="right" nowrap="true">[% 'Default Bin' | $T8 %]</th>
-<td><select id="bin_id" name="bin_id"></select></td>
-</tr>
-<tr>
-<th align="right" nowrap="true">[% 'Default Warehouse with ignoring on hand' | $T8 %]</th>
-<td>
- <select name="warehouse_id_ignore_onhand" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0, 'bin_id_ignore_onhand')">
- [%- FOREACH warehouse = SELF.WAREHOUSES %]
- <option value="[% HTML.escape(warehouse.id) %]"[% IF SELF.warehouse_id_ignore_onhand == warehouse.id %] selected[% END %]>[% warehouse.description %]</option>
- [%- END %]
- </select>
-</td>
-<td>
- [% 'This is the default bin for ignoring onhand' | $T8 %]<br>
- [% 'If the default transfer out always succeed use this bin for negative stock quantity.' | $T8 %]<br>
-</td>
-</tr>
-<tr>
-<th align="right" nowrap="true">[% 'Default Bin with ignoring onhand' | $T8 %]</th>
-<td><select id="bin_id_ignore_onhand" name="bin_id_ignore_onhand"></select></td>
-</tr>
-<tr>
- <td align="right">[% 'Show Bestbefore' | $T8 %]</td>
- <td>
- [% L.yes_no_tag('show_bestbefore', SELF.show_bestbefore) %]
- </td>
- <td>
- [% 'Show fields used for the best before date?' | $T8 %]<br>
- [% 'ATTENTION! If you enabled this feature you can not simply turn it off again without taking care that best_before fields are emptied in the database.' | $T8 %]<br>
- [% 'This can be done with the following query:' | $T8 %]<br>
- <br>
- UPDATE inventory SET bestbefore = NULL; <br>
- <br>
- [% 'Any stock contents containing a best before date will be impossible to stock out otherwise.' | $T8 %]
- </td>
- </tr>
- <tr class='listheading'>
- <th colspan="3">[% 'Weight' | $T8 %]</th>
- </tr>
- <tr>
- <td align="right">[% 'Show weights' | $T8 %]</td>
- <td>
- [% L.yes_no_tag('show_weight', SELF.show_weight) %]
- </td>
- <td>
- [% 'Show the weights of articles and the total weight in orders, invoices and delivery notes?' | $T8 %]<br>
- </td>
- </tr>
-</table>
-
-<br>
-
-[%- L.hidden_tag('action', 'ClientConfig/dispatch') %]
-[%- L.submit_tag('action_save', LxERP.t8('Save')) %]
-
-<br><br>
+ <div class="tabwidget">
+ <ul>
+ <li><a href="#posting_configuration">[% 'Posting Configuration' | $T8 %]</a></li>
+ <li><a href="#datev_check_configuration">[% 'DATEV check configuration' | $T8 %]</a></li>
+ <li><a href="#orders_deleteable">[% 'Orders / Delivery Orders deleteable' | $T8 %]</a></li>
+ <li><a href="#warehouse">[% 'Warehouse' | $T8 %]</a></li>
+ <li><a href="#miscellaneous">[% 'Miscellaneous' | $T8 %]</a></li>
+ </ul>
+
+[% PROCESS 'client_config/_posting_configuration.html' %]
+[% PROCESS 'client_config/_datev_check_configuration.html' %]
+[% PROCESS 'client_config/_orders_deleteable.html' %]
+[% PROCESS 'client_config/_warehouse.html' %]
+[% PROCESS 'client_config/_miscellaneous.html' %]
+
+ <div>
+ [%- L.hidden_tag('action', 'ClientConfig/dispatch') %]
+ [%- L.submit_tag('action_save', LxERP.t8('Save')) %]
+ </div>
</form>