Revision 5067d7bd
Von Martin Helmling martin.helmling@octosoft.eu vor etwa 8 Jahren hinzugefügt
SL/Controller/CsvImport/Part.pm | ||
---|---|---|
23 | 23 |
use Rose::Object::MakeMethods::Generic |
24 | 24 |
( |
25 | 25 |
scalar => [ qw(table makemodel_columns) ], |
26 |
'scalar --get_set_init' => [ qw(bg_by settings parts_by price_factors_by units_by partsgroups_by |
|
26 |
'scalar --get_set_init' => [ qw(bg_by settings parts_by price_factors_by classification_by units_by partsgroups_by
|
|
27 | 27 |
warehouses_by bins_by |
28 | 28 |
translation_columns all_pricegroups) ], |
29 | 29 |
); |
... | ... | |
40 | 40 |
article_number_policy => 'update_prices', |
41 | 41 |
shoparticle_if_missing => '0', |
42 | 42 |
part_type => 'part', |
43 |
parts_classification => 0, |
|
43 | 44 |
default_buchungsgruppe => ($bugru ? $bugru->id : undef), |
44 | 45 |
apply_buchungsgruppe => 'all', |
45 | 46 |
); |
... | ... | |
58 | 59 |
return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_bg } } ) } qw(id description) }; |
59 | 60 |
} |
60 | 61 |
|
62 |
sub init_classification_by { |
|
63 |
my ($self) = @_; |
|
64 |
my $all_classifications = SL::DB::Manager::PartsClassification->get_all; |
|
65 |
$_->abbreviation($::locale->text($_->abbreviation)) for @{ $all_classifications }; |
|
66 |
return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_classifications } } ) } qw(id abbreviation) }; |
|
67 |
} |
|
68 |
|
|
61 | 69 |
sub init_price_factors_by { |
62 | 70 |
my ($self) = @_; |
63 | 71 |
|
... | ... | |
126 | 134 |
|
127 | 135 |
return { map { ( $_ => $self->controller->profile->get($_) ) } qw(apply_buchungsgruppe default_buchungsgruppe article_number_policy |
128 | 136 |
sellprice_places sellprice_adjustment sellprice_adjustment_type |
129 |
shoparticle_if_missing part_type default_unit) }; |
|
137 |
shoparticle_if_missing part_type classification_id default_unit) };
|
|
130 | 138 |
} |
131 | 139 |
|
132 | 140 |
sub init_all_cvar_configs { |
... | ... | |
174 | 182 |
$i++; |
175 | 183 |
} |
176 | 184 |
|
177 |
$self->add_columns(qw(part_type)) if $self->settings->{part_type} eq 'mixed'; |
|
185 |
$self->add_columns(qw(part_type classification_id)) if $self->settings->{part_type} eq 'mixed';
|
|
178 | 186 |
$self->add_columns(qw(buchungsgruppen_id unit)); |
179 | 187 |
$self->add_columns(map { "${_}_id" } grep { exists $self->controller->data->[0]->{raw_data}->{$_} } qw (price_factor payment partsgroup warehouse bin)); |
180 | 188 |
$self->add_columns(qw(shop)) if $self->settings->{shoparticle_if_missing}; |
... | ... | |
413 | 421 |
# $bg ||= SL::DB::Buchungsgruppe->new(inventory_accno_id => 1); # does this case ever occur? |
414 | 422 |
|
415 | 423 |
my $part_type = $self->settings->{part_type}; |
416 |
if ($part_type eq 'mixed') { |
|
424 |
if ($part_type eq 'mixed' && $entry->{raw_data}->{part_type}) {
|
|
417 | 425 |
$part_type = $entry->{raw_data}->{part_type} =~ m/^p/i ? 'part' |
418 | 426 |
: $entry->{raw_data}->{part_type} =~ m/^s/i ? 'service' |
419 | 427 |
: $entry->{raw_data}->{part_type} =~ m/^assem/i ? 'assembly' |
420 | 428 |
: $entry->{raw_data}->{part_type} =~ m/^assor/i ? 'assortment' |
421 |
: undef; |
|
429 |
: $self->settings->{part_type}; |
|
430 |
} |
|
431 |
my $classification_id = $self->settings->{classification_id}; |
|
432 |
|
|
433 |
if ( $entry->{raw_data}->{pclass} && length($entry->{raw_data}->{pclass}) >= 2 ) { |
|
434 |
my $abbr1 = substr($entry->{raw_data}->{pclass},0,1); |
|
435 |
my $abbr2 = substr($entry->{raw_data}->{pclass},1); |
|
436 |
|
|
437 |
if ( $self->classification_by->{abbreviation}->{$abbr2} ) { |
|
438 |
my $tmp_classification_id = $self->classification_by->{abbreviation}->{$abbr2}->id; |
|
439 |
$classification_id = $tmp_classification_id if $tmp_classification_id; |
|
440 |
} |
|
441 |
if ($part_type eq 'mixed') { |
|
442 |
$part_type = $abbr1 eq $::locale->text('Part (typeabbreviation)') ? 'part' |
|
443 |
: $abbr1 eq $::locale->text('Service (typeabbreviation)') ? 'service' |
|
444 |
: $abbr1 eq $::locale->text('Assembly (typeabbreviation)') ? 'assembly' |
|
445 |
: $abbr1 eq $::locale->text('Assortment (typeabbreviation)') ? 'assortment' |
|
446 |
: undef; |
|
447 |
} |
|
422 | 448 |
} |
423 | 449 |
|
424 | 450 |
# when saving income_accno_id or expense_accno_id use ids from the selected |
... | ... | |
443 | 469 |
} |
444 | 470 |
|
445 | 471 |
$entry->{object}->part_type($part_type); |
472 |
$entry->{object}->classification_id( $classification_id ); |
|
446 | 473 |
|
447 | 474 |
return 1; |
448 | 475 |
} |
... | ... | |
699 | 726 |
|
700 | 727 |
$self->add_displayable_columns({ name => 'bin_id', description => $::locale->text('Bin (database ID)') }, |
701 | 728 |
{ name => 'bin', description => $::locale->text('Bin (name)') }, |
702 |
{ name => 'buchungsgruppen_id', description => $::locale->text('Booking group (database ID)') }, |
|
703 |
{ name => 'buchungsgruppe', description => $::locale->text('Booking group (name)') }, |
|
729 |
{ name => 'buchungsgruppen_id', description => $::locale->text('Booking group (database ID)') },
|
|
730 |
{ name => 'buchungsgruppe', description => $::locale->text('Booking group (name)') },
|
|
704 | 731 |
{ name => 'description', description => $::locale->text('Description') }, |
705 | 732 |
{ name => 'drawing', description => $::locale->text('Drawing') }, |
706 | 733 |
{ name => 'ean', description => $::locale->text('EAN') }, |
... | ... | |
721 | 748 |
{ name => 'partnumber', description => $::locale->text('Part Number') }, |
722 | 749 |
{ name => 'partsgroup_id', description => $::locale->text('Partsgroup (database ID)') }, |
723 | 750 |
{ name => 'partsgroup', description => $::locale->text('Partsgroup (name)') }, |
751 |
{ name => 'classification_by', description => $::locale->text('Article classification') . ' [3]' }, |
|
724 | 752 |
{ name => 'payment_id', description => $::locale->text('Payment terms (database ID)') }, |
725 | 753 |
{ name => 'payment', description => $::locale->text('Payment terms (name)') }, |
726 | 754 |
{ name => 'price_factor_id', description => $::locale->text('Price factor (database ID)') }, |
727 | 755 |
{ name => 'price_factor', description => $::locale->text('Price factor (name)') }, |
728 | 756 |
{ name => 'rop', description => $::locale->text('ROP') }, |
729 | 757 |
{ name => 'sellprice', description => $::locale->text('Sellprice') }, |
730 |
{ name => 'shop', description => $::locale->text('Shop article') },
|
|
731 |
{ name => 'type', description => $::locale->text('Article type') . ' [3]' }, |
|
758 |
{ name => 'shop', description => $::locale->text('Shop article') }, |
|
759 |
{ name => 'type', description => $::locale->text('Article type') . ' [3]' },
|
|
732 | 760 |
{ name => 'unit', description => $::locale->text('Unit (if missing or empty default unit will be used)') }, |
733 | 761 |
{ name => 've', description => $::locale->text('Verrechnungseinheit') }, |
734 | 762 |
{ name => 'warehouse_id', description => $::locale->text('Warehouse (database ID)') }, |
735 |
{ name => 'warehouse', description => $::locale->text('Warehouse (name)') }, |
|
763 |
{ name => 'warehouse', description => $::locale->text('Warehouse (name)') },
|
|
736 | 764 |
{ name => 'weight', description => $::locale->text('Weight') }, |
737 | 765 |
); |
738 | 766 |
|
SL/Controller/PartsClassification.pm | ||
---|---|---|
1 |
package SL::Controller::PartsClassification; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(SL::Controller::Base); |
|
6 |
|
|
7 |
use SL::DB::PartsClassification; |
|
8 |
use SL::Helper::Flash; |
|
9 |
|
|
10 |
use Rose::Object::MakeMethods::Generic |
|
11 |
( |
|
12 |
scalar => [ qw(parts_classification) ], |
|
13 |
); |
|
14 |
|
|
15 |
__PACKAGE__->run_before('check_auth'); |
|
16 |
__PACKAGE__->run_before('load_parts_classification', only => [ qw(edit update destroy) ]); |
|
17 |
|
|
18 |
# |
|
19 |
# actions |
|
20 |
# |
|
21 |
|
|
22 |
sub action_list { |
|
23 |
my ($self) = @_; |
|
24 |
|
|
25 |
$self->render('parts_classification/list', |
|
26 |
title => $::locale->text('Parts Classifications'), |
|
27 |
PARTS_CLASSIFICATIONS => SL::DB::Manager::PartsClassification->get_all_sorted); |
|
28 |
} |
|
29 |
|
|
30 |
sub action_new { |
|
31 |
my ($self) = @_; |
|
32 |
|
|
33 |
$self->{parts_classification} = SL::DB::PartsClassification->new; |
|
34 |
$self->render('parts_classification/form', title => $::locale->text('Create a new parts classification')); |
|
35 |
} |
|
36 |
|
|
37 |
sub action_edit { |
|
38 |
my ($self) = @_; |
|
39 |
$self->render('parts_classification/form', title => $::locale->text('Edit parts classification')); |
|
40 |
} |
|
41 |
|
|
42 |
sub action_create { |
|
43 |
my ($self) = @_; |
|
44 |
|
|
45 |
$self->{parts_classification} = SL::DB::PartsClassification->new; |
|
46 |
$self->create_or_update; |
|
47 |
} |
|
48 |
|
|
49 |
sub action_update { |
|
50 |
my ($self) = @_; |
|
51 |
$self->create_or_update; |
|
52 |
} |
|
53 |
|
|
54 |
sub action_destroy { |
|
55 |
my ($self) = @_; |
|
56 |
|
|
57 |
if ( $self->{parts_classification}->id < 5 ) { |
|
58 |
flash_later('error', $::locale->text('The basic parts classification cannot be deleted.')); |
|
59 |
} |
|
60 |
elsif (eval { $self->{parts_classification}->delete; 1; }) { |
|
61 |
flash_later('info', $::locale->text('The parts classification has been deleted.')); |
|
62 |
} else { |
|
63 |
flash_later('error', $::locale->text('The parts classification is in use and cannot be deleted.')); |
|
64 |
} |
|
65 |
|
|
66 |
$self->redirect_to(action => 'list'); |
|
67 |
} |
|
68 |
|
|
69 |
sub action_reorder { |
|
70 |
my ($self) = @_; |
|
71 |
|
|
72 |
SL::DB::PartsClassification->reorder_list(@{ $::form->{parts_classification_id} || [] }); |
|
73 |
|
|
74 |
$self->render(\'', { type => 'json' }); |
|
75 |
} |
|
76 |
|
|
77 |
# |
|
78 |
# filters |
|
79 |
# |
|
80 |
|
|
81 |
sub check_auth { |
|
82 |
$::auth->assert('config'); |
|
83 |
} |
|
84 |
|
|
85 |
# |
|
86 |
# helpers |
|
87 |
# |
|
88 |
|
|
89 |
sub create_or_update { |
|
90 |
my $self = shift; |
|
91 |
my $is_new = !$self->{parts_classification}->id; |
|
92 |
my $params = delete($::form->{parts_classification}) || { }; |
|
93 |
|
|
94 |
$self->{parts_classification}->assign_attributes(%{ $params }); |
|
95 |
|
|
96 |
my @errors = $self->{parts_classification}->validate; |
|
97 |
|
|
98 |
if (@errors) { |
|
99 |
flash('error', @errors); |
|
100 |
$self->render('parts_classification/form', title => $is_new ? $::locale->text('Create a new parts classification') : $::locale->text('Edit parts classification')); |
|
101 |
return; |
|
102 |
} |
|
103 |
|
|
104 |
$self->{parts_classification}->save; |
|
105 |
|
|
106 |
flash_later('info', $is_new ? $::locale->text('The parts classification has been created.') : $::locale->text('The parts classification has been saved.')); |
|
107 |
$self->redirect_to(action => 'list'); |
|
108 |
} |
|
109 |
|
|
110 |
sub load_parts_classification { |
|
111 |
my ($self) = @_; |
|
112 |
$self->{parts_classification} = SL::DB::PartsClassification->new(id => $::form->{id})->load; |
|
113 |
} |
|
114 |
|
|
115 |
1; |
SL/DB/Helper/Mappings.pm | ||
---|---|---|
153 | 153 |
oe => 'order', |
154 | 154 |
parts => 'part', |
155 | 155 |
partsgroup => 'parts_group', |
156 |
parts_classifications => 'PartsClassification', |
|
156 | 157 |
parts_price_history => 'PartsPriceHistory', |
157 | 158 |
payment_terms => 'payment_term', |
158 | 159 |
periodic_invoices => 'periodic_invoice', |
SL/DB/Manager/PartsClassification.pm | ||
---|---|---|
1 |
# This file has been auto-generated only because it didn't exist. |
|
2 |
# Feel free to modify it at will; it will not be overwritten automatically. |
|
3 |
|
|
4 |
package SL::DB::Manager::PartsClassification; |
|
5 |
|
|
6 |
use strict; |
|
7 |
|
|
8 |
use parent qw(SL::DB::Helper::Manager); |
|
9 |
use SL::DB::Helper::Sorted; |
|
10 |
|
|
11 |
sub object_class { 'SL::DB::PartsClassification' } |
|
12 |
|
|
13 |
__PACKAGE__->make_manager_methods; |
|
14 |
|
|
15 |
|
|
16 |
sub get_abbreviation { |
|
17 |
my ($class,$id) = @_; |
|
18 |
my $obj = $class->get_first(query => [ id => $id ]); |
|
19 |
return $obj->abbreviation?$obj->abbreviation:undef; |
|
20 |
} |
|
21 |
|
|
22 |
1; |
SL/DB/MetaSetup/Part.pm | ||
---|---|---|
12 | 12 |
bin_id => { type => 'integer' }, |
13 | 13 |
bom => { type => 'boolean', default => 'false' }, |
14 | 14 |
buchungsgruppen_id => { type => 'integer' }, |
15 |
classification_id => { type => 'integer', default => '0' }, |
|
15 | 16 |
description => { type => 'text' }, |
16 | 17 |
drawing => { type => 'text' }, |
17 | 18 |
ean => { type => 'text' }, |
... | ... | |
63 | 64 |
key_columns => { buchungsgruppen_id => 'id' }, |
64 | 65 |
}, |
65 | 66 |
|
67 |
classification => { |
|
68 |
class => 'SL::DB::PartsClassification', |
|
69 |
key_columns => { classification_id => 'id' }, |
|
70 |
}, |
|
71 |
|
|
66 | 72 |
partsgroup => { |
67 | 73 |
class => 'SL::DB::PartsGroup', |
68 | 74 |
key_columns => { partsgroup_id => 'id' }, |
SL/DB/MetaSetup/PartsClassification.pm | ||
---|---|---|
1 |
# This file has been auto-generated. Do not modify it; it will be overwritten |
|
2 |
# by rose_auto_create_model.pl automatically. |
|
3 |
package SL::DB::PartsClassification; |
|
4 |
|
|
5 |
use strict; |
|
6 |
|
|
7 |
use parent qw(SL::DB::Object); |
|
8 |
|
|
9 |
__PACKAGE__->meta->table('parts_classifications'); |
|
10 |
|
|
11 |
__PACKAGE__->meta->columns( |
|
12 |
abbreviation => { type => 'text' }, |
|
13 |
description => { type => 'text' }, |
|
14 |
id => { type => 'serial', not_null => 1 }, |
|
15 |
used_for_purchase => { type => 'boolean', default => 'true' }, |
|
16 |
used_for_sale => { type => 'boolean', default => 'true' }, |
|
17 |
); |
|
18 |
|
|
19 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
|
20 |
|
|
21 |
1; |
|
22 |
; |
SL/DB/PartsClassification.pm | ||
---|---|---|
1 |
# This file has been auto-generated only because it didn't exist. |
|
2 |
# Feel free to modify it at will; it will not be overwritten automatically. |
|
3 |
|
|
4 |
package SL::DB::PartsClassification; |
|
5 |
|
|
6 |
use strict; |
|
7 |
|
|
8 |
use SL::DB::MetaSetup::PartsClassification; |
|
9 |
use SL::DB::Manager::PartsClassification; |
|
10 |
|
|
11 |
__PACKAGE__->meta->initialize; |
|
12 |
|
|
13 |
sub validate { |
|
14 |
my ($self) = @_; |
|
15 |
|
|
16 |
my @errors; |
|
17 |
push @errors, $::locale->text('The description is missing.') if !$self->description; |
|
18 |
push @errors, $::locale->text('The abbreviation is missing.') if !$self->abbreviation; |
|
19 |
|
|
20 |
return @errors; |
|
21 |
} |
|
22 |
|
|
23 |
|
|
24 |
1; |
SL/IC.pm | ||
---|---|---|
85 | 85 |
# retrieve assembly items |
86 | 86 |
$query = |
87 | 87 |
qq|SELECT p.id, p.partnumber, p.description, |
88 |
p.classification_id, |
|
88 | 89 |
p.sellprice, p.lastcost, p.weight, a.qty, a.bom, p.unit, |
89 | 90 |
pg.partsgroup, p.price_factor_id, pfac.factor AS price_factor |
90 | 91 |
FROM parts p |
... | ... | |
101 | 102 |
foreach my $key (keys %{$ref}) { |
102 | 103 |
$form->{"${key}_$form->{assembly_rows}"} = $ref->{$key}; |
103 | 104 |
} |
105 |
$form->{"type_and_classific_$form->{assembly_rows}"} = $::request->presenter->type_abbreviation($ref->{part_type}). |
|
106 |
$::request->presenter->classification_abbreviation($ref->{classification_id}); |
|
104 | 107 |
} |
105 | 108 |
$sth->finish; |
106 | 109 |
|
... | ... | |
334 | 337 |
partnumber = ?, |
335 | 338 |
description = ?, |
336 | 339 |
makemodel = ?, |
340 |
classification_id = ?, |
|
337 | 341 |
listprice = ?, |
338 | 342 |
sellprice = ?, |
339 | 343 |
lastcost = ?, |
... | ... | |
367 | 371 |
@values = ($form->{partnumber}, |
368 | 372 |
$form->{description}, |
369 | 373 |
$makemodel ? 't' : 'f', |
374 |
$form->{classification_id}, |
|
370 | 375 |
$form->{listprice}, |
371 | 376 |
$form->{sellprice}, |
372 | 377 |
$form->{lastcost}, |
... | ... | |
642 | 647 |
|
643 | 648 |
my $query = |
644 | 649 |
qq|SELECT p.id, p.partnumber, p.description, p.sellprice, |
650 |
p.classification_id, |
|
645 | 651 |
p.weight, p.onhand, p.unit, pg.partsgroup, p.lastcost, |
646 | 652 |
p.price_factor_id, pfac.factor AS price_factor, p.notes as longdescription |
647 | 653 |
FROM parts p |
... | ... | |
723 | 729 |
# my @other_flags = qw(onhand); # ToDO: implement these |
724 | 730 |
# my @inactive_flags = qw(l_subtotal short l_linetotal); |
725 | 731 |
|
726 |
my @select_tokens = qw(id factor); |
|
732 |
my @select_tokens = qw(id factor part_type classification_id);
|
|
727 | 733 |
my @where_tokens = qw(1=1); |
728 | 734 |
my @group_tokens = (); |
729 | 735 |
my @bind_vars = (); |
... | ... | |
800 | 806 |
insertdate => 'itime::DATE', |
801 | 807 |
); |
802 | 808 |
|
803 |
if (($form->{searchitems} eq 'assembly') && $form->{l_lastcost}) {
|
|
809 |
if ($form->{l_assembly} && $form->{l_lastcost}) {
|
|
804 | 810 |
@simple_l_switches = grep { $_ ne 'lastcost' } @simple_l_switches; |
805 | 811 |
} |
806 | 812 |
|
... | ... | |
890 | 896 |
push @select_tokens, $_; |
891 | 897 |
} |
892 | 898 |
|
893 |
for ($form->{searchitems}) { |
|
894 |
push @where_tokens, "p.part_type = 'part'" if /part/; |
|
895 |
push @where_tokens, "p.part_type = 'service'" if /service/; |
|
896 |
push @where_tokens, "p.part_type = 'assembly'" if /assembly/; |
|
899 |
# Oder Bedingungen fuer Ware Dienstleistung Erzeugnis: |
|
900 |
if ($form->{l_part} || $form->{l_assembly} || $form->{l_service}) { |
|
901 |
my @or_tokens = (); |
|
902 |
push @or_tokens, "p.part_type = 'service'" if $form->{l_service}; |
|
903 |
push @or_tokens, "p.part_type = 'assembly'" if $form->{l_assembly}; |
|
904 |
push @or_tokens, "p.part_type = 'part'" if $form->{l_part}; |
|
905 |
push @where_tokens, join ' OR ', map { "($_)" } @or_tokens; |
|
906 |
} |
|
907 |
else { |
|
908 |
# gar keine Teile |
|
909 |
push @where_tokens, q|'F' = 'T'|; |
|
910 |
} |
|
911 |
|
|
912 |
if ( $form->{classification_id} > 0 ) { |
|
913 |
push @where_tokens, "p.classification_id = ?"; |
|
914 |
push @bind_vars, $form->{classification_id}; |
|
897 | 915 |
} |
898 | 916 |
|
899 | 917 |
for ($form->{itemstatus}) { |
... | ... | |
951 | 969 |
|
952 | 970 |
push @select_tokens, @qsooqr_flags, 'quotation', 'cv', 'ioi.id', 'ioi.ioi' if $bsooqr; |
953 | 971 |
push @select_tokens, @deliverydate_flags if $bsooqr && $form->{l_deliverydate}; |
954 |
push @select_tokens, $q_assembly_lastcost if ($form->{searchitems} eq 'assembly') && $form->{l_lastcost};
|
|
972 |
push @select_tokens, $q_assembly_lastcost if $form->{l_assembly} && $form->{l_lastcost};
|
|
955 | 973 |
push @bsooqr_tokens, q|module = 'ir' AND NOT ioi.assemblyitem| if $form->{bought}; |
956 | 974 |
push @bsooqr_tokens, q|module = 'is' AND NOT ioi.assemblyitem| if $form->{sold}; |
957 | 975 |
push @bsooqr_tokens, q|module = 'oe' AND NOT quotation AND cv = 'customer'| if $form->{ordered}; |
... | ... | |
1049 | 1067 |
# post processing for assembly parts lists (bom) |
1050 | 1068 |
# for each part get the assembly parts and add them into the partlist. |
1051 | 1069 |
my @assemblies; |
1052 |
if ($form->{searchitems} eq 'assembly' && $form->{bom}) {
|
|
1070 |
if ($form->{l_assembly} && $form->{bom}) {
|
|
1053 | 1071 |
$query = |
1054 | 1072 |
qq|SELECT p.id, p.partnumber, p.description, a.qty AS onhand, |
1055 | 1073 |
p.unit, p.notes, p.itime::DATE as insertdate, |
... | ... | |
1079 | 1097 |
$form->{parts} = \@assemblies; |
1080 | 1098 |
} |
1081 | 1099 |
|
1082 |
if ($form->{l_pricegroups} ) { |
|
1100 |
if ($form->{l_pricegroups} && SL::DB::Manager::Price->get_all_count() > 0 ) {
|
|
1083 | 1101 |
my $query = <<SQL; |
1084 | 1102 |
SELECT parts_id, price, pricegroup_id |
1085 | 1103 |
FROM prices |
... | ... | |
1096 | 1114 |
} |
1097 | 1115 |
$sth->finish; |
1098 | 1116 |
} |
1099 |
}; |
|
1100 |
|
|
1117 |
} |
|
1101 | 1118 |
|
1102 | 1119 |
$main::lxdebug->leave_sub(); |
1103 | 1120 |
|
... | ... | |
1393 | 1410 |
} |
1394 | 1411 |
|
1395 | 1412 |
my $query = |
1396 |
qq|SELECT id, partnumber, description, unit, sellprice |
|
1413 |
qq|SELECT id, partnumber, description, unit, sellprice, |
|
1414 |
classification_id |
|
1397 | 1415 |
FROM parts |
1398 | 1416 |
WHERE $where ORDER BY $order|; |
1399 | 1417 |
|
... | ... | |
1406 | 1424 |
} |
1407 | 1425 |
|
1408 | 1426 |
$j++; |
1427 |
$form->{"type_and_classific_$j"} = $::request->presenter->type_abbreviation($ref->{part_type}). |
|
1428 |
$::request->presenter->classification_abbreviation($ref->{classification_id}); |
|
1409 | 1429 |
$form->{"id_$j"} = $ref->{id}; |
1410 | 1430 |
$form->{"partnumber_$j"} = $ref->{partnumber}; |
1411 | 1431 |
$form->{"description_$j"} = $ref->{description}; |
... | ... | |
1733 | 1753 |
for my $i (1..$rowcount) { |
1734 | 1754 |
my $id = $form->{"${prefix}${i}"}; |
1735 | 1755 |
next unless $id; |
1736 |
|
|
1737 |
push @{ $template_arrays{part_type} }, $parts_by_id{$id}->type; |
|
1756 |
my $prt = $parts_by_id{$id}; |
|
1757 |
my $type_abbr = $::request->presenter->type_abbreviation($prt->part_type); |
|
1758 |
push @{ $template_arrays{part_type} }, $type_abbr; |
|
1759 |
push @{ $template_arrays{type_and_classific}}, $type_abbr.$::request->presenter->classification_abbreviation($prt->classification_id); |
|
1738 | 1760 |
} |
1739 | 1761 |
|
1740 |
return %template_arrays; |
|
1741 | 1762 |
$main::lxdebug->leave_sub(); |
1763 |
return %template_arrays; |
|
1742 | 1764 |
} |
1743 | 1765 |
|
1744 | 1766 |
sub normalize_text_blocks { |
... | ... | |
1760 | 1782 |
$main::lxdebug->leave_sub(); |
1761 | 1783 |
} |
1762 | 1784 |
|
1763 |
|
|
1764 | 1785 |
1; |
SL/IR.pm | ||
---|---|---|
1020 | 1020 |
i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.parts_id AS id, i.unit, i.deliverydate, i.project_id, i.serialnumber, |
1021 | 1021 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.discount, i.active_price_source, i.active_discount_source, |
1022 | 1022 |
p.partnumber, p.part_type, pr.projectnumber, pg.partsgroup |
1023 |
,p.classification_id |
|
1023 | 1024 |
|
1024 | 1025 |
FROM invoice i |
1025 | 1026 |
JOIN parts p ON (i.parts_id = p.id) |
... | ... | |
1279 | 1280 |
p.notes AS partnotes, p.notes AS longdescription, p.not_discountable, |
1280 | 1281 |
p.inventory_accno_id, p.price_factor_id, |
1281 | 1282 |
p.ean, |
1283 |
p.classification_id, |
|
1282 | 1284 |
|
1283 | 1285 |
pfac.factor AS price_factor, |
1284 | 1286 |
|
... | ... | |
1294 | 1296 |
c3.new_chart_id AS expense_new_chart, |
1295 | 1297 |
date($transdate) - c3.valid_from AS expense_valid, |
1296 | 1298 |
|
1299 |
pt.used_for_purchase AS used_for_purchase, |
|
1297 | 1300 |
pg.partsgroup |
1298 | 1301 |
|
1299 | 1302 |
FROM parts p |
... | ... | |
1310 | 1313 |
FROM taxzone_charts tc |
1311 | 1314 |
WHERE tc.taxzone_id = '$taxzone_id' and tc.buchungsgruppen_id = p.buchungsgruppen_id) = c3.id) |
1312 | 1315 |
LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) |
1316 |
LEFT JOIN parts_classifications pt ON (pt.id = p.classification_id) |
|
1313 | 1317 |
LEFT JOIN price_factors pfac ON (pfac.id = p.price_factor_id) |
1314 | 1318 |
WHERE $where|; |
1315 | 1319 |
my $sth = prepare_execute_query($form, $dbh, $query, @values); |
... | ... | |
1328 | 1332 |
map { push @{ $_ }, prepare_query($form, $dbh, $_->[0]) } @translation_queries; |
1329 | 1333 |
|
1330 | 1334 |
$form->{item_list} = []; |
1335 |
my $has_wrong_pclass = 0; |
|
1331 | 1336 |
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) { |
1332 | 1337 |
|
1333 | 1338 |
if ($mm_by_id{$ref->{id}}) { |
... | ... | |
1338 | 1343 |
if (($::form->{"partnumber_$i"} ne '') && ($ref->{ean} eq $::form->{"partnumber_$i"})) { |
1339 | 1344 |
push @{ $ref->{matches} ||= [] }, $::locale->text('EAN') . ': ' . $ref->{ean}; |
1340 | 1345 |
} |
1346 |
$ref->{type_and_classific} = $::request->presenter->type_abbreviation($ref->{part_type}). |
|
1347 |
$::request->presenter->classification_abbreviation($ref->{classification_id}); |
|
1341 | 1348 |
|
1349 |
if (! $ref->{used_for_purchase} ) { |
|
1350 |
$has_wrong_pclass = 2; |
|
1351 |
next; |
|
1352 |
} |
|
1342 | 1353 |
# In der Buchungsgruppe ist immer ein Bestandskonto verknuepft, auch wenn |
1343 | 1354 |
# es sich um eine Dienstleistung handelt. Bei Dienstleistungen muss das |
1344 | 1355 |
# Buchungskonto also aus dem Ergebnis rausgenommen werden. |
... | ... | |
1408 | 1419 |
$sth->finish(); |
1409 | 1420 |
$_->[1]->finish for @translation_queries; |
1410 | 1421 |
|
1422 |
$form->{is_wrong_pclass} = $has_wrong_pclass; |
|
1411 | 1423 |
foreach my $item (@{ $form->{item_list} }) { |
1412 | 1424 |
my $custom_variables = CVar->get_custom_variables(module => 'IC', |
1413 | 1425 |
trans_id => $item->{id}, |
1414 | 1426 |
dbh => $dbh, |
1415 | 1427 |
); |
1416 |
|
|
1428 |
$form->{is_wrong_pclass} = 0; # one correct type |
|
1417 | 1429 |
map { $item->{"ic_cvar_" . $_->{name} } = $_->{value} } @{ $custom_variables }; |
1418 | 1430 |
} |
1419 | 1431 |
|
SL/IS.pm | ||
---|---|---|
2003 | 2003 |
i.project_id, i.serialnumber, i.pricegroup_id, i.ordnumber, i.donumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost, |
2004 | 2004 |
i.price_factor_id, i.price_factor, i.marge_price_factor, i.active_price_source, i.active_discount_source, |
2005 | 2005 |
p.partnumber, p.part_type, p.notes AS partnotes, p.formel, p.listprice, |
2006 |
p.classification_id, |
|
2006 | 2007 |
pr.projectnumber, pg.partsgroup, prg.pricegroup |
2007 | 2008 |
|
2008 | 2009 |
FROM invoice i |
... | ... | |
2300 | 2301 |
p.id, p.partnumber, p.description, p.sellprice, |
2301 | 2302 |
p.listprice, p.part_type, p.lastcost, |
2302 | 2303 |
p.ean, p.notes, |
2304 |
p.classification_id, |
|
2303 | 2305 |
|
2304 | 2306 |
c1.accno AS inventory_accno, |
2305 | 2307 |
c1.new_chart_id AS inventory_new_chart, |
... | ... | |
2319 | 2321 |
p.price_factor_id, p.weight, |
2320 | 2322 |
|
2321 | 2323 |
pfac.factor AS price_factor, |
2322 |
|
|
2324 |
pt.used_for_sale AS used_for_sale, |
|
2323 | 2325 |
pg.partsgroup |
2324 | 2326 |
|
2325 | 2327 |
FROM parts p |
... | ... | |
2336 | 2338 |
FROM taxzone_charts tc |
2337 | 2339 |
WHERE tc.buchungsgruppen_id = p.buchungsgruppen_id and tc.taxzone_id = ${taxzone_id}) = c3.id) |
2338 | 2340 |
LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) |
2341 |
LEFT JOIN parts_classifications pt ON (pt.id = p.classification_id) |
|
2339 | 2342 |
LEFT JOIN price_factors pfac ON (pfac.id = p.price_factor_id) |
2340 | 2343 |
WHERE $where|; |
2341 | 2344 |
my $sth = prepare_execute_query($form, $dbh, $query, @values); |
... | ... | |
2353 | 2356 |
LIMIT 1| ] ); |
2354 | 2357 |
map { push @{ $_ }, prepare_query($form, $dbh, $_->[0]) } @translation_queries; |
2355 | 2358 |
|
2359 |
my $has_wrong_pclass = 0; |
|
2356 | 2360 |
while (my $ref = $sth->fetchrow_hashref('NAME_lc')) { |
2357 | 2361 |
|
2358 | 2362 |
if ($mm_by_id{$ref->{id}}) { |
... | ... | |
2364 | 2368 |
push @{ $ref->{matches} ||= [] }, $::locale->text('EAN') . ': ' . $ref->{ean}; |
2365 | 2369 |
} |
2366 | 2370 |
|
2371 |
$ref->{type_and_classific} = $::request->presenter->type_abbreviation($ref->{part_type}). |
|
2372 |
$::request->presenter->classification_abbreviation($ref->{classification_id}); |
|
2373 |
if (! $ref->{used_for_sale} ) { |
|
2374 |
$has_wrong_pclass = 1; |
|
2375 |
next; |
|
2376 |
} |
|
2367 | 2377 |
# In der Buchungsgruppe ist immer ein Bestandskonto verknuepft, auch wenn |
2368 | 2378 |
# es sich um eine Dienstleistung handelt. Bei Dienstleistungen muss das |
2369 | 2379 |
# Buchungskonto also aus dem Ergebnis rausgenommen werden. |
... | ... | |
2447 | 2457 |
$sth->finish; |
2448 | 2458 |
$_->[1]->finish for @translation_queries; |
2449 | 2459 |
|
2460 |
$form->{is_wrong_pclass} = $has_wrong_pclass; |
|
2450 | 2461 |
foreach my $item (@{ $form->{item_list} }) { |
2451 | 2462 |
my $custom_variables = CVar->get_custom_variables(module => 'IC', |
2452 | 2463 |
trans_id => $item->{id}, |
2453 | 2464 |
dbh => $dbh, |
2454 | 2465 |
); |
2455 |
|
|
2466 |
$form->{is_wrong_pclass} = 0; # one correct type |
|
2456 | 2467 |
map { $item->{"ic_cvar_" . $_->{name} } = $_->{value} } @{ $custom_variables }; |
2457 | 2468 |
} |
2458 |
|
|
2459 | 2469 |
$main::lxdebug->leave_sub(); |
2460 | 2470 |
} |
2461 | 2471 |
|
SL/OE.pm | ||
---|---|---|
1094 | 1094 |
c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, |
1095 | 1095 |
oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe, |
1096 | 1096 |
p.partnumber, p.part_type, p.listprice, o.description, o.qty, |
1097 |
p.classification_id, |
|
1097 | 1098 |
o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.part_type, |
1098 | 1099 |
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost, |
1099 | 1100 |
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription, |
SL/Presenter/Part.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use SL::DB::Part; |
6 |
use SL::DB::Manager::PartsClassification; |
|
6 | 7 |
|
7 | 8 |
use Exporter qw(import); |
8 |
our @EXPORT = qw(part_picker part); |
|
9 |
our @EXPORT = qw(part_picker part select_classification classification_abbreviation type_abbreviation type_and_classification);
|
|
9 | 10 |
|
10 | 11 |
use Carp; |
11 | 12 |
|
... | ... | |
46 | 47 |
$self->html_tag('span', $ret, class => 'part_picker'); |
47 | 48 |
} |
48 | 49 |
|
50 |
# |
|
51 |
# Must be addapted to new type table |
|
52 |
# |
|
53 |
sub type_abbreviation { |
|
54 |
my ($self, $part_type) = @_; |
|
55 |
$main::lxdebug->message(LXDebug->DEBUG2(),"parttype=".$part_type); |
|
56 |
return $::locale->text('Assembly (typeabbreviation)') if $part_type eq 'assembly'; |
|
57 |
return $::locale->text('Part (typeabbreviation)') if $part_type eq 'part'; |
|
58 |
return $::locale->text('Assortment (typeabbreviation)') if $part_type eq 'assortment'; |
|
59 |
return $::locale->text('Service (typeabbreviation)'); |
|
60 |
} |
|
61 |
|
|
62 |
# |
|
63 |
# Translations for Abbreviations: |
|
64 |
# |
|
65 |
# $::locale->text('None (typeabbreviation)') |
|
66 |
# $::locale->text('Purchase (typeabbreviation)') |
|
67 |
# $::locale->text('Sales (typeabbreviation)') |
|
68 |
# $::locale->text('Merchandise (typeabbreviation)') |
|
69 |
# $::locale->text('Production (typeabbreviation)') |
|
70 |
# |
|
71 |
# and for descriptions |
|
72 |
# $::locale->text('Purchase') |
|
73 |
# $::locale->text('Sales') |
|
74 |
# $::locale->text('Merchandise') |
|
75 |
# $::locale->text('Production') |
|
76 |
|
|
77 |
sub classification_abbreviation { |
|
78 |
my ($self, $id) = @_; |
|
79 |
$main::lxdebug->message(LXDebug->DEBUG2(),"classif=".$id); |
|
80 |
return $::locale->text(SL::DB::Manager::PartsClassification->get_abbreviation($id)); |
|
81 |
} |
|
82 |
|
|
83 |
sub select_classification { |
|
84 |
my ($self, $name, %attributes) = @_; |
|
85 |
$attributes{value_key} = 'id'; |
|
86 |
$attributes{title_key} = 'description'; |
|
87 |
my $collection = SL::DB::Manager::PartsClassification->get_all_sorted(); |
|
88 |
$_->description($::locale->text($_->description)) for @{ $collection }; |
|
89 |
return $self->select_tag( $name, $collection, %attributes ); |
|
90 |
} |
|
91 |
|
|
49 | 92 |
1; |
50 | 93 |
|
51 | 94 |
__END__ |
SL/WH.pm | ||
---|---|---|
368 | 368 |
push @filter_vars, like($filter{description}); |
369 | 369 |
} |
370 | 370 |
|
371 |
if ($filter{classification_id}) { |
|
372 |
push @filter_ary, "p.classification_id = ?"; |
|
373 |
push @filter_vars, $filter{classification_id}; |
|
374 |
} |
|
375 |
|
|
371 | 376 |
if ($filter{chargenumber}) { |
372 | 377 |
push @filter_ary, "i1.chargenumber ILIKE ?"; |
373 | 378 |
push @filter_vars, like($filter{chargenumber}); |
... | ... | |
426 | 431 |
"qty" => "ABS(SUM(i1.qty))", |
427 | 432 |
"partnumber" => "p.partnumber", |
428 | 433 |
"partdescription" => "p.description", |
434 |
"classification_id" => "p.classification_id", |
|
435 |
"assembly" => "p.assembly", |
|
436 |
"inventory_accno_id" => "p.inventory_accno_id", |
|
429 | 437 |
"bindescription" => "b.description", |
430 | 438 |
"chargenumber" => "i1.chargenumber", |
431 | 439 |
"bestbefore" => "i1.bestbefore", |
... | ... | |
457 | 465 |
"warehouse_from" => "'$filter{na}'", |
458 | 466 |
}; |
459 | 467 |
|
468 |
$form->{l_classification_id} = 'Y'; |
|
469 |
$form->{l_assembly} = 'Y'; |
|
470 |
$form->{l_inventory_accno_id} = 'Y'; |
|
460 | 471 |
$form->{l_invoice_id} = $form->{l_oe_id} if $form->{l_oe_id}; |
461 | 472 |
|
462 | 473 |
# build the select clauses. |
... | ... | |
614 | 625 |
# - warehouse_id - will return matches with this warehouse_id only |
615 | 626 |
# - partnumber - will return only matches where the given string is a substring of the partnumber |
616 | 627 |
# - partsid - will return matches with this parts_id only |
628 |
# - classification_id - will return matches with this parts with this classification only |
|
617 | 629 |
# - description - will return only matches where the given string is a substring of the description |
618 | 630 |
# - chargenumber - will return only matches where the given string is a substring of the chargenumber |
619 | 631 |
# - bestbefore - will return only matches with this bestbefore date |
... | ... | |
665 | 677 |
push @filter_vars, like($filter{partnumber}); |
666 | 678 |
} |
667 | 679 |
|
680 |
if ($filter{classification_id}) { |
|
681 |
push @filter_ary, "p.classification_id = ?"; |
|
682 |
push @filter_vars, $filter{classification_id}; |
|
683 |
} |
|
684 |
|
|
668 | 685 |
if ($filter{description}) { |
669 | 686 |
push @filter_ary, "p.description ILIKE ?"; |
670 | 687 |
push @filter_vars, like($filter{description}); |
... | ... | |
737 | 754 |
"warehouseid" => "i.warehouse_id", |
738 | 755 |
"partnumber" => "p.partnumber", |
739 | 756 |
"partdescription" => "p.description", |
757 |
"classification_id" => "p.classification_id", |
|
758 |
"assembly" => "p.assembly", |
|
759 |
"inventory_accno_id" => "p.inventory_accno_id", |
|
740 | 760 |
"bindescription" => "b.description", |
741 | 761 |
"binid" => "b.id", |
742 | 762 |
"chargenumber" => "i.chargenumber", |
... | ... | |
747 | 767 |
"partunit" => "p.unit", |
748 | 768 |
"stock_value" => "p.lastcost / COALESCE(pfac.factor, 1)", |
749 | 769 |
); |
770 |
$form->{l_classification_id} = 'Y'; |
|
771 |
$form->{l_assembly} = 'Y'; |
|
772 |
$form->{l_inventory_accno_id} = 'Y'; |
|
750 | 773 |
my $select_clause = join ', ', map { +/^l_/; "$select_tokens{$'} AS $'" } |
751 | 774 |
( grep( { !/qty/ and /^l_/ and $form->{$_} eq 'Y' } keys %$form), |
752 | 775 |
qw(l_parts_id l_qty l_partunit) ); |
bin/mozilla/ic.pl | ||
---|---|---|
100 | 100 |
$form->{lastsort} = ""; # memory for which table was sort at last time |
101 | 101 |
$form->{ndxs_counter} = 0; # counter for added entries to top100 |
102 | 102 |
|
103 |
my %is_xyz = map { +"is_$_" => ($form->{searchitems} eq $_) } qw(part service assembly); |
|
103 |
# for seach all possibibilities, is_service only used as UNLESS so == 0 |
|
104 |
my %is_xyz = ("is_part" => 1, "is_service" => 0, "is_assembly" =>1 ); |
|
104 | 105 |
|
105 | 106 |
$form->{title} = (ucfirst $form->{searchitems}) . "s"; |
107 |
$form->{title} =~ s/ys$/ies/; |
|
106 | 108 |
$form->{title} = $locale->text($form->{title}); |
107 |
$form->{title} = $locale->text('Assemblies') if ($is_xyz{is_assembly}); |
|
108 | 109 |
|
109 | 110 |
$form->{CUSTOM_VARIABLES} = CVar->get_configs('module' => 'IC'); |
110 | 111 |
($form->{CUSTOM_VARIABLES_FILTER_CODE}, |
... | ... | |
233 | 234 |
# searchitems=part revers=0 lastsort='' |
234 | 235 |
# |
235 | 236 |
# filter: |
236 |
# partnumber ean description partsgroup serialnumber make model drawing microfiche |
|
237 |
# partnumber ean description partsgroup classification serialnumber make model drawing microfiche
|
|
237 | 238 |
# transdatefrom transdateto |
238 | 239 |
# |
239 | 240 |
# radio: |
... | ... | |
300 | 301 |
'unit' => { 'text' => $locale->text('Unit'), }, |
301 | 302 |
'weight' => { 'text' => $locale->text('Weight'), }, |
302 | 303 |
'shop' => { 'text' => $locale->text('Shop article'), }, |
304 |
'type_and_classific' => { 'text' => $locale->text('Type'), }, |
|
303 | 305 |
'projectnumber' => { 'text' => $locale->text('Project Number'), }, |
304 | 306 |
'projectdescription' => { 'text' => $locale->text('Project Description'), }, |
305 | 307 |
); |
... | ... | |
424 | 426 |
$form->{l_linetotallastcost} = $form->{searchitems} eq 'assembly' && !$form->{bom} ? "" : 'Y' if $form->{l_lastcost}; |
425 | 427 |
$form->{l_linetotallistprice} = "Y" if $form->{l_listprice}; |
426 | 428 |
} |
429 |
$form->{"l_type_and_classific"} = "Y"; |
|
427 | 430 |
|
428 |
if ($form->{searchitems} eq 'service') {
|
|
431 |
if ($form->{l_service} && !$form->{l_assembly} && !$form->{l_part}) {
|
|
429 | 432 |
|
430 | 433 |
# remove bin, weight and rop from list |
431 | 434 |
map { $form->{"l_$_"} = "" } qw(bin weight rop); |
... | ... | |
472 | 475 |
IC->all_parts(\%myconfig, \%$form); |
473 | 476 |
|
474 | 477 |
my @columns = qw( |
475 |
partnumber description notes partsgroup bin onhand rop soldtotal unit listprice |
|
478 |
partnumber type_and_classific description notes partsgroup bin onhand rop soldtotal unit listprice
|
|
476 | 479 |
linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost |
477 | 480 |
priceupdate weight image drawing microfiche invnumber ordnumber quonumber |
478 | 481 |
transdate name serialnumber deliverydate ean projectnumber projectdescription |
... | ... | |
505 | 508 |
|
506 | 509 |
my @hidden_variables = ( |
507 | 510 |
qw(l_subtotal l_linetotal searchitems itemstatus bom l_pricegroups insertdatefrom insertdateto), |
511 |
qw(l_type_and_classific classification_id), |
|
508 | 512 |
@itemstatus_keys, |
509 | 513 |
@callback_keys, |
510 | 514 |
map({ "cvar_$_->{name}" } @searchable_custom_variables), |
... | ... | |
531 | 535 |
'part' => $locale->text('part_list'), |
532 | 536 |
'service' => $locale->text('service_list'), |
533 | 537 |
'assembly' => $locale->text('assembly_list'), |
538 |
'article' => $locale->text('article_list'), |
|
534 | 539 |
); |
535 | 540 |
|
536 | 541 |
$report->set_options('raw_top_info_text' => $form->parse_html_template('ic/generate_report_top', { options => \@options }), |
537 | 542 |
'raw_bottom_info_text' => $form->parse_html_template('ic/generate_report_bottom'), |
538 | 543 |
'output_format' => 'HTML', |
539 | 544 |
'title' => $form->{title}, |
540 |
'attachment_basename' => $attachment_basenames{$form->{searchitems}} . strftime('_%Y%m%d', localtime time),
|
|
545 |
'attachment_basename' => 'article_list' . strftime('_%Y%m%d', localtime time),
|
|
541 | 546 |
); |
542 | 547 |
$report->set_options_from_form(); |
543 | 548 |
$locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv'; |
... | ... | |
647 | 652 |
map { $row->{$_}{link} = $ref->{$_} } qw(drawing microfiche); |
648 | 653 |
|
649 | 654 |
$row->{notes}{data} = SL::HTML::Util->strip($ref->{notes}); |
655 |
$row->{type_and_classific}{data} = $::request->presenter->type_abbreviation($ref->{part_type}). |
|
656 |
$::request->presenter->classification_abbreviation($ref->{classification_id}); |
|
650 | 657 |
|
651 | 658 |
$report->add_data($row); |
652 | 659 |
|
... | ... | |
658 | 665 |
(!$next_ref->{assemblyitem} && ($same_item ne $next_ref->{ $form->{sort} })))) { |
659 | 666 |
my $row = { map { $_ => { 'class' => 'listsubtotal', } } @columns }; |
660 | 667 |
|
661 |
if (($form->{searchitems} ne 'assembly') || !$form->{bom}) {
|
|
668 |
if ( !$form->{l_assembly} || !$form->{bom}) {
|
|
662 | 669 |
$row->{soldtotal}->{data} = $form->format_amount(\%myconfig, $subtotals{soldtotal}); |
663 | 670 |
} |
664 | 671 |
|
... | ... | |
696 | 703 |
my ($column_index, $subtotalonhand, $subtotalsellprice, $subtotallastcost, $subtotallistprice) = @_; |
697 | 704 |
|
698 | 705 |
map { $column_data{$_} = "<td> </td>" } @{ $column_index }; |
699 |
$$subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{bom});
|
|
706 |
$$subtotalonhand = 0 if ($form->{l_assembly} && $form->{bom});
|
|
700 | 707 |
|
701 | 708 |
$column_data{onhand} = |
702 | 709 |
"<th class=listsubtotal align=right>" |
... | ... | |
938 | 945 |
my (@column_index); |
939 | 946 |
my ($nochange, $callback, $previousform, $linetotal, $line_purchase_price, $href); |
940 | 947 |
|
941 |
@column_index = qw(runningnumber qty unit bom partnumber description partsgroup lastcost total); |
|
948 |
@column_index = qw(runningnumber qty unit bom partnumber type_and_classific description partsgroup lastcost total);
|
|
942 | 949 |
|
943 | 950 |
if ($form->{previousform}) { |
944 | 951 |
$nochange = 1; |
945 |
@column_index = qw(qty unit bom partnumber description partsgroup total); |
|
952 |
@column_index = qw(qty unit bom partnumber type_and_classific description partsgroup total);
|
|
946 | 953 |
} else { |
947 | 954 |
|
948 | 955 |
# change callback |
... | ... | |
965 | 972 |
} |
966 | 973 |
|
967 | 974 |
my %header = ( |
968 |
runningnumber => { text => $locale->text('No.'), nowrap => 1, width => '5%', align => 'left',}, |
|
969 |
qty => { text => $locale->text('Qty'), nowrap => 1, width => '10%', align => 'left',}, |
|
970 |
unit => { text => $locale->text('Unit'), nowrap => 1, width => '5%', align => 'left',}, |
|
971 |
partnumber => { text => $locale->text('Part Number'), nowrap => 1, width => '20%', align => 'left',}, |
|
972 |
description => { text => $locale->text('Part Description'), nowrap => 1, width => '50%', align => 'left',}, |
|
973 |
lastcost => { text => $locale->text('Purchase Prices'), nowrap => 1, width => '50%', align => 'right',}, |
|
974 |
total => { text => $locale->text('Sale Prices'), nowrap => 1, align => 'right',}, |
|
975 |
bom => { text => $locale->text('BOM'), align => 'center',}, |
|
976 |
partsgroup => { text => $locale->text('Group'), align => 'left',}, |
|
975 |
runningnumber => { text => $locale->text('No.'), nowrap => 1, width => '5%', align => 'left',}, |
|
976 |
qty => { text => $locale->text('Qty'), nowrap => 1, width => '10%', align => 'left',}, |
|
977 |
unit => { text => $locale->text('Unit'), nowrap => 1, width => '5%', align => 'left',}, |
|
978 |
partnumber => { text => $locale->text('Part Number'), nowrap => 1, width => '20%', align => 'left',}, |
|
979 |
type_and_classific => { text => $locale->text('Typ'), nowrap => 1, width => '5%' , align => 'left',}, |
|
980 |
description => { text => $locale->text('Part Description'), nowrap => 1, width => '50%', align => 'left',}, |
|
981 |
lastcost => { text => $locale->text('Purchase Prices'), nowrap => 1, width => '45%', align => 'right',}, |
|
982 |
total => { text => $locale->text('Sale Prices'), nowrap => 1, align => 'right',}, |
|
983 |
bom => { text => $locale->text('BOM'), align => 'center',}, |
|
984 |
partsgroup => { text => $locale->text('Group'), align => 'left',}, |
|
977 | 985 |
); |
978 | 986 |
|
979 | 987 |
my @ROWS; |
... | ... | |
991 | 999 |
$linetotal = $form->format_amount(\%myconfig, $linetotal, 2); |
992 | 1000 |
$line_purchase_price = $form->format_amount(\%myconfig, $line_purchase_price, 2); |
993 | 1001 |
$href = build_std_url("action=edit", qq|id=$form->{"id_$i"}|, "rowcount=$numrows", "currow=$i", "previousform=$previousform"); |
994 |
map { $row{$_}{data} = "" } qw(qty unit partnumber description bom partsgroup runningnumber); |
|
1002 |
map { $row{$_}{data} = "" } qw(qty unit partnumber typ_and_class description bom partsgroup runningnumber);
|
|
995 | 1003 |
|
996 | 1004 |
# last row |
997 | 1005 |
if (($i >= 1) && ($i == $numrows)) { |
... | ... | |
1011 | 1019 |
$row{qty}{align} = 'right'; |
1012 | 1020 |
} else { |
1013 | 1021 |
$row{partnumber}{data} = qq|$form->{"partnumber_$i"}|; |
1014 |
$row{partnumber}{link} = $href;
|
|
1022 |
$row{partnumber}{link} = $href; |
|
1015 | 1023 |
$row{qty}{data} = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|; |
1016 | 1024 |
$row{runningnumber}{data} = qq|<input name="runningnumber_$i" size=3 value="$i">|; |
1017 | 1025 |
$row{bom}{data} = sprintf qq|<input name="bom_$i" type=checkbox class=checkbox value=1 %s>|, |
1018 | 1026 |
$form->{"bom_$i"} ? 'checked' : ''; |
1019 | 1027 |
} |
1028 |
# type impl $row{type_and_classific}{data} = $::request->presenter->type_abbreviation($form->{"type_$i"}). |
|
1029 |
$row{type_and_classific}{data} = $::request->presenter->type_abbreviation($form->{"assembly_$i"},$form->{"inventory_accno_id_$i"}). |
|
1030 |
$::request->presenter->classification_abbreviation($form->{"classification_id_$i"}); |
|
1020 | 1031 |
push @row_hiddens, qw(unit description partnumber partsgroup); |
1021 | 1032 |
$row{unit}{data} = $form->{"unit_$i"}; |
1022 | 1033 |
#Bei der Artikelbeschreibung und Warengruppe können Sonderzeichen verwendet |
bin/mozilla/io.pl | ||
---|---|---|
159 | 159 |
|
160 | 160 |
# column_index |
161 | 161 |
my @header_sort = qw( |
162 |
runningnumber partnumber description ship ship_missing qty price_factor |
|
162 |
runningnumber partnumber type_and_classific description ship ship_missing qty price_factor
|
|
163 | 163 |
unit weight price_source sellprice discount linetotal |
164 | 164 |
bin stock_in_out |
165 | 165 |
); |
... | ... | |
169 | 169 |
my %column_def = ( |
170 | 170 |
runningnumber => { width => 5, value => $locale->text('No.'), display => 1, }, |
171 | 171 |
partnumber => { width => 8, value => $locale->text('Number'), display => 1, }, |
172 |
type_and_classific |
|
173 |
=> { width => 2, value => $locale->text('Type'), display => 1, }, |
|
172 | 174 |
description => { width => 30, value => $locale->text('Part Description'), display => 1, }, |
173 | 175 |
ship => { width => 5, value => $locale->text('Delivered'), display => $is_s_p_order, }, |
174 | 176 |
ship_missing => { width => 5, value => $locale->text('Not delivered'), display => $show_ship_missing, }, |
... | ... | |
295 | 297 |
my $rows = $form->numtextrows($form->{"description_$i"}, 30, 6); |
296 | 298 |
|
297 | 299 |
# quick delete single row |
298 |
$column_data{runningnumber} .= q|<a onclick= "$('#partnumber_| . $i . q|').val(''); $('#update_button').click();">| .
|
|
300 |
$column_data{runningnumber} = q|<a onclick= "$('#partnumber_| . $i . q|').val(''); $('#update_button').click();">| .
|
|
299 | 301 |
q|<img height="10px" width="10px" src="image/cross.png" alt="| . $locale->text('Remove') . q|"></a> |; |
300 | 302 |
$column_data{runningnumber} .= $cgi->textfield(-name => "runningnumber_$i", -id => "runningnumber_$i", -size => 5, -value => $i); # HuT |
301 | 303 |
|
302 | 304 |
|
303 | 305 |
$column_data{partnumber} = $cgi->textfield(-name => "partnumber_$i", -id => "partnumber_$i", -size => 12, -value => $form->{"partnumber_$i"}); |
306 |
# type impl $column_data{type_and_classific} = $::request->presenter->type_abbreviation(($form->{"type_$i"}). |
|
307 |
$column_data{type_and_classific} = $::request->presenter->type_abbreviation($form->{"assembly_$i"},$form->{"inventory_accno_id_$i"}). |
|
308 |
$::request->presenter->classification_abbreviation($form->{"classification_id_$i"}) if $form->{"id_$i"}; |
|
304 | 309 |
$column_data{description} = (($rows > 1) # if description is too large, use a textbox instead |
305 | 310 |
? $cgi->textarea( -name => "description_$i", -id => "description_$i", -default => $form->{"description_$i"}, -rows => $rows, -columns => 30) |
306 | 311 |
: $cgi->textfield(-name => "description_$i", -id => "description_$i", -value => $form->{"description_$i"}, -size => 30)) |
... | ... | |
665 | 670 |
map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded}; |
666 | 671 |
|
667 | 672 |
$form->{creditremaining} -= $amount; |
668 |
|
|
669 | 673 |
$form->{"runningnumber_$i"} = $i; |
670 | 674 |
|
671 | 675 |
# format amounts |
bin/mozilla/wh.pl | ||
---|---|---|
677 | 677 |
$form->{report_generator_output_format} = 'HTML' if !$form->{report_generator_output_format}; |
678 | 678 |
|
679 | 679 |
my %filter; |
680 |
my @columns = qw(trans_id date warehouse_from bin_from warehouse_to bin_to partnumber partdescription chargenumber bestbefore trans_type comment qty employee oe_id projectnumber);
|
|
680 |
my @columns = qw(trans_id date warehouse_from bin_from warehouse_to bin_to partnumber type_and_classific partdescription chargenumber bestbefore trans_type comment qty unit partunit employee oe_id projectnumber);
|
|
681 | 681 |
|
682 | 682 |
# filter stuff |
683 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partnumber description chargenumber bestbefore); |
|
683 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id classification_id partnumber description chargenumber bestbefore);
|
|
684 | 684 |
|
685 | 685 |
$filter{qty_op} = WH->convert_qty_op($form->{qty_op}); |
686 | 686 |
if ($filter{qty_op}) { |
... | ... | |
696 | 696 |
|
697 | 697 |
my @hidden_variables = map { "l_${_}" } @columns; |
698 | 698 |
push @hidden_variables, qw(warehouse_id bin_id partnumber description chargenumber bestbefore qty_op qty qty_unit fromdate todate); |
699 |
push @hidden_variables, qw(classification_id); |
|
699 | 700 |
|
700 | 701 |
my %column_defs = ( |
701 | 702 |
'date' => { 'text' => $locale->text('Date'), }, |
... | ... | |
707 | 708 |
'bin_from' => { 'text' => $locale->text('Bin From'), }, |
708 | 709 |
'bin_to' => { 'text' => $locale->text('Bin To'), }, |
709 | 710 |
'partnumber' => { 'text' => $locale->text('Part Number'), }, |
711 |
'type_and_classific' |
|
712 |
=> { 'text' => $locale->text('Type'), }, |
|
710 | 713 |
'partdescription' => { 'text' => $locale->text('Part Description'), }, |
711 | 714 |
'chargenumber' => { 'text' => $locale->text('Charge Number'), }, |
712 | 715 |
'bestbefore' => { 'text' => $locale->text('Best Before'), }, |
... | ... | |
725 | 728 |
my %column_alignment = map { $_ => 'right' } qw(qty); |
726 | 729 |
|
727 | 730 |
map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns; |
731 |
$column_defs{type_and_classific}->{visible} = 1; |
|
732 |
$column_defs{type_and_classific}->{link} =''; |
|
728 | 733 |
|
729 | 734 |
$report->set_columns(%column_defs); |
730 | 735 |
$report->set_column_order(@columns); |
... | ... | |
763 | 768 |
my $idx = 0; |
764 | 769 |
|
765 | 770 |
foreach my $entry (@contents) { |
771 |
# type impl $entry->{type_and_classific} = $::request->presenter->type_abbreviation($entry->{type}). |
|
772 |
$entry->{type_and_classific} = $::request->presenter->type_abbreviation($entry->{assembly},$entry->{inventory_accno_id}). |
|
773 |
$::request->presenter->classification_abbreviation($entry->{classification_id}); |
|
766 | 774 |
$entry->{qty} = $form->format_amount_units('amount' => $entry->{qty}, |
767 | 775 |
'part_unit' => $entry->{partunit}, |
768 | 776 |
'conv_units' => 'convertible'); |
... | ... | |
852 | 860 |
my $sort_col = $form->{sort}; |
853 | 861 |
|
854 | 862 |
my %filter; |
855 |
my @columns = qw(warehousedescription bindescription partnumber partdescription chargenumber bestbefore qty stock_value);
|
|
863 |
my @columns = qw(warehousedescription bindescription partnumber type_and_classific partdescription chargenumber bestbefore comment qty partunit stock_value);
|
|
856 | 864 |
|
857 | 865 |
# filter stuff |
858 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partstypes_id partnumber description chargenumber bestbefore date include_invalid_warehouses);
|
|
866 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id classification_id partnumber description chargenumber bestbefore date include_invalid_warehouses);
|
|
859 | 867 |
|
860 | 868 |
# show filter stuff also in report |
861 | 869 |
my @options; |
870 |
my $currentdate = $form->current_date(\%myconfig); |
|
871 |
push @options, $locale->text('Printdate') . " : ".$locale->date(\%myconfig, $currentdate, 1); |
|
872 |
|
|
862 | 873 |
# dispatch all options |
863 | 874 |
my $dispatch_options = { |
864 | 875 |
warehouse_id => sub { push @options, $locale->text('Warehouse') . " : " . |
... | ... | |
866 | 877 |
bin_id => sub { push @options, $locale->text('Bin') . " : " . |
867 | 878 |
SL::DB::Manager::Bin->find_by(id => $form->{bin_id})->description}, |
868 | 879 |
partnumber => sub { push @options, $locale->text('Partnumber') . " : $form->{partnumber}"}, |
880 |
classification_id => sub { push @options, $locale->text('Parts Classification'). " : ". |
|
881 |
SL::DB::Manager::PartsClassification->get_first(where => [ id => $form->{classification_id} ] )->description; }, |
|
869 | 882 |
description => sub { push @options, $locale->text('Description') . " : $form->{description}"}, |
870 | 883 |
chargenumber => sub { push @options, $locale->text('Charge Number') . " : $form->{chargenumber}"}, |
871 | 884 |
bestbefore => sub { push @options, $locale->text('Best Before') . " : $form->{bestbefore}"}, |
872 |
date => sub { push @options, $locale->text('Date') . " : $form->{date}"}, |
|
873 | 885 |
include_invalid_warehouses => sub { push @options, $locale->text('Include invalid warehouses ')}, |
874 | 886 |
}; |
875 | 887 |
foreach (keys %filter) { |
876 | 888 |
$dispatch_options->{$_}->() if $dispatch_options->{$_}; |
877 | 889 |
} |
890 |
push @options, $locale->text('Stock Qty for Date') . " " . $locale->date(\%myconfig, $form->{date}?$form->{date}:$currentdate, 1); |
|
891 |
|
|
878 | 892 |
# / end show filter stuff also in report |
879 | 893 |
|
880 | 894 |
$filter{qty_op} = WH->convert_qty_op($form->{qty_op}); |
... | ... | |
895 | 909 |
my @hidden_variables = map { "l_${_}" } @columns; |
896 | 910 |
push @hidden_variables, qw(warehouse_id bin_id partnumber partstypes_id description chargenumber bestbefore qty_op qty qty_unit partunit l_warehousedescription l_bindescription); |
897 | 911 |
push @hidden_variables, qw(include_empty_bins subtotal include_invalid_warehouses date); |
912 |
push @hidden_variables, qw(classification_id); |
|
898 | 913 |
|
899 | 914 |
my %column_defs = ( |
900 | 915 |
'warehousedescription' => { 'text' => $locale->text('Warehouse'), }, |
901 | 916 |
'bindescription' => { 'text' => $locale->text('Bin'), }, |
902 | 917 |
'partnumber' => { 'text' => $locale->text('Part Number'), }, |
918 |
'type_and_classific' => { 'text' => $locale->text('Type'), }, |
|
903 | 919 |
'partdescription' => { 'text' => $locale->text('Part Description'), }, |
904 | 920 |
'chargenumber' => { 'text' => $locale->text('Charge Number'), }, |
905 | 921 |
'bestbefore' => { 'text' => $locale->text('Best Before'), }, |
... | ... | |
916 | 932 |
|
917 | 933 |
map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns; |
918 | 934 |
|
935 |
$column_defs{type_and_classific}->{visible} = 1; |
|
936 |
$column_defs{type_and_classific}->{link} =''; |
|
937 |
|
|
919 | 938 |
$report->set_columns(%column_defs); |
920 | 939 |
$report->set_column_order(@columns); |
921 | 940 |
|
... | ... | |
950 | 969 |
my $last_nr = $first_nr + $pages->{per_page}; |
951 | 970 |
|
952 | 971 |
foreach my $entry (@contents) { |
972 |
|
|
973 |
# type impl $entry->{type_and_classific} = $::request->presenter->type_abbreviation($entry->{type}). |
|
974 |
$entry->{type_and_classific} = $::request->presenter->type_abbreviation($entry->{assembly},$entry->{inventory_accno_id}). |
|
975 |
$::request->presenter->classification_abbreviation($entry->{classification_id}); |
|
953 | 976 |
map { $subtotals{$_} += $entry->{$_} } @subtotals_columns; |
954 | 977 |
$total_stock_value += $entry->{stock_value} * 1; |
955 | 978 |
$entry->{qty} = $form->format_amount(\%myconfig, $entry->{qty}); |
doc/changelog | ||
---|---|---|
4 | 4 |
|
5 | 5 |
2016-xx-xx - Release 3.4.x Unstable |
6 | 6 |
|
7 |
große Features: |
|
8 |
|
|
9 |
- Artikel-Klassifizierung |
|
10 |
|
|
11 |
Die Klassifizierung von Artikeln |
|
12 |
Sie dient einer weiteren Gliederung um zum Beispiel den Einkauf vom Verkauf zu trennen, etc. |
|
13 |
|
|
14 |
Gekennzeichnet durch eine Beschreibung (z.B. "Einkauf") und ein Kürzel (z.B. "E") |
|
15 |
Flexibel änderbar und erweiterbar. |
|
16 |
|
|
17 |
- Neue Datenbanktablle und Rose-Objekte, sowie Controller zum Bearbeiten der Tabelle |
|
18 |
|
|
19 |
- Zwei-Zeichen Abkürzung: |
|
20 |
|
|
21 |
Der Typ des Artikel und die Klassifizierung werden durch zwei Buchstaben dargestellt. |
|
22 |
Der erste Buchstabe ist eine Lokalisierung des Typs des Artikel ('P','A','S') , |
|
23 |
deutch 'W', 'E', und 'D' für Ware Erzeugnis oder Dienstleistung, ggf. weitere Typen. |
|
24 |
Der zweite Buchstabe ist eine Lokalisierung der Klassifizierungsabkürzung (abbreviation). |
|
25 |
|
|
26 |
Die Abkürzungen sind aus dem Part Presenter abholbar: |
|
27 |
- SL::Presenter::Part->type_abbreviation($assembly,inventory_accno_id) bzw |
|
28 |
bei neuer Type Implementierung SL::Presenter::Part->type_abbreviation($type_id) |
|
29 |
- SL::Presenter::Part->classification_abbreviation($classification_id) |
|
30 |
|
|
31 |
Wenn im ERP-Dokument nach einer Artikelnummer oder Beschreibung gesucht wird, |
|
32 |
diese in den Stammdaten vorhanden ist, |
|
33 |
aber der Artikeltyp leer oder falsch ist, bzw im Typ for_purchase bzw for_sale nicht gesetzt ist, |
|
34 |
wird die Fehlermeldung "Gesuchter Artikel ist nicht für den Einkauf bzw Verkauf" gemeldet |
|
35 |
|
|
36 |
Anpassung des CSV Import, |
|
37 |
nun wird alternativ zur 'type'-Spalte die 'pclass'-Spalte mit zwei Buchstaben geparsed und entsprechend |
|
38 |
classification_id,assembly sowie inventory_accno_id gesetzt (oder type_id falls neue Implementierung eingebaut). |
|
39 |
|
|
7 | 40 |
kleinere neue Features und Detailverbesserungen: |
8 | 41 |
|
9 | 42 |
- SEPA Überweisungen zusätzlich Kunden- oder Lieferantennummer im Verwendungszweck vorbelegen |
locale/de/all | ||
---|---|---|
297 | 297 |
'Article' => 'Artikel', |
298 | 298 |
'Article Code' => 'Artikelkürzel', |
299 | 299 |
'Article Code missing!' => 'Artikelkürzel fehlt', |
300 |
'Article classification' => 'Artikel-Klassifizierung', |
|
300 | 301 |
'Article type' => 'Artikeltyp', |
301 | 302 |
'Articles' => 'Artikel', |
302 | 303 |
'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.', |
303 | 304 |
'Assemblies' => 'Erzeugnisse', |
304 |
'Assemblies can not be imported (yet). But the type column is used for sanity checks on price updates in order to prevent that articles with the wrong type will be updated.' => 'Erzeugnisse können (noch) nicht importiert werden. Aber die Typ-Spalte wird für Plausibilitätsprüfungen bei Preisaktualisierungen verwendet, um zu verhindern, dass Artikel vom falschen Typ aktualisiert werden.', |
|
305 | 305 |
'Assembly' => 'Erzeugnis', |
306 |
'Assembly (typeabbreviation)' => 'E', |
|
306 | 307 |
'Assembly Description' => 'Erzeugnis-Beschreibung', |
307 | 308 |
'Assembly Number' => 'Erzeugnis-Nummer', |
308 | 309 |
'Assembly Number missing!' => 'Erzeugnisnummer fehlt!', |
... | ... | |
662 | 663 |
'Create a new delivery term' => 'Neue Lieferbedingungen anlegen', |
663 | 664 |
'Create a new department' => 'Eine neue Abteilung erfassen', |
664 | 665 |
'Create a new group' => 'Neue Benutzergruppe erfassen', |
666 |
'Create a new parts classification' => 'Erzeuge eine neue Artikel-Klassifizierung', |
|
665 | 667 |
'Create a new payment term' => 'Neue Zahlungsbedingungen anlegen', |
666 | 668 |
'Create a new predefined text' => 'Einen neuen vordefinierten Textblock anlegen', |
667 | 669 |
'Create a new price rule' => 'Neue Preisregel anlegen', |
... | ... | |
1108 | 1110 |
'Edit general settings' => 'Grundeinstellungen bearbeiten', |
1109 | 1111 |
'Edit greetings' => 'Anreden bearbeiten', |
1110 | 1112 |
'Edit note' => 'Notiz bearbeiten', |
1113 |
'Edit parts classification' => 'Bearbeite eine Artikel-Klassifizierung', |
|
1111 | 1114 |
'Edit payment term' => 'Zahlungsbedingungen bearbeiten', |
1112 | 1115 |
'Edit picture' => 'Bild bearbeiten', |
1113 | 1116 |
'Edit predefined text' => 'Vordefinierten Textblock bearbeiten', |
... | ... | |
1444 | 1447 |
'If all of the following match' => 'Wenn alle der folgenden Bedingungen zutreffen', |
1445 | 1448 |
'If amounts differ more than "Maximal amount difference" (see settings), this item is marked as invalid.' => 'Weichen die Beträge mehr als die "maximale Betragsabweichung" (siehe Einstellungen) ab, so wird diese Position als ungültig markiert.', |
1446 | 1449 |
'If checked the taxkey will not be exported in the DATEV Export, but only IF chart taxkeys differ from general ledger taxkeys' => 'Falls angehakt wird der DATEV-Steuerschlüssel bei Buchungen auf dieses Konto nicht beim DATEV-Export mitexportiert, allerdings nur wenn zusätzlich der Konto-Steuerschlüssel vom Buchungs (Hauptbuch) Steuerschlüssel abweicht', |
1450 |
'If column \'pclass\' is present the article type is then irrelevant or used as default ' => 'Falls Spalte \'pclass\' existiert, wird dies nur als default genommen', |
|
1447 | 1451 |
'If configured this bin will be preselected for all new parts. Also this bin will be used as the master default bin, if default transfer out with master bin is activated.' => 'Falls konfiguriert, wird dieses Lager mit Lagerplatz für neu angelegte Waren vorausgewählt.', |
1448 | 1452 |
'If disabled purchase delivery orders can only be created by conversion from existing requests for quotations and purchase orders.' => 'Falls deaktiviert, so können Einkaufslieferscheine nur durch Umwandlung aus bestehenden Preisanfragen und Lieferantenaufträgen angelegt werden.', |
1449 | 1453 |
'If disabled purchase invoices can only be created by conversion from existing requests for quotations, purchase orders and purchase delivery orders.' => 'Falls deaktiviert, so können Einkaufsrechnungen nur durch Umwandlung aus bestehenden Preisanfragen, Lieferantenaufträgen und Einkaufslieferscheinen angelegt werden.', |
... | ... | |
1455 | 1459 |
'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.', |
1456 | 1460 |
'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).', |
1457 | 1461 |
'If missing then the start date will be used.' => 'Falls es fehlt, so wird die erste Rechnung für das Startdatum erzeugt.', |
1458 |
'If the article type is set to \'mixed\' then a column called \'type\' must be present.' => 'Falls der Artikeltyp auf \'gemischt\' gestellt wird, muss eine Spalte namens \'type\' vorhanden sein.',
|
|
1462 |
'If the article type is set to \'mixed\' then a column called \'type\' or called \'pclass\' must be present.' => 'Falls der Artikeltyp auf \'mixed\' eingestellt muß entwder die Spale \'type\' oder die Spalte \'pclass\' vorhanden sein',
|
|
1459 | 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 über Mahngebühren und Zinsen für ein Mahnlevel aktiviert ist, so werden die folgenden Konten für die Rechnung benutzt.', |
1460 | 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önnen Sie hier den Namen und das Passwort des Datenbankadministratoraccounts angeben:', |
1461 | 1465 |
'If the default transfer out always succeed use this bin for negative stock quantity.' => 'Standardlagerplatz für Auslagern ohne Prüfung auf Bestand', |
... | ... | |
1572 | 1576 |
'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.', |
1573 | 1577 |
'Italy' => 'Italien', |
1574 | 1578 |
'Item deleted!' => 'Artikel gelöscht!', |
1579 |
'Item does not exists in File' => 'Gesuchter Artikel nicht in den Stammdaten vorhanden.', |
|
1575 | 1580 |
'Item mode' => 'Artikelmodus', |
1576 | 1581 |
'Item multi selection with qty' => 'Artikel-Mehrfachauswahl mit Menge', |
1577 |
'Item not on file!' => 'Dieser Artikel ist nicht in der Datenbank!', |
|
1578 | 1582 |
'Item values' => 'Artikelwerte', |
1579 | 1583 |
'Item variables' => 'Artikelvariablen', |
1580 | 1584 |
'Jahresverkehrszahlen neu' => 'Jahresverkehrszahlen neu', |
... | ... | |
1735 | 1739 |
'Media \'#1\' is not supported yet/anymore.' => 'Das Medium \'#1\' wird noch nicht oder nicht mehr unterstützt.', |
1736 | 1740 |
'Medium Number' => 'Datenträgernummer', |
1737 | 1741 |
'Memo' => 'Memo', |
1742 |
'Merchandise' => 'Handelsware', |
|
1743 |
'Merchandise (typeabbreviation)' => 'H', |
|
1738 | 1744 |
'Message' => 'Nachricht', |
1739 | 1745 |
'Method' => 'Verfahren', |
1740 | 1746 |
'Microfiche' => 'Mikrofilm', |
... | ... | |
1751 | 1757 |
'Missing taxkeys in invoices with taxes.' => 'Fehlende Steuerschlüssel in Rechnungen mit Steuern', |
1752 | 1758 |
'Missing transport cost: #1 Are you sure?' => 'Fehlender Transportkosten-Artikel #1 Trotzdem speichern?', |
1753 | 1759 |
'Mitarbeiter' => 'Mitarbeiter', |
1754 |
'Mixed (requires column "type")' => 'Gemischt (erfordert Spalte "type")',
|
|
1760 |
'Mixed (requires column "type" or "pclass")' => 'Gemischt (Spalte "type" oder "pclass" notwendig',
|
|
1755 | 1761 |
'Mobile' => 'Mobiltelefon', |
1756 | 1762 |
'Mobile1' => 'Mobil 1', |
1757 | 1763 |
'Mobile2' => 'Mobil 2', |
... | ... | |
1789 | 1795 |
'New Password' => 'Neues Passwort', |
1790 | 1796 |
'New Purchase Price Rule' => 'Neue Einkaufspreisregel', |
1791 | 1797 |
'New Sales Price Rule' => 'Neue Verkaufspreisregel', |
1792 |
'New assembly' => 'Neues Erzeugnis', |
|
1793 | 1798 |
'New client #1: The database configuration fields "host", "port", "name" and "user" must not be empty.' => 'Neuer Mandant #1: Die Datenbankkonfigurationsfelder "Host", "Port" und "Name" dürfen nicht leer sein.', |
1794 | 1799 |
'New client #1: The name must be unique and not empty.' => 'Neuer Mandant #1: Der Name darf nicht leer und muss eindeutig sein.', |
1795 | 1800 |
'New contact' => 'Neue Ansprechperson', |
... | ... | |
1801 | 1806 |
'New row, description' => 'Neue Zeile, Artikelbeschreibung', |
1802 | 1807 |
'New row, partnumber' => 'Neue Zeile, Nummer', |
1803 | 1808 |
'New sales order' => 'Neuer Auftrag', |
1804 |
'New service' => 'Neue Dienstleistung', |
|
1805 | 1809 |
'New shipto' => 'Neue Lieferadresse', |
1806 | 1810 |
'New vendor' => 'Neuer Lieferant', |
1807 | 1811 |
'New window/tab' => 'Neues Fenster/Tab', |
... | ... | |
1847 | 1851 |
'No or an unknown authenticantion module specified in "config/kivitendo.conf".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/kivitendo.conf" angegeben.', |
1848 | 1852 |
'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.', |
1849 | 1853 |
'No part was selected.' => 'Es wurde kein Artikel ausgewählt', |
1854 |
'No parts classification has been created yet.' => 'Keine Artikel-Klassifizierung erzeugt.', |
|
1850 | 1855 |
'No payment term has been created yet.' => 'Es wurden noch keine Zahlungsbedingungen angelegt.', |
1851 | 1856 |
'No picture has been uploaded' => 'Es wurde kein Bild hochgeladen', |
1852 | 1857 |
'No picture uploaded yet' => 'Noch kein Bild hochgeladen', |
... | ... | |
1889 | 1894 |
'None' => 'Kein', |
1890 | 1895 |
'None (PriceSource Discount)' => 'Freier Rabatt', |
1891 | 1896 |
'None (PriceSource)' => 'Freier Preis', |
1897 |
'None (typeabbreviation)' => '-', |
|
1892 | 1898 |
'Normal' => 'Normal', |
1893 | 1899 |
'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.', |
1894 | 1900 |
'Normalize Customer / Vendor names' => 'Normalisierung Kunden- / Lieferantennamen', |
... | ... | |
2011 | 2017 |
'POSTED' => 'Gebucht', |
2012 | 2018 |
'POSTED AS NEW' => 'Als neu gebucht', |
2013 | 2019 |
'PRINTED' => 'Gedruckt', |
2020 |
'PType' => 'Typ', |
|
2014 | 2021 |
'Package name' => 'Paketname', |
2015 | 2022 |
'Packing Lists' => 'Lieferschein', |
2016 | 2023 |
'Page' => 'Seite', |
... | ... | |
2020 | 2027 |
'Part' => 'Ware', |
2021 | 2028 |
'Part "#1" has chargenumber or best before date set. So it cannot be transfered automatically.' => 'Bei Artikel "#1" ist eine Chargenummer oder ein Mindesthaltbarkeitsdatum vergeben. Deshalb kann dieser Artikel nicht automatisch ausgelagert werden.', |
2022 | 2029 |
'Part (database ID)' => 'Artikel (Datenbank-ID)', |
2030 |
'Part (typeabbreviation)' => 'W', |
|
2031 |
'Part Classification' => 'Artikel-Klassifizierung', |
|
2023 | 2032 |
'Part Description' => 'Artikelbeschreibung', |
2024 | 2033 |
'Part Description missing!' => 'Artikelbezeichnung fehlt!', |
2025 | 2034 |
'Part Notes' => 'Bemerkungen', |
2026 | 2035 |
'Part Number' => 'Artikelnummer', |
2027 | 2036 |
'Part Number missing!' => 'Artikelnummer fehlt!', |
2028 |
'Part Unit' => 'Artikeleinheit',
|
|
2037 |
'Part Unit' => 'Einheit des Artikels',
|
|
2029 | 2038 |
'Part picker' => 'Artikelauswahl', |
2030 | 2039 |
'Part_br_Description' => 'Beschreibung', |
2031 | 2040 |
'Partial invoices' => 'Teilrechnungen', |
... | ... | |
2033 | 2042 |
'Partnumber must not be set to empty!' => 'Die Artikelnummer darf nicht auf leer geändert werden.', |
2034 | 2043 |
'Partnumber not unique!' => 'Artikelnummer bereits vorhanden!', |
2035 | 2044 |
'Parts' => 'Waren', |
2045 |
'Parts Classification' => 'Artikel-Klassifizierung', |
|
2046 |
'Parts Classifications' => 'Artikel-Klassifizierung', |
|
2036 | 2047 |
'Parts Inventory' => 'Warenliste', |
2037 | 2048 |
'Parts Master Data' => 'Artikelstammdaten', |
2038 | 2049 |
'Parts must have an entry type.' => 'Waren müssen eine Buchungsgruppe haben.', |
... | ... | |
2183 | 2194 |
'Print template base file name' => 'Druckvorlagen-Basisdateiname', |
2184 | 2195 |
'Print templates' => 'Druckvorlagen', |
2185 | 2196 |
'Print templates to use' => 'Zu verwendende Druckvorlagen', |
2197 |
'Printdate' => '', |
|
2186 | 2198 |
'Printer' => 'Drucker', |
2187 | 2199 |
'Printer Command' => 'Druckbefehl', |
2188 | 2200 |
'Printer Description' => 'Druckerbeschreibung', |
... | ... | |
2196 | 2208 |
'Private Phone' => 'Privates Tel.', |
2197 | 2209 |
'Problem' => 'Problem', |
2198 | 2210 |
'Produce Assembly' => 'Erzeugnis fertigen', |
2211 |
'Production' => 'Produktion', |
|
2212 |
'Production (typeabbreviation)' => 'P', |
|
2199 | 2213 |
'Productivity' => 'Produktivität', |
2200 | 2214 |
'Profit determination' => 'Gewinnermittlung', |
2201 | 2215 |
'Proforma Invoice' => 'Proformarechnung', |
... | ... | |
2219 | 2233 |
'Proposal' => 'Vorschlag', |
2220 | 2234 |
'Proposals' => 'Vorschläge', |
2221 | 2235 |
'Prozentual/Absolut' => 'Prozentual/Absolut', |
2236 |
'Purchase' => 'Einkauf', |
|
2237 |
'Purchase (typeabbreviation)' => 'E', |
|
2222 | 2238 |
'Purchase Delivery Order' => 'Einkaufslieferschein', |
2223 | 2239 |
'Purchase Delivery Orders' => 'Einkaufslieferscheine', |
2224 | 2240 |
'Purchase Delivery Orders deleteable' => 'Einkaufslieferscheine löschbar', |
... | ... | |
2421 | 2437 |
'Saldo neu' => 'Saldo neu', |
2422 | 2438 |
'Saldo per' => 'Saldo per', |
2423 | 2439 |
'Sale Prices' => 'Verkaufspreise', |
2440 |
'Sales' => 'Verkauf', |
|
2441 |
'Sales (typeabbreviation)' => 'V', |
|
2424 | 2442 |
'Sales Delivery Order' => 'Verkaufslieferschein', |
2425 | 2443 |
'Sales Delivery Orders' => 'Verkaufslieferscheine', |
2426 | 2444 |
'Sales Delivery Orders deleteable' => 'Verkaufslieferscheine löschbar', |
... | ... | |
2543 | 2561 |
'Serial No.' => 'Seriennummer', |
2544 | 2562 |
'Serial Number' => 'Seriennummer', |
2545 | 2563 |
'Service' => 'Dienstleistung', |
2564 |
'Service (typeabbreviation)' => 'D', |
|
2546 | 2565 |
'Service Items' => 'Dienstleistungen', |
2547 | 2566 |
'Service Number missing!' => 'Dienstleistungsnummer fehlt!', |
2548 | 2567 |
'Service, assembly or part' => 'Dienstleistung, Erzeugnis oder Ware', |
... | ... | |
2796 | 2815 |
'That export does not exist.' => 'Dieser Export existiert nicht.', |
2797 | 2816 |
'That is why kivitendo could not find a default currency.' => 'Daher konnte kivitendo keine Standardwährung finden.', |
2798 | 2817 |
'The \'name\' is the field shown to the user during login.' => 'Der \'Name\' ist derjenige, der dem Benutzer beim Login angezeigt wird.', |
2818 |
'The \'pclass\' column has the same abbreviation like a part export. The first letter is for the type Part,Assembly or Service, the second(and third) for Part Classification' => 'Die Spalte \'pclass\' besteht aus zwei Buchstaben entsprechend dem Export. Der erste Buchstabe ist für \'W\'=Ware \'E\'=Erzeugnis oder \'D\' für Dienstleistung, der zweite steht für den Artikeltyp, z.B. E,V,H,P oder - ', |
|
2799 | 2819 |
'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.', |
2800 | 2820 |
'The AP transaction #1 has been deleted.' => 'Die Kreditorenbuchung #1 wurde gelöscht.', |
2801 | 2821 |
'The AR transaction #1 has been deleted.' => 'Die Debitorenbuchung #1 wurde gelöscht.', |
... | ... | |
2812 | 2832 |
'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt', |
2813 | 2833 |
'The SEPA strings have been saved.' => 'Die bei SEPA-Überweisungen verwendeten Begriffe wurden gespeichert.', |
2814 | 2834 |
'The WebDAV feature has been used.' => 'Das WebDAV-Feature wurde benutzt.', |
2835 |
'The abbreviation is missing.' => 'Abkürzung fehlt', |
|
2815 | 2836 |
'The acceptance status has been created.' => 'Der Abnahmestatus wurde angelegt.', |
2816 | 2837 |
'The acceptance status has been deleted.' => 'Der Abnahmestatus wurde gelöscht.', |
2817 | 2838 |
'The acceptance status has been saved.' => 'Der Abnahmestatus wurde gespeichert.', |
... | ... | |
2846 | 2867 |
'The base unit does not exist.' => 'Die Basiseinheit existiert nicht.', |
2847 | 2868 |
'The base unit relations must not contain loops (e.g. by saying that unit A\'s base unit is B, B\'s base unit is C and C\'s base unit is A) in row %d.' => 'Die Beziehungen der Einheiten dürfen keine Schleifen beinhalten (z.B. wenn gesagt wird, dass Einheit As Basiseinheit B, Bs Basiseinheit C und Cs Basiseinheit A ist) in Zeile %d.', |
2848 | 2869 |
'The basic client tables have not been created for this client\'s database yet.' => 'Die grundlegenden Mandantentabellen wurden in der für diesen Mandanten konfigurierten Datenbank noch nicht angelegt.', |
2870 |
'The basic parts classification cannot be deleted.' => '', |
|
2849 | 2871 |
'The body is missing.' => 'Der Text fehlt', |
2850 | 2872 |
'The booking group has been created.' => 'Die Buchungsgruppe wurde erstellt.', |
2851 | 2873 |
'The booking group has been deleted.' => 'Die Buchungsgruppe wurde gelöscht.', |
... | ... | |
2915 | 2937 |
'The discounted amount will be shown in documents.' => 'Der Rabattbetrag wird in Belegen ausgewiesen.', |
2916 | 2938 |
'The document has been changed by another user. No mail was sent. Please reopen it in another window and copy the changes to the new window' => 'Die Daten wurden bereits von einem anderen Benutzer verändert. Deshalb ist das Dokument ungültig und es wurde keine E-Mail verschickt. Bitte öffnen Sie das Dokument erneut in einem extra Fenster und übertragen Sie die Daten', |
2917 | 2939 |
'The document has been changed by another user. Please reopen it in another window and copy the changes to the new window' => 'Die Daten wurden bereits von einem anderen Benutzer verändert. Deshalb ist das Dokument ungültig. Bitte öffnen Sie das Dokument erneut in einem extra Fenster und übertragen Sie die Daten', |
2918 |
'The documents have been sent to the printer \'#1\'.' => 'Die Dokumente wurden an den Drucker \'#1\' geschickt.',
|
|
2940 |
'The documents have been sent to the printer \'#1\'.' => 'Die Dokumente sind zum Drucker \'#1\' geschickt',
|
|
2919 | 2941 |
'The dunning process started' => 'Der Mahnprozess ist gestartet.', |
2920 | 2942 |
'The dunnings have been printed.' => 'Die Mahnung(en) wurden gedruckt.', |
2921 | 2943 |
'The email has been sent.' => 'Die E-Mail wurde verschickt.', |
... | ... | |
2976 | 2998 |
'The order has been deleted' => 'Der Auftrag wurde gelöscht.', |
2977 | 2999 |
'The order has been saved' => 'Der Auftrag wurde gespeichert.', |
2978 | 3000 |
'The package name is invalid.' => 'Der Paketname ist ungültig.', |
3001 |
'The parts classification has been created.' => 'Die Artikel-Klassifizierung ist erzeugt', |
|
3002 |
'The parts classification has been deleted.' => 'Die Artikel-Klassifizierung ist gelöscht', |
|
3003 |
'The parts classification has been saved.' => 'Die Artikel-Klassifizierung ist gespeichert', |
|
3004 |
'The parts classification is in use and cannot be deleted.' => 'Die Artikel-Klassifizierung ist in Verwendung, kann deshalb nicht gelöscht werden.', |
|
2979 | 3005 |
'The parts for this delivery order have already been transferred in.' => 'Die Artikel dieses Lieferscheins wurden bereits eingelagert.', |
2980 | 3006 |
'The parts for this delivery order have already been transferred out.' => 'Die Artikel dieses Lieferscheins wurden bereits ausgelagert.', |
2981 | 3007 |
'The parts have been removed.' => 'Die Waren wurden aus dem Lager entnommen.', |
Auch abrufbar als: Unified diff
Artikel-Klassifizierung
Die ursprünglich als "Artikeltyp" bezeichnete Klassifizierung von Artikeln
Sie dient einer weiteren Gliederung um zum Beispiel den Einkauf vom Verkauf zu trennen, etc.
Gekennzeichnet durch eine Beschreibung (z.B. "Einkauf") und ein Kürzel (z.B. "E")
Flexibel änderbar und erweiterbar.
- Neue Datenbanktablle und Rose-Objekte, sowie Controller zum Bearbeiten der Tabelle
- Zwei-Zeichen Abkürzung:
Der Typ des Artikel und die Klassifizierung werden durch zwei Buchstaben dargestellt.
Der erste Buchstabe ist eine Lokalisierung des Typs des Artikel ('P','A','S') ,
deutch 'W', 'E', und 'D' für Ware Erzeugnis oder Dienstleistung, ggf. weitere Typen.
Der zweite Buchstabe ist eine Lokalisierung der Klassifizierungsabkürzung (abbreviation).
Die Abkürzungen sind aus dem Part Presenter abholbar:
- SL::Presenter::Part->type_abbreviation($part_type)
- SL::Presenter::Part->classification_abbreviation($classification_id)
Wenn im ERP-Dokument nach einer Artikelnummer oder Beschreibung gesucht wird,
diese in den Stammdaten vorhanden ist,
aber der Artikeltyp leer oder falsch ist, bzw im Typ for_purchase bzw for_sale nicht gesetzt ist,
wird die Fehlermeldung "Gesuchter Artikel ist nicht für den Einkauf bzw Verkauf" gemeldet
Anpassung des CSV Import,
nun wird alternativ zur 'type'-Spalte die 'pclass'-Spalte mit zwei Buchstaben geparsed und entsprechend
classification_id,assembly sowie inventory_accno_id gesetzt (oder type_id falls neue Implementierung eingebaut).