X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FDB%2FHelper%2FTransNumberGenerator.pm;h=f7c77930568d0e2a02ea9eea6e85d758a9331dc6;hb=508801bbaf7b9c5e144bf7ab9763a342ab80f176;hp=d3417860626e61bb17be654d3a040036bdd48d6c;hpb=a37f2a8b590b7537e2938fa9545f6eae0ca7ae6e;p=kivitendo-erp.git diff --git a/SL/DB/Helper/TransNumberGenerator.pm b/SL/DB/Helper/TransNumberGenerator.pm index d34178606..f7c779305 100644 --- a/SL/DB/Helper/TransNumberGenerator.pm +++ b/SL/DB/Helper/TransNumberGenerator.pm @@ -10,21 +10,30 @@ use List::Util qw(max); use SL::DB::Default; -my $oe_scoping = sub { +sub oe_scoping { SL::DB::Manager::Order->type_filter($_[0]); -}; +} -my $do_scoping = sub { +sub do_scoping { SL::DB::Manager::DeliveryOrder->type_filter($_[0]); -}; - -my %specs = ( ar => { number_column => 'invnumber', fill_holes_in_range => 1 }, - sales_quotation => { number_column => 'quonumber', number_range_column => 'sqnumber', scoping => $oe_scoping, }, - sales_order => { number_column => 'ordnumber', number_range_column => 'sonumber', scoping => $oe_scoping, }, - request_quotation => { number_column => 'quonumber', number_range_column => 'rfqnumber', scoping => $oe_scoping, }, - purchase_order => { number_column => 'ordnumber', number_range_column => 'ponumber', scoping => $oe_scoping, }, - sales_delivery_order => { number_column => 'donumber', number_range_column => 'sdonumber', scoping => $do_scoping, fill_holes_in_range => 1 }, - purchase_delivery_order => { number_column => 'donumber', number_range_column => 'pdonumber', scoping => $do_scoping, fill_holes_in_range => 1 }, +} + +sub parts_scoping { + SL::DB::Manager::Part->type_filter($_[0]); +} + +my %specs = ( ar => { number_column => 'invnumber', fill_holes_in_range => 1 }, + sales_quotation => { number_column => 'quonumber', number_range_column => 'sqnumber', scoping => \&oe_scoping, }, + sales_order => { number_column => 'ordnumber', number_range_column => 'sonumber', scoping => \&oe_scoping, }, + request_quotation => { number_column => 'quonumber', number_range_column => 'rfqnumber', scoping => \&oe_scoping, }, + purchase_order => { number_column => 'ordnumber', number_range_column => 'ponumber', scoping => \&oe_scoping, }, + sales_delivery_order => { number_column => 'donumber', number_range_column => 'sdonumber', scoping => \&do_scoping, fill_holes_in_range => 1 }, + purchase_delivery_order => { number_column => 'donumber', number_range_column => 'pdonumber', scoping => \&do_scoping, fill_holes_in_range => 1 }, + customer => { number_column => 'customernumber', number_range_column => 'customernumber', }, + vendor => { number_column => 'vendornumber', number_range_column => 'vendornumber', }, + 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 => 'articlenumber', scoping => \&parts_scoping }, ); sub get_next_trans_number { @@ -78,3 +87,92 @@ sub create_trans_number { } 1; + +__END__ + +=pod + +=encoding utf8 + +=head1 NAME + +SL::DB::Helper::TransNumberGenerator - A mixin for creating unique record numbers + +=head1 FUNCTIONS + +=over 4 + +=item C + +Generates a new unique record number for the mixing class. Each record +type (invoices, sales quotations, purchase orders etc) has its own +number range. Within these ranges all numbers should be unique. The +table C contains the last record number assigned for all of +the number ranges. + +This function contains hard-coded knowledge about the modules it can +be mixed into. This way the models themselves don't have to contain +boilerplate code for the details like the the number range column's +name in the C table. + +The process of creating a unique number involves the following steps: + +At first all existing record numbers for the current type are +retrieved from the database as well as the last number assigned from +the table C. + +The next step is separating the number range from C into two +parts: an optional non-numeric prefix and its numeric suffix. The +prefix, if present, will be kept intact. + +Now the number itself is increased as often as neccessary to create a +unique one by comparing the generated numbers with the existing ones +retrieved in the first step. In this step gaps in the assigned numbers +are filled for some tables (e.g. invoices) but not for others +(e.g. sales orders). + +After creating the unique record number this function can update +C<$self> and the C table if requested. This is controlled +with the following parameters: + +=over 2 + +=item * C + +Determines whether or not C<$self>'s record number field is set to the +newly generated number. C<$self> will not be saved even if this +parameter is trueish. Defaults to false. + +=item * C + +Determines whether or not the number range value in the C +table should be updated. Unlike C<$self> the C table will be +saved. Defaults to false. + +=back + +Always returns the newly generated number. This function cannot fail +and return a value. If it fails then it is due to exceptions. + +=item C + +Calls and returns with the parameters +C and C. C<%params> is passed +to it as well. + +=back + +=head1 EXPORTS + +This mixin exports all of its functions: L and +L. There are no optional exports. + +=head1 BUGS + +Nothing here yet. + +=head1 AUTHOR + +Moritz Bunkus Em.bunkus@linet-services.deE + +=cut