]> wagnertech.de Git - kivitendo-erp.git/commitdiff
PriceRule: Preisregeln können jetzt auch Rabatte
authorSven Schöling <s.schoeling@linet-services.de>
Thu, 16 Oct 2014 12:40:11 +0000 (14:40 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Thu, 18 Dec 2014 15:18:52 +0000 (16:18 +0100)
ausserdem Doku

12 files changed:
SL/Controller/PriceRule.pm
SL/DB/Manager/PriceRule.pm
SL/DB/MetaSetup/PriceRule.pm
SL/DB/PriceRule.pm
SL/PriceSource/PriceRules.pm
js/kivi.PriceRule.js
js/locale/de.js
locale/de/all
sql/Pg-upgrade2/price_rules_discount.sql [new file with mode: 0644]
templates/webpages/price_rule/_filter.html
templates/webpages/price_rule/form.html
templates/webpages/price_rule/price_type_help.html [new file with mode: 0644]

index c77a2da48e007a2f80ae863727318edf8bc67d3f..23dacc03cf821bc92c071c78646c80b9ce6b404b 100644 (file)
@@ -90,6 +90,10 @@ sub action_add_item_row {
     ->render($self);
 }
 
+sub action_price_type_help {
+  $_[0]->render('price_rule/price_type_help', { layout => 0 });
+}
+
 #
 # filters
 #
@@ -145,13 +149,14 @@ sub prepare_report {
   my $report      = SL::ReportGenerator->new(\%::myconfig, $::form);
   $self->{report} = $report;
 
-  my @columns     = qw(name type priority price discount items);
-  my @sortable    = qw(name type priority price discount      );
+  my @columns     = qw(name type priority price reduction discount items);
+  my @sortable    = qw(name type priority price reduction discount      );
 
   my %column_defs = (
     name          => { obj_link => sub { $self->url_for(action => 'edit', 'price_rule.id' => $_[0]->id, callback => $callback) } },
     priority      => { sub  => sub { $_[0]->priority_as_text } },
     price         => { sub  => sub { $_[0]->price_as_number } },
+    reduction     => { sub  => sub { $_[0]->reduction_as_number } },
     discount      => { sub  => sub { $_[0]->discount_as_number } },
     obsolete      => { sub  => sub { $_[0]->obsolete_as_bool_yn } },
     items         => { sub  => sub { $_[0]->item_summary } },
@@ -258,6 +263,10 @@ sub init_partsgroups {
   SL::DB::Manager::PartsGroup->get_all;
 }
 
+sub all_price_types {
+  SL::DB::Manager::PriceRule->all_price_types;
+}
+
 sub init_models {
   my ($self) = @_;
 
@@ -269,6 +278,7 @@ sub init_models {
       priority => t8('Priority'),
       price    => t8('Price'),
       discount => t8('Discount'),
+      reduction => t8('Reduced Master Data'),
       obsolete => t8('Obsolete'),
       items    => t8('Rule Details'),
     },
index 99065dbb5ee60f56048fe8c7fba92d099c1f1e7f..d5b5489d67e181d85a7cd3f7d2bb23eb2c541be3 100644 (file)
@@ -7,6 +7,10 @@ use strict;
 
 use parent qw(SL::DB::Helper::Manager);
 
+use constant PRICE_NEW                 => 0;
+use constant PRICE_REDUCED_MASTER_DATA => 1;
+use constant PRICE_DISCOUNT            => 2;
+
 use SL::DB::Helper::Filtered;
 use SL::DB::Helper::Paginated;
 use SL::DB::Helper::Sorted;
@@ -76,6 +80,12 @@ sub get_all_matching {
   $self->get_all(query => [ id => \@ids ]);
 }
 
+sub all_price_types {
+  [ PRICE_NEW,                 t8('Price')               ],
+  [ PRICE_REDUCED_MASTER_DATA, t8('Reduced Master Data') ],
+  [ PRICE_DISCOUNT,            t8('Discount')            ],
+}
+
 sub _sort_spec {
   return ( columns => { SIMPLE => 'ALL', },
            default => [ 'name', 1 ],
index 00469ad12fd17eadf96d2e8b724c787e929be1c8..a3e70288a7afb9d1faac8d294f8a302b717be5e7 100644 (file)
@@ -9,15 +9,16 @@ use base qw(SL::DB::Object);
 __PACKAGE__->meta->table('price_rules');
 
 __PACKAGE__->meta->columns(
-  discount => { type => 'numeric', precision => 15, scale => 5 },
-  id       => { type => 'serial', not_null => 1 },
-  itime    => { type => 'timestamp' },
-  mtime    => { type => 'timestamp' },
-  name     => { type => 'text' },
-  obsolete => { type => 'boolean', default => 'false', not_null => 1 },
-  price    => { type => 'numeric', precision => 15, scale => 5 },
-  priority => { type => 'integer', default => 3, not_null => 1 },
-  type     => { type => 'text' },
+  discount  => { type => 'numeric', precision => 15, scale => 5 },
+  id        => { type => 'serial', not_null => 1 },
+  itime     => { type => 'timestamp' },
+  mtime     => { type => 'timestamp' },
+  name      => { type => 'text' },
+  obsolete  => { type => 'boolean', default => 'false', not_null => 1 },
+  price     => { type => 'numeric', precision => 15, scale => 5 },
+  priority  => { type => 'integer', default => 3, not_null => 1 },
+  reduction => { type => 'numeric', precision => 15, scale => 5 },
+  type      => { type => 'text' },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 0a9f09d850123840602c1790d7893ad59b424875..3deac758f2caaf910e85ecf61e133d6fac873f44 100644 (file)
@@ -44,15 +44,19 @@ sub is_sales {
   : $_[0]->type eq 'vendor'   ? 0 : do { die 'wrong type' };
 }
 
-sub price_or_discount {
+sub price_type {
   my ($self, $value) = @_;
 
   if (@_ > 1) {
     my $number = $self->price || $self->discount;
-    if ($value) {
+    if ($value == SL::DB::Manager::PriceRule::PRICE_NEW()) {
+      $self->price($number);
+    } elsif ($value == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()) {
+      $self->reduction($number);
+    } elsif ($value == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
       $self->discount($number);
     } else {
-      $self->price($number);
+      die 'unknown price_or_discount value';
     }
     $self->price_or_discount_state($value);
   }
@@ -61,14 +65,29 @@ sub price_or_discount {
 
 sub price_or_discount_as_number {
   my ($self, @slurp) = @_;
+  my $type = $self->price_type;
+
+  $self->price(undef)     unless $type == SL::DB::Manager::PriceRule::PRICE_NEW();
+  $self->reduction(undef) unless $type == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA();
+  $self->discount(undef)  unless $type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT();
 
-  $self->price_or_discount ? $self->price(undef)               : $self->discount(undef);
-  $self->price_or_discount ? $self->discount_as_number(@slurp) : $self->price_as_number(@slurp);
+
+  if ($type == SL::DB::Manager::PriceRule::PRICE_NEW()) {
+    return $self->price_as_number(@slurp)
+  } elsif ($type == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()) {
+    return $self->reduction_as_number(@slurp);
+  } elsif ($type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
+    return $self->discount_as_number(@slurp)
+  } else {
+    die 'unknown price_or_discount';
+  }
 }
 
 sub init_price_or_discount_state {
-    defined $_[0]->price ? 0
-  : defined $_[0]->discount ? 1 : 0
+    defined $_[0]->price     ? SL::DB::Manager::PriceRule::PRICE_NEW()
+  : defined $_[0]->reduction ? SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()
+  : defined $_[0]->discount  ? SL::DB::Manager::PriceRule::PRICE_DISCOUNT()
+  :                            SL::DB::Manager::PriceRule::PRICE_NEW();
 }
 
 sub validate {
@@ -76,7 +95,7 @@ sub validate {
 
   my @errors;
   push @errors, $::locale->text('The name must not be empty.')              if !$self->name;
-  push @errors, $::locale->text('Price or discount must not be zero.')      if !$self->price && !$self->discount;
+  push @errors, $::locale->text('Price or discount must not be zero.')      if !$self->price && !$self->discount && !$self->reduction;
   push @errors, $::locale->text('Pirce rules must have at least one rule.') if !@{[ $self->items ]};
 
   return @errors;
index 697369d0f73aae2bfb792aa4fee566e4fe4684a8..c9cecf9314e24d5f1723b73aa0484089166e9144 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use parent qw(SL::PriceSource::Base);
 
 use SL::PriceSource::Price;
+use SL::PriceSource::Discount;
 use SL::Locale::String;
 use SL::DB::PriceRule;
 use List::UtilsBy qw(min_by max_by);
@@ -15,45 +16,72 @@ sub description { t8('Price Rule') }
 sub available_rules {
   my ($self, %params) = @_;
 
-  SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
+  $self->{available} ||= SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
+}
+
+sub available_price_rules {
+  my $rules = $_[0]->available_rules;
+  grep { $_->price_type != SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
+}
+
+sub available_discount_rules {
+  my $rules = $_[0]->available_rules;
+  grep { $_->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
 }
 
 sub available_prices {
   my ($self, %params) = @_;
 
-  my $rules = $self->available_rules;
-
-  map { $self->make_price_from_rule($_) } @$rules;
+  map { $self->make_price_from_rule($_) } $self->available_price_rules;
 }
 
-sub available_discounts { }
+sub available_discounts {
+  my ($self, %params) = @_;
+
+  map { $self->make_discount_from_rule($_) } $self->available_discount_rules;
+}
 
 sub price_from_source {
   my ($self, $source, $spec) = @_;
 
   my $rule = SL::DB::Manager::PriceRule->find_by(id => $spec);
-  $self->make_price_from_rule($rule);
+  if ($rule->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
+    return $self->make_discount_from_rule($rule);
+  } else {
+    return $self->make_price_from_rule($rule);
+  }
 }
 
 sub best_price {
   my ($self) = @_;
 
-  my $rules     = $self->available_rules;
+  my @rules     = $self->available_price_rules;
 
-  return unless @$rules;
+  return unless @rules;
 
-  my @max_prio  = max_by { $_->priority } @$rules;
+  my @max_prio  = max_by { $_->priority } @rules;
   my $min_price = min_by { $self->price_for_rule($_) } @max_prio;
 
   $self->make_price_from_rule($min_price);
 }
 
-sub best_discount { }
+sub best_discount {
+  my ($self) = @_;
+
+  my @rules     = $self->available_discount_rules;
+
+  return unless @rules;
+
+  my @max_prio     = max_by { $_->priority } @rules;
+  my $max_discount = max_by { $_->discount } @max_prio;
+
+  $self->make_discount_from_rule($max_discount);
+}
 
 sub price_for_rule {
   my ($self, $rule) = @_;
-  $rule->price_or_discount
-    ? (1 - $rule->discount / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
+  $rule->price_type != SL::DB::Manager::PriceRule::PRICE_NEW()
+    ? (1 - $rule->reduction / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
     : $rule->price;
 }
 
@@ -68,4 +96,15 @@ sub make_price_from_rule {
   )
 }
 
+sub make_discount_from_rule {
+  my ($self, $rule) = @_;
+
+  SL::PriceSource::Discount->new(
+    discount     => $rule->discount / 100,
+    spec         => $rule->id,
+    description  => $rule->name,
+    price_source => $self,
+  )
+}
+
 1;
index 736f3f21a81916fa4ab3bd5cd32b2da9be84d9e2..5c56b87b061a1a3b4bf9f89ed2c5049e774e8fcd 100644 (file)
@@ -8,6 +8,13 @@ namespace('kivi.PriceRule', function(ns) {
     $.post('controller.pl', data, kivi.eval_json_result);
   }
 
+  ns.open_price_type_help_popup = function() {
+    kivi.popup_dialog({
+      url:    'controller.pl?action=PriceRule/price_type_help',
+      dialog: { title: kivi.t8('Price Types') },
+    });
+  }
+
   $(function() {
     $('#price_rule_item_add').click(function() {
       ns.add_new_row($('#price_rules_empty_item_select').val());
@@ -15,5 +22,6 @@ namespace('kivi.PriceRule', function(ns) {
     $('#price_rule_items').on('click', 'a.price_rule_remove_line', function(){
       $(this).closest('div').remove();
     })
+    $('#price_rule_price_type_help').click(ns.open_price_type_help_popup);
   });
 });
index 34be75d99a307037c811e4bf1d9ed09757938ea5..a525b21fa95afe437627de32fcad84e32d3c334c 100644 (file)
@@ -45,6 +45,7 @@ namespace("kivi").setupLocale({
 "Part picker":"Artikelauswahl",
 "Paste":"Einfügen",
 "Paste template":"Vorlage einfügen",
+"Price Types":"Preistypen",
 "Project link actions":"Projektverknüpfungs-Aktionen",
 "Quotations/Orders actions":"Aktionen für Angebote/Aufträge",
 "Re-numbering all sections and function blocks in the order they are currently shown cannot be undone.":"Das Neu-Nummerieren aller Abschnitte und Funktionsblöcke kann nicht rückgängig gemacht werden.",
index 6da14086dfb926cbc1f85209cc88f876ab78af8d..d96cfe7cbe754e2d5839c2ceb99e314463cc4bcf 100755 (executable)
@@ -551,6 +551,7 @@ $self->{texts} = {
   'Content'                     => 'Inhalt',
   'Continue'                    => 'Weiter',
   'Contra'                      => 'gegen',
+  'Contrary to Reduced Master Data this will be shown as discount in records.' => 'Im Gegensatz zu Abschlag wird der Rabatt in Belegen ausgewiesen',
   'Conversion of "birthday" contact person attribute' => 'Umstellung des Kontaktpersonenfeldes "Geburtstag"',
   'Conversion to PDF failed: #1' => 'Konvertierung zu PDF schlug fehl: #1',
   'Copies'                      => 'Kopien',
@@ -1070,6 +1071,7 @@ $self->{texts} = {
   'EuR'                         => 'EuR',
   'Everyone can log in.'        => 'Alle können sich anmelden.',
   'Exact'                       => 'Genau',
+  'Example'                     => 'Beispiel',
   'Example: http://kivitendo.de' => 'Beispiel:  http://kivitendo.de',
   'Excel'                       => 'Excel',
   'Exch'                        => 'Wechselkurs.',
@@ -1349,6 +1351,7 @@ $self->{texts} = {
   'It is not allowed that a summary account occurs in a drop-down menu!' => 'Ein Sammelkonto darf nicht in Aufklappmenüs aufgenommen werden!',
   'It is possible that even after such a correction there is something wrong with this transaction (e.g. taxes that don\'t match the selected taxkey). Therefore you should re-run the general ledger analysis.' => 'Auch nach einer Korrektur kann es mit dieser Buchung noch weitere Probleme geben (z.B. nicht zum Steuerschlüssel passende Steuern), weshalb ein erneutes Ausführen der Hauptbuchanalyse empfohlen wird.',
   '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.' => 'Es ist möglich, bei jeder Buchung einen schnellen DATEV-Export durchzuführen, um sicherzustellen, dass die Datensätze den DATEV-Anforderungen genügen. Da dies einen kleinen Overhead bedeutet, lässt sich die Einstellung für jeden Buchungstyp getrennt einstellen.',
+  'It will not be further modified by any other source, and will be offered in records like this.' => 'Er wird nicht weiter verändert werden und genau so im Beleg vorgeschlagen werden.',
   'It will simply set the taxkey to 0 (meaning "no taxes") which is the correct value for such inventory transactions.' => 'Es wird einfach die Steuerschlüssel auf  0 setzen, was "keine Steuer" bedeutet und für solche Warenbestandsbuchungen der richtige Wert ist.',
   'Item deleted!'               => 'Artikel gelöscht!',
   'Item mode'                   => 'Artikelmodus',
@@ -1484,6 +1487,7 @@ $self->{texts} = {
   'Marked entries printed!'     => 'Markierte Einträge wurden gedruckt!',
   'Master Data'                 => 'Stammdaten',
   'Master Data Bin Text Deleted' => 'Gelöschte Stammdaten Freitext-Lagerplätze',
+  'Matching Price Rules can apply in one of three types:' => 'Preisregeln können Preise in drei Varianten vorschlagen:',
   'Max. Dunning Level'          => 'höchste Mahnstufe',
   'Maximal amount difference'   => 'maximale Betragsabweichung',
   'Maximum future booking interval' => 'Maximale Anzahl von Tagen an denen Buchungen in der Zukunft erlaubt sind.',
@@ -1529,6 +1533,7 @@ $self->{texts} = {
   'Name and Street'             => 'Name und Straße',
   'Name does not make sense without any bsooqr options' => 'Option "Name in gewählten Belegen" wird ignoriert.',
   'Name in Selected Records'    => 'Name in gewählten Belegen',
+  'Negative reductions are possible to model price increases.' => 'Negative Abschläge sind möglich um Aufschläge zu modellieren.',
   'Neither sections nor function blocks have been created yet.' => 'Es wurden bisher weder Abschnitte noch Funktionsblöcke angelegt.',
   'Net Income Statement'        => 'Einnahmenüberschußrechnung',
   'Net amount'                  => 'Nettobetrag',
@@ -1865,6 +1870,7 @@ $self->{texts} = {
   'Price Rules'                 => 'Preisregeln',
   'Price Source'                => 'Preisquelle',
   'Price Sources to be disabled in this client' => 'Preisquellen die in diesem Mandanten deaktiviert werden sollen',
+  'Price Types'                 => 'Preistypen',
   'Price factor (database ID)'  => 'Preisfaktor (Datenbank-ID)',
   'Price factor (name)'         => 'Preisfaktor (Name)',
   'Price factor deleted!'       => 'Preisfaktor gel&ouml;scht.',
@@ -1874,6 +1880,7 @@ $self->{texts} = {
   'Price information'           => 'Preisinformation',
   'Price or discount must not be zero.' => 'Preis/Rabatt darf nicht 0,00 sein',
   'Price sources deactivated in this client' => 'Preisquellen die in diesem Mandanten deaktiviert sind',
+  'Price type explanation'      => 'Preistyp Erklärung',
   'Pricegroup'                  => 'Preisgruppe',
   'Pricegroup deleted!'         => 'Preisgruppe gelöscht!',
   'Pricegroup missing!'         => 'Preisgruppe fehlt!',
@@ -1992,6 +1999,7 @@ $self->{texts} = {
   'Record type to create'       => 'Anzulegender Belegtyp',
   'Recorded Tax'                => 'Gespeicherte Steuern',
   'Recorded taxkey'             => 'Gespeicherter Steuerschlüssel',
+  'Reduced Master Data'         => 'Abschlag',
   'Reference'                   => 'Referenz',
   'Reference / Invoice Number'  => 'Referenz / Rechnungsnummer',
   'Reference day'               => 'Stichtag',
@@ -2505,6 +2513,7 @@ $self->{texts} = {
   'The discount in percent'     => 'Der prozentuale Rabatt',
   'The discount must be less than 100%.' => 'Der Rabatt muss kleiner als 100% sein.',
   'The discount must not be negative.' => 'Der Rabatt darf nicht negativ sein.',
+  'The discounted amount will be shown in documents.' => 'Der Rabattbetrag wird in Belegen ausgewiesen.',
   'The dunning process started' => 'Der Mahnprozess ist gestartet.',
   'The dunnings have been printed.' => 'Die Mahnung(en) wurden gedruckt.',
   'The end date is the last day for which invoices will possibly be created.' => 'Das Enddatum ist das letztmögliche Datum, an dem eine Rechnung erzeugt wird.',
@@ -2739,6 +2748,11 @@ $self->{texts} = {
   'This user is a member in the following groups' => 'Dieser Benutzer ist Mitglied in den folgenden Gruppen',
   'This user will have access to the following clients' => 'Dieser Benutzer wird Zugriff auf die folgenden Mandanten haben',
   'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.',
+  'This will apply a 3% reduction to the master data price before entering it into the record item.' => 'Diese Zeile zieht vom Stammdatenpreis 3% ab, und schlägt den resultierenden Preis vor.',
+  'This will be treated as a discount in percent points.' => 'Diese Option schlägt den Wert in Prozentpunkten als Rabatt vor.',
+  'This will happen before the price is offered, and the reduction will not be printed in documents.' => 'Das passiert, bevor der Preis vorgeschlagen wird, und der Abschlag wird nicht in Belegen ausgewiesen.',
+  'This will reduce the appropriate Master Data price by this in percent points.' => 'Diese Option reduziert den zugehörigen Stammdatenpreis um den angegebenen Wert in Prozentpunkten.',
+  'This will set an exact price.' => 'Diese Option setzt einen festen Preis.',
   'Three Options:'              => 'Drei Optionen:',
   'Time Format'                 => 'Uhrzeitformat',
   'Time Tracking'               => 'Zeiterfassung',
diff --git a/sql/Pg-upgrade2/price_rules_discount.sql b/sql/Pg-upgrade2/price_rules_discount.sql
new file mode 100644 (file)
index 0000000..2f9d06b
--- /dev/null
@@ -0,0 +1,6 @@
+-- @tag: price_rules_discount
+-- @description:  Preisregeln: Beim Löschen items mitlöschen
+-- @depends: release_3_1_0 price_rules_cascade_delete
+
+ALTER TABLE price_rules RENAME COLUMN discount TO reduction;
+ALTER TABLE price_rules ADD COLUMN discount NUMERIC(15,5);
index 3dfc3b3e8afe1e20557b97795a51c2072e0a20e6..8dc346d361dc171a0e98868ac7e2b9950dfcc52a 100644 (file)
    <th align="right">[% 'Price' | $T8 %]</th>
    <td>[% L.input_tag('filter.price:number', filter.price_number, size=20, style='width: 300px') %]</td>
   </tr>
+  <tr>
+   <th align="right">[% 'Reduced Master Data' | $T8 %]</th>
+   <td>[% L.input_tag('filter.reduction:number', filter.reduction_number, size=20, style='width: 300px') %]</td>
+  </tr>
   <tr>
    <th align="right">[% 'Discount' | $T8 %]</th>
    <td>[% L.input_tag('filter.discount:number', filter.discount_number, size=20, style='width: 300px') %]</td>
index 62d7988418398c2bf7c9fac2ee858a13e296fc3f..0d6dbab32072b40f08e1d7962577b0750ace447c 100644 (file)
@@ -46,7 +46,7 @@
 </div>
 
 <h3>[% 'Then' | $T8 %]:</h3>
-<div>[% 'Set (set to)' | $T8 %] [% L.select_tag('price_rule.price_or_discount', [ [0, LxERP.t8('Price') ], [1, LxERP.t8('Discount') ]], default=SELF.price_rule.price_or_discount) %] [% 'to (set to)' | $T8 %] [% L.input_tag('price_rule.price_or_discount_as_number', SELF.price_rule.price_or_discount_as_number) %]
+<div>[% 'Set (set to)' | $T8 %] [% L.select_tag('price_rule.price_type', SELF.all_price_types, default=SELF.price_rule.price_type) %] [% 'to (set to)' | $T8 %] [% L.input_tag('price_rule.price_or_discount_as_number', SELF.price_rule.price_or_discount_as_number) %] <a id='price_rule_price_type_help' title='[% 'Price type explanation' | $T8 %]'>[?]</a>
 </div>
 
   <p>
diff --git a/templates/webpages/price_rule/price_type_help.html b/templates/webpages/price_rule/price_type_help.html
new file mode 100644 (file)
index 0000000..608d345
--- /dev/null
@@ -0,0 +1,33 @@
+[% USE T8 %]
+[% 'Matching Price Rules can apply in one of three types:' | $T8 %]
+
+<h3>[% 'Price' | $T8 %]</h3>
+
+<p>
+[% 'This will set an exact price.' | $T8 %]
+[% 'It will not be further modified by any other source, and will be offered in records like this.' | $T8 %]
+</p>
+
+<h3>[% 'Reduced Master Data' | $T8 %]</h3>
+
+<p>
+[% 'This will reduce the appropriate Master Data price by this in percent points.' | $T8 %]
+[% 'This will happen before the price is offered, and the reduction will not be printed in documents.' | $T8 %]
+[% 'Negative reductions are possible to model price increases.' | $T8 %]
+</p>
+
+<p>[% 'Example' | $T8 %]:</p>
+
+<pre>[% 'Set (set to)' | $T8 %] [% 'Reduced Master Data' | $T8 %] [% 'to (set to)' | $T8 %] 3</pre>
+
+<p>
+[% 'This will apply a 3% reduction to the master data price before entering it into the record item.' | $T8 %]
+</p>
+
+<h3>[% 'Discount' | $T8 %]</h3>
+
+<p>
+[% 'This will be treated as a discount in percent points.' | $T8 %]
+[% 'Contrary to Reduced Master Data this will be shown as discount in records.' | $T8 %]
+[% 'The discounted amount will be shown in documents.' | $T8 %]
+</p>