2 <transition name="modal">
3 <div v-if="show_modal" class="modal">
4 <h2>{{ $__("Copy item to the following train") }}</h2>
5 <form @submit="copyItem($event)">
6 <div class="page-section">
7 <fieldset class="rows">
10 <label class="required" for="train_list"
11 >{{ $__("Select a train") }}:</label
14 v-model="train_id_selected_for_copy"
17 :reduce="t => t.train_id"
19 <template #search="{ attributes, events }">
22 !train_id_selected_for_copy
30 <span class="required">{{
36 <fieldset class="action">
37 <input type="submit" value="Copy" />
40 @click="show_modal = false"
48 <div v-if="!initialized">{{ $__("Loading") }}</div>
49 <div v-else id="trains_show">
52 v-if="train.closed_on == null"
54 name: 'TrainsFormAddItem',
55 params: { train_id: train.train_id },
57 class="btn btn-default"
59 :title="$__('Add items')"
63 class="btn btn-default"
65 :title="$__('Cannot add items to a closed train')"
67 <font-awesome-icon icon="plus" /> {{ $__("Add items") }}
71 name: 'TrainsFormEdit',
72 params: { train_id: train.train_id },
74 class="btn btn-default"
78 <a @click="deleteTrain(train)" class="btn btn-default"
79 ><font-awesome-icon icon="trash" /> {{ $__("Delete") }}</a
82 v-if="!train.closed_on"
83 class="btn btn-default"
85 ><font-awesome-icon icon="remove" /> {{ $__("Close") }}</a
88 v-else-if="!train.sent_on"
89 class="btn btn-default"
91 ><font-awesome-icon icon="paper-plane" /> {{ $__("Send") }}</a
94 v-else-if="!train.received_on"
95 class="btn btn-default"
97 ><font-awesome-icon icon="inbox" /> {{ $__("Receive") }}</a
101 {{ $__("Train #%s").format(train.train_id) }}
104 <fieldset class="rows">
107 <label>{{ $__("Name") }}:</label>
113 <label>{{ $__("Description") }}:</label>
115 {{ train.description }}
118 <li v-if="train.closed_on">
119 <label>{{ $__("Closed on") }}:</label>
121 {{ format_date(train.closed_on) }}
124 <li v-if="train.sent_on">
125 <label>{{ $__("Sent on") }}:</label>
127 {{ format_date(train.sent_on) }}
130 <li v-if="train.received_on">
131 <label>{{ $__("Received on") }}:</label>
133 {{ format_date(train.received_on) }}
139 $__("Status for item added to this train")
143 get_lib_from_av("av_notforloan", train.not_for_loan)
147 <label>{{ $__("Default processing") }}:</label>
149 {{ train.default_processing.name }}
154 <fieldset v-if="train.items.length" class="rows">
155 <legend>{{ $__("Items") }}</legend>
156 <table v-if="item_table.display" :id="table_id"></table>
159 :id="`item_${counter}`"
161 v-for="(item, counter) in train.items"
165 >{{ item.user_train_item_id }}
166 <span class="action_links">
169 @click="editItem(item.train_item_id)"
171 ><i class="fa fa-pencil"></i
175 @click="removeItem(item.train_item_id)"
176 :title="$__('Remove')"
177 ><i class="fa fa-trash"></i
180 v-if="train.received_on !== null"
183 selectTrainForCopy(item.train_item_id)
186 ><i class="fa fa-copy"></i></a
189 <div class="attributes_values">
191 :id="`attribute_${counter_attribute}`"
192 class="attribute_value"
194 attribute, counter_attribute
195 ) in item.attributes"
196 v-bind:key="counter_attribute"
198 {{ attribute.processing_attribute.name }}={{
199 attribute._strings.value.str
206 <fieldset class="action">
208 :to="{ name: 'TrainsList' }"
211 >{{ $__("Close") }}</router-link
219 import { inject, createVNode, render } from "vue"
220 import { APIClient } from "../../fetch/api-client"
221 import { useDataTable } from "../../composables/datatables"
222 import Toolbar from "../Toolbar.vue"
223 import ToolbarButton from "../ToolbarButton.vue"
227 const format_date = $date
229 const AVStore = inject("AVStore")
230 const { get_lib_from_av } = AVStore
232 const { setConfirmationDialog, setMessage, setWarning } =
235 const table_id = "item_list"
236 useDataTable(table_id)
242 setConfirmationDialog,
262 train_id_selected_for_copy: null,
263 train_item_id_to_copy: null,
267 beforeRouteEnter(to, from, next) {
269 vm.getTrain(to.params.train_id).then(() => vm.build_datatable())
274 async getTrain(train_id) {
275 const client = APIClient.preservation
276 await client.trains.get(train_id).then(
279 let display_table = this.train.items.every(
281 item.processing_id ==
282 this.train.default_processing_id
285 this.item_table.data = []
286 this.train.items.forEach(item => {
288 this.train.default_processing.attributes.forEach(
291 attribute.processing_attribute_id
295 a.processing_attribute_id ==
296 attribute.processing_attribute_id
298 .map(a => a._strings.value.str)
302 this.item_table.data.push(item_row)
304 this.item_table.columns = []
305 this.item_table.columns.push({
307 title: this.$__("ID"),
308 data: "item.user_train_item_id",
310 train.default_processing.attributes.forEach(a =>
311 this.item_table.columns.push({
314 data: a.processing_attribute_id,
315 render: (data, type, row) => {
316 return data.join("<br/>")
320 this.item_table.columns.push({
322 className: "actions noExport",
323 title: this.$__("Actions"),
326 render: (data, type, row) => {
331 this.initialized = true
332 this.item_table.display = display_table
337 getTrainList: function () {
338 const client = APIClient.preservation
339 let q = { "me.closed_on": null }
340 client.trains.getAll(q).then(
341 trains => (this.train_list = trains),
345 deleteTrain: function (train) {
346 this.setConfirmationDialog(
349 "Are you sure you want to remove this train?"
352 accept_label: this.$__("Yes, delete"),
353 cancel_label: this.$__("No, do not delete"),
356 const client = APIClient.preservation
357 client.trains.delete(train.train_id).then(
360 this.$__("Train %s deleted").format(train.name),
363 this.$router.push({ name: "TrainsList" })
370 async updateTrainDate(attribute) {
371 let train = JSON.parse(JSON.stringify(this.train))
372 let train_id = train.train_id
373 delete train.train_id
375 delete train.default_processing
376 train[attribute] = new Date()
377 const client = APIClient.preservation
380 .update(train, train_id)
381 .then(() => this.getTrain(this.train.train_id))
385 .then(() => this.getTrain(this.train.train_id))
389 this.updateTrainDate("closed_on")
392 this.updateTrainDate("sent_on")
395 this.updateTrainDate("received_on").then(
397 // Rebuild the table to show the "copy" button
398 $("#" + this.table_id)
401 this.build_datatable()
406 editItem(train_item_id) {
408 name: "TrainsFormEditItem",
409 params: { train_id: this.train.train_id, train_item_id },
412 removeItem(train_item_id) {
413 this.setConfirmationDialog(
416 "Are you sure you want to remove this item?"
418 accept_label: this.$__("Yes, remove"),
419 cancel_label: this.$__("No, do not remove"),
422 const client = APIClient.preservation
424 .delete(this.train.train_id, train_item_id)
427 this.setMessage(this.$__("Item removed"), true)
428 this.getTrain(this.train.train_id).then(() => {
429 $("#" + this.table_id)
432 this.build_datatable()
440 printSlip(train_item_id) {
442 "/cgi-bin/koha/preservation/print_slip.pl?train_item_id=" +
447 selectTrainForCopy(train_item_id) {
448 this.show_modal = true
449 this.train_item_id_to_copy = train_item_id
452 event.preventDefault()
453 const client = APIClient.preservation
456 this.train_id_selected_for_copy,
458 this.train_item_id_to_copy
462 this.setMessage(this.$__("Item copied successfully."))
463 this.show_modal = false
468 "Item cannot be copied to a train, it is already in a non-received train."
474 build_datatable: function () {
475 let table_id = this.table_id
476 let item_table = this.item_table
477 let removeItem = this.removeItem
478 let editItem = this.editItem
479 let printSlip = this.printSlip
480 let selectTrainForCopy = this.selectTrainForCopy
481 let train = this.train
483 let table = KohaTable(table_id, {
484 data: item_table.data,
487 columns: item_table.columns,
488 drawCallback: function (settings) {
489 var api = new $.fn.dataTable.Api(settings)
490 $.each($(this).find("td.actions"), function (index, e) {
491 let tr = $(this).parent()
492 let train_item = api.row(tr).data().item
493 let train_item_id = train_item.train_item_id
495 let editButton = createVNode(
498 class: "btn btn-default btn-xs",
501 editItem(train_item_id)
506 class: "fa fa-pencil",
507 "aria-hidden": "true",
514 let removeButton = createVNode(
517 class: "btn btn-default btn-xs",
520 removeItem(train_item_id)
525 class: "fa fa-trash",
526 "aria-hidden": "true",
532 let buttons = [editButton, " ", removeButton]
534 if (train.received_on !== null) {
540 class: "btn btn-default btn-xs",
543 selectTrainForCopy(train_item_id)
549 "aria-hidden": "true",
558 if (train_item.processing.letter_code !== null) {
559 let printButton = createVNode(
562 class: "btn btn-default btn-xs",
565 printSlip(train_item_id)
570 class: "fa fa-print",
571 "aria-hidden": "true",
577 buttons.push(printButton)
580 let n = createVNode("span", {}, buttons)
587 components: { Toolbar, ToolbarButton },
605 overflow-y: inherit !important;
610 background-color: rgba(0, 0, 0, 0.5);
612 transition: opacity 0.3s ease;
615 background-color: #fff;
617 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
618 transition: all 0.3s ease;