From: Jan Büren Date: Thu, 30 May 2013 11:14:42 +0000 (+0200) Subject: Migration von parts.bin nach wirklichen Lager und Lagerplatz s.a. Ticket 2284 X-Git-Tag: release-3.1.0beta1~402 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=82c4717d48bbdb8d30c9671e71ecb0d6d8eac963;p=kivitendo-erp.git Migration von parts.bin nach wirklichen Lager und Lagerplatz s.a. Ticket 2284 --- diff --git a/SL/AM.pm b/SL/AM.pm index c85c47911..85080e8a1 100644 --- a/SL/AM.pm +++ b/SL/AM.pm @@ -2101,9 +2101,10 @@ sub get_warehouse { map { $form->{$_} = $ref->{$_} } keys %{ $ref }; $query = qq|SELECT b.*, EXISTS - (SELECT i.warehouse_id - FROM inventory i + (SELECT i.warehouse_id, p.warehouse_id + FROM inventory i, parts p WHERE i.bin_id = b.id + OR p.bin_id = b.id LIMIT 1) AS in_use FROM bin b diff --git a/SL/Common.pm b/SL/Common.pm index e86e6c425..dc1cc04ec 100644 --- a/SL/Common.pm +++ b/SL/Common.pm @@ -85,7 +85,7 @@ sub retrieve_parts { } if ($form->{no_services}) { - $filter .= qq| AND (inventory_accno_id is not NULL or assembly=TRUE)|; # @mb hier nochmal optimieren ... nach kurzer ruecksprache alles i.o. + $filter .= qq| AND (inventory_accno_id is not NULL or assembly=TRUE)|; } substr($filter, 1, 3) = "WHERE" if ($filter); @@ -94,7 +94,8 @@ sub retrieve_parts { $order_dir = $order_dir ? "ASC" : "DESC"; my $query = - qq|SELECT id, partnumber, description, ean | . + qq|SELECT id, partnumber, description, ean, | . + qq| warehouse_id, bin_id | . qq|FROM parts $filter | . qq|ORDER BY $order_by $order_dir|; my $sth = $dbh->prepare($query); diff --git a/SL/DB/MetaSetup/Default.pm b/SL/DB/MetaSetup/Default.pm index bb174ebaa..8063f9ed5 100644 --- a/SL/DB/MetaSetup/Default.pm +++ b/SL/DB/MetaSetup/Default.pm @@ -68,9 +68,23 @@ __PACKAGE__->meta->setup( ar_show_mark_as_paid => { type => 'boolean', default => 'true' }, ap_show_mark_as_paid => { type => 'boolean', default => 'true' }, assemblynumber => { type => 'text' }, + warehouse_id => { type => 'integer' }, + bin_id => { type => 'integer' }, ], primary_key_columns => [ 'id' ], + + foreign_keys => [ + bin => { + class => 'SL::DB::Bin', + key_columns => { bin_id => 'id' }, + }, + + warehouse => { + class => 'SL::DB::Warehouse', + key_columns => { warehouse_id => 'id' }, + }, + ], ); 1; diff --git a/SL/DB/MetaSetup/Part.pm b/SL/DB/MetaSetup/Part.pm index c94c66c38..ddc3f6fbe 100644 --- a/SL/DB/MetaSetup/Part.pm +++ b/SL/DB/MetaSetup/Part.pm @@ -26,7 +26,6 @@ __PACKAGE__->meta->setup( inventory_accno_id => { type => 'integer' }, income_accno_id => { type => 'integer' }, expense_accno_id => { type => 'integer' }, - bin => { type => 'text' }, shop => { type => 'boolean', default => 'false' }, obsolete => { type => 'boolean', default => 'false' }, bom => { type => 'boolean', default => 'false' }, @@ -48,6 +47,8 @@ __PACKAGE__->meta->setup( onhand => { type => 'numeric', default => '0', precision => 5, scale => 25 }, stockable => { type => 'boolean', default => 'false' }, has_sernumber => { type => 'boolean', default => 'false' }, + warehouse_id => { type => 'integer' }, + bin_id => { type => 'integer' }, ], primary_key_columns => [ 'id' ], @@ -55,6 +56,11 @@ __PACKAGE__->meta->setup( allow_inline_column_values => 1, foreign_keys => [ + bin => { + class => 'SL::DB::Bin', + key_columns => { bin_id => 'id' }, + }, + buchungsgruppen => { class => 'SL::DB::Buchungsgruppe', key_columns => { buchungsgruppen_id => 'id' }, @@ -79,6 +85,11 @@ __PACKAGE__->meta->setup( class => 'SL::DB::Unit', key_columns => { unit => 'name' }, }, + + warehouse => { + class => 'SL::DB::Warehouse', + key_columns => { warehouse_id => 'id' }, + }, ], ); diff --git a/SL/DO.pm b/SL/DO.pm index 8d71fbcda..a598f025d 100644 --- a/SL/DO.pm +++ b/SL/DO.pm @@ -684,7 +684,7 @@ sub retrieve { $query = qq|SELECT doi.id AS delivery_order_items_id, p.partnumber, p.assembly, p.listprice, doi.description, doi.qty, - doi.sellprice, doi.parts_id AS id, doi.unit, doi.discount, p.bin, p.notes AS partnotes, + doi.sellprice, doi.parts_id AS id, doi.unit, doi.discount, p.notes AS partnotes, doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost, doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription, doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id, diff --git a/SL/IC.pm b/SL/IC.pm index 74cfe1702..0b8924ba3 100644 --- a/SL/IC.pm +++ b/SL/IC.pm @@ -346,7 +346,8 @@ sub save { notes = ?, formel = ?, rop = ?, - bin = ?, + warehouse_id = ?, + bin_id = ?, buchungsgruppen_id = ?, payment_id = ?, inventory_accno_id = $subq_inventory, @@ -378,7 +379,8 @@ sub save { $form->{notes}, $form->{formel}, $form->{rop}, - $form->{bin}, + conv_i($form->{warehouse_id}), + conv_i($form->{bin_id}), conv_i($form->{buchungsgruppen_id}), conv_i($form->{payment_id}), conv_i($form->{buchungsgruppen_id}), @@ -567,7 +569,7 @@ sub retrieve_assemblies { # retrieve assembly items my $query = qq|SELECT p.id, p.partnumber, p.description, - p.bin, p.onhand, p.rop, + p.onhand, p.rop, (SELECT sum(p2.inventory_accno_id) FROM parts p2, assembly a WHERE (p2.id = a.parts_id) AND (a.id = p.id)) AS inventory @@ -671,7 +673,7 @@ sub assembly_item { # partnumber ean description partsgroup microfiche drawing # # column flags: -# l_partnumber l_description l_listprice l_sellprice l_lastcost l_priceupdate l_weight l_unit l_bin l_rop l_image l_drawing l_microfiche l_partsgroup +# l_partnumber l_description l_listprice l_sellprice l_lastcost l_priceupdate l_weight l_unit l_rop l_image l_drawing l_microfiche l_partsgroup # # exclusives: # itemstatus = active | onhand | short | obsolete | orphaned @@ -721,7 +723,7 @@ sub all_parts { my @apoe_filters = qw(transdate); my @like_filters = (@simple_filters, @invoice_oi_filters); my @all_columns = (@simple_filters, @makemodel_filters, @apoe_filters, @project_filters, qw(serialnumber)); - my @simple_l_switches = (@all_columns, qw(notes listprice sellprice lastcost priceupdate weight unit bin rop image)); + my @simple_l_switches = (@all_columns, qw(notes listprice sellprice lastcost priceupdate weight unit rop image)); my @oe_flags = qw(bought sold onorder ordered rfq quoted); my @qsooqr_flags = qw(invnumber ordnumber quonumber trans_id name module qty); my @deliverydate_flags = qw(deliverydate); @@ -964,7 +966,7 @@ sub all_parts { my $token_builder = $make_token_builder->(\%joins_needed); - my @sort_cols = (@simple_filters, qw(id bin priceupdate onhand invnumber ordnumber quonumber name serialnumber soldtotal deliverydate)); + my @sort_cols = (@simple_filters, qw(id priceupdate onhand invnumber ordnumber quonumber name serialnumber soldtotal deliverydate)); $form->{sort} = 'id' unless grep { $form->{"l_$_"} } grep { $form->{sort} eq $_ } @sort_cols; # sort by id if unknown or invisible column my $sort_order = ($form->{revers} ? ' DESC' : ' ASC'); my $order_clause = " ORDER BY " . $token_builder->($form->{sort}) . ($form->{revers} ? ' DESC' : ' ASC'); @@ -1022,7 +1024,7 @@ sub all_parts { if ($form->{searchitems} eq 'assembly' && $form->{bom}) { $query = qq|SELECT p.id, p.partnumber, p.description, a.qty AS onhand, - p.unit, p.bin, p.notes, + p.unit, p.notes, p.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, @@ -1496,7 +1498,7 @@ sub retrieve_accounts { $transdate = $form->{deliverydate}; } } elsif ($form->{script} eq 'ir.pl') { - # when a purchase invoice is opened from the report of purchase invoices + # when a purchase invoice is opened from the report of purchase invoices # $form->{type} isn't set, but $form->{script} is, not sure why this is or # whether this distinction matters in some other scenario. Otherwise one # could probably take out this elsif and add a diff --git a/SL/IR.pm b/SL/IR.pm index 06f84abbc..b71555cc7 100644 --- a/SL/IR.pm +++ b/SL/IR.pm @@ -975,7 +975,7 @@ sub retrieve_invoice { i.id AS invoice_id, i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.parts_id AS id, i.unit, i.deliverydate, i.project_id, i.serialnumber, i.price_factor_id, i.price_factor, i.marge_price_factor, i.discount, - p.partnumber, p.inventory_accno_id AS part_inventory_accno_id, p.bin, pr.projectnumber, pg.partsgroup + p.partnumber, p.inventory_accno_id AS part_inventory_accno_id, pr.projectnumber, pg.partsgroup FROM invoice i JOIN parts p ON (i.parts_id = p.id) @@ -1234,7 +1234,7 @@ sub retrieve_item { my $query = qq|SELECT p.id, p.partnumber, p.description, p.lastcost AS sellprice, p.listprice, - p.unit, p.assembly, p.bin, p.onhand, p.formel, + p.unit, p.assembly, p.onhand, p.formel, p.notes AS partnotes, p.notes AS longdescription, p.not_discountable, p.inventory_accno_id, p.price_factor_id, diff --git a/SL/IS.pm b/SL/IS.pm index 9ecc64818..785cda9db 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -1638,7 +1638,7 @@ sub retrieve_invoice { i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.discount, i.parts_id AS id, i.unit, i.deliverydate AS reqdate, i.project_id, i.serialnumber, i.id AS invoice_pos, i.pricegroup_id, i.ordnumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost, i.price_factor_id, i.price_factor, i.marge_price_factor, - p.partnumber, p.assembly, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, p.formel, p.listprice, + p.partnumber, p.assembly, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, p.formel, p.listprice, pr.projectnumber, pg.partsgroup, prg.pricegroup FROM invoice i @@ -1946,7 +1946,7 @@ sub retrieve_item { c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from AS expense_valid, - p.unit, p.assembly, p.bin, p.onhand, + p.unit, p.assembly, p.onhand, p.notes AS partnotes, p.notes AS longdescription, p.not_discountable, p.formel, p.payment_id AS part_payment_id, p.price_factor_id, diff --git a/SL/InstanceConfiguration.pm b/SL/InstanceConfiguration.pm index 1e9c6a10f..59d4035a4 100644 --- a/SL/InstanceConfiguration.pm +++ b/SL/InstanceConfiguration.pm @@ -144,6 +144,16 @@ sub get_purchase_delivery_order_show_delete { return $self->{data}->{purchase_delivery_order_show_delete}; } +sub get_default_warehouse_id { + my ($self) = @_; + return ($self->{data}->{warehouse_id}); +} + +sub get_default_bin_id { + my ($self) = @_; + return ($self->{data}->{bin_id}); +} + 1; __END__ @@ -256,6 +266,14 @@ corresponding record type (true or false). Returns the default behavior for showing the delete button for the corresponding record type (true or false). +=item C + +Returns the default warehouse_id + +=item C + +Returns the default bin_id + =back =head1 BUGS diff --git a/SL/OE.pm b/SL/OE.pm index 3b3845c50..7302088ae 100644 --- a/SL/OE.pm +++ b/SL/OE.pm @@ -874,7 +874,7 @@ sub retrieve { c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe, p.partnumber, p.assembly, p.listprice, o.description, o.qty, - o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, + o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost, o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription, o.price_factor_id, o.price_factor, o.marge_price_factor, diff --git a/bin/mozilla/ic.pl b/bin/mozilla/ic.pl index 222a4d1d5..5269d09fc 100644 --- a/bin/mozilla/ic.pl +++ b/bin/mozilla/ic.pl @@ -1586,7 +1586,20 @@ sub form_header { $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS', 'partsgroup' => 'all_partsgroup', - 'vendors' => 'ALL_VENDORS',); + 'vendors' => 'ALL_VENDORS', + 'warehouses' => { 'key' => 'WAREHOUSES', + 'bins' => 'BINS', }); + # leerer wert für Lager und Lagerplatz korrekt einstellt + # ID 0 sollte in Ordnung sein, da der Zähler sowieso höher ist + my $no_default_bin_entry = { 'id' => '0', description => '--', 'BINS' => [ { id => '0', description => ''} ] }; + push @ { $form->{WAREHOUSES} }, $no_default_bin_entry; + if (my $max = scalar @{ $form->{WAREHOUSES} }) { + + my $default_warehouse_id = $::instance_conf->get_default_warehouse_id; + my $default_bin_id = $::instance_conf->get_default_bin_id; + $form->{warehouse_id} ||= $default_warehouse_id || $form->{WAREHOUSES}->[$max -1]->{id}; + $form->{bin_id} ||= $default_bin_id || $form->{WAREHOUSES}->[$max -1]->{BINS}->[0]->{id}; + } IC->retrieve_buchungsgruppen(\%myconfig, $form); @@ -1847,6 +1860,11 @@ sub save { $form->error($locale->text('Description must not be empty!')) unless $form->{description}; $form->error($locale->text('Partnumber must not be set to empty!')) if $form->{id} && !$form->{partnumber}; + # 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}; + } # save part if (IC->save(\%myconfig, \%$form) == 3) { $form->error($locale->text('Partnumber not unique!')); diff --git a/locale/de/all b/locale/de/all index dbfe63586..44c068ea7 100755 --- a/locale/de/all +++ b/locale/de/all @@ -32,6 +32,12 @@ $self->{texts} = { '2. Quarter' => '2. Quartal', '3. Quarter' => '3. Quartal', '4. Quarter' => '4. Quartal', + ' I DO CARE! Please check create warehouse and bins and define a name for the warehouse (Bins will be created automatically) and then continue' => 'ICH KÜMMER MICH Bitte haken Sie Lager und Lagerplätze erzeugen an (Automatisches Zuweisen der Lagerplätze) und vergeben einen Namen für dieses Lager (Lagerplätze werden automatisch übernommen). Danach auf weiter.', + ' I DO CARE! Please click back and cancel the update and come back after there has been at least one warehouse defined with bin(s).:' => 'ICH KÜMMER MICH Brechen Sie das Update ab und legen selber mindestens ein Lager mit Lagerplätzen unter dem Menü System / Lager an.', + ' I DO NOT CARE Please click continue and the following data (see list) will be deleted:' => 'IST MIR EGAL Mit einem Klick auf Weiter (rot) werden keine Daten übernommen, bzw. migriert und die folgende Information in der untenstehenden Liste wird gelöscht.', + 'Automatically create new bins in the following new warehouse ' => 'Automatisches Zuweisen der Lagerplätze im folgenden neuem Lager:', + 'Automatically create new bins in the following warehouse if not selected in the list above' => 'Automatisches Zuweisen der Lagerplätze im folgenden Lager, falls keine andere Zuweisung oben ausgewählt ist. ', + 'Default Bins Migration !READ CAREFULLY!' => 'Standardlagerplatz Migraition !AUFMERKSAM LESEN!', 'What do you want to look for?' => 'Wonach wollen Sie suchen?', 'A Buchungsgruppe consists of a descriptive name and the account numbers for the income and expense accounts for those four tax zones as well as the inventory account number.' => 'Eine Buchungsgruppe besteht aus einem deskriptiven Namen, den Erlös- und Aufwandskonten für diese vier Steuerzonen sowie aus einem Inventarkonto.', 'A digit is required.' => 'Eine Ziffer ist vorgeschrieben.', @@ -65,6 +71,7 @@ $self->{texts} = { 'ASSETS' => 'AKTIVA', '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.' => 'ACHTUNG! Wenn Sie diese Einstellung aktivieren, dann können Sie sie später nicht ohne Weiteres deaktivieren, ohne dafür zu sorgen, dass die Felder der Mindeshaltbarkeitsdaten in der Datenbank leer gemacht werden.', 'ATTENTION! You can not simply change it from periodic to perpetual once you started posting.' => 'ACHTUNG! Es kann nicht ohne Weiteres im laufenden Betrieb von der Aufwandsmethode zur Bestandsmethode gewechselt werden.', + 'AUTOMATICALLY MATCH BINS' => 'LAGERPLÄTZE AUTOMATISCH ZUWEISEN', 'Abort' => 'Abbrechen', 'Abrechnungsnummer' => 'Abrechnungsnummer', 'Abteilung' => 'Abteilung', @@ -297,7 +304,6 @@ $self->{texts} = { 'Billing/shipping address (street)' => 'Rechnungsadresse (Straße)', 'Billing/shipping address (zipcode)' => 'Rechnungsadresse (PLZ)', 'Bin' => 'Lagerplatz', - 'Bin 2' => '', 'Bin From' => 'Quelllagerplatz', 'Bin List' => 'Lagerliste', 'Bin To' => 'Ziellagerplatz', @@ -396,6 +402,7 @@ $self->{texts} = { 'Cash' => 'Zahlungsverkehr', 'Cc' => 'Cc', 'Cc E-mail' => 'CC (E-Mail)', + 'Change default bin for this parts' => 'Standardlagerplatz für diese Waren ändern', 'Change kivitendo installation settings (all menu entries beneath \'System\')' => 'Verändern der kivitendo-Installationseinstellungen (Menüpunkte unterhalb von \'System\')', 'Change representative to' => 'Vertreter ändern in', 'Changes in this block are only sensible if the account is NOT a summary account AND there exists one valid taxkey. To select both Receivables and Payables only make sense for Payment / Receipt (i.e. account cash).' => 'Es ist nur sinnvoll Änderungen vorzunehmen, wenn das Konto KEIN Sammelkonto ist und wenn ein gültiger Steuerschlüssel für das Konto existiert. Gleichzeitig Haken bei Forderungen und Verbindlichkeiten zu setzen, macht auch NUR für den Zahlungsein- und Ausgang (bspw. Bank oder Kasse) Sinn.', @@ -606,9 +613,9 @@ $self->{texts} = { 'Decrease' => 'Verringern', 'Default (no language selected)' => 'Standard (keine Sprache ausgewählt)', 'Default Accounts' => 'Standardkonten', - 'Default Bin' => '', + 'Default Bin' => 'Standard-Lagerplatz', 'Default Customer/Vendor Language' => 'Standard-Kunden-/Lieferantensprache', - 'Default Warehouse' => '', + 'Default Warehouse' => 'Standard-Lager', 'Default buchungsgruppe' => 'Standardbuchungsgruppe', 'Default output medium' => 'Standardausgabekanal', 'Default printer' => 'Standarddrucker', @@ -1006,6 +1013,7 @@ $self->{texts} = { 'If you want to change any of these parameters then press the "Back" button, edit the file "config/kivitendo.conf" and login into the admin module again.' => 'Wenn Sie einen der Parameter ändern wollen, so drücken Sie auf den "Zurück"-Button, bearbeiten Sie die Datei "config/kivitendo.conf", und melden Sie sich erneut im Administrationsbereich an.', 'If you want to delete such a dataset you have to edit the user(s) that are using the dataset in question and have them use another dataset.' => 'Wenn Sie eine solche Datenbank löschen wollen, so müssen Sie zuerst die Benutzer bearbeiten, die die fragliche Datenbank benutzen, und sie so ändern, dass sie eine andere Datenbank benutzen.', 'If you want to set up the authentication database yourself then log in to the administration panel. kivitendo will then create the database and tables for you.' => 'Wenn Sie die Authentifizierungs-Datenbank selber einrichten wollen, so melden Sie sich im Administrationsbereich an. kivitendo wird dann die Datenbank und die erforderlichen Tabellen für Sie anlegen.', + 'If your old bins match exactly Bins in the Warehouse CLICK on AUTOMATICALLY MATCH BINS.' => 'Falls die alte Lagerplatz-Beschreibung in Stammdaten genau mit einem Lagerplatz in einem vorhandenem Lager übereinstimmt, KLICK auf LAGERPLÄTZE AUTOMATISCH ZUORDNEN', 'Illegal characters have been removed from the following fields: #1' => 'Ungültige Zeichen wurden aus den folgenden Feldern entfernt: #1', 'Image' => 'Grafik', 'Import' => 'Import', @@ -1204,6 +1212,7 @@ $self->{texts} = { 'Marked as paid' => 'Als bezahlt markiert', 'Marked entries printed!' => 'Markierte Einträge wurden gedruckt!', 'Master Data' => 'Stammdaten', + 'Master Data Bin Text Deleted' => 'Gelöschte Stammdaten Freitext-Lagerplätze', 'Max. Dunning Level' => 'höchste Mahnstufe', 'May' => 'Mai', 'May ' => 'Mai', @@ -1379,6 +1388,7 @@ $self->{texts} = { 'Others' => 'Andere', 'Otherwise all users will only have access to their own settings.' => 'Andernfalls haben alle Benutzer nur Zugriff auf ihre Einstellungen.', 'Otherwise the variable is only available for printing.' => 'Andernfalls steht die Variable nur beim Ausdruck zur Verfügung.', + 'Otherwise you can simply check create warehouse and bins and define a name for the warehouse (Bins will be created automatically) and then continue' => 'Andernfalls einfach Lager und Lagerplätze erschaffen anhaken und einen Namen für das Lager vergeben (Lagerplätze werden dann automatisch hinzugefügt) danach auf weiter', 'Out of balance transaction!' => 'Buchung ist nicht ausgeglichen!', 'Out of balance!' => 'Summen stimmen nicht berein!', 'Output Number Format' => 'Zahlenformat (Ausgabe)', @@ -1929,6 +1939,8 @@ $self->{texts} = { 'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.', 'The AP transaction #1 has been deleted.' => 'Die Kreditorenbuchung #1 wurde gelöscht.', '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 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 überprüfen Sie die Angaben in config/kivitendo.conf.', 'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt', @@ -2101,6 +2113,8 @@ $self->{texts} = { 'There are #1 more open invoices for this customer with other currencies.' => 'Es gibt #1 weitere offene Rechnungen für diesen Kunden, die in anderen Währungen ausgestellt wurden.', 'There are #1 more open invoices from this vendor with other currencies.' => 'Es gibt #1 weitere offene Rechnungen von diesem Lieferanten, die in anderen Währungen ausgestellt wurden.', 'There are #1 unfinished follow-ups of which #2 are due.' => 'Es gibt #1 Wiedervorlage(n), von denen #2 fällig ist/sind.', + 'There are Bins defined in your Inventory.' => 'Unter Stammdaten/Waren sind Lagerplätze defininert', + 'There are Bins defined in your master data.' => 'Unter Stammdaten/Waren sind Lagerplätze defininert', 'There are bookings to the account 3803 after 01.01.2007. If you didn\'t change this account manually to 19% the bookings are probably incorrect.' => 'Das Konto 3803 wurde nach dem 01.01.2007 bebucht. Falls Sie dieses Konto nicht manuell auf 19% gestellt haben sind die Buchungen wahrscheinlich mit falscher Umsatzsteuer gebucht worden.', 'There are double partnumbers in your database.' => 'In ihrer Datenbank befinden sich mehrfach vergebene Artikelnummern.', 'There are entries in tax where taxkey is NULL.' => 'In der Datenbank sind Steuern ohne Steuerschlüssel vorhanden (in der Tabelle tax Spalte taxkey).', @@ -2133,9 +2147,12 @@ $self->{texts} = { 'This customer number is already in use.' => 'Diese Kundennummer wird bereits verwendet.', 'This feature especially prevents mistakes by mixing up prior tax and sales tax.' => 'Dieses Feature vermeidet insbesondere Verwechslungen von Umsatz- und Vorsteuer.', 'This group will be called "Full Access".' => 'Diese Gruppe wird "Vollzugriff" genannt.', + 'This has been changed in this version, therefore please change the "old" bins to some real warehouse bins.' => 'Das wurde in dieser Version umgestellt, bitte ändern Sie die Freitext-Lagerplätze auf wirkliche Lagerplätze.', + 'This has been changed in this version.' => 'Ab dieser Version ist dies nicht mehr so.', 'This installation uses an unknown chart of accounts ("#1"). This database upgrade cannot create standard buchungsgruppen automatically.' => 'Diese Installation benutzt einen unbekannten Kontenrahmen ("#1"). Dieses Datenbankupgrade kann die Standardbuchungsgruppen nicht automatisch anlegen.', 'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'In diesem Schritt werden bestehende Datenbanken gesucht. Es werden noch keine Änderungen vorgenommen!', 'This is a very critical problem.' => 'Dieses Problem ist sehr schwerwiegend.', + 'This is the default bin for parts' => 'Standard-Lagerplatz für Stammdaten/Waren', 'This list is capped at 15 items to keep it fast. If you need a full list, please use reports.' => 'Diese Liste ist auf 15 Zeilen begrenzt. Wenn Sie eine vollständige Liste benötigen, erstellen Sie bitte einen Bericht.', 'This means that the user has created an AP transaction and chosen a taxkey for sales taxes, or that he has created an AR transaction and chosen a taxkey for input taxes.' => 'Das bedeutet, dass ein Benutzer eine Kreditorenbuchung angelegt und in ihr einen Umsatzsteuer-Steuerschlüssel verwendet oder eine Debitorenbuchung mit Vorsteuer-Steuerschlüssel angelegt hat.', 'This module can help you identify and correct such entries by analyzing the general ledger and presenting you likely solutions but also allowing you to fix problems yourself.' => 'Dieses Modul kann Ihnen helfen, problematische Einträge im Hauptbuch zu identifizieren und teilweise zu beheben. Dabei werden je nach Problem mögliche Lösungen aufgezeigt, wobei Sie die entscheiden können, welche Probleme automatisch gelöst werden sollen.', @@ -2149,6 +2166,7 @@ $self->{texts} = { 'This upgrade script tries to map all existing parts in the database to the newly created Buchungsgruppen.' => 'Dieses Upgradescript versucht, bei allen bestehenden Artikeln neu erstellte Buchungsgruppen zuzuordnen.', 'This upgrade script tries to map all existing units in the database to the newly created units.' => 'Dieses Update-Script versucht, alle bestehenden Einheiten automatisch in die neuen Einheiten umzuwandeln.', 'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.', + 'Three Options:' => 'Drei Optionen:', 'Time period for the analysis:' => 'Analysezeitraum:', 'Timestamp' => 'Uhrzeit', 'Title' => 'Titel', @@ -2218,6 +2236,7 @@ $self->{texts} = { 'Unbalanced Ledger' => 'Bilanzfehler', 'Unchecked custom variables will not appear in orders and invoices.' => 'Unmarkierte Variablen werden für diesen Artikel nicht in Aufträgen und Rechnungen angezeigt.', 'Unfinished follow-ups' => 'Nicht erledigte Wiedervorlagen', + 'Unfortunately you have no warehouse defined.' => 'Leider, gibt es kein Lager in diesem Mandanten.', 'Unit' => 'Einheit', 'Unit (if missing or empty default unit will be used)' => 'Einheit (falls nicht vorhanden oder leer wird die Standardeinheit benutzt)', 'Unit missing.' => 'Die Einheit fehlt.', diff --git a/sql/Pg-upgrade2/add_warehouse_defaults.sql b/sql/Pg-upgrade2/add_warehouse_defaults.sql new file mode 100644 index 000000000..0cc00c838 --- /dev/null +++ b/sql/Pg-upgrade2/add_warehouse_defaults.sql @@ -0,0 +1,9 @@ +-- @tag: add_warehouse_defaults +-- @description: Standardlager und Lagerplatz in der Tabelle defaults. Sowie als ID-Verknüpfung in parts +-- @depends: release_3_0_0 +-- @charset: utf-8 +ALTER TABLE defaults ADD COLUMN warehouse_id integer references warehouse(id); +ALTER TABLE defaults add column bin_id integer references bin(id); +ALTER TABLE parts ADD COLUMN warehouse_id integer references warehouse(id); +ALTER TABLE parts add column bin_id integer references bin(id); + diff --git a/sql/Pg-upgrade2/default_bin_parts.pl b/sql/Pg-upgrade2/default_bin_parts.pl new file mode 100644 index 000000000..89ec6195e --- /dev/null +++ b/sql/Pg-upgrade2/default_bin_parts.pl @@ -0,0 +1,120 @@ +# @tag: default_bin_parts +# @description: Freitext Feld Lagerplatz nach Lager und Lagerplatz migrieren +# @depends: release_3_0_0 add_warehouse_defaults + +package SL::DBUpgrade2::default_bin_parts; + +use strict; +use utf8; +use Data::Dumper; +use SL::DBUtils; +use parent qw(SL::DBUpgrade2::Base); + +sub run { + my ($self) = @_; + $::form->get_lists('warehouses' => { 'key' => 'WAREHOUSES', + 'bins' => 'BINS', }); + if (scalar @{ $::form->{WAREHOUSES} }) { + $::form->{warehouse_id} ||= $::form->{WAREHOUSES}->[0]->{id}; + $::form->{bin_id} ||= $::form->{WAREHOUSES}->[0]->{BINS}->[0]->{id}; + } else { + $::form->{NO_WAREHOUSE} = 1; + } + $::form->{warehouse_id} = 0; # 0 ist die ID für leere Option + + if ( $::form->{'continued'} ) { + my $CREATE_BINS = 0; + my $CREATE_WAREHOUSE = 0; + if (!defined($::form->{NO_WAREHOUSE}) && defined($::form->{create_new_bins}) && $::form->{warehouse_id_default}) { + $CREATE_BINS = 1; + } + if (defined($::form->{NO_WAREHOUSE}) && defined($::form->{create_new_bins}) && $::form->{new_warehouse}) { + $CREATE_WAREHOUSE = 1; + $CREATE_BINS = 1; + } + + # Lager anlegen + my $insert_warehouse_query = qq|INSERT into warehouse (description, invalid, sortkey) VALUES (?, 'false', 1) |; + my $prepared_insert_warehouse_query = $self->dbh->prepare($insert_warehouse_query) || $self->db_error($insert_warehouse_query); + + # Lagerplatz anlegen + my $insert_bin_query = qq|INSERT into bin (description, warehouse_id) VALUES (?, ?) |; + my $prepared_insert_bin_query = $self->dbh->prepare($insert_bin_query) || $self->db_error($insert_bin_query); + + # Lagerplatz aus Liste zuweisen + my $update_query = qq|UPDATE parts SET warehouse_id = ?, bin_id = ? WHERE id = ?|; + my $prepared_update_query = $self->dbh->prepare($update_query) || $self->db_error($update_query); + + + # gerade angelegten Lagerplatz zuweisen + my $update_new_bin_query = qq|UPDATE parts SET warehouse_id = (SELECT warehouse_id from bin where description = ?), + bin_id = (SELECT id from bin where description = ?) + WHERE id = ?|; + my $prepared_update_new_bin_query = $self->dbh->prepare($update_new_bin_query) || $self->db_error($update_new_bin_query); + + + # kein lager vorhanden, aber wir legen ein neues an. + if ($CREATE_WAREHOUSE && $CREATE_BINS) { + $prepared_insert_warehouse_query->execute($::form->{new_warehouse}) || $self->db_error($insert_warehouse_query); + $prepared_insert_warehouse_query->finish(); + my $query = qq|SELECT id FROM warehouse LIMIT 1;|; + my $sth = $self->dbh->prepare($query); + $sth->execute || $::form->dberror($query); + $::form->{warehouse_id_default} = $sth->fetchrow_array(); + } + + foreach my $i (1 .. $::form->{rowcount}) { + + # Best Case: Lagerplatz aus Liste gewählt + if ($::form->{"bin_id_$i"}) { + $prepared_update_query->execute($::form->{"warehouse_id_$i"}, $::form->{"bin_id_$i"}, $::form->{"partid_$i"}) || $self->db_error($update_query); + } elsif ($CREATE_BINS) { + # Lager vorhanden, bzw. vorher erstellt. alte bins automatisch hinzufügen und zum Standardlagerplatz verdrahten + $prepared_insert_bin_query->execute($::form->{"bin_$i"}, $::form->{warehouse_id_default}) || $self->db_error($insert_bin_query); + $prepared_update_new_bin_query->execute($::form->{"bin_$i"}, $::form->{"bin_$i"}, $::form->{"partid_$i"}) || $self->db_error($update_new_bin_query); + } + } + $prepared_insert_bin_query->finish(); + $prepared_update_new_bin_query->finish(); + $prepared_update_query->finish(); + $::form->{FINISH} = 1; + # das alte textfeld entfernen + #my $query = qq|ALTER TABLE parts drop COLUMN bin|; + #$self->db_query($query); + #return 1; + } + + my $query = qq|SELECT id, partnumber, description, bin + FROM parts pa + WHERE '' <> NULLIF ( bin, '') + ORDER BY partnumber;|; + + my $sth = $self->dbh->prepare($query); + $sth->execute || $::form->dberror($query); + + $::form->{PARTS} = [ selectall_hashref_query($::form, $self->dbh, $query) ]; + + if ( (scalar @{ $::form->{PARTS} } > 0 ) && !$::form->{NO_WAREHOUSE} && !$::form->{FINISH} ) { + &print_error_message; + return 2; + } elsif ( (scalar @{ $::form->{PARTS} } > 0 ) && $::form->{NO_WAREHOUSE} && !$::form->{FINISH} ) { + &print_error_message_no_warehouse; + return 2; + } + # das alte textfeld entfernen + # hier nochmal, da oben schon ein return 1 gesetzt ist + my $query = qq|ALTER TABLE parts drop COLUMN bin|; + $self->db_query($query); + return 1; +} + +sub print_error_message { + print $::form->parse_html_template("dbupgrade/default_bin_parts"); +} + +sub print_error_message_no_warehouse { + print $::form->parse_html_template("dbupgrade/default_bin_parts_no_warehouse"); +} + + +1; diff --git a/templates/webpages/dbupgrade/default_bin_parts.html b/templates/webpages/dbupgrade/default_bin_parts.html new file mode 100644 index 000000000..eb0c549d2 --- /dev/null +++ b/templates/webpages/dbupgrade/default_bin_parts.html @@ -0,0 +1,154 @@ +[%- USE T8 %] +[%- USE HTML %] +[%- USE LxERP %] +[%- USE JavaScript %] + + + + + + +
[% 'Default Bins Migration !READ CAREFULLY!' | $T8 %]
+
+ + + + + +

[% 'There are Bins defined in your Inventory.' | $T8 %]

+

[% 'The Bins in Inventory were only a information text field.' | $T8 %]

+

[% 'This has been changed in this version, therefore please change the "old" bins to some real warehouse bins.' | $T8 %]

+

[% 'If your old bins match exactly Bins in the Warehouse CLICK on AUTOMATICALLY MATCH BINS.' | $T8 %]

+

[% 'Otherwise you can simply check create warehouse and bins and define a name for the warehouse (Bins will be created automatically) and then continue' | $T8 %]

+ +

[% 'Please change the partnumber of the following parts and run the update again:' | $T8 %]

+ + + + + + + + + + [% SET row_odd = '1' %][% FOREACH row = PARTS %] + + + + + + + + [% SET rowcount = loop.count %] + [% END %] + + + + + + + +
[% 'Partnumber' | $T8 %][% 'Description' | $T8 %][% 'Bin' | $T8 %][% 'Default Warehouse' | $T8 %][% 'Default Bin' | $T8 %]
[% HTML.escape(row.partnumber) %] [% HTML.escape(row.description) %][% HTML.escape(row.bin) %] + + + + +

+ [% 'Automatically create new bins in the following warehouse if not selected in the list above' | $T8 %] + +

+
diff --git a/templates/webpages/dbupgrade/default_bin_parts_no_warehouse.html b/templates/webpages/dbupgrade/default_bin_parts_no_warehouse.html new file mode 100644 index 000000000..23a7b63f9 --- /dev/null +++ b/templates/webpages/dbupgrade/default_bin_parts_no_warehouse.html @@ -0,0 +1,43 @@ +[%- USE T8 %] +[%- USE HTML %] +[%- USE LxERP %] + +
[% 'Default Bins Migration !READ CAREFULLY!' | $T8 %]
+
+ + + +

[% 'There are Bins defined in your master data.' | $T8 %]

+

[% 'The Bins in master data were only a information text field.' | $T8 %]

+

[% 'This has been changed in this version.' | $T8 %]

+

[% 'Unfortunately you have no warehouse defined.' | $T8 %]

+ +

[% 'Three Options:' | $T8 %]

+

[% ' I DO NOT CARE Please click continue and the following data (see list) will be deleted:' | $T8 %]

+

[% ' I DO CARE! Please click back and cancel the update and come back after there has been at least one warehouse defined with bin(s).:' | $T8 %]

+

[% ' I DO CARE! Please check create warehouse and bins and define a name for the warehouse (Bins will be created automatically) and then continue' | $T8 %]

+ + + + + + + + + [% SET row_odd = '1' %][% FOREACH row = PARTS %] + + + + + [% SET rowcount = loop.count %] + [% END %] + + + + + +
[% 'Partnumber' | $T8 %][% 'Description' | $T8 %][% 'Master Data Bin Text Deleted' | $T8 %]
[% HTML.escape(row.partnumber) %] [% HTML.escape(row.description) %][% HTML.escape(row.bin) %] + + +

[% 'Automatically create new bins in the following new warehouse ' | $T8 %]

+
diff --git a/templates/webpages/ic/form_header.html b/templates/webpages/ic/form_header.html index d1d80c391..32527a967 100644 --- a/templates/webpages/ic/form_header.html +++ b/templates/webpages/ic/form_header.html @@ -1,9 +1,7 @@ -[%- USE T8 %] +[[%- USE T8 %] [%- USE HTML %] [%- USE LxERP %] - - - +[% PROCESS 'common/select_warehouse_bin.html' %]

[% title %] [% HTML.escape(partnumber) %] [% HTML.escape(description) %]

[% PROCESS 'common/flash.html' %] @@ -233,8 +231,18 @@ - [% 'Bin' | $T8 %] - + [% 'Default Warehouse' | $T8 %] [% HTML.escape(bin_id) %] + + + + + + [% 'Default Bin' | $T8 %] + [%- END %]