aktualisieren wollen?',
'Article Code' => 'Artikelkürzel',
'Article Code missing!' => 'Artikelkürzel fehlt',
+ 'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => 'Als Konsequenz können die gespeicherten Mengen entweder in ein Lager überführt werden, oder für eine frische Lagerverwaltung resettet werden.',
'Assemblies' => 'Erzeugnisse',
'Assembly Number missing!' => 'Erzeugnisnummer fehlt!',
'Asset' => 'Aktiva/Mittelverwendung',
'Do you want Lx-Office to create a group for access to all functions?' => 'Wollen Sie, dass Lx-Office eine Gruppe mit Zugriff auf alle Funktionen anlegt?',
'Do you want to <b>limit</b> your search?' => 'Wollen Sie Ihre Suche <b>spezialisieren</b>?',
'Do you want to carry this shipping address over to the new purchase order so that the vendor can deliver the goods directly to your customer?' => 'Wollen Sie diese Lieferadresse in den neuen Lieferantenauftrag übernehmen, damit der Händler die Waren direkt an Ihren Kunden liefern kann?',
+ 'Do you want to store the existing onhand values into a new warehouse?' => 'Möchten Sie die vorhandenen Mengendaten in ein Lager übertragen?',
'Documents in the WebDAV repository' => 'Dokumente im WebDAV-Repository',
'Done' => 'Fertig',
'Download the backup' => 'Die Sicherungsdatei herunterladen',
'Lx-Office 2.4.0 introduces two new concepts: tax zones and Buchungsgruppen.' => 'Lx-Office 2.4.0 führt zwei neue Konzepte ein: Steuerzonen und Buchungsgruppen.',
'Lx-Office has been switched to group-based access restrictions.' => 'Lx-Office wurde auf eine gruppenbasierte Benutzerzugriffsverwaltung umgestellt.',
'Lx-Office is about to update the database <b>[% HTML.escape(dbname) %]</b>. You should create a backup of the database before proceeding because the backup might not be reversible.' => 'Lx-Office wird gleich die Datenbank <b>[% HTML.escape(dbname) %]</b> aktualisieren. Sie sollten eine Sicherungskopie der Datenbank erstellen, bevor Sie fortfahren, da die Aktualisierung unter Umständen nicht umkehrbar ist.',
+ 'Lx-Office is now able to manage warehouses instead of just tracking the amount of goods in your system.' => 'Lx-Office enthält jetzt auch echte Lagerverwaultung anstatt reiner Mengenzählung.',
'Lx-Office website' => 'Lx-Office-Webseite',
'MAILED' => 'Gesendet',
'MSG_BROWSER_DOES_NOT_SUPPORT_IFRAMES' => 'Ihr Browser kann leider keine eingebetteten Frames anzeigen. Bitte wählen Sie ein anderes Menü in der Benutzerkonfiguration im Administrationsmenü aus.',
'Please select the chart of accounts this installation is using from the list below.' => 'Bitte wählen Sie den Kontenrahmen aus, der bei dieser Installation verwendet wird.',
'Please select the database you want to backup' => 'Bitte wählen Sie die zu sichernde Datenbank gefunden',
'Please seletct the dataset you want to delete:' => 'Bitte wählen Sie die zu löschende Datenbank aus:',
+ 'Please specify a description for the warehouse designated for these goods.' => 'Bitte geben Sie den Namen des Ziellagers für die übernommenen Daten ein.',
'Plural' => 'Plural',
'Port' => 'Port',
'Portrait' => 'Hochformat',
'Show overdue sales quotations...' => 'Zeige überfällige Angebote...',
'Show your TODO list after loggin in' => 'Aufgabenliste nach dem Anmelden anzeigen',
'Signature' => 'Unterschrift',
+ 'Since bin is not enforced in the parts data, please specify a bin where goods without a specified bin will be put.' => 'Da Lagerplätze kein Pflichtfeld sind, geben Sie bitte einen Lagerplatz an, in dem Waren ohne spezifizierten Lagerplatz eingelagert werden sollen.',
'Skip' => 'Überspringen',
'Skonto' => 'Skonto',
'Skonto Terms' => 'Zahlungsziel Skonto',
'This group will be called "Full Access".' => 'Diese Gruppe wird "Vollzugriff" genannt.',
'This installation uses an unknown chart of accounts ("[% HTML.escape(coa) %]"). This database upgrade cannot create standard buchungsgruppen automatically.' => 'Diese Installation benutzt einen unbekannten Kontenrahmen ("[% HTML.escape(coa) %]"). 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 update will change the nature the onhand of goods is tracked.' => 'Dieses update ändert die Art und Weise wie Lagermengen gezält werden.',
'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.',
'WHJournal' => 'Lagerbuchungen',
'Warehouse' => 'Lager',
'Warehouse From' => 'Quelllager',
+ 'Warehouse MIgration' => 'Lagermigration',
'Warehouse To' => 'Ziellager',
'Warehouse content' => 'Lagerbestand',
'Warehouse deleted.' => 'Lager gelöscht.',
--- /dev/null
+# @tag: warehouse
+# @description: Diverse neue Tabellen und Spalten zur Mehrlagerfähigkeit inkl. Migration
+# @depends: release_2_4_3
+
+
+die("This script cannot be run from the command line.") unless ($main::form);
+$do_sql_migration = 0;
+
+sub print_question {
+ print $main::form->parse_html_template("dbupgrade/warehouse_form");
+}
+
+sub do_update {
+ if (!$main::form->{do_migrate}
+ && (selectfirst_array_query($main::form, $dbh, $check_sql))[0]) { # check if update is needed
+ print_question();
+ return 2;
+ } else {
+ if ($main::form->{do_migrate} eq 'Y') {
+ # if yes, both warehouse and bin must be given
+ if (!$main::form->{import_warehouse} || !$main::form->{bin_default}) {
+ print_question();
+ return 2;
+ }
+ # flag for extra code
+ $do_sql_migration = 1;
+ }
+ }
+ my $warehouse = $main::form->{import_warehouse} ne '' ? $main::form->{import_warehouse} : "Transfer";
+ my $bin = $main::form->{bin_default} ne '' ? $main::form->{bin_default} : "1";
+
+
+ my $migration_code = <<EOF
+
+-- Warehouse anpassen
+INSERT INTO warehouse (description) VALUES ('$warehouse');
+
+UPDATE tmp_parts SET bin = NULL WHERE bin = '';
+
+-- Warenbestand wiederherstellen
+INSERT INTO bin
+ (warehouse_id, description)
+ (SELECT DISTINCT warehouse.id, COALESCE(bin, '$bin')
+ FROM warehouse, tmp_parts
+ WHERE warehouse.description='$warehouse');
+INSERT INTO inventory
+ (warehouse_id, parts_id, bin_id, qty, employee_id, trans_id, trans_type_id)
+ (SELECT warehouse.id, tmp_parts.id, bin.id, onhand, (SELECT id FROM employee LIMIT 1), nextval('id'), transfer_type.id
+ FROM transfer_type, warehouse, tmp_parts, bin
+ WHERE warehouse.description = '$warehouse'
+ AND COALESCE(bin, '$bin') = bin.description
+ AND transfer_type.description = 'stock');
+EOF
+;
+
+ # do standard code
+ my $query = $sqlcode;
+ $query .= $migration_code if $do_sql_migration;
+
+ do_query($main::form, $dbh, $query);
+
+ return 1;
+}
+
+
+
+$sqlcode = <<EOF
+-- Tabelle "bin" für Lagerplätze.
+CREATE TABLE bin (
+ id integer NOT NULL DEFAULT nextval('id'),
+ warehouse_id integer NOT NULL,
+ description text,
+ itime timestamp DEFAULT now(),
+ mtime timestamp,
+
+ PRIMARY KEY (id),
+ FOREIGN KEY (warehouse_id) REFERENCES warehouse (id)
+);
+
+CREATE TRIGGER mtime_bin BEFORE UPDATE ON bin
+ FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+-- Tabelle "warehouse"
+ALTER TABLE warehouse ADD COLUMN sortkey integer;
+CREATE SEQUENCE tmp_counter;
+UPDATE warehouse SET sortkey = nextval('tmp_counter');
+DROP SEQUENCE tmp_counter;
+
+ALTER TABLE warehouse ADD COLUMN invalid boolean;
+UPDATE warehouse SET invalid = 'f';
+
+CREATE TRIGGER mtime_warehouse BEFORE UPDATE ON warehouse
+ FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+-- Tabelle "transfer_type"
+CREATE TABLE transfer_type (
+ id integer NOT NULL DEFAULT nextval('id'),
+ direction varchar(10) NOT NULL,
+ description text,
+ sortkey integer,
+ itime timestamp DEFAULT now(),
+ mtime timestamp,
+
+ PRIMARY KEY (id)
+);
+
+CREATE TRIGGER mtime_transfer_type BEFORE UPDATE ON transfer_type
+ FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'stock', 1);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'found', 2);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'correction', 3);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'used', 4);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'disposed', 5);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'back', 6);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'missing', 7);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'correction', 9);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'transfer', 10);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'correction', 11);
+
+-- Anpassungen an "inventory".
+DELETE FROM inventory;
+
+ALTER TABLE inventory ADD COLUMN bin_id integer;
+ALTER TABLE inventory ADD FOREIGN KEY (bin_id) REFERENCES bin (id);
+ALTER TABLE inventory ALTER COLUMN bin_id SET NOT NULL;
+
+ALTER TABLE inventory DROP COLUMN qty;
+ALTER TABLE inventory ADD COLUMN qty numeric(25, 5);
+
+ALTER TABLE inventory ALTER COLUMN parts_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (parts_id) REFERENCES parts(id);
+
+ALTER TABLE inventory ALTER COLUMN warehouse_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (warehouse_id) REFERENCES warehouse(id);
+
+ALTER TABLE inventory ALTER COLUMN employee_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (employee_id) REFERENCES employee (id);
+
+ALTER TABLE inventory ADD COLUMN trans_id integer;
+ALTER TABLE inventory ALTER COLUMN trans_id SET NOT NULL;
+
+ALTER TABLE inventory ADD COLUMN trans_type_id integer;
+ALTER TABLE inventory ALTER COLUMN trans_type_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (trans_type_id) REFERENCES transfer_type (id);
+
+ALTER TABLE inventory ADD COLUMN project_id integer;
+ALTER TABLE inventory ADD FOREIGN KEY (project_id) REFERENCES project (id);
+
+ALTER TABLE inventory ADD COLUMN chargenumber text;
+ALTER TABLE inventory ADD COLUMN comment text;
+
+-- "onhand" in "parts" über einen Trigger automatisch berechnen lassen.
+-- Vorher Warenbestand sichern JZ
+SELECT id, onhand, bin INTO TEMP TABLE tmp_parts FROM parts WHERE onhand > 0;
+ALTER TABLE parts DROP COLUMN onhand;
+ALTER TABLE parts ADD COLUMN onhand numeric(25,5);
+UPDATE parts SET onhand = COALESCE((SELECT SUM(qty) FROM inventory WHERE inventory.parts_id = parts.id), 0);
+
+ALTER TABLE parts ADD COLUMN stockable boolean;
+ALTER TABLE parts ALTER COLUMN stockable SET DEFAULT 'f';
+UPDATE parts SET stockable = 'f';
+
+CREATE OR REPLACE FUNCTION update_onhand() RETURNS trigger AS '
+BEGIN
+ IF tg_op = ''INSERT'' THEN
+ UPDATE parts SET onhand = COALESCE(onhand, 0) + new.qty WHERE id = new.parts_id;
+ RETURN new;
+ ELSIF tg_op = ''DELETE'' THEN
+ UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty WHERE id = old.parts_id;
+ RETURN old;
+ ELSE
+ UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty + new.qty WHERE id = old.parts_id;
+ RETURN new;
+ END IF;
+END;
+' LANGUAGE plpgsql;
+
+CREATE TRIGGER trig_update_onhand
+ AFTER INSERT OR UPDATE OR DELETE ON inventory
+ FOR EACH ROW EXECUTE PROCEDURE update_onhand();
+EOF
+;
+
+
+$check_sql = <<EOF
+SELECT COUNT(id) FROM parts WHERE onhand > 0;
+EOF
+;
+
+return do_update();
+++ /dev/null
--- @tag: warehouse
--- @description: Diverse neue Tabellen und Spalten zur Mehrlagerfähigkeit
--- @depends: release_2_4_3
-
--- Tabelle "bin" für Lagerplätze.
-CREATE TABLE bin (
- id integer NOT NULL DEFAULT nextval('id'),
- warehouse_id integer NOT NULL,
- description text,
- itime timestamp DEFAULT now(),
- mtime timestamp,
-
- PRIMARY KEY (id),
- FOREIGN KEY (warehouse_id) REFERENCES warehouse (id)
-);
-
-CREATE TRIGGER mtime_bin BEFORE UPDATE ON bin
- FOR EACH ROW EXECUTE PROCEDURE set_mtime();
-
--- Tabelle "warehouse"
-ALTER TABLE warehouse ADD COLUMN sortkey integer;
-CREATE SEQUENCE tmp_counter;
-UPDATE warehouse SET sortkey = nextval('tmp_counter');
-DROP SEQUENCE tmp_counter;
-
-ALTER TABLE warehouse ADD COLUMN invalid boolean;
-UPDATE warehouse SET invalid = 'f';
-
-CREATE TRIGGER mtime_warehouse BEFORE UPDATE ON warehouse
- FOR EACH ROW EXECUTE PROCEDURE set_mtime();
-
--- Tabelle "transfer_type"
-CREATE TABLE transfer_type (
- id integer NOT NULL DEFAULT nextval('id'),
- direction varchar(10) NOT NULL,
- description text,
- sortkey integer,
- itime timestamp DEFAULT now(),
- mtime timestamp,
-
- PRIMARY KEY (id)
-);
-
-CREATE TRIGGER mtime_transfer_type BEFORE UPDATE ON transfer_type
- FOR EACH ROW EXECUTE PROCEDURE set_mtime();
-
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'stock', 1);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'found', 2);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'correction', 3);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'used', 4);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'disposed', 5);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'back', 6);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'missing', 7);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'correction', 9);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'transfer', 10);
-INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'correction', 11);
-
--- Anpassungen an "inventory".
-DELETE FROM inventory;
-
-ALTER TABLE inventory ADD COLUMN bin_id integer;
-ALTER TABLE inventory ADD FOREIGN KEY (bin_id) REFERENCES bin (id);
-ALTER TABLE inventory ALTER COLUMN bin_id SET NOT NULL;
-
-ALTER TABLE inventory DROP COLUMN qty;
-ALTER TABLE inventory ADD COLUMN qty numeric(25, 5);
-
-ALTER TABLE inventory ALTER COLUMN parts_id SET NOT NULL;
-ALTER TABLE inventory ADD FOREIGN KEY (parts_id) REFERENCES parts(id);
-
-ALTER TABLE inventory ALTER COLUMN warehouse_id SET NOT NULL;
-ALTER TABLE inventory ADD FOREIGN KEY (warehouse_id) REFERENCES warehouse(id);
-
-ALTER TABLE inventory ALTER COLUMN employee_id SET NOT NULL;
-ALTER TABLE inventory ADD FOREIGN KEY (employee_id) REFERENCES employee (id);
-
-ALTER TABLE inventory ADD COLUMN trans_id integer;
-ALTER TABLE inventory ALTER COLUMN trans_id SET NOT NULL;
-
-ALTER TABLE inventory ADD COLUMN trans_type_id integer;
-ALTER TABLE inventory ALTER COLUMN trans_type_id SET NOT NULL;
-ALTER TABLE inventory ADD FOREIGN KEY (trans_type_id) REFERENCES transfer_type (id);
-
-ALTER TABLE inventory ADD COLUMN project_id integer;
-ALTER TABLE inventory ADD FOREIGN KEY (project_id) REFERENCES project (id);
-
-ALTER TABLE inventory ADD COLUMN chargenumber text;
-ALTER TABLE inventory ADD COLUMN comment text;
-
--- "onhand" in "parts" über einen Trigger automatisch berechnen lassen.
-ALTER TABLE parts DROP COLUMN onhand;
-ALTER TABLE parts ADD COLUMN onhand numeric(25,5);
-UPDATE parts SET onhand = COALESCE((SELECT SUM(qty) FROM inventory WHERE inventory.parts_id = parts.id), 0);
-
-ALTER TABLE parts ADD COLUMN stockable boolean;
-ALTER TABLE parts ALTER COLUMN stockable SET DEFAULT 'f';
-UPDATE parts SET stockable = 'f';
-
-CREATE OR REPLACE FUNCTION update_onhand() RETURNS trigger AS '
-BEGIN
- IF tg_op = ''INSERT'' THEN
- UPDATE parts SET onhand = COALESCE(onhand, 0) + new.qty WHERE id = new.parts_id;
- RETURN new;
- ELSIF tg_op = ''DELETE'' THEN
- UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty WHERE id = old.parts_id;
- RETURN old;
- ELSE
- UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty + new.qty WHERE id = old.parts_id;
- RETURN new;
- END IF;
-END;
-' LANGUAGE plpgsql;
-
-CREATE TRIGGER trig_update_onhand
- AFTER INSERT OR UPDATE OR DELETE ON inventory
- FOR EACH ROW EXECUTE PROCEDURE update_onhand();
-
--- /dev/null
+[% USE HTML %]<div class="listtop">Lagermigration</div>
+
+<form action="[% script %]" method="POST">
+
+<p>Lx-Office enthält jetzt auch echte Lagerverwaultung anstatt reiner Mengenzählung.
+Dieses update ändert die Art und Weise wie Lagermengen gezält werden.
+Als Konsequenz können die gespeicherten Mengen entweder in ein Lager überführt werden, oder für eine frische Lagerverwaltung resettet werden.</p>
+
+<p>Möchten Sie die vorhandenen Mengendaten in ein Lager übertragen?</p>
+<input id=do_migrate_Y name=do_migrate type=radio value=Y> <label for=do_migrate_Y>Ja</label>
+<input id=do_migrate_N name=do_migrate type=radio value=N checked> <label for=do_migrate_N>Nein</label>
+
+<p>Bitte geben Sie den Namen des Ziellagers für die übernommenen Daten ein.</p>
+<input name=import_warehouse size=50>
+
+<p>Da Lagerplätze kein Pflichtfeld sind, geben Sie bitte einen Lagerplatz an, in dem Waren ohne spezifizierten Lagerplatz eingelagert werden sollen.<p>
+<input name=bin_default size=50>
+
+<p><input type=submit value="Weiter"></p>
--- /dev/null
+[% USE HTML %]<div class="listtop"><translate>Warehouse MIgration</translate></div>
+
+<form action="[% script %]" method="POST">
+
+<p><translate>Lx-Office is now able to manage warehouses instead of just tracking the amount of goods in your system.</translate>
+<translate>This update will change the nature the onhand of goods is tracked.</translate>
+<translate>As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking</translate></p>
+
+<p><translate>Do you want to store the existing onhand values into a new warehouse?</translate></p>
+<input id=do_migrate_Y name=do_migrate type=radio value=Y> <label for=do_migrate_Y><translate>Yes</translate></label>
+<input id=do_migrate_N name=do_migrate type=radio value=N checked> <label for=do_migrate_N><translate>No</translate></label>
+
+<p><translate>Please specify a description for the warehouse designated for these goods.</translate></p>
+<input name=import_warehouse size=50>
+
+<p><translate>Since bin is not enforced in the parts data, please specify a bin where goods without a specified bin will be put.</translate><p>
+<input name=bin_default size=50>
+
+<p><input type=submit value="<translate>Continue</translate>"></p>