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

(-)a/Koha/Preservation/Train.pm (-7 / +14 lines)
Lines 56-90 sub default_processing { Link Here
56
56
57
Add item to this train
57
Add item to this train
58
58
59
my $train_item = $train->add_item({item_id => $itemnumber, processing_id => $processing_id});
59
my $train_item = $train->add_item({item_id => $itemnumber, processing_id => $processing_id}, { skip_waiting_list_check => 0|1 });
60
my $train_item = $train->add_item({barcode => $barcode, processing_id => $processing_id});
60
my $train_item = $train->add_item({barcode => $barcode, processing_id => $processing_id, { skip_waiting_list_check => 0|1 });
61
62
skip_waitin_list_check can be set to true if the item can be added to the train even if the item is not in the waiting list.
61
63
62
=cut
64
=cut
63
65
64
sub add_item {
66
sub add_item {
65
    my ( $self, $train_item ) = @_;
67
    my ( $self, $train_item, $params ) = @_;
68
69
    my $skip_waiting_list_check = $params->{skip_waiting_list_check} || 0;
66
70
67
    my $not_for_loan = C4::Context->preference('PreservationNotForLoanWaitingListIn');
71
    my $not_for_loan = C4::Context->preference('PreservationNotForLoanWaitingListIn');
68
72
69
    my $key  = exists $train_item->{item_id} ? 'itemnumber' : 'barcode';
73
    my $key  = exists $train_item->{item_id} ? 'itemnumber' : 'barcode';
70
    my $item = Koha::Items->find( { $key => $train_item->{item_id} || $train_item->{barcode} } );
74
    my $item = Koha::Items->find( { $key => $train_item->{item_id} || $train_item->{barcode} } );
71
    Koha::Exceptions::Preservation::ItemNotFound->throw unless $item;
75
    Koha::Exceptions::Preservation::ItemNotFound->throw unless $item;
72
    Koha::Exceptions::Preservation::ItemNotInWaitingList->throw if $item->notforloan != $not_for_loan;
76
77
    Koha::Exceptions::Preservation::ItemNotInWaitingList->throw
78
      if !$skip_waiting_list_check && $item->notforloan != $not_for_loan;
73
79
74
    # FIXME We need a LOCK here
80
    # FIXME We need a LOCK here
75
    # Not important for now as we have add_items
81
    # Not important for now as we have add_items
76
    # Note that there are several other places in Koha with this max+1 problem
82
    # Note that there are several other places in Koha with this max+1 problem
77
    my $max = $self->items->search->_resultset->get_column("user_train_item_id")->max || 0;
83
    my $max = $self->items->search->_resultset->get_column("user_train_item_id")->max || 0;
78
    my $train_item_rs = $self->_result->add_to_preservation_trains_items(
84
    my $train_item_object = Koha::Preservation::Train::Item->new(
79
        {
85
        {
86
            train_id      => $self->train_id,
80
            item_id       => $item->itemnumber,
87
            item_id       => $item->itemnumber,
81
            processing_id => $train_item->{processing_id} || $self->default_processing_id,
88
            processing_id => $train_item->{processing_id} || $self->default_processing_id,
82
            user_train_item_id => $max + 1,
89
            user_train_item_id => $max + 1,
83
            added_on      => \'NOW()',
90
            added_on      => \'NOW()',
84
        }
91
        }
85
    );
92
    )->store;
86
    $item->notforloan( $self->not_for_loan )->store;
93
    $item->notforloan( $self->not_for_loan )->store;
87
    return Koha::Preservation::Train::Item->_new_from_dbic($train_item_rs);
94
    return $train_item_object->get_from_storage;
88
}
95
}
89
96
90
=head3 add_items
97
=head3 add_items
(-)a/Koha/REST/V1/Preservation/Trains.pm (+92 lines)
Lines 389-394 sub add_item { Link Here
389
    };
389
    };
390
}
390
}
391
391
392
=head3 copy_item
393
394
=cut
395
396
sub copy_item {
397
    my $c = shift->openapi->valid_input or return;
398
399
    my $train_id = $c->validation->param('train_id');
400
    my $train = Koha::Preservation::Trains->find( $train_id );
401
402
    unless ($train) {
403
        return $c->render(
404
            status  => 404,
405
            openapi => { error => "Train not found" }
406
        );
407
    }
408
409
    my $train_item_id = $c->validation->param('train_item_id');
410
411
    my $train_item = Koha::Preservation::Train::Items->search({ train_item_id => $train_item_id, train_id => $train_id })->single;
412
413
    unless ($train_item) {
414
        return $c->render(
415
            status  => 404,
416
            openapi => { error => "Item not found" }
417
        );
418
    }
419
420
    my $body = $c->validation->param('body');
421
    return try {
422
        Koha::Database->new->schema->txn_do(
423
            sub {
424
                my $new_train_id = delete $body->{train_id};
425
                my $new_train = Koha::Preservation::Trains->find( $new_train_id );
426
                unless ($train) {
427
                    return $c->render(
428
                        status  => 404,
429
                        openapi => { error => "Train not found" }
430
                    );
431
                }
432
                my $new_train_item = $new_train->add_item(
433
                    {
434
                        item_id       => $train_item->item_id,
435
                        processing_id => $train_item->processing_id
436
                    },
437
                    {
438
                        skip_waiting_list_check => 1,
439
                    },
440
                );
441
                my $attributes = [
442
                    map {
443
                        {
444
                            processing_attribute_id => $_->processing_attribute_id,
445
                            train_item_id => $new_train_item->train_item_id,
446
                            value         => $_->value
447
                        }
448
                    } $train_item->attributes->as_list
449
                  ];
450
                $new_train_item->attributes($attributes);
451
                return $c->render( status => 201, openapi => $train_item );
452
              }
453
        );
454
    }
455
    catch {
456
        if ( blessed $_ ) {
457
            if ( $_->isa('Koha::Exceptions::Preservation::MissingSettings') ) {
458
                return $c->render(
459
                    status  => 400,
460
                    openapi => { error => "MissingSettings", parameter => $_->parameter }
461
                );
462
            } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotFound') ) {
463
                return $c->render(
464
                    status  => 404,
465
                    openapi => { error => "Item not found" }
466
                );
467
            } elsif ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
468
                return $c->render(
469
                    status  => 409,
470
                    openapi => { error => $_->error, conflict => $_->duplicate_id }
471
                );
472
            } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotInWaitingList') ) {
473
                return $c->render(
474
                    status  => 400,
475
                    openapi => { error => 'Item not in waiting list' }
476
                );
477
            }
478
        }
479
480
        $c->unhandled_exception($_);
481
    };
482
}
483
392
=head3 update_item
484
=head3 update_item
393
485
394
Controller function that handles updating an item from a train
486
Controller function that handles updating an item from a train
(-)a/api/v1/swagger/paths/preservation_trains.yaml (+75 lines)
Lines 619-621 Link Here
619
    x-koha-authorization:
619
    x-koha-authorization:
620
      permissions:
620
      permissions:
621
        preservation: 1
621
        preservation: 1
622
623
"/preservation/trains/{train_id}/items/{train_item_id}/copy":
624
  post:
625
    x-mojo-to: Preservation::Trains#copy_item
626
    operationId: copyItemToAnotherTrain
627
    tags:
628
      - preservation_train
629
    summary: Copy an item to an other train
630
    consumes:
631
      - application/json
632
    produces:
633
      - application/json
634
    parameters:
635
      - $ref: "../swagger.yaml#/parameters/preservation_train_id_pp"
636
      - $ref: "../swagger.yaml#/parameters/preservation_train_item_id_pp"
637
      - description: The train_id of the new train
638
        in: body
639
        name: body
640
        required: true
641
        schema:
642
          type: object
643
    responses:
644
      201:
645
        description: A successfully copied item
646
        schema:
647
          type: object
648
      400:
649
        description: Bad parameter
650
        schema:
651
          $ref: "../swagger.yaml#/definitions/error"
652
      401:
653
        description: Authentication required
654
        schema:
655
          $ref: "../swagger.yaml#/definitions/error"
656
      403:
657
        description: Access forbidden
658
        schema:
659
          $ref: "../swagger.yaml#/definitions/error"
660
      404:
661
        description: Ressource not found
662
        schema:
663
          $ref: "../swagger.yaml#/definitions/error"
664
      409:
665
        description: Conflict in creating resource
666
        schema:
667
          $ref: "../swagger.yaml#/definitions/error"
668
      413:
669
        description: Payload too large
670
        schema:
671
          $ref: "../swagger.yaml#/definitions/error"
672
      500:
673
        description: |-
674
          Internal server error. Possible `error_code` attribute values:
675
          * `internal_server_error`
676
        schema:
677
          $ref: "../swagger.yaml#/definitions/error"
678
      503:
679
        description: Under maintenance
680
        schema:
681
          $ref: "../swagger.yaml#/definitions/error"
682
    x-koha-authorization:
683
      permissions:
684
        preservation: 1
685
        description: |-
686
          Internal server error. Possible `error_code` attribute values:
687
          * `internal_server_error`
688
        schema:
689
          $ref: "../swagger.yaml#/definitions/error"
690
      503:
691
        description: Under maintenance
692
        schema:
693
          $ref: "../swagger.yaml#/definitions/error"
694
    x-koha-authorization:
695
      permissions:
696
        preservation: 1
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 331-336 paths: Link Here
331
    $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1batch"
331
    $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1batch"
332
  "/preservation/trains/{train_id}/items/{train_item_id}":
332
  "/preservation/trains/{train_id}/items/{train_item_id}":
333
    $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1{train_item_id}"
333
    $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1{train_item_id}"
334
  "/preservation/trains/{train_id}/items/{train_item_id}/copy":
335
    $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1{train_item_id}~1copy"
334
  /preservation/processings:
336
  /preservation/processings:
335
    $ref: ./paths/preservation_processings.yaml#/~1preservation~1processings
337
    $ref: ./paths/preservation_processings.yaml#/~1preservation~1processings
336
  "/preservation/processings/{processing_id}":
338
  "/preservation/processings/{processing_id}":
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsShow.vue (-27 / +11 lines)
Lines 410-443 export default { Link Here
410
        copyItem(event) {
410
        copyItem(event) {
411
            event.preventDefault()
411
            event.preventDefault()
412
            const client = APIClient.preservation
412
            const client = APIClient.preservation
413
            let new_train_item = {}
414
            client.train_items
413
            client.train_items
415
                .get(this.train.train_id, this.train_item_id_to_copy)
414
                .copy(
416
                .then(train_item => {
415
                    this.train_id_selected_for_copy,
417
                    new_train_item = {
416
                    this.train.train_id,
418
                        attributes: train_item.attributes.map(attr => {
417
                    this.train_item_id_to_copy
419
                            return {
418
                )
420
                                processing_attribute_id:
419
                .then(
421
                                    attr.processing_attribute_id,
420
                    success => {
422
                                value: attr.value,
421
                        this.setMessage(this.$__("Item copied successfully."))
423
                            }
422
                        this.show_modal = false
424
                        }),
423
                    },
425
                        item_id: train_item.item_id,
424
                    error => {}
426
                        processing_id: train_item.processing_id,
427
                    }
428
                })
429
                .then(() =>
430
                    client.train_items
431
                        .create(new_train_item, this.train_id_selected_for_copy)
432
                        .then(
433
                            success => {
434
                                this.setMessage(
435
                                    this.$__("Item copied successfully.")
436
                                )
437
                                this.show_modal = false
438
                            },
439
                            error => {}
440
                        )
441
                )
425
                )
442
        },
426
        },
443
        build_datatable: function () {
427
        build_datatable: function () {
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/preservation-api-client.js (+5 lines)
Lines 121-126 export class PreservationAPIClient extends HttpClient { Link Here
121
                    endpoint: "trains/" + train_id + "/items/batch",
121
                    endpoint: "trains/" + train_id + "/items/batch",
122
                    body: train_items,
122
                    body: train_items,
123
                }),
123
                }),
124
            copy: (new_train_id, train_id, id) =>
125
                this.post({
126
                    endpoint: "trains/" + train_id + "/items/" + id + "/copy",
127
                    body: { train_id: new_train_id },
128
                }),
124
            update: (train_item, train_id, id) =>
129
            update: (train_item, train_id, id) =>
125
                this.put({
130
                this.put({
126
                    endpoint: "trains/" + train_id + "/items/" + id,
131
                    endpoint: "trains/" + train_id + "/items/" + id,
(-)a/t/db_dependent/Koha/Preservation/Trains.t (-2 / +7 lines)
Lines 52-58 subtest 'default_processing' => sub { Link Here
52
};
52
};
53
53
54
subtest 'add_items & items' => sub {
54
subtest 'add_items & items' => sub {
55
    plan tests => 9;
55
    plan tests => 12;
56
56
57
    $schema->storage->txn_begin;
57
    $schema->storage->txn_begin;
58
58
Lines 98-102 subtest 'add_items & items' => sub { Link Here
98
    is( $item_2->get_from_storage->notforloan, 0 );
98
    is( $item_2->get_from_storage->notforloan, 0 );
99
    is( $item_3->get_from_storage->notforloan, $not_for_loan_train_in );
99
    is( $item_3->get_from_storage->notforloan, $not_for_loan_train_in );
100
100
101
    warning_is {
102
        $train->add_item( { item_id => $item_2->itemnumber }, { skip_waiting_list_check => 1 } );
103
    } '';
104
    is( $train->items->count, 3, 'the item has been added to the train' );
105
    is( $item_2->get_from_storage->notforloan, $not_for_loan_train_in );
106
101
    $schema->storage->txn_rollback;
107
    $schema->storage->txn_rollback;
102
};
108
};
103
- 

Return to bug 30708