Bug 11844: Use additional fields for order lines

This patch allows to create additional fields for order lines.
Once created, these fields can be filled during order line creation or
modification.

If additional field is linked to a MARC field, there are two possible
scenario:
- MARC field mode = get: The field cannot be modified and its value is
  retrieved from the bibliographic record (current behaviour)
- MARC field mode = set: The field can be modified and its value is
  saved to the bibliographic record (new behaviour)

If additional field is linked to an authorised value category, then
authorised values are used. If not directly linked to an authorised
value category, but linked to a MARC field, a search for an AV category
is made on MARC default framework.

This patch doesn't display additional fields value anywhere (except in
order line creation/modification). Future patches will do that.

Test plan:
1/ Go to Acquisitions home
2/ In the left menu, click on "Add order line fields"
3/ Click on "New field" button
4/ Give the field a name (unique), no AV category and no MARC field.
5/ Save.
6/ Create 5 other fields:
   a/ no AV category, a MARC field not linked to AV category, MARC field
      mode = get
   b/ no AV category, a MARC field not linked to AV category, MARC field
      mode = set
   c/ no AV category, a MARC field linked to AV category, MARC field
      mode = get
   d/ no AV category, a MARC field linked to AV category, MARC field
      mode = set
   e/ an AV category, no MARC field
7/ Create everything you need to be able to create order lines
   (supplier, basket, ...)
8/ Create an order line. At bottom of the page, you should see your
   additional fields, with authorised values dropdrown list for fields
   (c), (d) and (e). Fields (a) and (c) should be disabled.
9/ Fill these fields with some data and save order line
10/ check that data was correctly saved into biblio for fields (b) and
    (d), but not for (a) and (c)
11/ modify the same order line, check that values you've filled are
    correctly retrieved and that values for (a) and (c) were correctly
    retrieved from the bibliographic record
12/ modify all values, save, and check biblio once again

Signed-off-by: Harold Dramer <harold.dramer@nyls.edu>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Julian Maurice 2014-02-05 11:12:21 +01:00 committed by Jonathan Druart
parent 09c0c2c876
commit b997250026
14 changed files with 192 additions and 31 deletions

View file

@ -32,6 +32,7 @@ use Koha::Acquisition::Baskets;
use Koha::Acquisition::Booksellers;
use Koha::Acquisition::Invoices;
use Koha::Acquisition::Orders;
use Koha::AdditionalFieldValue;
use Koha::Biblios;
use Koha::Exceptions;
use Koha::Items;
@ -1880,7 +1881,7 @@ sub TransferOrder {
my $order = Koha::Acquisition::Orders->find( $ordernumber ) or return;
return if $order->datereceived;
$order = $order->unblessed;
my $orderhash = $order->unblessed;
my $basket = GetBasket($basketno);
return unless $basket;
@ -1896,11 +1897,12 @@ sub TransferOrder {
$sth = $dbh->prepare($query);
$rv = $sth->execute('cancelled', $ordernumber);
delete $order->{'ordernumber'};
delete $order->{parent_ordernumber};
$order->{'basketno'} = $basketno;
delete $orderhash->{ordernumber};
delete $orderhash->{parent_ordernumber};
$orderhash->{basketno} = $basketno;
my $newordernumber = Koha::Acquisition::Order->new($order)->store->ordernumber;
my $neworder = Koha::Acquisition::Order->new($orderhash);
my $newordernumber = $neworder->store->ordernumber;
$query = q{
UPDATE aqorders_items
@ -1917,6 +1919,15 @@ sub TransferOrder {
$sth = $dbh->prepare($query);
$sth->execute($ordernumber, $newordernumber);
# Copy additional fields values
foreach my $afv ($order->additional_field_values->as_list) {
Koha::AdditionalFieldValue->new({
field_id => $afv->field_id,
record_id => $newordernumber,
value => $afv->value,
})->store;
}
return $newordernumber;
}

View file

@ -36,7 +36,7 @@ use Koha::Number::Price;
use Koha::Patrons;
use Koha::Subscriptions;
use base qw(Koha::Object);
use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields);
=head1 NAME

View file

@ -11,6 +11,25 @@ use Modern::Perl;
use base qw(Koha::Object);
use C4::Context;
use Koha::MarcSubfieldStructures;
sub effective_authorised_value_category {
my ($self) = @_;
my $category = $self->authorised_value_category;
unless ($category) {
if ($self->marcfield) {
my ($tag, $subfield) = split /\$/, $self->marcfield;
my $mss = Koha::MarcSubfieldStructures->find('', $tag, $subfield);
if ($mss) {
$category = $mss->authorised_value;
}
}
}
return $category;
}
sub _type { 'AdditionalField' }

View file

@ -46,8 +46,36 @@ sub set_additional_fields {
$self->additional_field_values->delete;
my $biblionumber;
my $record;
my $record_updated;
if ($self->_result->has_column('biblionumber')) {
$biblionumber = $self->biblionumber;
}
foreach my $additional_field (@$additional_fields) {
my $field = Koha::AdditionalFields->find($additional_field->{id});
my $value = $additional_field->{value};
if ($biblionumber and $field->marcfield) {
require Koha::Biblios;
$record //= Koha::Biblios->find($biblionumber)->metadata->record;
my ($tag, $subfield) = split /\$/, $field->marcfield;
my $marc_field = $record->field($tag);
if ($field->marcfield_mode eq 'get') {
$value = $marc_field ? $marc_field->subfield($subfield) : '';
} elsif ($field->marcfield_mode eq 'set') {
if ($marc_field) {
$marc_field->update($subfield => $value);
} else {
$marc_field = MARC::Field->new($tag, '', '', $subfield => $value);
$record->append_fields($marc_field);
}
$record_updated = 1;
}
}
if (defined $value) {
my $field_value = Koha::AdditionalFieldValue->new({
field_id => $additional_field->{id},
@ -56,6 +84,10 @@ sub set_additional_fields {
})->store;
}
}
if ($record_updated) {
C4::Biblio::ModBiblio($record, $biblionumber);
}
}
=head3 additional_field_values

View file

@ -892,6 +892,23 @@ __PACKAGE__->belongs_to(
},
);
__PACKAGE__->has_many(
"additional_field_values",
"Koha::Schema::Result::AdditionalFieldValue",
sub {
my ($args) = @_;
return {
"$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.ordernumber" },
# TODO Add column additional_field_values.tablename to avoid subquery ?
"$args->{foreign_alias}.field_id" =>
{ -in => \'(SELECT id FROM additional_fields WHERE tablename = "aqorders")' },
};
},
{ cascade_copy => 0, cascade_delete => 0 },
);
sub koha_objects_class {
'Koha::Acquisition::Orders';
}

View file

@ -139,6 +139,8 @@ use Koha::Acquisition::Baskets;
use C4::Barcodes;
use Koha::DateUtils qw( dt_from_string );
use Koha::AdditionalFields;
### "-------------------- addorder.pl ----------"
# FIXME: This needs to do actual error checking and possibly return user to the same form,
@ -368,6 +370,19 @@ if ( $basket->{is_standing} || $orderinfo->{quantity} ne '0' ) {
my @order_users = split( /:/, $order_users_ids );
ModOrderUsers( $order->ordernumber, @order_users );
# Retrieve and save additional fields values
my @additional_fields = Koha::AdditionalFields->search({ tablename => 'aqorders' })->as_list;
my @additional_field_values;
foreach my $af (@additional_fields) {
my $id = $af->id;
my $value = $input->param("additional_field_$id");
push @additional_field_values, {
id => $id,
value => $value,
};
}
$order->set_additional_fields(\@additional_field_values);
# now, add items if applicable
if ($basket->effective_create_items eq 'ordering') {

View file

@ -100,6 +100,7 @@ use Koha::Patrons;
use Koha::RecordProcessor;
use Koha::Subscriptions;
use Koha::UI::Form::Builder::Biblio;
use Koha::AdditionalFields;
our $input = CGI->new;
my $booksellerid = $input->param('booksellerid'); # FIXME: else ERROR!
@ -415,6 +416,29 @@ my $quantity = $input->param('rr_quantity_to_order') ?
$data->{'quantity'};
$quantity //= 0;
# Get additional fields
my $record;
my @additional_fields = Koha::AdditionalFields->search({ tablename => 'aqorders' })->as_list;
my %additional_field_values;
if ($ordernumber) {
my $order = Koha::Acquisition::Orders->find($ordernumber);
foreach my $value ($order->additional_field_values->as_list) {
$additional_field_values{$value->field_id} = $value->value;
}
} elsif ( $biblionumber ) {
foreach my $af (@additional_fields) {
if ($af->marcfield) {
$record //= Koha::Biblios->find($biblionumber)->metadata->record;
my ($field, $subfield) = split /\$/, $af->marcfield;
$additional_field_values{$af->id} = $record->subfield($field, $subfield);
}
}
}
$template->param(
additional_fields => \@additional_fields,
additional_field_values => \%additional_field_values,
);
# fill template
$template->param(
existing => $biblionumber,

View file

@ -51,6 +51,7 @@ if ( $op eq 'add' ) {
my $name = $input->param('name') // q{};
my $authorised_value_category = $input->param('authorised_value_category') // q{};
my $marcfield = $input->param('marcfield') // q{};
my $marcfield_mode = $input->param('marcfield_mode') // 'get';
my $searchable = $input->param('searchable') ? 1 : 0;
if ( $field_id and $name ) {
my $updated = 0;
@ -60,6 +61,7 @@ if ( $op eq 'add' ) {
name => $name,
authorised_value_category => $authorised_value_category,
marcfield => $marcfield,
marcfield_mode => $marcfield_mode,
searchable => $searchable,
});
$updated = $af->store ? 1 : 0;
@ -76,6 +78,7 @@ if ( $op eq 'add' ) {
name => $name,
authorised_value_category => $authorised_value_category,
marcfield => $marcfield,
marcfield_mode => $marcfield_mode,
searchable => $searchable,
});
$inserted = $af->store ? 1 : 0;

View file

@ -0,0 +1,17 @@
use Modern::Perl;
return {
bug_number => '11844',
description => 'Add column additional_fields.marcfield_mode',
up => sub {
my ($args) = @_;
my ($dbh, $out) = @$args{qw(dbh out)};
unless ( column_exists( 'additional_fields', 'marcfield_mode' ) ) {
$dbh->do(q{
ALTER TABLE additional_fields
ADD COLUMN marcfield_mode ENUM('get', 'set') NOT NULL DEFAULT 'get' COMMENT 'mode of operation (get or set) for marcfield' AFTER marcfield
});
}
},
};

View file

@ -244,6 +244,7 @@ CREATE TABLE `additional_fields` (
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'name of the field',
`authorised_value_category` varchar(32) NOT NULL DEFAULT '' COMMENT 'is an authorised value category',
`marcfield` varchar(16) NOT NULL DEFAULT '' COMMENT 'contains the marc field to copied into the record',
`marcfield_mode` ENUM('get', 'set') NOT NULL DEFAULT 'get' COMMENT 'mode of operation (get or set) for marcfield',
`searchable` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'is the field searchable?',
PRIMARY KEY (`id`),
UNIQUE KEY `fields_uniq` (`tablename`(191),`name`(191))

View file

@ -5,26 +5,34 @@
<ol>
[% END %]
[% FOR field IN available %]
[% authorised_value_category = field.effective_authorised_value_category %]
<li>
<label for="additional_field_[% field.id | html %]"> [% field.name | html %]: </label>
[% IF field.authorised_value_category %]
<select name="additional_field_[% field.id | html %]" id="additional_field_[% field.id | html %]">
[% IF authorised_value_category %]
[% IF field.marcfield && field.marcfield_mode == 'get' %]
<select name="additional_field_[% field.id | html %]" id="additional_field_[% field.id | html %]" disabled>
[% ELSE %]
<select name="additional_field_[% field.id | html %]" id="additional_field_[% field.id | html %]">
[% END %]
<option value=""></option>
[% FOREACH av IN AuthorisedValues.GetAuthValueDropbox( field.authorised_value_category ) %]
[% FOREACH av IN AuthorisedValues.GetAuthValueDropbox( authorised_value_category ) %]
[% IF av.authorised_value == values.${field.id} %]
<option value="[% av.authorised_value | html %]" selected="selected">[% av.lib | html %]</option>
[% ELSE %]
<option value="[% av.authorised_value | html %]">[% av.lib | html %]</option>
[% END %]
[% END %]
</select> <span>(Authorised values for [% field.authorised_value_category | html %])</span>
</select> <span>(Authorised values for [% authorised_value_category | html %])</span>
[% ELSIF field.marcfield && field.marcfield_mode == 'get' %]
<input type="text" value="[% values.${field.id} | html %]" id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]" readonly="readonly" />
[% ELSE %]
[% IF field.marcfield %]
<input type="text" value="[% values.${field.id} | html %]" id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]" readonly="readonly" />
This value will be filled with the [% field.marcfield | html %] subfield of the selected biblio.
[% ELSE %]
<input type="text" value="[% values.${field.id} | html %]" id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]" />
[% END %]
<input type="text" value="[% values.${field.id} | html %]" id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]" />
[% END %]
[% IF field.marcfield && field.marcfield_mode == 'get' %]
This value will be filled with the [% field.marcfield | html %] subfield of the selected biblio.
[% ELSIF field.marcfield && field.marcfield_mode == 'set' %]
This value will be saved to the [% field.marcfield %] subfield of the selected biblio.
[% END %]
</li>
[% END %]

View file

@ -4,6 +4,7 @@
[% USE KohaDates %]
[% USE Price %]
[% USE ItemTypes %]
[% USE AuthorisedValues %]
[% INCLUDE 'doc-head-open.inc' %]
<title>[% IF ( ordernumber ) %]Modify order details (line #[% ordernumber | html %])[% ELSE %]New order[% END %] &rsaquo; Basket [% basketno | html %] &rsaquo; Acquisitions &rsaquo; Koha</title>
[% INCLUDE 'doc-head-close.inc' %]
@ -697,6 +698,9 @@
</li>
</ol>
</fieldset>
[% INCLUDE 'additional-fields-entry.inc' available = additional_fields values = additional_field_values %]
<fieldset class="action">
<input type="hidden" name="subscriptionid" value="[% subscriptionid | html %]" />
<input type="submit" class="btn btn-primary" value="Save" />

View file

@ -11,7 +11,7 @@
[% INCLUDE 'doc-head-close.inc' %]
</head>
[% marcfield_tables = ['subscription'] %]
[% marcfield_tables = ['subscription', 'aqorders'] %]
[% searchable_tables = ['subscription', 'aqbasket', 'aqinvoices'] %]
[% show_marcfield = marcfield_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
[% show_searchable = searchable_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
@ -105,6 +105,7 @@
<ul>
[% IF CAN_user_acquisition_order_manage %]
[% WRAPPER table_option value="aqbasket" %]<span>Order baskets</span>[% END %]
[% WRAPPER table_option value="aqorders" %]<span>Order lines</span>[% END %]
[% END %]
[% IF CAN_user_acquisition_edit_invoices %]
[% WRAPPER table_option value="aqinvoices" %]<span>Invoices</span>[% END %]
@ -132,6 +133,7 @@
<th>Authorized value category</th>
[% IF show_marcfield %]
<th>MARC field</th>
<th>MARC field mode</th>
[% END %]
[% IF show_searchable %]
<th>Searchable</th>
@ -146,6 +148,12 @@
<td>[% field.authorised_value_category | html %]</td>
[% IF show_marcfield %]
<td>[% field.marcfield | html %]</td>
<td>
[% SWITCH field.marcfield_mode %]
[% CASE 'get' %]Get value from MARC record
[% CASE 'set' %]Save value to MARC record
[% END %]
</td>
[% END %]
[% IF show_searchable %]
<td>
@ -190,6 +198,22 @@
<label for="marcfield">MARC field: </label>
<input type="text" name="marcfield" id="marcfield" value="[% field.marcfield | html %]" />
</li>
<li>
<label for="marcfield_mode">MARC field mode: </label>
<select id="marcfield_mode" name="marcfield_mode">
[% IF field.marcfield_mode == 'get' %]
<option value="get" selected>Get value from MARC record (not modifiable)</option>
[% ELSE %]
<option value="get">Get value from MARC record (not modifiable)</option>
[% END %]
[% IF field.marcfield_mode == 'set' %]
<option value="set" selected>Save value to MARC record</option>
[% ELSE %]
<option value="set">Save value to MARC record</option>
[% END %]
</select>
</li>
[% END %]
[% IF show_searchable %]
<li>

View file

@ -365,16 +365,9 @@ sub redirect_add_subscription {
my @additional_fields;
my $biblio = Koha::Biblios->find($biblionumber);
my $record = $biblio->metadata->record({ embed_items => 1 });
my $subscription_fields = Koha::AdditionalFields->search({ tablename => 'subscription' });
while ( my $field = $subscription_fields->next ) {
my $value = $query->param('additional_field_' . $field->id);
if ($field->marcfield) {
my ($field, $subfield) = split /\$/, $field->marcfield;
if ( $record and $field and $subfield ) {
$value = $record->subfield( $field, $subfield );
}
}
push @additional_fields, {
id => $field->id,
value => $value,
@ -485,16 +478,9 @@ sub redirect_mod_subscription {
my @additional_fields;
my $biblio = Koha::Biblios->find($biblionumber);
my $record = $biblio->metadata->record({ embed_items => 1 });
my $subscription_fields = Koha::AdditionalFields->search({ tablename => 'subscription' });
while ( my $field = $subscription_fields->next ) {
my $value = $query->param('additional_field_' . $field->id);
if ($field->marcfield) {
my ($field, $subfield) = split /\$/, $field->marcfield;
if ( $record and $field and $subfield ) {
$value = $record->subfield( $field, $subfield );
}
}
push @additional_fields, {
id => $field->id,
value => $value,