Neuen Artikeltyp Sortiment eingeführt - sql und rose
authorG. Richardson <information@kivitendo-premium.de>
Sun, 7 Aug 2016 20:30:45 +0000 (22:30 +0200)
committerG. Richardson <information@kivitendo-premium.de>
Tue, 22 Nov 2016 13:11:25 +0000 (14:11 +0100)
SL/DB/AssortmentItem.pm [new file with mode: 0644]
SL/DB/Helper/ALL.pm
SL/DB/Helper/Mappings.pm
SL/DB/Manager/AssortmentItem.pm [new file with mode: 0644]
SL/DB/MetaSetup/AssortmentItem.pm [new file with mode: 0644]
SL/DB/MetaSetup/Default.pm
SL/DB/Part.pm
doc/changelog
scripts/rose_auto_create_model.pl
sql/Pg-upgrade2/assortment.sql [new file with mode: 0644]
templates/webpages/client_config/_ranges_of_numbers.html

diff --git a/SL/DB/AssortmentItem.pm b/SL/DB/AssortmentItem.pm
new file mode 100644 (file)
index 0000000..1f53f96
--- /dev/null
@@ -0,0 +1,28 @@
+# This file has been auto-generated only because it didn't exist.
+# Feel free to modify it at will; it will not be overwritten automatically.
+
+package SL::DB::AssortmentItem;
+
+use strict;
+
+use SL::DB::MetaSetup::AssortmentItem;
+use SL::DB::Manager::AssortmentItem;
+use Rose::DB::Object::Helpers qw(clone);
+
+__PACKAGE__->meta->initialize;
+
+sub linetotal {
+  my ($self) = @_;
+
+  return 0 unless $self->qty > 0 and $self->part->sellprice > 0;
+  return $self->qty * $self->part->sellprice / ( $self->part->price_factor_id ? $self->part->price_factor->factor : 1 );
+}
+
+sub linetotal_lastcost {
+  my ($self) = @_;
+
+  return 0 unless $self->qty > 0 and $self->part->lastcost > 0;
+  return $self->qty * $self->part->lastcost / ( $self->part->price_factor_id ? $self->part->price_factor->factor : 1 );
+}
+
+1;
index da11bb4..bf6bd40 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 
 use SL::DB::AccTransaction;
 use SL::DB::Assembly;
+use SL::DB::AssortmentItem;
 use SL::DB::AuthClient;
 use SL::DB::AuthClientUser;
 use SL::DB::AuthClientGroup;
index 738a93c..7d1907d 100644 (file)
@@ -99,6 +99,7 @@ my %kivitendo_package_names = (
   ar                             => 'invoice',
   ap                             => 'purchase_invoice',
   assembly                       => 'assembly',
+  assortment_items               => 'assortment_item',
   background_jobs                => 'background_job',
   background_job_histories       => 'background_job_history',
   ap                             => 'purchase_invoice',
diff --git a/SL/DB/Manager/AssortmentItem.pm b/SL/DB/Manager/AssortmentItem.pm
new file mode 100644 (file)
index 0000000..1b0cb60
--- /dev/null
@@ -0,0 +1,14 @@
+# This file has been auto-generated only because it didn't exist.
+# Feel free to modify it at will; it will not be overwritten automatically.
+
+package SL::DB::Manager::AssortmentItem;
+
+use strict;
+
+use parent qw(SL::DB::Helper::Manager);
+
+sub object_class { 'SL::DB::AssortmentItem' }
+
+__PACKAGE__->make_manager_methods;
+
+1;
diff --git a/SL/DB/MetaSetup/AssortmentItem.pm b/SL/DB/MetaSetup/AssortmentItem.pm
new file mode 100644 (file)
index 0000000..5cedfbf
--- /dev/null
@@ -0,0 +1,43 @@
+# This file has been auto-generated. Do not modify it; it will be overwritten
+# by rose_auto_create_model.pl automatically.
+package SL::DB::AssortmentItem;
+
+use strict;
+
+use parent qw(SL::DB::Object);
+
+__PACKAGE__->meta->table('assortment_items');
+
+__PACKAGE__->meta->columns(
+  assortment_id => { type => 'integer', not_null => 1 },
+  itime         => { type => 'timestamp', default => 'now()' },
+  mtime         => { type => 'timestamp' },
+  parts_id      => { type => 'integer', not_null => 1 },
+  position      => { type => 'integer', not_null => 1 },
+  qty           => { type => 'float', not_null => 1, scale => 4 },
+  unit          => { type => 'varchar', length => 20, not_null => 1 },
+);
+
+__PACKAGE__->meta->primary_key_columns([ 'assortment_id', 'parts_id' ]);
+
+__PACKAGE__->meta->allow_inline_column_values(1);
+
+__PACKAGE__->meta->foreign_keys(
+  assortment => {
+    class       => 'SL::DB::Part',
+    key_columns => { assortment_id => 'id' },
+  },
+
+  part => {
+    class       => 'SL::DB::Part',
+    key_columns => { parts_id => 'id' },
+  },
+
+  unit_obj => {
+    class       => 'SL::DB::Unit',
+    key_columns => { unit => 'name' },
+  },
+);
+
+1;
+;
index 0ef66db..4963364 100644 (file)
@@ -24,6 +24,7 @@ __PACKAGE__->meta->columns(
   ar_show_mark_as_paid                      => { type => 'boolean', default => 'true' },
   articlenumber                             => { type => 'text' },
   assemblynumber                            => { type => 'text' },
+  assortmentnumber                          => { type => 'text' },
   balance_startdate_method                  => { type => 'text' },
   bin_id                                    => { type => 'integer' },
   bin_id_ignore_onhand                      => { type => 'integer' },
index d6ffc35..8b149ad 100644 (file)
@@ -38,6 +38,11 @@ __PACKAGE__->meta->add_relationships(
     class        => 'SL::DB::Translation',
     column_map   => { id => 'parts_id' },
   },
+  assortment_items => {
+    type         => 'one to many',
+    class        => 'SL::DB::AssortmentItem',
+    column_map   => { id => 'assortment_id' },
+  },
 );
 
 __PACKAGE__->meta->initialize;
index 90cd476..0f78189 100644 (file)
@@ -47,6 +47,25 @@ kleinere neue Features und Detailverbesserungen:
     Verkaufsauträge finden zu können:
     Verkauf -> Berichte -> Auftragsartikelsuche
 
+  - Neuer Artikeltyp "Sortiment"
+    Einem Sortiment    können wie einem Erzeugnis mehrere Artikel zugeordnet
+    werden. Beim Hinzufügen eines Sortiments zu einem Beleg werden alle
+    Bestandteile des Sortiments als Einzelteile zum Beleg hinzugefügt, so als
+    ob man das manuell gemacht hätte. Der Sortimentsartikel wird ohne Preis
+    hinzugefügt und fungiert als Überschrift, und kann sogar gelöscht werden.
+    Nach dem Hinzufügen können die Einzelbestandteile auch gelöscht oder
+    verändert werden. Dadurch hat das Sortiment auch keinen festen Preis,
+    sondern der Preis im Beleg richtet sich nach dem Preis der
+    Einzelbestandteile, die je nach Kunde z.B. durch Preisgruppenpreise
+    variieren können.
+
+    Das Sortiment eignet sich z.B. als Definition von Gruppierungen von
+    Artikeln die häufig zusammen gekauft werden, z.B. ein Artikel in 10
+    Farbvariationen.
+
+    Einschränkungen: das "Auspacken" eines Sortiments beim Hinzufügen in einem
+    Beleg funktioniert derzeit nur beim neuen Auftragscontroller.
+
 Administrative Änderungen
 
   - Diverse Textsuchen werden jetzt durch eine neue Klasse Indizes
index 2604fce..5d311c1 100755 (executable)
@@ -82,6 +82,7 @@ our %foreign_key_name_map     = (
     reconciliation_links      => { acc_trans_id => 'acc_trans' },
 
     assembly                  => { parts_id => 'part', id => 'assembly_part' },
+    assortment_items          => { parts_id => 'part' },
   },
 );
 
diff --git a/sql/Pg-upgrade2/assortment.sql b/sql/Pg-upgrade2/assortment.sql
new file mode 100644 (file)
index 0000000..5d9c685
--- /dev/null
@@ -0,0 +1,20 @@
+-- @tag: assortment_items
+-- @description: Sortimentsartikel eingeführt
+-- @depends: release_3_4_1 part_type_enum
+
+-- adding a new value isn't allowed inside a transaction, which is what DBUpgrade automatically does
+-- run this afterwards manually for now
+-- ALTER TYPE part_type_enum ADD VALUE 'assortment';
+
+CREATE TABLE assortment_items (
+  assortment_id INTEGER REFERENCES parts(id) ON DELETE CASCADE, -- the part id of the assortment
+  parts_id      INTEGER REFERENCES parts(id),
+  itime         timestamp without time zone default now(),
+  mtime         timestamp without time zone,
+  qty           REAL NOT NULL,
+  position      INTEGER NOT NULL,
+  unit          character varying(20) NOT NULL REFERENCES units(name),
+  CONSTRAINT assortment_part_pkey PRIMARY KEY (assortment_id, parts_id)
+);
+
+ALTER TABLE defaults ADD assortmentnumber TEXT;
index 51b11b9..a7cc993 100644 (file)
@@ -44,6 +44,8 @@
   <tr>
    <td align="right" nowrap>[% LxERP.t8('Last Sales Delivery Order Number') %]</td>
    <td>[% L.input_tag("defaults.sdonumber", SELF.defaults.sdonumber, size="15") %]</td>
+   <td align="right" nowrap>[% LxERP.t8('Last Assortment Number') %]</td>
+   <td>[% L.input_tag("defaults.assortmentnumber", SELF.defaults.assortmentnumber, size="15") %]</td>
   </tr>
 
   <tr>