From 9b287ee45e27aeea1b263a3918f4a1ab6e93a1cc Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Thu, 3 Oct 2024 13:13:45 +0000 Subject: [PATCH] Bug 38010: Allow embedding for baskets table Signed-off-by: Michaela Sieber Signed-off-by: Jonathan Druart --- api/v1/swagger/definitions/basket.yaml | 18 +- .../swagger/paths/acquisitions_baskets.yaml | 14 +- .../vue/components/Vendors/VendorBaskets.vue | 176 ++++++++++-------- .../js/vue/components/Vendors/VendorList.vue | 1 + .../js/vue/components/Vendors/VendorShow.vue | 7 +- .../prog/js/vue/modules/acquisitions.ts | 3 +- 6 files changed, 137 insertions(+), 82 deletions(-) diff --git a/api/v1/swagger/definitions/basket.yaml b/api/v1/swagger/definitions/basket.yaml index 5b02068190a..6968bd6b698 100644 --- a/api/v1/swagger/definitions/basket.yaml +++ b/api/v1/swagger/definitions/basket.yaml @@ -73,6 +73,22 @@ properties: - string - "null" description: basket notes + orders: + type: array + description: List of orderlines for the basket + items: + $ref: "order.yaml" + creator: + type: + - object + - "null" + description: Creator for the basket + $ref: "patron.yaml" + basket_group: + type: + - object + - "null" + description: Basket group create_items: type: - string @@ -84,4 +100,4 @@ properties: - null description: "When items should be created for orders in this basket (Options: 'ordering', 'receiving', 'cataloguing'. Null means system wide config)" -additionalProperties: false +additionalProperties: false \ No newline at end of file diff --git a/api/v1/swagger/paths/acquisitions_baskets.yaml b/api/v1/swagger/paths/acquisitions_baskets.yaml index 30a6c6e2e6f..01c6aad2d3f 100644 --- a/api/v1/swagger/paths/acquisitions_baskets.yaml +++ b/api/v1/swagger/paths/acquisitions_baskets.yaml @@ -14,6 +14,18 @@ - $ref: "../swagger.yaml#/parameters/per_page" - $ref: "../swagger.yaml#/parameters/q_param" - $ref: "../swagger.yaml#/parameters/q_body" + - name: x-koha-embed + in: header + required: false + description: Embed list sent as a request header + type: array + items: + type: string + enum: + - orders + - creator + - basket_group + collectionFormat: csv produces: - application/json responses: @@ -107,4 +119,4 @@ $ref: "../swagger.yaml#/definitions/error" x-koha-authorization: permissions: - acquisition: order_manage + acquisition: order_manage \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorBaskets.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorBaskets.vue index 86e5461951b..f82c607af8c 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorBaskets.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorBaskets.vue @@ -4,10 +4,9 @@
@@ -23,6 +22,9 @@ import KohaTable from "../KohaTable.vue"; export default { setup() { + const patronToHTML = $patron_to_html; + const formatDate = $date; + const vendorStore = inject("vendorStore"); const { vendors } = storeToRefs(vendorStore); @@ -36,6 +38,8 @@ export default { setConfirmationDialog, setMessage, escape_str, + patronToHTML, + formatDate, }; }, data() { @@ -44,79 +48,53 @@ export default { initialized: false, tableOptions: { columns: this.getTableColumns(), + options: { embed: "orders,creator,basket_group" }, url: () => this.tableURL(), add_filters: true, - // filters_options: { - // 1: [ - // { _id: 0, _str: this.$__("Inactive") }, - // { _id: 1, _str: this.$__("Active") }, - // ], - // ...(this.map_av_dt_filter("vendor_types").length && { - // 2: () => this.map_av_dt_filter("vendor_types"), - // }), - // }, actions: { - "-1": ["edit", "delete"], + "-1": [ + { + addToBasket: { + text: this.$__("Add to basket"), + icon: "fa fa-plus", + }, + }, + { + closeBasket: { + text: this.$__("Close basket"), + icon: "fa fa-close", + should_display: row => + row.orders.length > 0 && !row.standing, + }, + }, + { + uncertainPrices: { + text: this.$__("Uncertain prices"), + icon: "fa fa-question", + should_display: row => + row.orders.filter(o => o.uncertain_price) + .length > 0, + }, + }, + ], }, }, - before_route_entered: false, - building_table: false, }; }, methods: { - doShow({ id }, dt, event) { + addToBasket({ agreement_id }, dt, event) { event.preventDefault(); - this.$router.push({ - name: "VendorShow", - params: { vendor_id: id }, - }); - }, - doEdit({ id }, dt, event) { - this.$router.push({ - name: "VendorFormAddEdit", - params: { vendor_id: id }, - }); - }, - doDelete(vendor, dt, event) { - this.setConfirmationDialog( - { - title: this.$__( - "Are you sure you want to remove this vendor?" - ), - message: vendor.name, - accept_label: this.$__("Yes, delete"), - cancel_label: this.$__("No, do not delete"), - }, - () => { - const client = APIClient.acquisition; - client.vendors.delete(vendor.id).then( - success => { - this.setMessage( - this.$__("Vendor %s deleted").format( - vendor.name - ), - true - ); - dt.draw(); - }, - error => {} - ); - } - ); - }, - doSelect(vendor, dt, event) { - this.$emit("select-vendor", vendor.id); - this.$emit("close"); }, tableURL() { let url = "/api/v1/acquisitions/baskets?q=" + - JSON.stringify({ vendor_id: this.vendorId }); + JSON.stringify({ "me.vendor_id": this.vendorId }); return url; }, getTableColumns() { const escape_str = this.escape_str; - const get_lib_from_av = this.get_lib_from_av; + const patronToHTML = this.patronToHTML; + const formatDate = this.formatDate; return [ { @@ -126,7 +104,7 @@ export default { orderable: true, render(data, type, row, meta) { return ( - '' + escape_str(`${row.name} (#${row.basket_id})`) + @@ -137,59 +115,111 @@ export default { { title: __("Item count"), data: "name", - searchable: true, + searchable: false, orderable: true, + render(data, type, row, meta) { - return escape_str(row.name); + let count = row.orders.length; + const cancelledOrders = row.orders.filter( + o => o.status == "cancelled" + ).length; + if (cancelledOrders) { + count += + " (" + cancelledOrders + _(" cancelled") + ")"; + } + return count; }, }, { title: __("Bibliographic record count"), data: "name", - searchable: true, + searchable: false, orderable: true, render(data, type, row, meta) { - return escape_str(row.name); + const recordCount = row.orders.reduce( + (acc, order) => { + if ( + !acc.cancelledBibs.includes( + order.biblio_id + ) && + order.status == "cancelled" + ) { + acc.cancelledBibs.push(order.biblio_id); + } + if (acc.bibNumbers.includes(order.biblio_id)) { + return acc; + } + acc.bibNumbers.push(order.biblio_id); + return acc; + }, + { + bibNumbers: [], + cancelledBibs: [], + } + ); + let count = recordCount.bibNumbers.length; + if (recordCount.cancelledBibs.length) { + count += + " (" + + recordCount.cancelledBibs.length + + _(" cancelled") + + ")"; + } + return count; }, }, { title: __("Items expected"), data: "name", - searchable: true, + searchable: false, orderable: true, render(data, type, row, meta) { - return escape_str(row.name); + return row.orders.filter( + o => !o.date_received && !o.cancellation_date + ).length; }, }, { title: __("Created by"), data: "creator_id", - searchable: true, + searchable: false, orderable: true, + render(data, type, row, meta) { + return patronToHTML(row.creator); + }, }, { title: __("Date"), data: "creation_date", - searchable: true, + searchable: false, orderable: true, + render(data, type, row, meta) { + return formatDate(row.creation_date); + }, }, { title: __("Basket group"), data: "basket_group_id", - searchable: true, + searchable: false, orderable: true, + render(data, type, row, meta) { + return row.basket_group ? row.basket_group.name : ""; + }, }, { title: __("Internal note"), data: "note", - searchable: true, + searchable: false, orderable: true, }, { - title: __("Close"), + title: __("Closed"), data: "close_date", - searchable: true, + searchable: false, orderable: true, + render(data, type, row, meta) { + return formatDate(row.close_date); + }, }, ]; }, diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue index 35a550a0e35..f719cb188b3 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue @@ -75,6 +75,7 @@ export default { }), }, actions: { + 0: ["show"], "-1": [ "edit", { diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorShow.vue index 44a269ec810..0971f74efb6 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorShow.vue @@ -20,7 +20,7 @@ path: '/cgi-bin/koha/acqui/parcels.pl', query: { booksellerid: vendor.id }, }" - icon="plus" + icon="inbox" :title="$__('Receive shipments')" callback="redirect" /> @@ -76,14 +76,9 @@ import VendorBaskets from "./VendorBaskets.vue"; export default { setup() { - const format_date = $date; - const patron_to_html = $patron_to_html; - const { setConfirmationDialog, setMessage } = inject("mainStore"); return { - format_date, - patron_to_html, setConfirmationDialog, setMessage, }; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/acquisitions.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/acquisitions.ts index bdd1ae37330..c8f132c138a 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/acquisitions.ts +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/acquisitions.ts @@ -9,11 +9,12 @@ import { faPencil, faTrash, faSpinner, + faInbox, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import vSelect from "vue-select"; -library.add(faPlus, faMinus, faPencil, faTrash, faSpinner); +library.add(faPlus, faMinus, faPencil, faTrash, faSpinner, faInbox); import App from "../components/Vendors/Main.vue"; -- 2.34.1