View | Details | Raw Unified | Return to bug 40391
Collapse All | Expand All

(-)a/Koha/EDI.pm (-3 / +107 lines)
Lines 44-49 use Koha::Plugins; # Adds plugin dirs to @INC Link Here
44
use Koha::Plugins::Handler;
44
use Koha::Plugins::Handler;
45
use Koha::Acquisition::Baskets;
45
use Koha::Acquisition::Baskets;
46
use Koha::Acquisition::Booksellers;
46
use Koha::Acquisition::Booksellers;
47
use Koha::AuthorisedValues;
47
use Koha::Util::FrameworkPlugin qw( biblio_008 );
48
use Koha::Util::FrameworkPlugin qw( biblio_008 );
48
49
49
our $VERSION = 1.1;
50
our $VERSION = 1.1;
Lines 993-999 sub quote_item { Link Here
993
                    };
994
                    };
994
995
995
                    my $lsq_field = C4::Context->preference('EdifactLSQ');
996
                    my $lsq_field = C4::Context->preference('EdifactLSQ');
996
                    $new_item->{$lsq_field} = $item->girfield( 'sequence_code', $occurrence );
997
                    my $lsl_field = C4::Context->preference('EdifactLSL');
998
999
                    # Handle LSQ field
1000
                    if ( $lsq_field && $item->girfield( 'sequence_code', $occurrence ) ) {
1001
                        my $lsq_value = $item->girfield( 'sequence_code', $occurrence );
1002
                        my $valid =
1003
                            ( $lsq_field eq 'location' )
1004
                            ? _validate_location_code( $lsq_value, $quote_message )
1005
                            : _validate_collection_code( $lsq_value, $quote_message );
1006
1007
                        $new_item->{$lsq_field} = $lsq_value if $valid;
1008
                    }
1009
1010
                    # Handle LSL field
1011
                    if ( $lsl_field && $item->girfield( 'sub_location_code', $occurrence ) ) {
1012
                        my $lsl_value = $item->girfield( 'sub_location_code', $occurrence );
1013
                        my $valid =
1014
                            ( $lsl_field eq 'location' )
1015
                            ? _validate_location_code( $lsl_value, $quote_message )
1016
                            : _validate_collection_code( $lsl_value, $quote_message );
1017
1018
                        $new_item->{$lsl_field} = $lsl_value if $valid;
1019
                    }
997
1020
998
                    if ( $new_item->{itype} ) {
1021
                    if ( $new_item->{itype} ) {
999
                        $item_hash->{itype} = $new_item->{itype};
1022
                        $item_hash->{itype} = $new_item->{itype};
Lines 1077-1083 sub quote_item { Link Here
1077
                        homebranch    => $item->girfield( 'branch', $occurrence ),
1100
                        homebranch    => $item->girfield( 'branch', $occurrence ),
1078
                    };
1101
                    };
1079
                    my $lsq_field = C4::Context->preference('EdifactLSQ');
1102
                    my $lsq_field = C4::Context->preference('EdifactLSQ');
1080
                    $new_item->{$lsq_field}       = $item->girfield( 'sequence_code', $occurrence );
1103
                    my $lsl_field = C4::Context->preference('EdifactLSL');
1104
1105
                    # Handle LSQ mapping with validation
1106
                    if ( $lsq_field && $item->girfield( 'sequence_code', $occurrence ) ) {
1107
                        my $lsq_value = $item->girfield( 'sequence_code', $occurrence );
1108
                        my $valid =
1109
                            ( $lsq_field eq 'location' )
1110
                            ? _validate_location_code( $lsq_value, $quote_message )
1111
                            : _validate_collection_code( $lsq_value, $quote_message );
1112
1113
                        $new_item->{$lsq_field} = $lsq_value if $valid;
1114
                    }
1115
1116
                    # Handle LSL mapping with validation
1117
                    if ( $lsl_field && $item->girfield( 'sub_location_code', $occurrence ) ) {
1118
                        my $lsl_value = $item->girfield( 'sub_location_code', $occurrence );
1119
                        my $valid =
1120
                            ( $lsl_field eq 'location' )
1121
                            ? _validate_location_code( $lsl_value, $quote_message )
1122
                            : _validate_collection_code( $lsl_value, $quote_message );
1123
1124
                        $new_item->{$lsl_field} = $lsl_value if $valid;
1125
                    }
1081
                    $new_item->{biblionumber}     = $bib->{biblionumber};
1126
                    $new_item->{biblionumber}     = $bib->{biblionumber};
1082
                    $new_item->{biblioitemnumber} = $bib->{biblioitemnumber};
1127
                    $new_item->{biblioitemnumber} = $bib->{biblioitemnumber};
1083
                    my $kitem      = Koha::Item->new($new_item)->store;
1128
                    my $kitem      = Koha::Item->new($new_item)->store;
Lines 1127-1132 sub get_edifact_ean { Link Here
1127
    return $eans->[0];
1172
    return $eans->[0];
1128
}
1173
}
1129
1174
1175
sub _validate_location_code {
1176
    my ( $location_code, $quote_message ) = @_;
1177
1178
    return 1 unless $location_code;    # Skip if empty
1179
1180
    my $av = Koha::AuthorisedValues->find(
1181
        {
1182
            category         => 'LOC',
1183
            authorised_value => $location_code
1184
        }
1185
    );
1186
1187
    unless ($av) {
1188
        $quote_message->add_to_edifact_errors(
1189
            {
1190
                section => "GIR+LSQ/LSL validation",
1191
                details => "Invalid location code '$location_code' - not found in LOC authorized values"
1192
            }
1193
        );
1194
        return 0;
1195
    }
1196
    return 1;
1197
}
1198
1199
sub _validate_collection_code {
1200
    my ( $ccode, $quote_message ) = @_;
1201
1202
    return 1 unless $ccode;    # Skip if empty
1203
1204
    my $av = Koha::AuthorisedValues->find(
1205
        {
1206
            category         => 'CCODE',
1207
            authorised_value => $ccode
1208
        }
1209
    );
1210
1211
    unless ($av) {
1212
        $quote_message->add_to_edifact_errors(
1213
            {
1214
                section => "GIR+LSQ/LSL validation",
1215
                details => "Invalid collection code '$ccode' - not found in CCODE authorized values"
1216
            }
1217
        );
1218
        return 0;
1219
    }
1220
    return 1;
1221
}
1222
1130
# We should not need to have a routine to do this here
1223
# We should not need to have a routine to do this here
1131
sub _discounted_price {
1224
sub _discounted_price {
1132
    my ( $discount, $price, $discounted_price ) = @_;
1225
    my ( $discount, $price, $discounted_price ) = @_;
Lines 1280-1287 sub _create_item_from_quote { Link Here
1280
    $item_hash->{booksellerid} = $quote->vendor_id;
1373
    $item_hash->{booksellerid} = $quote->vendor_id;
1281
    $item_hash->{price}        = $item_hash->{replacementprice} = $item->price;
1374
    $item_hash->{price}        = $item_hash->{replacementprice} = $item->price;
1282
    $item_hash->{itype}        = $item->girfield('stock_category');
1375
    $item_hash->{itype}        = $item->girfield('stock_category');
1376
1283
    my $lsq_field = C4::Context->preference('EdifactLSQ');
1377
    my $lsq_field = C4::Context->preference('EdifactLSQ');
1284
    $item_hash->{$lsq_field} = $item->girfield('sequence_code');
1378
    my $lsl_field = C4::Context->preference('EdifactLSL');
1379
1380
    # Handle LSQ mapping
1381
    if ( $lsq_field && $item->girfield('sequence_code') ) {
1382
        $item_hash->{$lsq_field} = $item->girfield('sequence_code');
1383
    }
1384
1385
    # Handle LSL mapping
1386
    if ( $lsl_field && $item->girfield('sub_location_code') ) {
1387
        $item_hash->{$lsl_field} = $item->girfield('sub_location_code');
1388
    }
1285
1389
1286
    my $note = {};
1390
    my $note = {};
1287
1391
(-)a/Koha/Edifact/Line.pm (+1 lines)
Lines 658-663 sub extract_gir { Link Here
658
        LRS => 'record_sublocation',
658
        LRS => 'record_sublocation',
659
        LSM => 'shelfmark',
659
        LSM => 'shelfmark',
660
        LSQ => 'sequence_code',
660
        LSQ => 'sequence_code',
661
        LSL => 'sub_location_code',
661
        LST => 'stock_category',
662
        LST => 'stock_category',
662
        LSZ => 'size_code',
663
        LSZ => 'size_code',
663
        LVC => 'coded_servicing_instruction',
664
        LVC => 'coded_servicing_instruction',
(-)a/Koha/Edifact/Order.pm (-7 / +38 lines)
Lines 371-376 sub order_line { Link Here
371
    #     we dont currently support this in koha
371
    #     we dont currently support this in koha
372
    # GIR copy-related data
372
    # GIR copy-related data
373
    my $lsq_field = C4::Context->preference('EdifactLSQ');
373
    my $lsq_field = C4::Context->preference('EdifactLSQ');
374
    my $lsl_field = C4::Context->preference('EdifactLSL');
374
    my @items;
375
    my @items;
375
    if ( $basket->effective_create_items eq 'ordering' ) {
376
    if ( $basket->effective_create_items eq 'ordering' ) {
376
377
Lines 378-389 sub order_line { Link Here
378
        foreach my $item (@linked_itemnumbers) {
379
        foreach my $item (@linked_itemnumbers) {
379
            my $i_obj = $schema->resultset('Item')->find( $item->itemnumber );
380
            my $i_obj = $schema->resultset('Item')->find( $item->itemnumber );
380
            if ( defined $i_obj ) {
381
            if ( defined $i_obj ) {
381
                push @items, {
382
                my $item_data = {
382
                    branchcode     => $i_obj->get_column('homebranch'),
383
                    branchcode     => $i_obj->get_column('homebranch'),
383
                    itype          => $i_obj->effective_itemtype,
384
                    itype          => $i_obj->effective_itemtype,
384
                    $lsq_field     => $i_obj->$lsq_field,
385
                    itemcallnumber => $i_obj->itemcallnumber,
385
                    itemcallnumber => $i_obj->itemcallnumber,
386
                };
386
                };
387
388
                # Handle LSQ mapping
389
                if ($lsq_field) {
390
                    $item_data->{$lsq_field} = $i_obj->$lsq_field;
391
                }
392
393
                # Handle LSL mapping
394
                if ($lsl_field) {
395
                    $item_data->{$lsl_field} = $i_obj->$lsl_field;
396
                }
397
398
                push @items, $item_data;
387
            }
399
            }
388
        }
400
        }
389
    } else {
401
    } else {
Lines 404-416 sub order_line { Link Here
404
416
405
    my $item_fields = [];
417
    my $item_fields = [];
406
    for my $item (@items) {
418
    for my $item (@items) {
407
        push @{$item_fields},
419
        my $item_field_data = {
408
            {
409
            branchcode     => $item->{branchcode},
420
            branchcode     => $item->{branchcode},
410
            itype          => $item->{itype},
421
            itype          => $item->{itype},
411
            $lsq_field     => $item->{$lsq_field},
412
            itemcallnumber => $item->{itemcallnumber},
422
            itemcallnumber => $item->{itemcallnumber},
413
            };
423
        };
424
425
        # Handle LSQ mapping
426
        if ( $lsq_field && $item->{$lsq_field} ) {
427
            $item_field_data->{$lsq_field} = $item->{$lsq_field};
428
        }
429
430
        # Handle LSL mapping
431
        if ( $lsl_field && $item->{$lsl_field} ) {
432
            $item_field_data->{$lsl_field} = $item->{$lsl_field};
433
        }
434
435
        push @{$item_fields}, $item_field_data;
414
    }
436
    }
415
    $self->add_seg(
437
    $self->add_seg(
416
        gir_segments(
438
        gir_segments(
Lines 541-546 sub gir_segments { Link Here
541
    my @segments;
563
    my @segments;
542
    my $sequence_no = 1;
564
    my $sequence_no = 1;
543
    my $lsq_field   = C4::Context->preference('EdifactLSQ');
565
    my $lsq_field   = C4::Context->preference('EdifactLSQ');
566
    my $lsl_field   = C4::Context->preference('EdifactLSL');
544
    foreach my $item (@onorderitems) {
567
    foreach my $item (@onorderitems) {
545
        my $elements_added = 0;
568
        my $elements_added = 0;
546
        my @gir_elements;
569
        my @gir_elements;
Lines 556-565 sub gir_segments { Link Here
556
            push @gir_elements,
579
            push @gir_elements,
557
                { identity_number => 'LST', data => $item->{itype} };
580
                { identity_number => 'LST', data => $item->{itype} };
558
        }
581
        }
559
        if ( $item->{$lsq_field} ) {
582
583
        # Handle LSQ mapping
584
        if ( $lsq_field && $item->{$lsq_field} ) {
560
            push @gir_elements,
585
            push @gir_elements,
561
                { identity_number => 'LSQ', data => $item->{$lsq_field} };
586
                { identity_number => 'LSQ', data => $item->{$lsq_field} };
562
        }
587
        }
588
589
        # Handle LSL mapping
590
        if ( $lsl_field && $item->{$lsl_field} ) {
591
            push @gir_elements,
592
                { identity_number => 'LSL', data => $item->{$lsl_field} };
593
        }
563
        if ( $item->{itemcallnumber} ) {
594
        if ( $item->{itemcallnumber} ) {
564
            push @gir_elements,
595
            push @gir_elements,
565
                { identity_number => 'LSM', data => $item->{itemcallnumber} };
596
                { identity_number => 'LSM', data => $item->{itemcallnumber} };
(-)a/installer/data/mysql/atomicupdate/bug_40391.pl (+31 lines)
Line 0 Link Here
1
use Modern::Perl;
2
use Koha::Installer::Output qw(say_warning say_success say_info);
3
4
return {
5
    bug_number  => "40391",
6
    description => "Add EdifactLSL system preference for GIR:LSL (Library Sub-Location) field mapping",
7
    up          => sub {
8
        my ($args) = @_;
9
        my ( $dbh, $out ) = @$args{qw(dbh out)};
10
11
        # Update existing EdifactLSQ preference to include empty option
12
        $dbh->do(
13
            q{
14
            UPDATE systempreferences
15
            SET options = 'location|ccode|', explanation = 'Map EDI sequence code (GIR+LSQ) to Koha Item field, empty to ignore'
16
            WHERE variable = 'EdifactLSQ'
17
        }
18
        );
19
20
        # Add new EdifactLSL preference
21
        $dbh->do(
22
            q{
23
            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type)
24
            VALUES ('EdifactLSL', '', 'location|ccode|', 'Map EDI sub-location code (GIR+LSL) to Koha Item field, empty to ignore', 'Choice')
25
        }
26
        );
27
28
        say_success( $out, "Updated EdifactLSQ system preference to include empty option" );
29
        say_success( $out, "Added EdifactLSL system preference for GIR:LSL field mapping" );
30
    },
31
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-2 / +3 lines)
Lines 233-239 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
233
('EasyAnalyticalRecords','0','','If on, display in the catalogue screens tools to easily setup analytical record relationships','YesNo'),
233
('EasyAnalyticalRecords','0','','If on, display in the catalogue screens tools to easily setup analytical record relationships','YesNo'),
234
('EDIFACT','0',NULL,'Enables EDIFACT acquisitions functions','YesNo'),
234
('EDIFACT','0',NULL,'Enables EDIFACT acquisitions functions','YesNo'),
235
('EdifactInvoiceImport', 'automatic', 'automatic|manual', "If on, don't auto-import EDI invoices, just keep them in the database with the status 'new'", 'Choice'),
235
('EdifactInvoiceImport', 'automatic', 'automatic|manual', "If on, don't auto-import EDI invoices, just keep them in the database with the status 'new'", 'Choice'),
236
('EdifactLSQ', 'location', 'location|ccode', 'Map EDI sequence code (GIR+LSQ) to Koha Item field', 'Choice'),
236
('EdifactLSL', 'ccode', 'location|ccode|', 'Map EDI sub-location code (GIR+LSL) to Koha Item field, empty to ignore', 'Choice'),
237
('EdifactLSQ', 'location', 'location|ccode|', 'Map EDI sequence code (GIR+LSQ) to Koha Item field, empty to ignore', 'Choice'),
237
('ElasticsearchBoostFieldMatch', '0', NULL, 'Add a "match" query to es when searching, will follow indexes chosen in advanced search, or use title-cover for generic keyword or title index search', 'YesNo'),
238
('ElasticsearchBoostFieldMatch', '0', NULL, 'Add a "match" query to es when searching, will follow indexes chosen in advanced search, or use title-cover for generic keyword or title index search', 'YesNo'),
238
('ElasticsearchCrossFields', '1', '', 'Enable "cross_fields" option for searches using Elastic search.', 'YesNo'),
239
('ElasticsearchCrossFields', '1', '', 'Enable "cross_fields" option for searches using Elastic search.', 'YesNo'),
239
('ElasticsearchIndexStatus_authorities', '0', 'Authorities index status', NULL, NULL),
240
('ElasticsearchIndexStatus_authorities', '0', 'Authorities index status', NULL, NULL),
Lines 889-892 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
889
('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'),
890
('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'),
890
('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo'),
891
('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo'),
891
('z3950Status','','','This syspref allows to define custom YAML based rules for marking items unavailable in z3950 results.','Textarea')
892
('z3950Status','','','This syspref allows to define custom YAML based rules for marking items unavailable in z3950 results.','Textarea')
892
;
893
;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref (-1 / +10 lines)
Lines 185-188 Acquisitions: Link Here
185
              choices:
185
              choices:
186
                location: "location"
186
                location: "location"
187
                ccode: "collection"
187
                ccode: "collection"
188
                "": "ignore"
189
            - " in items."
190
        -
191
            - "Map sub-location code (GIR:LSL) field to "
192
            - pref: EdifactLSL
193
              default: ""
194
              choices:
195
                location: "location"
196
                ccode: "collection"
197
                "": "ignore"
188
            - " in items."
198
            - " in items."
189
- 

Return to bug 40391