Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision bc8c26f3

Von Sven Schöling vor fast 10 Jahren hinzugefügt

  • ID bc8c26f36837b8f7e7ded304cdf475b479999277
  • Vorgänger 594592cb
  • Nachfolger 704f339f

PriceRule: Preisregeln können jetzt auch Rabatte

ausserdem Doku

Unterschiede anzeigen:

SL/Controller/PriceRule.pm
90 90
    ->render($self);
91 91
}
92 92

  
93
sub action_price_type_help {
94
  $_[0]->render('price_rule/price_type_help', { layout => 0 });
95
}
96

  
93 97
#
94 98
# filters
95 99
#
......
145 149
  my $report      = SL::ReportGenerator->new(\%::myconfig, $::form);
146 150
  $self->{report} = $report;
147 151

  
148
  my @columns     = qw(name type priority price discount items);
149
  my @sortable    = qw(name type priority price discount      );
152
  my @columns     = qw(name type priority price reduction discount items);
153
  my @sortable    = qw(name type priority price reduction discount      );
150 154

  
151 155
  my %column_defs = (
152 156
    name          => { obj_link => sub { $self->url_for(action => 'edit', 'price_rule.id' => $_[0]->id, callback => $callback) } },
153 157
    priority      => { sub  => sub { $_[0]->priority_as_text } },
154 158
    price         => { sub  => sub { $_[0]->price_as_number } },
159
    reduction     => { sub  => sub { $_[0]->reduction_as_number } },
155 160
    discount      => { sub  => sub { $_[0]->discount_as_number } },
156 161
    obsolete      => { sub  => sub { $_[0]->obsolete_as_bool_yn } },
157 162
    items         => { sub  => sub { $_[0]->item_summary } },
......
258 263
  SL::DB::Manager::PartsGroup->get_all;
259 264
}
260 265

  
266
sub all_price_types {
267
  SL::DB::Manager::PriceRule->all_price_types;
268
}
269

  
261 270
sub init_models {
262 271
  my ($self) = @_;
263 272

  
......
269 278
      priority => t8('Priority'),
270 279
      price    => t8('Price'),
271 280
      discount => t8('Discount'),
281
      reduction => t8('Reduced Master Data'),
272 282
      obsolete => t8('Obsolete'),
273 283
      items    => t8('Rule Details'),
274 284
    },
SL/DB/Manager/PriceRule.pm
7 7

  
8 8
use parent qw(SL::DB::Helper::Manager);
9 9

  
10
use constant PRICE_NEW                 => 0;
11
use constant PRICE_REDUCED_MASTER_DATA => 1;
12
use constant PRICE_DISCOUNT            => 2;
13

  
10 14
use SL::DB::Helper::Filtered;
11 15
use SL::DB::Helper::Paginated;
12 16
use SL::DB::Helper::Sorted;
......
76 80
  $self->get_all(query => [ id => \@ids ]);
77 81
}
78 82

  
83
sub all_price_types {
84
  [ PRICE_NEW,                 t8('Price')               ],
85
  [ PRICE_REDUCED_MASTER_DATA, t8('Reduced Master Data') ],
86
  [ PRICE_DISCOUNT,            t8('Discount')            ],
87
}
88

  
79 89
sub _sort_spec {
80 90
  return ( columns => { SIMPLE => 'ALL', },
81 91
           default => [ 'name', 1 ],
SL/DB/MetaSetup/PriceRule.pm
9 9
__PACKAGE__->meta->table('price_rules');
10 10

  
11 11
__PACKAGE__->meta->columns(
12
  discount => { type => 'numeric', precision => 15, scale => 5 },
13
  id       => { type => 'serial', not_null => 1 },
14
  itime    => { type => 'timestamp' },
15
  mtime    => { type => 'timestamp' },
16
  name     => { type => 'text' },
17
  obsolete => { type => 'boolean', default => 'false', not_null => 1 },
18
  price    => { type => 'numeric', precision => 15, scale => 5 },
19
  priority => { type => 'integer', default => 3, not_null => 1 },
20
  type     => { type => 'text' },
12
  discount  => { type => 'numeric', precision => 15, scale => 5 },
13
  id        => { type => 'serial', not_null => 1 },
14
  itime     => { type => 'timestamp' },
15
  mtime     => { type => 'timestamp' },
16
  name      => { type => 'text' },
17
  obsolete  => { type => 'boolean', default => 'false', not_null => 1 },
18
  price     => { type => 'numeric', precision => 15, scale => 5 },
19
  priority  => { type => 'integer', default => 3, not_null => 1 },
20
  reduction => { type => 'numeric', precision => 15, scale => 5 },
21
  type      => { type => 'text' },
21 22
);
22 23

  
23 24
__PACKAGE__->meta->primary_key_columns([ 'id' ]);
SL/DB/PriceRule.pm
44 44
  : $_[0]->type eq 'vendor'   ? 0 : do { die 'wrong type' };
45 45
}
46 46

  
47
sub price_or_discount {
47
sub price_type {
48 48
  my ($self, $value) = @_;
49 49

  
50 50
  if (@_ > 1) {
51 51
    my $number = $self->price || $self->discount;
52
    if ($value) {
52
    if ($value == SL::DB::Manager::PriceRule::PRICE_NEW()) {
53
      $self->price($number);
54
    } elsif ($value == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()) {
55
      $self->reduction($number);
56
    } elsif ($value == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
53 57
      $self->discount($number);
54 58
    } else {
55
      $self->price($number);
59
      die 'unknown price_or_discount value';
56 60
    }
57 61
    $self->price_or_discount_state($value);
58 62
  }
......
61 65

  
62 66
sub price_or_discount_as_number {
63 67
  my ($self, @slurp) = @_;
68
  my $type = $self->price_type;
69

  
70
  $self->price(undef)     unless $type == SL::DB::Manager::PriceRule::PRICE_NEW();
71
  $self->reduction(undef) unless $type == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA();
72
  $self->discount(undef)  unless $type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT();
64 73

  
65
  $self->price_or_discount ? $self->price(undef)               : $self->discount(undef);
66
  $self->price_or_discount ? $self->discount_as_number(@slurp) : $self->price_as_number(@slurp);
74

  
75
  if ($type == SL::DB::Manager::PriceRule::PRICE_NEW()) {
76
    return $self->price_as_number(@slurp)
77
  } elsif ($type == SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()) {
78
    return $self->reduction_as_number(@slurp);
79
  } elsif ($type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
80
    return $self->discount_as_number(@slurp)
81
  } else {
82
    die 'unknown price_or_discount';
83
  }
67 84
}
68 85

  
69 86
sub init_price_or_discount_state {
70
    defined $_[0]->price ? 0
71
  : defined $_[0]->discount ? 1 : 0
87
    defined $_[0]->price     ? SL::DB::Manager::PriceRule::PRICE_NEW()
88
  : defined $_[0]->reduction ? SL::DB::Manager::PriceRule::PRICE_REDUCED_MASTER_DATA()
89
  : defined $_[0]->discount  ? SL::DB::Manager::PriceRule::PRICE_DISCOUNT()
90
  :                            SL::DB::Manager::PriceRule::PRICE_NEW();
72 91
}
73 92

  
74 93
sub validate {
......
76 95

  
77 96
  my @errors;
78 97
  push @errors, $::locale->text('The name must not be empty.')              if !$self->name;
79
  push @errors, $::locale->text('Price or discount must not be zero.')      if !$self->price && !$self->discount;
98
  push @errors, $::locale->text('Price or discount must not be zero.')      if !$self->price && !$self->discount && !$self->reduction;
80 99
  push @errors, $::locale->text('Pirce rules must have at least one rule.') if !@{[ $self->items ]};
81 100

  
82 101
  return @errors;
SL/PriceSource/PriceRules.pm
4 4
use parent qw(SL::PriceSource::Base);
5 5

  
6 6
use SL::PriceSource::Price;
7
use SL::PriceSource::Discount;
7 8
use SL::Locale::String;
8 9
use SL::DB::PriceRule;
9 10
use List::UtilsBy qw(min_by max_by);
......
15 16
sub available_rules {
16 17
  my ($self, %params) = @_;
17 18

  
18
  SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
19
  $self->{available} ||= SL::DB::Manager::PriceRule->get_all_matching(record => $self->record, record_item => $self->record_item);
20
}
21

  
22
sub available_price_rules {
23
  my $rules = $_[0]->available_rules;
24
  grep { $_->price_type != SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
25
}
26

  
27
sub available_discount_rules {
28
  my $rules = $_[0]->available_rules;
29
  grep { $_->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT() } @$rules
19 30
}
20 31

  
21 32
sub available_prices {
22 33
  my ($self, %params) = @_;
23 34

  
24
  my $rules = $self->available_rules;
25

  
26
  map { $self->make_price_from_rule($_) } @$rules;
35
  map { $self->make_price_from_rule($_) } $self->available_price_rules;
27 36
}
28 37

  
29
sub available_discounts { }
38
sub available_discounts {
39
  my ($self, %params) = @_;
40

  
41
  map { $self->make_discount_from_rule($_) } $self->available_discount_rules;
42
}
30 43

  
31 44
sub price_from_source {
32 45
  my ($self, $source, $spec) = @_;
33 46

  
34 47
  my $rule = SL::DB::Manager::PriceRule->find_by(id => $spec);
35
  $self->make_price_from_rule($rule);
48
  if ($rule->price_type == SL::DB::Manager::PriceRule::PRICE_DISCOUNT()) {
49
    return $self->make_discount_from_rule($rule);
50
  } else {
51
    return $self->make_price_from_rule($rule);
52
  }
36 53
}
37 54

  
38 55
sub best_price {
39 56
  my ($self) = @_;
40 57

  
41
  my $rules     = $self->available_rules;
58
  my @rules     = $self->available_price_rules;
42 59

  
43
  return unless @$rules;
60
  return unless @rules;
44 61

  
45
  my @max_prio  = max_by { $_->priority } @$rules;
62
  my @max_prio  = max_by { $_->priority } @rules;
46 63
  my $min_price = min_by { $self->price_for_rule($_) } @max_prio;
47 64

  
48 65
  $self->make_price_from_rule($min_price);
49 66
}
50 67

  
51
sub best_discount { }
68
sub best_discount {
69
  my ($self) = @_;
70

  
71
  my @rules     = $self->available_discount_rules;
72

  
73
  return unless @rules;
74

  
75
  my @max_prio     = max_by { $_->priority } @rules;
76
  my $max_discount = max_by { $_->discount } @max_prio;
77

  
78
  $self->make_discount_from_rule($max_discount);
79
}
52 80

  
53 81
sub price_for_rule {
54 82
  my ($self, $rule) = @_;
55
  $rule->price_or_discount
56
    ? (1 - $rule->discount / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
83
  $rule->price_type != SL::DB::Manager::PriceRule::PRICE_NEW()
84
    ? (1 - $rule->reduction / 100) * ($rule->is_sales ? $self->part->sellprice : $self->part->lastcost)
57 85
    : $rule->price;
58 86
}
59 87

  
......
68 96
  )
69 97
}
70 98

  
99
sub make_discount_from_rule {
100
  my ($self, $rule) = @_;
101

  
102
  SL::PriceSource::Discount->new(
103
    discount     => $rule->discount / 100,
104
    spec         => $rule->id,
105
    description  => $rule->name,
106
    price_source => $self,
107
  )
108
}
109

  
71 110
1;
js/kivi.PriceRule.js
8 8
    $.post('controller.pl', data, kivi.eval_json_result);
9 9
  }
10 10

  
11
  ns.open_price_type_help_popup = function() {
12
    kivi.popup_dialog({
13
      url:    'controller.pl?action=PriceRule/price_type_help',
14
      dialog: { title: kivi.t8('Price Types') },
15
    });
16
  }
17

  
11 18
  $(function() {
12 19
    $('#price_rule_item_add').click(function() {
13 20
      ns.add_new_row($('#price_rules_empty_item_select').val());
......
15 22
    $('#price_rule_items').on('click', 'a.price_rule_remove_line', function(){
16 23
      $(this).closest('div').remove();
17 24
    })
25
    $('#price_rule_price_type_help').click(ns.open_price_type_help_popup);
18 26
  });
19 27
});
js/locale/de.js
45 45
"Part picker":"Artikelauswahl",
46 46
"Paste":"Einfügen",
47 47
"Paste template":"Vorlage einfügen",
48
"Price Types":"Preistypen",
48 49
"Project link actions":"Projektverknüpfungs-Aktionen",
49 50
"Quotations/Orders actions":"Aktionen für Angebote/Aufträge",
50 51
"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.",
locale/de/all
551 551
  'Content'                     => 'Inhalt',
552 552
  'Continue'                    => 'Weiter',
553 553
  'Contra'                      => 'gegen',
554
  'Contrary to Reduced Master Data this will be shown as discount in records.' => 'Im Gegensatz zu Abschlag wird der Rabatt in Belegen ausgewiesen',
554 555
  'Conversion of "birthday" contact person attribute' => 'Umstellung des Kontaktpersonenfeldes "Geburtstag"',
555 556
  'Conversion to PDF failed: #1' => 'Konvertierung zu PDF schlug fehl: #1',
556 557
  'Copies'                      => 'Kopien',
......
1070 1071
  'EuR'                         => 'EuR',
1071 1072
  'Everyone can log in.'        => 'Alle können sich anmelden.',
1072 1073
  'Exact'                       => 'Genau',
1074
  'Example'                     => 'Beispiel',
1073 1075
  'Example: http://kivitendo.de' => 'Beispiel:  http://kivitendo.de',
1074 1076
  'Excel'                       => 'Excel',
1075 1077
  'Exch'                        => 'Wechselkurs.',
......
1349 1351
  'It is not allowed that a summary account occurs in a drop-down menu!' => 'Ein Sammelkonto darf nicht in Aufklappmenüs aufgenommen werden!',
1350 1352
  '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.',
1351 1353
  '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.',
1354
  '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.',
1352 1355
  '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.',
1353 1356
  'Item deleted!'               => 'Artikel gelöscht!',
1354 1357
  'Item mode'                   => 'Artikelmodus',
......
1484 1487
  'Marked entries printed!'     => 'Markierte Einträge wurden gedruckt!',
1485 1488
  'Master Data'                 => 'Stammdaten',
1486 1489
  'Master Data Bin Text Deleted' => 'Gelöschte Stammdaten Freitext-Lagerplätze',
1490
  'Matching Price Rules can apply in one of three types:' => 'Preisregeln können Preise in drei Varianten vorschlagen:',
1487 1491
  'Max. Dunning Level'          => 'höchste Mahnstufe',
1488 1492
  'Maximal amount difference'   => 'maximale Betragsabweichung',
1489 1493
  'Maximum future booking interval' => 'Maximale Anzahl von Tagen an denen Buchungen in der Zukunft erlaubt sind.',
......
1529 1533
  'Name and Street'             => 'Name und Straße',
1530 1534
  'Name does not make sense without any bsooqr options' => 'Option "Name in gewählten Belegen" wird ignoriert.',
1531 1535
  'Name in Selected Records'    => 'Name in gewählten Belegen',
1536
  'Negative reductions are possible to model price increases.' => 'Negative Abschläge sind möglich um Aufschläge zu modellieren.',
1532 1537
  'Neither sections nor function blocks have been created yet.' => 'Es wurden bisher weder Abschnitte noch Funktionsblöcke angelegt.',
1533 1538
  'Net Income Statement'        => 'Einnahmenüberschußrechnung',
1534 1539
  'Net amount'                  => 'Nettobetrag',
......
1865 1870
  'Price Rules'                 => 'Preisregeln',
1866 1871
  'Price Source'                => 'Preisquelle',
1867 1872
  'Price Sources to be disabled in this client' => 'Preisquellen die in diesem Mandanten deaktiviert werden sollen',
1873
  'Price Types'                 => 'Preistypen',
1868 1874
  'Price factor (database ID)'  => 'Preisfaktor (Datenbank-ID)',
1869 1875
  'Price factor (name)'         => 'Preisfaktor (Name)',
1870 1876
  'Price factor deleted!'       => 'Preisfaktor gelöscht.',
......
1874 1880
  'Price information'           => 'Preisinformation',
1875 1881
  'Price or discount must not be zero.' => 'Preis/Rabatt darf nicht 0,00 sein',
1876 1882
  'Price sources deactivated in this client' => 'Preisquellen die in diesem Mandanten deaktiviert sind',
1883
  'Price type explanation'      => 'Preistyp Erklärung',
1877 1884
  'Pricegroup'                  => 'Preisgruppe',
1878 1885
  'Pricegroup deleted!'         => 'Preisgruppe gelöscht!',
1879 1886
  'Pricegroup missing!'         => 'Preisgruppe fehlt!',
......
1992 1999
  'Record type to create'       => 'Anzulegender Belegtyp',
1993 2000
  'Recorded Tax'                => 'Gespeicherte Steuern',
1994 2001
  'Recorded taxkey'             => 'Gespeicherter Steuerschlüssel',
2002
  'Reduced Master Data'         => 'Abschlag',
1995 2003
  'Reference'                   => 'Referenz',
1996 2004
  'Reference / Invoice Number'  => 'Referenz / Rechnungsnummer',
1997 2005
  'Reference day'               => 'Stichtag',
......
2505 2513
  'The discount in percent'     => 'Der prozentuale Rabatt',
2506 2514
  'The discount must be less than 100%.' => 'Der Rabatt muss kleiner als 100% sein.',
2507 2515
  'The discount must not be negative.' => 'Der Rabatt darf nicht negativ sein.',
2516
  'The discounted amount will be shown in documents.' => 'Der Rabattbetrag wird in Belegen ausgewiesen.',
2508 2517
  'The dunning process started' => 'Der Mahnprozess ist gestartet.',
2509 2518
  'The dunnings have been printed.' => 'Die Mahnung(en) wurden gedruckt.',
2510 2519
  '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 2748
  'This user is a member in the following groups' => 'Dieser Benutzer ist Mitglied in den folgenden Gruppen',
2740 2749
  'This user will have access to the following clients' => 'Dieser Benutzer wird Zugriff auf die folgenden Mandanten haben',
2741 2750
  'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.',
2751
  '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.',
2752
  'This will be treated as a discount in percent points.' => 'Diese Option schlägt den Wert in Prozentpunkten als Rabatt vor.',
2753
  '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.',
2754
  '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.',
2755
  'This will set an exact price.' => 'Diese Option setzt einen festen Preis.',
2742 2756
  'Three Options:'              => 'Drei Optionen:',
2743 2757
  'Time Format'                 => 'Uhrzeitformat',
2744 2758
  'Time Tracking'               => 'Zeiterfassung',
sql/Pg-upgrade2/price_rules_discount.sql
1
-- @tag: price_rules_discount
2
-- @description:  Preisregeln: Beim Löschen items mitlöschen
3
-- @depends: release_3_1_0 price_rules_cascade_delete
4

  
5
ALTER TABLE price_rules RENAME COLUMN discount TO reduction;
6
ALTER TABLE price_rules ADD COLUMN discount NUMERIC(15,5);
templates/webpages/price_rule/_filter.html
59 59
   <th align="right">[% 'Price' | $T8 %]</th>
60 60
   <td>[% L.input_tag('filter.price:number', filter.price_number, size=20, style='width: 300px') %]</td>
61 61
  </tr>
62
  <tr>
63
   <th align="right">[% 'Reduced Master Data' | $T8 %]</th>
64
   <td>[% L.input_tag('filter.reduction:number', filter.reduction_number, size=20, style='width: 300px') %]</td>
65
  </tr>
62 66
  <tr>
63 67
   <th align="right">[% 'Discount' | $T8 %]</th>
64 68
   <td>[% L.input_tag('filter.discount:number', filter.discount_number, size=20, style='width: 300px') %]</td>
templates/webpages/price_rule/form.html
46 46
</div>
47 47

  
48 48
<h3>[% 'Then' | $T8 %]:</h3>
49
<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) %]
49
<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>
50 50
</div>
51 51

  
52 52
  <p>
templates/webpages/price_rule/price_type_help.html
1
[% USE T8 %]
2
[% 'Matching Price Rules can apply in one of three types:' | $T8 %]
3

  
4
<h3>[% 'Price' | $T8 %]</h3>
5

  
6
<p>
7
[% 'This will set an exact price.' | $T8 %]
8
[% 'It will not be further modified by any other source, and will be offered in records like this.' | $T8 %]
9
</p>
10

  
11
<h3>[% 'Reduced Master Data' | $T8 %]</h3>
12

  
13
<p>
14
[% 'This will reduce the appropriate Master Data price by this in percent points.' | $T8 %]
15
[% 'This will happen before the price is offered, and the reduction will not be printed in documents.' | $T8 %]
16
[% 'Negative reductions are possible to model price increases.' | $T8 %]
17
</p>
18

  
19
<p>[% 'Example' | $T8 %]:</p>
20

  
21
<pre>[% 'Set (set to)' | $T8 %] [% 'Reduced Master Data' | $T8 %] [% 'to (set to)' | $T8 %] 3</pre>
22

  
23
<p>
24
[% 'This will apply a 3% reduction to the master data price before entering it into the record item.' | $T8 %]
25
</p>
26

  
27
<h3>[% 'Discount' | $T8 %]</h3>
28

  
29
<p>
30
[% 'This will be treated as a discount in percent points.' | $T8 %]
31
[% 'Contrary to Reduced Master Data this will be shown as discount in records.' | $T8 %]
32
[% 'The discounted amount will be shown in documents.' | $T8 %]
33
</p>

Auch abrufbar als: Unified diff