Bug 35026: Make add_items_from_import_record DRY

This patch improves the code in add_items_from_import_record to make sure that the code is not repeating itself

It also fixes a minor error in the template file and rebases in changes from bugs 35254 and 33170

Signed-off-by: Barbara Johnson <barbara.johnson@bedfordtx.gov>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Matt Blenkinsop 2023-11-28 17:05:26 +00:00 committed by Katrin Fischer
parent 5292426e3e
commit 7608566440
Signed by: kfischer
GPG key ID: 0EF6E2C03357A834
2 changed files with 353 additions and 380 deletions

View file

@ -90,7 +90,7 @@ sub import_record_and_create_order_lines {
my $budget_id = $args->{budget_id}; my $budget_id = $args->{budget_id};
my $vendor = $args->{vendor}; my $vendor = $args->{vendor};
my $result = add_biblios_from_import_record( my $result = add_biblio_from_import_record(
{ {
import_batch_id => $import_batch_id, import_batch_id => $import_batch_id,
import_record => $import_record, import_record => $import_record,
@ -167,8 +167,8 @@ sub _get_MarcFieldsToOrder_syspref_data {
=cut =cut
sub _get_MarcItemFieldsToOrder_syspref_data { sub _get_MarcItemFieldsToOrder_syspref_data {
my ( $syspref_name, $record, $field_list ) = @_; my ($record) = @_;
my $syspref = C4::Context->preference($syspref_name); my $syspref = C4::Context->preference('MarcItemFieldsToOrder');
$syspref = "$syspref\n\n"; $syspref = "$syspref\n\n";
my $yaml = eval { YAML::XS::Load( Encode::encode_utf8($syspref) ); }; my $yaml = eval { YAML::XS::Load( Encode::encode_utf8($syspref) ); };
if ($@) { if ($@) {
@ -179,8 +179,7 @@ sub _get_MarcItemFieldsToOrder_syspref_data {
my @tags_list; my @tags_list;
# Check tags in syspref definition # Check tags in syspref definition
for my $field_name (@$field_list) { for my $field_name ( keys %$yaml ) {
next unless exists $yaml->{$field_name};
my @fields = split /\|/, $yaml->{$field_name}; my @fields = split /\|/, $yaml->{$field_name};
for my $field (@fields) { for my $field (@fields) {
my ( $f, $sf ) = split /\$/, $field; my ( $f, $sf ) = split /\$/, $field;
@ -208,8 +207,7 @@ sub _get_MarcItemFieldsToOrder_syspref_data {
if ( $tags_count->{count} ) { if ( $tags_count->{count} ) {
for ( my $i = 0 ; $i < $tags_count->{count} ; $i++ ) { for ( my $i = 0 ; $i < $tags_count->{count} ; $i++ ) {
my $r; my $r;
for my $field_name (@$field_list) { for my $field_name ( keys %$yaml ) {
next unless exists $yaml->{$field_name};
my @fields = split /\|/, $yaml->{$field_name}; my @fields = split /\|/, $yaml->{$field_name};
for my $field (@fields) { for my $field (@fields) {
my ( $f, $sf ) = split /\$/, $field; my ( $f, $sf ) = split /\$/, $field;
@ -254,9 +252,9 @@ sub _verify_number_of_fields {
return { error => 0, count => $tags_count }; return { error => 0, count => $tags_count };
} }
=head3 add_biblios_from_import_record =head3 add_biblio_from_import_record
my ($record_results, $duplicates_in_batch) = add_biblios_from_import_record({ my ($record_results, $duplicates_in_batch) = add_biblio_from_import_record({
import_record => $import_record, import_record => $import_record,
matcher_id => $matcher_id, matcher_id => $matcher_id,
overlay_action => $overlay_action, overlay_action => $overlay_action,
@ -271,7 +269,7 @@ sub _verify_number_of_fields {
=cut =cut
sub add_biblios_from_import_record { sub add_biblio_from_import_record {
my ($args) = @_; my ($args) = @_;
my $import_batch_id = $args->{import_batch_id}; my $import_batch_id = $args->{import_batch_id};
@ -369,270 +367,88 @@ sub add_items_from_import_record {
my $active_currency = Koha::Acquisition::Currencies->get_active; my $active_currency = Koha::Acquisition::Currencies->get_active;
my $biblionumber = $record_result->{biblionumber}; my $biblionumber = $record_result->{biblionumber};
my $marcrecord = $record_result->{marcrecord}; my $marcrecord = $record_result->{marcrecord};
my @order_line_details;
if ( $agent eq 'cron' ) { if ( $agent eq 'cron' ) {
my $marc_fields_to_order = _get_MarcFieldsToOrder_syspref_data( my $marc_fields_to_order = _get_MarcFieldsToOrder_syspref_data(
'MarcFieldsToOrder', $marcrecord, 'MarcFieldsToOrder', $marcrecord,
[ 'price', 'quantity', 'budget_code', 'discount', 'sort1', 'sort2' ] [ 'price', 'quantity', 'budget_code', 'discount', 'sort1', 'sort2' ]
); );
my $quantity = $marc_fields_to_order->{quantity};
my $budget_code =
$marc_fields_to_order->{budget_code} || $budget_id; # Use fallback from ordering profile if not mapped
my $price = $marc_fields_to_order->{price};
my $discount = $marc_fields_to_order->{discount};
my $sort1 = $marc_fields_to_order->{sort1};
my $sort2 = $marc_fields_to_order->{sort2};
my $mapped_budget;
if ($budget_code) { my $marc_item_fields_to_order = _get_MarcItemFieldsToOrder_syspref_data($marcrecord);
my $biblio_budget = GetBudgetByCode($budget_code);
if ($biblio_budget) {
$mapped_budget = $biblio_budget->{budget_id};
} else {
$mapped_budget = $budget_id;
}
}
my $marc_item_fields_to_order = _get_MarcItemFieldsToOrder_syspref_data( my $item_fields = {
'MarcItemFieldsToOrder', homebranch => $marc_item_fields_to_order->{homebranch},
$marcrecord, holdingbranch => $marc_item_fields_to_order->{holdingbranch},
[ itype => $marc_item_fields_to_order->{itype},
'homebranch', 'holdingbranch', 'itype', 'nonpublic_note', 'public_note', 'loc', 'ccode', 'notforloan', nonpublic_note => $marc_item_fields_to_order->{nonpublic_note},
'uri', 'copyno', 'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code' public_note => $marc_item_fields_to_order->{public_note},
] loc => $marc_item_fields_to_order->{loc},
); ccode => $marc_item_fields_to_order->{ccode},
my $item_homebranch = $marc_item_fields_to_order->{homebranch}; notforloan => $marc_item_fields_to_order->{notforloan},
my $item_holdingbranch = $marc_item_fields_to_order->{holdingbranch}; uri => $marc_item_fields_to_order->{uri},
my $item_itype = $marc_item_fields_to_order->{itype}; copyno => $marc_item_fields_to_order->{copyno},
my $item_nonpublic_note = $marc_item_fields_to_order->{nonpublic_note}; quantity => $marc_item_fields_to_order->{quantity},
my $item_public_note = $marc_item_fields_to_order->{public_note}; price => $marc_item_fields_to_order->{price},
my $item_loc = $marc_item_fields_to_order->{loc}; replacementprice => $marc_item_fields_to_order->{replacementprice},
my $item_ccode = $marc_item_fields_to_order->{ccode}; itemcallnumber => $marc_item_fields_to_order->{itemcallnumber},
my $item_notforloan = $marc_item_fields_to_order->{notforloan}; budget_code => $marc_item_fields_to_order->{budget_code},
my $item_uri = $marc_item_fields_to_order->{uri}; c_quantity => $marc_fields_to_order->{quantity},
my $item_copyno = $marc_item_fields_to_order->{copyno}; c_budget_code => $marc_fields_to_order->{budget_code},
my $item_quantity = $marc_item_fields_to_order->{quantity} || 0; c_price => $marc_fields_to_order->{price},
my $item_budget_code = $marc_item_fields_to_order->{budget_code}; c_discount => $marc_fields_to_order->{discount},
my $item_budget_id; c_sort1 => $marc_fields_to_order->{sort1},
c_sort2 => $marc_fields_to_order->{sort2},
};
if ( $marc_item_fields_to_order->{budget_code} ) { my $order_line_fields = parse_input_into_order_line_fields(
my $item_budget = GetBudgetByCode( $marc_item_fields_to_order->{budget_code} ); {
if ($item_budget) { agent => $agent,
$item_budget_id = $item_budget->{budget_id};
} else {
$item_budget_id = $budget_id;
}
} else {
$item_budget_id = $budget_id;
}
my $item_price = $marc_item_fields_to_order->{price};
my $item_replacement_price = $marc_item_fields_to_order->{replacementprice};
my $item_callnumber = $marc_item_fields_to_order->{itemcallnumber};
my $itemcreation = 0;
for ( my $i = 0 ; $i < $item_quantity ; $i++ ) {
$itemcreation = 1;
my $item = Koha::Item->new(
{
biblionumber => $biblionumber,
homebranch => $item_homebranch,
holdingbranch => $item_holdingbranch,
itype => $item_itype,
itemnotes_nonpublic => $item_nonpublic_note,
itemnotes => $item_public_note,
location => $item_loc,
ccode => $item_ccode,
notforloan => $item_notforloan,
uri => $item_uri,
copynumber => $item_copyno,
price => $item_price,
replacementprice => $item_replacement_price,
itemcallnumber => $item_callnumber,
}
)->store;
my %order_detail_hash = (
biblionumber => $biblionumber, biblionumber => $biblionumber,
basketno => $basket_id, budget_id => $budget_id,
itemnumbers => ( $item->itemnumber ), basket_id => $basket_id,
quantity => 1, fields => $item_fields,
budget_id => $item_budget_id,
currency => $vendor->listprice,
);
if ($item_price) {
$order_detail_hash{tax_rate_on_ordering} = $vendor->tax_rate;
$order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
$order_detail_hash{discount} = $vendor->discount;
$order_detail_hash{rrp} = $item_price;
$order_detail_hash{ecost} =
$vendor->discount ? $item_price * ( 1 - $vendor->discount / 100 ) : $item_price;
$order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
$order_detail_hash{unitprice} = $order_detail_hash{ecost};
} else {
$order_detail_hash{listprice} = 0;
} }
$order_detail_hash{replacementprice} = $item_replacement_price || 0; );
$order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
push @order_line_details, \%order_detail_hash; my $order_line_details = create_items_and_generate_order_hash(
} {
fields => $order_line_fields,
if ( !$itemcreation ) { vendor => $vendor,
my %order_detail_hash = ( agent => $agent,
biblionumber => $biblionumber, active_currency => $active_currency,
basketno => $basket_id,
quantity => $quantity,
budget_id => $mapped_budget,
uncertainprice => 1,
sort1 => $sort1,
sort2 => $sort2,
);
if ($price) {
$order_detail_hash{tax_rate_on_ordering} = $vendor->tax_rate;
$order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
my $order_discount = $discount ? $discount : $vendor->discount;
$order_detail_hash{discount} = $order_discount;
$order_detail_hash{rrp} = $price;
$order_detail_hash{ecost} = $order_discount ? $price * ( 1 - $order_discount / 100 ) : $price;
$order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
$order_detail_hash{unitprice} = $order_detail_hash{ecost};
} else {
$order_detail_hash{listprice} = 0;
} }
);
$order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice}; return $order_line_details;
push @order_line_details, \%order_detail_hash;
}
} }
if ( $agent eq 'client' ) { if ( $agent eq 'client' ) {
my $homebranches = $client_item_fields->{homebranches}; my $order_line_fields = parse_input_into_order_line_fields(
my $count = scalar @$homebranches; {
my $holdingbranches = $client_item_fields->{holdingbranches}; agent => $agent,
my $itypes = $client_item_fields->{itypes};
my $nonpublic_notes = $client_item_fields->{nonpublic_notes};
my $public_notes = $client_item_fields->{public_notes};
my $locs = $client_item_fields->{locs};
my $ccodes = $client_item_fields->{ccodes};
my $notforloans = $client_item_fields->{notforloans};
my $uris = $client_item_fields->{uris};
my $copynos = $client_item_fields->{copynos};
my $budget_codes = $client_item_fields->{budget_codes};
my $itemprices = $client_item_fields->{itemprices};
my $replacementprices = $client_item_fields->{replacementprices};
my $itemcallnumbers = $client_item_fields->{itemcallnumbers};
my $itemcreation;
for ( my $i = 0 ; $i < $count ; $i++ ) {
$itemcreation = 1;
my $item = Koha::Item->new(
{
biblionumber => $biblionumber,
homebranch => @$homebranches[$i],
holdingbranch => @$holdingbranches[$i],
itemnotes_nonpublic => @$nonpublic_notes[$i],
itemnotes => @$public_notes[$i],
location => @$locs[$i],
ccode => @$ccodes[$i],
itype => @$itypes[$i],
notforloan => @$notforloans[$i],
uri => @$uris[$i],
copynumber => @$copynos[$i],
price => @$itemprices[$i],
replacementprice => @$replacementprices[$i],
itemcallnumber => @$itemcallnumbers[$i],
}
)->store;
my %order_detail_hash = (
biblionumber => $biblionumber, biblionumber => $biblionumber,
itemnumbers => ( $item->itemnumber ), budget_id => $budget_id,
basketno => $basket_id, basket_id => $basket_id,
quantity => 1, fields => $client_item_fields,
budget_id => @$budget_codes[$i]
|| $budget_id, # If no budget selected in the UI, default to the budget on the ordering account
currency => $vendor->listprice,
);
if ( @$itemprices[$i] ) {
$order_detail_hash{tax_rate_on_ordering} = $vendor->tax_rate;
$order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
my $order_discount =
$client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
$order_detail_hash{discount} = $order_discount;
$order_detail_hash{rrp} = @$itemprices[$i];
$order_detail_hash{ecost} =
$order_discount ? @$itemprices[$i] * ( 1 - $order_discount / 100 ) : @$itemprices[$i];
$order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
$order_detail_hash{unitprice} = $order_detail_hash{ecost};
} else {
$order_detail_hash{listprice} = 0;
} }
$order_detail_hash{replacementprice} = @$replacementprices[$i] || 0; );
$order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
push @order_line_details, \%order_detail_hash; my $order_line_details = create_items_and_generate_order_hash(
} {
fields => $order_line_fields,
if ( !$itemcreation ) { vendor => $vendor,
my $quantity = GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') ) || 1; agent => $agent,
my %order_detail_hash = ( active_currency => $active_currency,
biblionumber => $biblionumber,
basketno => $basket_id,
quantity => $client_item_fields->{c_quantity},
budget_id => $client_item_fields->{c_budget_id},
uncertainprice => 1,
sort1 => $client_item_fields->{c_sort1},
sort2 => $client_item_fields->{c_sort2},
order_internalnote => $client_item_fields->{all_order_internalnote},
order_vendornote => $client_item_fields->{all_order_vendornote},
currency => $client_item_fields->{all_currency},
replacementprice => $client_item_fields->{c_replacement_price},
);
if ( $client_item_fields->{c_price} ) {
$order_detail_hash{tax_rate_on_ordering} = $vendor->tax_rate;
$order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
my $order_discount =
$client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
$order_detail_hash{discount} = $order_discount;
$order_detail_hash{rrp} = $client_item_fields->{c_price};
$order_detail_hash{ecost} =
$order_discount
? $client_item_fields->{c_price} * ( 1 - $order_discount / 100 )
: $client_item_fields->{c_price};
$order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
$order_detail_hash{unitprice} = $order_detail_hash{ecost};
} else {
$order_detail_hash{listprice} = 0;
} }
);
$order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice}; return $order_line_details;
# Add items if applicable parsing the item sent by the form, and create an item just for the import_record_id we are dealing with
my $basket = Koha::Acquisition::Baskets->find($basket_id);
$order_detail_hash{itemnumbers} = ();
if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
my @tags = $client_item_fields->{tag};
my @subfields = $client_item_fields->{subfield};
my @field_values = $client_item_fields->{field_value};
my @serials = $client_item_fields->{serial};
my $xml = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
my $record = MARC::Record::new_from_xml( $xml, 'UTF-8' );
for ( my $qtyloop = 1 ; $qtyloop <= $client_item_fields->{c_quantity} ; $qtyloop++ ) {
my ( $biblionumber, undef, $itemnumber ) = AddItemFromMarc( $record, $biblionumber );
push @{ $order_detail_hash{itemnumbers} }, $itemnumber;
}
}
push @order_line_details, \%order_detail_hash;
}
} }
return \@order_line_details;
# return \@order_line_details;
} }
=head3 create_order_lines =head3 create_items_and_generate_order_hash
my $order_lines = create_order_lines({ my $order_lines = create_order_lines({
order_line_details => $order_line_details order_line_details => $order_line_details
@ -663,14 +479,14 @@ sub create_order_lines {
=head3 import_batches_list =head3 import_batches_list
Fetches import batches matching the batch to be added to the basket and adds these to the $template Fetches import batches matching the batch to be added to the basket and returns these to the template
Koha::MarcOrder->import_batches_list($template); Koha::MarcOrder->import_batches_list();
=cut =cut
sub import_batches_list { sub import_batches_list {
my ( $self, $template ) = @_; my ($self) = @_;
my $batches = GetImportBatchRangeDesc(); my $batches = GetImportBatchRangeDesc();
my @list = (); my @list = ();
@ -702,22 +518,25 @@ sub import_batches_list {
} }
} }
} }
$template->param( batch_list => \@list );
my $num_batches = GetNumberOfNonZ3950ImportBatches(); my $num_batches = GetNumberOfNonZ3950ImportBatches();
$template->param( num_results => $num_batches );
return {
list => \@list,
num_results => $num_batches
};
} }
=head3 =head3
For an import batch, this function reads the files and creates all the relevant data pertaining to that file For an import batch, this function reads the files and creates all the relevant data pertaining to that file
It then passes this to the $template variable to be shown in the UI It then returns this to the template to be shown in the UI
Koha::MarcOrder->import_biblios_list( $template, $cgiparams->{'import_batch_id'} ); Koha::MarcOrder->import_biblios_list( $cgiparams->{'import_batch_id'} );
=cut =cut
sub import_biblios_list { sub import_biblios_list {
my ( $self, $template, $import_batch_id ) = @_; my ( $self, $import_batch_id ) = @_;
my $batch = GetImportBatch( $import_batch_id, 'staged' ); my $batch = GetImportBatch( $import_batch_id, 'staged' );
return () unless $batch and $batch->{import_status} =~ /^staged$|^reverted$/; return () unless $batch and $batch->{import_status} =~ /^staged$|^reverted$/;
my $import_records = Koha::Import::Records->search( my $import_records = Koha::Import::Records->search(
@ -806,63 +625,33 @@ sub import_biblios_list {
# Items # Items
my @itemlist = (); my @itemlist = ();
my $all_items_quantity = 0; my $all_items_quantity = 0;
my $alliteminfos = _get_MarcItemFieldsToOrder_syspref_data( my $alliteminfos = _get_MarcItemFieldsToOrder_syspref_data($marcrecord);
'MarcItemFieldsToOrder',
$marcrecord,
[
'homebranch', 'holdingbranch', 'itype', 'nonpublic_note', 'public_note', 'loc', 'ccode', 'notforloan',
'uri', 'copyno', 'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code'
]
);
if ( !$alliteminfos || %$alliteminfos != -1 ) { if ( !$alliteminfos || %$alliteminfos != -1 ) {
my $item_homebranch = $alliteminfos->{homebranch};
my $item_holdingbranch = $alliteminfos->{holdingbranch};
my $item_itype = $alliteminfos->{itype};
my $item_nonpublic_note = $alliteminfos->{nonpublic_note};
my $item_public_note = $alliteminfos->{public_note};
my $item_loc = $alliteminfos->{loc};
my $item_ccode = $alliteminfos->{ccode};
my $item_notforloan = $alliteminfos->{notforloan};
my $item_uri = $alliteminfos->{uri};
my $item_copyno = $alliteminfos->{copyno};
my $item_quantity = $alliteminfos->{quantity} || 1;
my $item_budget_code = $alliteminfos->{budget_code};
my $item_budget_id;
if ( $alliteminfos->{budget_code} ) { # Quantity is required, default to one if not supplied
my $item_budget = GetBudgetByCode( $alliteminfos->{budget_code} ); my $quantity = delete $alliteminfos->{quantity} || 1;
if ($item_budget) {
$item_budget_id = $item_budget->{budget_id}; # Handle incorrectly named original parameters for MarcItemFieldsToOrder
} $alliteminfos->{location} = delete $alliteminfos->{loc} if $alliteminfos->{loc};
$alliteminfos->{copynumber} = delete $alliteminfos->{copyno} if $alliteminfos->{copyno};
# Convert budget code to a budget id
my $item_budget_code = delete $alliteminfos->{budget_code};
if ($item_budget_code) {
my $item_budget = GetBudgetByCode($item_budget_code);
$alliteminfos->{budget_id} = $item_budget->{budget_id} || $budget_id;
} }
my $item_price = $alliteminfos->{price};
my $item_replacement_price = $alliteminfos->{replacementprice};
my $item_callnumber = $alliteminfos->{itemcallnumber};
for ( my $i = 0 ; $i < $item_quantity ; $i++ ) { # Clone the item data for the needed quantity
# Add the incremented item id for each item in that quantity
for ( my $i = 0 ; $i < $quantity ; $i++ ) {
my $itemrecord = {%$alliteminfos};
$itemrecord->{item_id} = $item_id++;
my %itemrecord = ( # Rename price field to match UI
'item_id' => $item_id++, $itemrecord->{itemprice} = delete $itemrecord->{price} if $itemrecord->{price};
'biblio_count' => $biblio_count,
'homebranch' => $item_homebranch,
'holdingbranch' => $item_holdingbranch,
'itype' => $item_itype,
'nonpublic_note' => $item_nonpublic_note,
'public_note' => $item_public_note,
'loc' => $item_loc,
'ccode' => $item_ccode,
'notforloan' => $item_notforloan,
'uri' => $item_uri,
'copyno' => $item_copyno,
'quantity' => $item_quantity,
'budget_id' => $item_budget_id || $budget_id,
'itemprice' => $item_price || $price,
'replacementprice' => $item_replacement_price || $replacementprice,
'itemcallnumber' => $item_callnumber,
);
$all_items_quantity++; $all_items_quantity++;
push @itemlist, \%itemrecord; push @itemlist, $itemrecord;
} }
$cellrecord{'iteminfos'} = \@itemlist; $cellrecord{'iteminfos'} = \@itemlist;
@ -893,81 +682,226 @@ sub import_biblios_list {
my $overlay_action = GetImportBatchOverlayAction($import_batch_id); my $overlay_action = GetImportBatchOverlayAction($import_batch_id);
my $nomatch_action = GetImportBatchNoMatchAction($import_batch_id); my $nomatch_action = GetImportBatchNoMatchAction($import_batch_id);
my $item_action = GetImportBatchItemAction($import_batch_id); my $item_action = GetImportBatchItemAction($import_batch_id);
$template->param( my $result = {
import_biblio_list => \@list, import_biblio_list => \@list,
num_results => $num_records, num_results => $num_records,
import_batch_id => $import_batch_id, import_batch_id => $import_batch_id,
"overlay_action_${overlay_action}" => 1, overlay_action => $overlay_action,
overlay_action => $overlay_action, nomatch_action => $nomatch_action,
"nomatch_action_${nomatch_action}" => 1, item_action => $item_action,
nomatch_action => $nomatch_action, item_error => $item_error,
"item_action_${item_action}" => 1, locationloop => \@locations,
item_action => $item_action, ccodeloop => \@ccodes,
item_error => $item_error, notforloanloop => \@notforloans,
libraries => Koha::Libraries->search, batch => $batch,
locationloop => \@locations, };
itemtypes => Koha::ItemTypes->search,
ccodeloop => \@ccodes,
notforloanloop => \@notforloans,
);
_batch_info( $template, $batch );
}
=head3
Creates a hash of information to be used about an import batch in the template
=cut
sub _batch_info {
my ( $template, $batch ) = @_;
$template->param(
batch_info => 1,
file_name => $batch->{'file_name'},
comments => $batch->{'comments'},
import_status => $batch->{'import_status'},
upload_timestamp => $batch->{'upload_timestamp'},
num_records => $batch->{'num_records'},
num_items => $batch->{'num_items'}
);
if ( $batch->{'num_records'} > 0 ) { if ( $batch->{'num_records'} > 0 ) {
if ( $batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted' ) { if ( $batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted' ) {
$template->param( can_commit => 1 ); $result->{can_commit} = 1;
} }
if ( $batch->{'import_status'} eq 'imported' ) { if ( $batch->{'import_status'} eq 'imported' ) {
$template->param( can_revert => 1 ); $result->{can_revert} = 1;
} }
} }
if ( defined $batch->{'matcher_id'} ) { if ( defined $batch->{'matcher_id'} ) {
my $matcher = C4::Matcher->fetch( $batch->{'matcher_id'} ); my $matcher = C4::Matcher->fetch( $batch->{'matcher_id'} );
if ( defined $matcher ) { if ( defined $matcher ) {
$template->param( $result->{'current_matcher_id'} = $batch->{'matcher_id'};
'current_matcher_id' => $batch->{'matcher_id'}, $result->{'current_matcher_code'} = $matcher->code();
'current_matcher_code' => $matcher->code(), $result->{'current_matcher_description'} = $matcher->description();
'current_matcher_description' => $matcher->description()
);
} }
} }
_add_matcher_list( $batch->{'matcher_id'}, $template );
}
=head3
Adds a list of available matchers based on an import batch
=cut
sub _add_matcher_list {
my ( $current_matcher_id, $template ) = @_;
my @matchers = C4::Matcher::GetMatcherList(); my @matchers = C4::Matcher::GetMatcherList();
if ( defined $current_matcher_id ) { if ( defined $batch->{'matcher_id'} ) {
for ( my $i = 0 ; $i <= $#matchers ; $i++ ) { for ( my $i = 0 ; $i <= $#matchers ; $i++ ) {
if ( $matchers[$i]->{'matcher_id'} == $current_matcher_id ) { if ( $matchers[$i]->{'matcher_id'} == $batch->{'matcher_id'} ) {
$matchers[$i]->{'selected'} = 1; $matchers[$i]->{'selected'} = 1;
} }
} }
} }
$template->param( available_matchers => \@matchers ); $result->{available_matchers} = \@matchers;
return $result;
}
=head3 parse_input_into_order_line_fields
This function takes inputs from either the cronjob or UI and then parses that into a single set of order line fields that can be used to create items and order lines
my $order_line_fields = parse_input_into_order_line_fields(
{
agent => $agent,
biblionumber => $biblionumber,
budget_id => $budget_id,
basket_id => $basket_id,
fields => $item_fields,
}
);
=cut
sub parse_input_into_order_line_fields {
my ($args) = @_;
my $agent = $args->{agent};
my $client = $agent eq 'client' ? 1 : 0;
my $biblionumber = $args->{biblionumber};
my $budget_id = $args->{budget_id};
my $basket_id = $args->{basket_id};
my $fields = $args->{fields};
my $quantity = $fields->{quantity} || 1;
my @homebranches = $client ? @{ $fields->{homebranches} } : ( ( $fields->{homebranch} ) x $quantity );
my @holdingbranches = $client ? @{ $fields->{holdingbranches} } : ( ( $fields->{holdingbranch} ) x $quantity );
my @itypes = $client ? @{ $fields->{itypes} } : ( ( $fields->{itype} ) x $quantity );
my @nonpublic_notes = $client ? @{ $fields->{nonpublic_notes} } : ( ( $fields->{nonpublic_note} ) x $quantity );
my @public_notes = $client ? @{ $fields->{public_notes} } : ( ( $fields->{public_note} ) x $quantity );
my @locs = $client ? @{ $fields->{locs} } : ( ( $fields->{loc} ) x $quantity );
my @ccodes = $client ? @{ $fields->{ccodes} } : ( ( $fields->{ccode} ) x $quantity );
my @notforloans = $client ? @{ $fields->{notforloans} } : ( ( $fields->{notforloan} ) x $quantity );
my @uris = $client ? @{ $fields->{uris} } : ( ( $fields->{uri} ) x $quantity );
my @copynos = $client ? @{ $fields->{copynos} } : ( ( $fields->{copyno} ) x $quantity );
my @itemprices = $client ? @{ $fields->{itemprices} } : ( ( $fields->{price} ) x $quantity );
my @replacementprices =
$client ? @{ $fields->{replacementprices} } : ( ( $fields->{replacementprice} ) x $quantity );
my @itemcallnumbers = $client ? @{ $fields->{itemcallnumbers} } : ( ( $fields->{itemcallnumber} ) x $quantity );
my $c_quantity = $client ? $fields->{c_quantity} : $fields->{c_quantity};
my $c_budget_id = $client ? $fields->{c_budget_id} : $fields->{c_budget_id};
my $c_discount = $client ? $fields->{c_discount} : $fields->{c_discount};
my $c_sort1 = $client ? $fields->{c_sort1} : $fields->{c_sort1};
my $c_sort2 = $client ? $fields->{c_sort2} : $fields->{c_sort2};
my $c_replacement_price = $client ? $fields->{c_replacement_price} : $fields->{c_replacement_price};
my $c_price = $client ? $fields->{c_price} : $fields->{c_price};
# If using the cronjob, we want to default to the account budget if not mapped on the record
my $item_budget_id;
if ( !$client && ( $fields->{budget_code} || $fields->{c_budget_code} ) ) {
my $budget_code = $fields->{budget_code} || $fields->{c_budget_code};
my $item_budget = GetBudgetByCode($budget_code);
if ($item_budget) {
$item_budget_id = $item_budget->{budget_id};
} else {
$item_budget_id = $budget_id;
}
} else {
$item_budget_id = $budget_id;
}
my @budget_codes = $client ? @{ $fields->{budget_codes} } : ($item_budget_id);
my $loop_limit = $client ? scalar(@homebranches) : $quantity;
my $order_line_fields = {
biblionumber => $biblionumber,
homebranch => \@homebranches,
holdingbranch => \@holdingbranches,
itemnotes_nonpublic => \@nonpublic_notes,
itemnotes => \@public_notes,
location => \@locs,
ccode => \@ccodes,
itype => \@itypes,
notforloan => \@notforloans,
uri => \@uris,
copynumber => \@copynos,
price => \@itemprices,
replacementprice => \@replacementprices,
itemcallnumber => \@itemcallnumbers,
budget_code => \@budget_codes,
loop_limit => $loop_limit,
basket_id => $basket_id,
budget_id => $budget_id,
c_quantity => $c_quantity,
c_budget_id => $c_budget_id,
c_discount => $c_discount,
c_sort1 => $c_sort1,
c_sort2 => $c_sort2,
c_replacement_price => $c_replacement_price,
c_price => $c_price,
};
return $order_line_fields;
}
=head3 create_items_and_generate_order_hash
This method is used from both the cronjob and the UI to create items and generate order line details for those new items
my $order_line_details = create_items_and_generate_order_hash(
{
fields => $order_line_fields,
vendor => $vendor,
agent => $agent,
active_currency => $active_currency,
}
);
=cut
sub create_items_and_generate_order_hash {
my ($args) = @_;
my $agent = $args->{agent};
my $fields = $args->{fields};
my $loop_limit = $fields->{loop_limit};
my $basket_id = $fields->{basket_id};
my $budget_id = $fields->{budget_id};
my $vendor = $args->{vendor};
my $active_currency = $args->{active_currency};
my @order_line_details;
my $itemcreation = 0;
for ( my $i = 0 ; $i < $loop_limit ; $i++ ) {
$itemcreation = 1;
my $item = Koha::Item->new(
{
biblionumber => $fields->{biblionumber},
homebranch => @{ $fields->{homebranch} }[$i],
holdingbranch => @{ $fields->{holdingbranch} }[$i],
itemnotes_nonpublic => @{ $fields->{itemnotes_nonpublic} }[$i],
itemnotes => @{ $fields->{itemnotes} }[$i],
location => @{ $fields->{location} }[$i],
ccode => @{ $fields->{ccode} }[$i],
itype => @{ $fields->{itype} }[$i],
notforloan => @{ $fields->{notforloan} }[$i],
uri => @{ $fields->{uri} }[$i],
copynumber => @{ $fields->{copynumber} }[$i],
price => @{ $fields->{price} }[$i],
replacementprice => @{ $fields->{replacementprice} }[$i],
itemcallnumber => @{ $fields->{itemcallnumber} }[$i],
}
)->store;
my %order_detail_hash = (
biblionumber => $fields->{biblionumber},
itemnumbers => ( $item->itemnumber ),
basketno => $basket_id,
quantity => 1,
budget_id => @{ $fields->{budget_code} }[$i]
|| $budget_id,
currency => $vendor->listprice,
);
if ( @{ $fields->{price} }[$i] ) {
$order_detail_hash{tax_rate_on_ordering} = $vendor->tax_rate;
$order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
my $order_discount = $fields->{c_discount} ? $fields->{c_discount} : $vendor->discount;
$order_detail_hash{discount} = $order_discount;
$order_detail_hash{rrp} = @{ $fields->{price} }[$i];
$order_detail_hash{ecost} =
$order_discount ? @{ $fields->{price} }[$i] * ( 1 - $order_discount / 100 ) : @{ $fields->{price} }[$i];
$order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
$order_detail_hash{unitprice} = $order_detail_hash{ecost};
} else {
$order_detail_hash{listprice} = 0;
}
$order_detail_hash{replacementprice} = @{ $fields->{replacementprice} }[$i] || 0;
$order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
push @order_line_details, \%order_detail_hash;
}
return \@order_line_details;
} }
1; 1;

View file

@ -95,7 +95,11 @@ if ( $op eq "" ) {
$template->param( "basketno" => $cgiparams->{'basketno'} ); $template->param( "basketno" => $cgiparams->{'basketno'} );
#display batches #display batches
Koha::MarcOrder->import_batches_list($template); my $batches_list = Koha::MarcOrder->import_batches_list();
$template->param(
batch_list => $batches_list->{list},
num_results => $batches_list->{num_results}
);
# #
# 2nd step = display the content of the chosen file # 2nd step = display the content of the chosen file
# #
@ -112,7 +116,43 @@ if ( $op eq "" ) {
bookseller => $bookseller, bookseller => $bookseller,
"allmatch" => $allmatch, "allmatch" => $allmatch,
); );
Koha::MarcOrder->import_biblios_list( $template, $cgiparams->{'import_batch_id'} ); my $biblios_list = Koha::MarcOrder->import_biblios_list( $cgiparams->{'import_batch_id'} );
my $overlay_action = $biblios_list->{overlay_action};
my $nomatch_action = $biblios_list->{nomatch_action};
my $item_action = $biblios_list->{item_action};
my $batch = $biblios_list->{batch};
$template->param(
import_biblio_list => $biblios_list->{import_biblio_list},
num_results => $biblios_list->{num_results},
import_batch_id => $biblios_list->{import_batch_id},
"overlay_action_${overlay_action}" => 1,
overlay_action => $overlay_action,
"nomatch_action_${nomatch_action}" => 1,
nomatch_action => $nomatch_action,
"item_action_${item_action}" => 1,
item_action => $biblios_list->{item_action},
item_error => $biblios_list->{item_error},
libraries => Koha::Libraries->search,
locationloop => $biblios_list->{locationloop},
itemtypes => Koha::ItemTypes->search,
ccodeloop => $biblios_list->{ccodeloop},
notforloanloop => $biblios_list->{notforloanloop},
can_commit => $biblios_list->{can_commit},
can_revert => $biblios_list->{can_revert},
current_matcher_id => $biblios_list->{current_matcher_id},
current_matcher_code => $biblios_list->{current_matcher_code},
current_matcher_description => $biblios_list->{current_matcher_description},
available_matchers => $biblios_list->{available_matchers},
batch_info => 1,
file_name => $batch->{'file_name'},
comments => $batch->{'comments'},
import_status => $batch->{'import_status'},
upload_timestamp => $batch->{'upload_timestamp'},
num_records => $batch->{'num_records'},
num_items => $batch->{'num_items'}
);
if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) { if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
# prepare empty item form # prepare empty item form
@ -156,13 +196,6 @@ if ( $op eq "" ) {
my $duplinbatch; my $duplinbatch;
my $imported = 0; my $imported = 0;
my @import_record_id_selected = $input->multi_param("import_record_id"); my @import_record_id_selected = $input->multi_param("import_record_id");
my @quantities = $input->multi_param('quantity');
my @prices = $input->multi_param('price');
my @orderreplacementprices = $input->multi_param('replacementprice');
my @budgets_id = $input->multi_param('budget_id');
my @discount = $input->multi_param('discount');
my @sort1 = $input->multi_param('sort1');
my @sort2 = $input->multi_param('sort2');
my $matcher_id = $input->param('matcher_id'); my $matcher_id = $input->param('matcher_id');
my $active_currency = Koha::Acquisition::Currencies->get_active; my $active_currency = Koha::Acquisition::Currencies->get_active;
@ -184,6 +217,7 @@ if ( $op eq "" ) {
my @itemcallnumbers = $input->multi_param( 'itemcallnumber_' . $import_record->import_record_id ); my @itemcallnumbers = $input->multi_param( 'itemcallnumber_' . $import_record->import_record_id );
my $client_item_fields = { my $client_item_fields = {
quantity => scalar(@homebranches),
homebranches => \@homebranches, homebranches => \@homebranches,
holdingbranches => \@holdingbranches, holdingbranches => \@holdingbranches,
itypes => \@itypes, itypes => \@itypes,
@ -198,15 +232,20 @@ if ( $op eq "" ) {
itemprices => \@itemprices, itemprices => \@itemprices,
replacementprices => \@replacementprices, replacementprices => \@replacementprices,
itemcallnumbers => \@itemcallnumbers, itemcallnumbers => \@itemcallnumbers,
c_quantity => shift(@quantities) c_quantity =>
$input->param( 'quantity_' . $import_record->import_record_id )
|| GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') ) || GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') )
|| 1, || 1,
c_budget_id => shift(@budgets_id) || $input->param('all_budget_id') || $budget_id, c_budget_id =>
c_discount => shift(@discount), $input->param( 'budget_id_' . $import_record->import_record_id )
c_sort1 => shift(@sort1) || $input->param('all_sort1') || '', || $input->param('all_budget_id')
c_sort2 => shift(@sort2) || $input->param('all_sort2') || '', || $budget_id,
c_replacement_price => shift(@orderreplacementprices), c_discount => $input->param( 'discount_' . $import_record->import_record_id ),
c_price => shift(@prices) || GetMarcPrice( $marcrecord, C4::Context->preference('marcflavour') ), c_sort1 => $input->param( 'sort1_' . $import_record->import_record_id ) || $input->param('all_sort1') || '',
c_sort2 => $input->param( 'sort2_' . $import_record->import_record_id ) || $input->param('all_sort2') || '',
c_replacement_price => $input->param( 'replacementprice_' . $import_record->import_record_id ),
c_price => $input->param( 'price_' . $import_record->import_record_id )
|| GetMarcPrice( $marcrecord, C4::Context->preference('marcflavour') ),
}; };
my $args = { my $args = {