Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 219d88ab

Von Martin Helmling martin.helmling@octosoft.eu vor mehr als 7 Jahren hinzugefügt

  • ID 219d88ab03186a74e5dd474175e49bd74dacf15f
  • Vorgänger 65d2537d
  • Nachfolger 71d40510

Artikel-Klassifizierung: "Preis separat ausweisen"

Dieses neue Attribut an Artikelklassifizierung erlaubt in Aufträgen und Rechnungen
bestimmte Artikel extra auszuweisen.
Dazu werden diese als extra Variable der Dokumentengeneierung zur Verfügung gestellt.
Siehe neue Dokumentation Kapitel 3.7

Hintergrund:
Preise von Artikeln wie "Verpackung" oder "Transport" müssen
oftmals separat ausgewiesen werden, genauso wie der reine Warenwert

Unterschiede anzeigen:

SL/Controller/PartClassification.pm
116 116

  
117 117
  $::form->{part_classification}->{used_for_purchase} = 0 if ! $::form->{part_classification}->{used_for_purchase};
118 118
  $::form->{part_classification}->{used_for_sale}     = 0 if ! $::form->{part_classification}->{used_for_sale};
119
  $::form->{part_classification}->{report_separate}   = 0 if ! $::form->{part_classification}->{report_separate};
119 120

  
120 121
  my $params = delete($::form->{part_classification}) || { };
121 122

  
SL/DB/Manager/PartClassification.pm
9 9

  
10 10
__PACKAGE__->make_manager_methods;
11 11

  
12
#
13
# get the one/two character shortcut of the parts classification
14
#
15
sub get_abbreviation {
16
  my ($class,$id) = @_;
17
  my $obj = $class->get_first(query => [ id => $id ]);
18
  return '' unless $obj;
19
  return $obj->abbreviation?$obj->abbreviation:'';
20
}
21

  
22 12
1;
23 13

  
24 14

  
......
30 20

  
31 21
SL::DB::Manager::PartClassification
32 22

  
33

  
34
=head1 SYNOPSIS
35

  
36
This class has wrapper methodes to get the shortcuts
37

  
38
=head1 METHODS
39

  
40
=head2 get_abbreviation
41

  
42
 $class->get_abbreviation($classification_id);
43

  
44
get the one/two character shortcut of the parts classification
45

  
46
=head2 get_separate_abbreviation
47

  
48
 $class->get_separate_abbreviation($classification_id);
49

  
50
get the one/two character shortcut of the parts classification if it is a separate article
51

  
52
=head1 AUTHOR
53

  
54
Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>
55

  
56 23
=cut
SL/DB/MetaSetup/PartClassification.pm
12 12
  abbreviation      => { type => 'text' },
13 13
  description       => { type => 'text' },
14 14
  id                => { type => 'serial', not_null => 1 },
15
  report_separate   => { type => 'boolean', default => 'false' },
15 16
  used_for_purchase => { type => 'boolean', default => 'true' },
16 17
  used_for_sale     => { type => 'boolean', default => 'true' },
17 18
);
SL/DB/PartClassification.pm
42 42
The primary attributes are the rule
43 43
of the article as "used_for_sales" or "used_for_purchase".
44 44

  
45
Another attribute is "report_separate". This attribute may be used for some additional costs like
46
transport, packaging. These article are reported separate in the list of an invoice if
47
the print template is using the variables <%separate_XXX_subtotal%>  and XXX is the shortcut of the parts classification.
48
The variables <%non_separate_subtotal%> has the sum of all other parts of an invoice.
49
(See also LaTeX Documentation).
50

  
45 51
Additional other attributes may follow
46 52

  
47 53
To see this attributes in a short way there are shortcuts of one (or two characters, if needed for compare )
SL/IC.pm
1135 1135
    my $type_abbr = $::request->presenter->type_abbreviation($prt->part_type);
1136 1136
    push @{ $template_arrays{part_type} }, $type_abbr;
1137 1137
    push @{ $template_arrays{type_and_classific}},  $type_abbr.$::request->presenter->classification_abbreviation($prt->classification_id);
1138
    push @{ $template_arrays{separate}  },  $::request->presenter->separate_abbreviation($prt->classification_id);
1138 1139
  }
1139 1140

  
1140 1141
  $main::lxdebug->leave_sub();
SL/IS.pm
153 153
  # so that they can be sorted in later
154 154
  my %prepared_template_arrays = IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
155 155
  my @prepared_arrays          = keys %prepared_template_arrays;
156
  my @separate_totals          = qw(non_separate_subtotal);
156 157

  
157 158
  my $ic_cvar_configs = CVar->get_configs(module => 'IC');
158 159
  my $project_cvar_configs = CVar->get_configs(module => 'Projects');
......
336 337
      push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
337 338
      push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} },     $form->{"discount_$i"};
338 339

  
340
      if ( $prepared_template_arrays{separate}[$i - 1]  ) {
341
        my $pabbr = $prepared_template_arrays{separate}[$i - 1];
342
        if ( ! $form->{"separate_${pabbr}_subtotal"} ) {
343
            push @separate_totals , "separate_${pabbr}_subtotal";
344
            $form->{"separate_${pabbr}_subtotal"} = 0;
345
        }
346
        $form->{"separate_${pabbr}_subtotal"} += $linetotal;
347
      } else {
348
        $form->{non_separate_subtotal} += $linetotal;
349
      }
350

  
339 351
      $form->{total}            += $linetotal;
340 352
      $form->{nodiscount_total} += $nodiscount_linetotal;
341 353
      $form->{discount_total}   += $discount;
......
543 555
  $form->{delivery_term}->description_long($form->{delivery_term}->translated_attribute('description_long', $form->{language_id})) if $form->{delivery_term} && $form->{language_id};
544 556

  
545 557
  $form->{username} = $myconfig->{name};
558
  $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals;
546 559

  
547 560
  $main::lxdebug->leave_sub();
548 561
}
SL/OE.pm
1320 1320
  # so that they can be sorted in later
1321 1321
  my %prepared_template_arrays = IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
1322 1322
  my @prepared_arrays          = keys %prepared_template_arrays;
1323
  my @separate_totals          = qw(non_separate_subtotal);
1323 1324

  
1324 1325
  $form->{TEMPLATE_ARRAYS} = { };
1325 1326

  
......
1426 1427
      push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
1427 1428
      push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} },     $form->{"discount_$i"};
1428 1429

  
1430
      if ( $prepared_template_arrays{separate}[$i - 1]  ) {
1431
        my $pabbr = $prepared_template_arrays{separate}[$i - 1];
1432
        if ( ! $form->{"separate_${pabbr}_subtotal"} ) {
1433
            push @separate_totals , "separate_${pabbr}_subtotal";
1434
            $form->{"separate_${pabbr}_subtotal"} = 0;
1435
        }
1436
        $form->{"separate_${pabbr}_subtotal"} += $linetotal;
1437
      } else {
1438
        $form->{non_separate_subtotal} += $linetotal;
1439
      }
1440

  
1429 1441
      $form->{ordtotal}         += $linetotal;
1430 1442
      $form->{nodiscount_total} += $nodiscount_linetotal;
1431 1443
      $form->{discount_total}   += $discount;
......
1599 1611
  $form->{delivery_term}->description_long($form->{delivery_term}->translated_attribute('description_long', $form->{language_id})) if $form->{delivery_term} && $form->{language_id};
1600 1612

  
1601 1613
  $form->{order} = SL::DB::Manager::Order->find_by(id => $form->{id}) if $form->{id};
1614
  $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals;
1602 1615

  
1603 1616
  $main::lxdebug->leave_sub();
1604 1617
}
SL/Presenter/Part.pm
53 53
#
54 54
sub type_abbreviation {
55 55
  my ($self, $part_type) = @_;
56
  $main::lxdebug->message(LXDebug->DEBUG2(),"parttype=".$part_type);
57 56
  return $::locale->text('Assembly (typeabbreviation)')   if $part_type eq 'assembly';
58 57
  return $::locale->text('Part (typeabbreviation)')       if $part_type eq 'part';
59 58
  return $::locale->text('Assortment (typeabbreviation)') if $part_type eq 'assortment';
......
85 84
  $obj && $obj->abbreviation ? t8($obj->abbreviation) : '';
86 85
}
87 86

  
87
#
88
# shortcut for article type
89
#
90
sub separate_abbreviation {
91
  my ($self, $id) = @_;
92
  SL::DB::Manager::PartClassification->cache_all();
93
  my $obj = SL::DB::PartClassification->load_cached($id);
94
  $obj && $obj->abbreviation && $obj->report_separate ? t8($obj->abbreviation) : '';
95
}
96

  
88 97
#
89 98
# generate selection tag
90 99
#
......
152 161

  
153 162
=over 2
154 163

  
164
=item C<separate_abbreviation $classification_id>
165

  
166
Returns the shortcut of the classification if the classifiaction has the separate flag set.
167

  
168
=back
169

  
170
=over 2
171

  
155 172
=item C<select_classification $name,%params>
156 173

  
157 174
Returns a HTML Select Tag with all available Classifications
locale/de/all
1455 1455
  'If enabled a warning will be shown in sales and purchase orders if there are two or more positions of the same part (new controller only).' => 'Falls eingeschaltet, wird eine Warnung angezeigt, wenn der Auftrag mehrere gleiche Artikel enthält (nur neuer Controller).',
1456 1456
  'If enabled only those projects that are assigned to the currently selected customer are offered for selection in sales records.' => 'Wenn eingeschaltet, so werden in Verkaufsbelegen nur diejenigen Projekte zur Auswahl angeboten, die dem aktuell ausgewählten Kunden zugewiesen wurden.',
1457 1457
  'If enabled purchase and sales records cannot be saved if no transaction description has been entered.' => 'Wenn angeschaltet, so können Einkaufs- und Verkaufsbelege nicht gespeichert werden, solange keine Vorgangsbezeichnung eingegeben wurde.',
1458
  'If item not found, allow creation of new item' => 'Falls Artikel nicht gefunden, erlaube Erfassen eines Neuen',
1458 1459
  'If left empty the default sender from the kivitendo configuration will be used (key \'email_from\' in section \'periodic_invoices\'; current value: #1).' => 'Falls leer, so wird der Standardabsender aus der kivitendo-Konfiguration genutzt (Schlüssel »email_from« in Abschnitt »periodic_invoices«; aktueller Wert: #1).',
1459 1460
  'If missing then the start date will be used.' => 'Falls es fehlt, so wird die erste Rechnung für das Startdatum erzeugt.',
1461
  'If searching a part from a document and no part is found then offer to create a new part.' => 'Wenn bei der Artikelsuche aus einem Dokument heraus kein Artikel gefunden wird, dann wird ermöglicht, von dort aus einen neuen Artikel anzulegen.',
1460 1462
  'If the article type is set to \'mixed\' then a column called \'part_type\' or called \'pclass\' must be present.' => 'Falls der Rtikeltyp auf \'mixed\' gesetzt ist muss entweder eine Spalte \'part_type\' oder \'pclass\' im Import vorhanden sein',
1461 1463
  'If the automatic creation of invoices for fees and interest is switched on for a dunning level then the following accounts will be used for the invoice.' => 'Wenn das automatische Erstellen einer Rechnung &uuml;ber Mahngeb&uuml;hren und Zinsen f&uuml;r ein Mahnlevel aktiviert ist, so werden die folgenden Konten f&uuml;r die Rechnung benutzt.',
1462 1464
  'If the database user listed above does not have the right to create a database then enter the name and password of the superuser below:' => 'Falls der oben genannte Datenbankbenutzer nicht die Berechtigung zum Anlegen neuer Datenbanken hat, so k&ouml;nnen Sie hier den Namen und das Passwort des Datenbankadministratoraccounts angeben:',
......
2015 2017
  'POSTED'                      => 'Gebucht',
2016 2018
  'POSTED AS NEW'               => 'Als neu gebucht',
2017 2019
  'PRINTED'                     => 'Gedruckt',
2018
  'PType'                       => 'Typ',
2019 2020
  'Package name'                => 'Paketname',
2020 2021
  'Packing Lists'               => 'Lieferschein',
2021 2022
  'Page'                        => 'Seite',
......
2353 2354
  'Report and misc. Preferences' => 'Sonstige Einstellungen',
2354 2355
  'Report date'                 => 'Berichtsdatum',
2355 2356
  'Report for'                  => 'Bericht für',
2357
  'Report separately'           => 'Preis separat ausweisen',
2356 2358
  'Reports'                     => 'Berichte',
2357 2359
  'Representative'              => 'Vertreter',
2358 2360
  'Representative for Customer' => 'Vertreter für Kunden',
......
3480 3482
  'Weight unit'                 => 'Gewichtseinheit',
3481 3483
  'What <b>term</b> you are looking for?' => 'Nach welchem <b>Begriff</b> wollen Sie suchen?',
3482 3484
  'What this template contains' => 'Was diese Vorlage enthält',
3485
  'What type of item is this?'  => 'Was ist dieser Artikel?',
3483 3486
  'When converting a requirement spec into a quotation or an oder each section gets converted into a line position in the new record. This is the article used by default for this conversion.' => 'Wenn ein Pflichtenheft in ein Angebot oder Auftrag umgewandelt wird, wird für jeden Abschnitt eine Position im neuen Beleg angelegt. Dies ist der Artikel, der standardmäßig bei dieser Umwandlung genutzt wird.',
3484 3487
  'Which is located at doc/kivitendo-Dokumentation.pdf. Click here: ' => 'Diese befindet sich unter doc/kivitendo-Dokumentation.pdf. Klicken Sie hier:',
3485 3488
  'With Attachments'            => 'Journal mit Anhängen',
sql/Pg-upgrade2/part_classification_report_separate.sql
1
-- @tag: part_classification_report_separate
2
-- @description: "Artikelklassifikation mit weiterer boolschen Variable für separat ausweisen"
3
-- @depends: part_classifications
4
ALTER TABLE part_classifications ADD COLUMN report_separate BOOLEAN DEFAULT 'f' NOT NULL;
templates/webpages/part_classification/form.html
22 22
    <td>[% LxERP.t8('Used for Sale') %]</td>
23 23
    <td>[% L.checkbox_tag("part_classification.used_for_sale", checked=(SELF.part_classification.used_for_sale ? 1:'')) %]</td>
24 24
   </tr>
25
   <tr>
26
    <td>[% LxERP.t8('Report separately') %]</td>
27
    <td>[% L.checkbox_tag("part_classification.report_separate", checked=(SELF.part_classification.report_separate ? 1:'')) %]</td>
28
   </tr>
25 29
  </table>
26 30

  
27 31
  <p>
templates/webpages/part_classification/list.html
18 18
     <th>[%- LxERP.t8('TypeAbbreviation') %]</th>
19 19
     <th>[%- LxERP.t8('Used for Purchase') %]</th>
20 20
     <th>[%- LxERP.t8('Used for Sale') %]</th>
21
     <th>[%- LxERP.t8('Report separately') %]</th>
21 22
    </tr>
22 23
    </thead>
23 24

  
......
33 34
     <td>[%- HTML.escape(LxERP.t8(part_classification.abbreviation)) %]</td>
34 35
     <td>[% IF part_classification.used_for_purchase %][% LxERP.t8('Yes') %][% ELSE %][%  LxERP.t8('No') %][% END %]</td>
35 36
     <td>[% IF part_classification.used_for_sale     %][% LxERP.t8('Yes') %][% ELSE %][%  LxERP.t8('No') %][% END %]</td>
37
     <td>[% IF part_classification.report_separate   %][% LxERP.t8('Yes') %][% ELSE %][%  LxERP.t8('No') %][% END %]</td>
36 38
    </tr>
37 39
    [%- END %]
38 40
    </tbody>

Auch abrufbar als: Unified diff