'SL::Controller::TopQuickSearch::Part',
'SL::Controller::TopQuickSearch::Service',
'SL::Controller::TopQuickSearch::Assembly',
+ 'SL::Controller::TopQuickSearch::Assortment',
'SL::Controller::TopQuickSearch::Contact',
'SL::Controller::TopQuickSearch::SalesQuotation',
'SL::Controller::TopQuickSearch::SalesOrder',
my ($self, $term) = @_;
SL::Controller::Base->new->url_for(
- controller => 'ic.pl',
- action => 'edit',
+ controller => 'controller.pl',
+ action => 'Part/edit',
id => $term,
);
}
--- /dev/null
+package SL::Controller::TopQuickSearch::Assortment;
+
+use strict;
+use parent qw(SL::Controller::TopQuickSearch::Article);
+
+use SL::Locale::String qw(t8);
+
+sub name { 'assortment' }
+
+sub description_config { t8('Assortment') }
+
+sub description_field { t8('Assortment') }
+
+sub part_type { 'assortment' }
+
+1;
part => { number_column => 'partnumber', number_range_column => 'articlenumber', scoping => \&parts_scoping, },
service => { number_column => 'partnumber', number_range_column => 'servicenumber', scoping => \&parts_scoping, },
assembly => { number_column => 'partnumber', number_range_column => 'assemblynumber', scoping => \&parts_scoping, },
+ assortment => { number_column => 'partnumber', number_range_column => 'assortmentnumber', scoping => \&parts_scoping, },
);
sub get_next_trans_number {
my $range_table = ($business ? $business : SL::DB::Default->get)->load(for_update => 1);
my $start_number = $range_table->$number_range_column;
- $start_number = $range_table->articlenumber if ($number_range_column eq 'assemblynumber') && (length($start_number) < 1);
+ $start_number = $range_table->articlenumber if ($number_range_column =~ /^(assemblynumber|assortmentnumber)$/) && (length($start_number) < 1);
my $sequence = SL::PrefixedNumber->new(number => $start_number // 0);
if (!$fill_holes_in_range) {
push @filter, ($prefix . part_type => 'service');
} elsif ($type =~ m/^assembly/) {
push @filter, ($prefix . part_type => 'assembly');
+ } elsif ($type =~ m/^assortment/) {
+ push @filter, ($prefix . part_type => 'assortment');
}
}
sub is_type {
my $self = shift;
my $type = lc(shift || '');
- die 'invalid type' unless $type =~ /^(?:part|service|assembly)$/;
+ die 'invalid type' unless $type =~ /^(?:part|service|assembly|assortment)$/;
return $self->type eq $type ? 1 : 0;
}
-sub is_part { $_[0]->part_type eq 'part' }
-sub is_assembly { $_[0]->part_type eq 'assembly' }
-sub is_service { $_[0]->part_type eq 'service' }
+sub is_part { $_[0]->part_type eq 'part' }
+sub is_assembly { $_[0]->part_type eq 'assembly' }
+sub is_service { $_[0]->part_type eq 'service' }
+sub is_assortment { $_[0]->part_type eq 'assortment' }
sub type {
return $_[0]->part_type;
$class->new(%params, part_type => 'service');
}
+sub new_assortment {
+ my ($class, %params) = @_;
+ $class->new(%params, part_type => 'assortment');
+}
+
sub orphaned {
my ($self) = @_;
die 'not an accessor' if @_ > 1;
SL::DB::InvoiceItem
SL::DB::OrderItem
SL::DB::Inventory
+ SL::DB::Assembly
+ SL::DB::AssortmentItem
);
for my $class (@relations) {
=item Assembly - a collection of both parts and services
+=item Assortment - a collection of parts
+
=back
These types are sadly represented by data inside the class and cannot be
migrated into a flag. To work around this, each C<Part> object knows what type
it currently is. Since the type is data driven, there ist no explicit setting
method for it, but you can construct them explicitly with C<new_part>,
-C<new_service>, and C<new_assembly>. A Buchungsgruppe should be supplied in this
+C<new_service>, C<new_assembly> and C<new_assortment>. A Buchungsgruppe should be supplied in this
case, but it will use the default Buchungsgruppe if you don't.
Matching these there are assorted helper methods dealing with types,
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="ic.pl?action=edit&id=' . $self->escape($part->id) . '">',
+ $params{no_link} ? '' : '<a href="controller.pl?action=Part/edit&id=' . $self->escape($part->id) . '">',
$self->escape($part->partnumber),
$params{no_link} ? '' : '</a>',
);
scalar => [ qw(type id number save dbh dbh_provided business_id) ],
);
-my @SUPPORTED_TYPES = qw(invoice credit_note customer vendor sales_delivery_order purchase_delivery_order sales_order purchase_order sales_quotation request_quotation part service assembly letter);
+my @SUPPORTED_TYPES = qw(invoice credit_note customer vendor sales_delivery_order purchase_delivery_order sales_order purchase_order sales_quotation request_quotation part service assembly assortment letter);
sub new {
my $class = shift;
$filters{where} = 'COALESCE(quotation, FALSE)';
$filters{where} .= $type =~ /^sales/ ? ' AND (customer_id IS NOT NULL)' : ' AND (vendor_id IS NOT NULL)';
- } elsif ($type =~ /part|service|assembly/) {
+ } elsif ($type =~ /^(part|service|assembly|assortment)$/) {
$filters{trans_number} = "partnumber";
- $filters{numberfield} = $type eq 'service' ? 'servicenumber' : 'articlenumber';
- $filters{numberfield} = $type eq 'assembly' ? 'assemblynumber' : $filters{numberfield};
+ my %numberfield_hash = ( service => 'servicenumber',
+ assembly => 'assemblynumber',
+ assortment => 'assortmentnumber',
+ part => 'articlenumber'
+ );
+ $filters{numberfield} = $numberfield_hash{$type};
$filters{table} = "parts";
} elsif ($type =~ /letter/) {
$filters{trans_number} = "letternumber";
$soldtotal = 0 if ($form->{sold});
}
- my $edit_link = build_std_url('action=edit', 'id=' . E($ref->{id}), 'callback');
+ my $edit_link = build_std_url('script=controller.pl', 'action=Part/edit', 'id=' . E($ref->{id}), 'callback');
$row->{partnumber}->{link} = $edit_link;
$row->{description}->{link} = $edit_link;
'Add Accounts Payables Transaction' => 'Kreditorenbuchung erfassen',
'Add Accounts Receivables Transaction' => 'Debitorenbuchung erfassen',
'Add Assembly' => 'Erzeugnis erfassen',
+ 'Add Assortment' => 'Sortiment erfassen',
'Add Client' => 'Neuer Mandant',
'Add Credit Note' => 'Gutschrift erfassen',
'Add Customer' => 'Kunde erfassen',
'Assigned invoices' => 'Zugewiesene Rechnungen',
'Assignment of articles to sections' => 'Zuweisung von Artikeln zu Abschnitten',
'Assistant for general ledger corrections' => 'Assistent für die Korrektur von Hauptbucheinträgen',
+ 'Assortment' => 'Sortiment',
+ 'Assortment items' => 'Sortimentsartikel',
+ 'Assortments' => 'Sortimente',
'Assume Tax Consultant Data in Tax Computation?' => 'Beraterdaten in UStVA übernehmen?',
'At least' => 'Mindestens',
'At least one Perl module that kivitendo ERP requires for running is not installed on your system.' => 'Mindestes ein Perl-Modul, das kivitendo ERP zur Ausführung benötigt, ist auf Ihrem System nicht installiert.',
'Edit Accounts Payables Transaction' => 'Kreditorenbuchung bearbeiten',
'Edit Accounts Receivables Transaction' => 'Debitorenbuchung bearbeiten',
'Edit Assembly' => 'Erzeugnis bearbeiten',
+ 'Edit Assortment' => 'Sortiment bearbeiten',
'Edit Bins' => 'Lagerplätze bearbeiten',
'Edit Client' => 'Mandanten bearbeiten',
'Edit Credit Note' => 'Gutschrift bearbeiten',
'Languages and translations' => 'Sprachen und Übersetzungen',
'Last Article Number' => 'Letzte Artikelnummer',
'Last Assembly Number' => 'Letzte Erzeugnisnummer',
+ 'Last Assortment Number' => 'Letzte Sortimentsnummer',
'Last Cost' => 'Einkaufspreis',
'Last Credit Note Number' => 'Letzte Gutschriftnummer',
'Last Customer Number' => 'Letzte Kundennummer',
'The application "#1" was not found on the system.' => 'Die Anwendung "#1" wurde auf dem System nicht gefunden.',
'The assembly has been created.' => 'Das Erzeugnis wurde hergestellt.',
'The assistant could not find anything wrong with #1. Maybe the problem has been solved in the meantime.' => 'Der Korrekturassistent konnte kein Problem bei #1 feststellen. Eventuell wurde das Problem in der Zwischenzeit bereits behoben.',
+ 'The assortment doesn\'t have any items.' => 'Das Sortiment enthält keine Artikel.',
'The authentication database is not reachable at the moment. Either it hasn\'t been set up yet or the database server might be down. Please contact your administrator.' => 'Die Authentifizierungs-Datenbank kann momentan nicht erreicht werden. Entweder wurde sie noch nicht eingerichtet, oder der Datenbankserver ist momentan nicht verfügbar. Bitte wenden Sie sich an Ihren Administrator.',
'The available options depend on the varibale type:' => 'Die verfügbaren Optionen hängen vom Variablentypen ab:',
'The background job could not be destroyed.' => 'Der Hintergrund-Job konnte nicht gelöscht werden.',
icon: part_add
order: 300
access: part_service_assembly_edit
- module: ic.pl
params:
- action: add
- part_type: part
+ action: Part/add_part
- parent: master_data
id: master_data_add_service
name: Add Service
icon: service_add
order: 400
access: part_service_assembly_edit
- module: ic.pl
params:
- action: add
- part_type: service
+ action: Part/add_service
- parent: master_data
id: master_data_add_assembly
name: Add Assembly
icon: assembly_add
order: 500
access: part_service_assembly_edit
- module: ic.pl
params:
- action: add
- part_type: assembly
+ action: Part/add_assembly
+- parent: master_data
+ id: master_data_add_assortment
+ name: Add Assortment
+ icon: assortment_add
+ order: 550
+ access: part_service_assembly_edit
+ params:
+ action: Part/add_assortment
- parent: master_data
id: master_data_add_project
name: Add Project
params:
action: search
searchitems: assembly
+- parent: master_data_reports
+ id: master_data_reports_assortments
+ name: Assortments
+ icon: assortment_report
+ order: 650
+ access: part_service_assortment_details
+ module: ic.pl
+ params:
+ action: search
+ searchitems: assortment
- parent: master_data_reports
id: master_data_reports_projects
name: Projects