Bugzilla – Attachment 174201 Details for
Bug 38010
Migrate vendors to Vue
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 38010: Add the form to add a new vendor
Bug-38010-Add-the-form-to-add-a-new-vendor.patch (text/plain), 46.41 KB, created by
Matt Blenkinsop
on 2024-11-07 13:32:50 UTC
(
hide
)
Description:
Bug 38010: Add the form to add a new vendor
Filename:
MIME Type:
Creator:
Matt Blenkinsop
Created:
2024-11-07 13:32:50 UTC
Size:
46.41 KB
patch
obsolete
>From 2c6c8eaa55b72ab0fe02834f0c54f7d1c4bd2f47 Mon Sep 17 00:00:00 2001 >From: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com> >Date: Thu, 19 Sep 2024 14:43:25 +0000 >Subject: [PATCH] Bug 38010: Add the form to add a new vendor > >--- > Koha/REST/V1/Acquisitions/Vendors.pm | 25 ++- > acqui/booksellers.pl | 1 + > .../prog/js/vue/components/Vendors/Main.vue | 9 +- > .../vue/components/Vendors/VendorContacts.vue | 205 +++++++++++++++++- > .../vue/components/Vendors/VendorDetails.vue | 132 ++++++++++- > .../vue/components/Vendors/VendorFormAdd.vue | 154 +++++++++++++ > .../components/Vendors/VendorInterfaces.vue | 121 ++++++++++- > .../js/vue/components/Vendors/VendorList.vue | 36 ++- > .../Vendors/VendorOrderingInformation.vue | 186 +++++++++++++++- > .../js/vue/components/Vendors/VendorShow.vue | 7 +- > .../js/vue/fetch/acquisition-api-client.js | 3 + > .../prog/js/vue/routes/acquisitions.js | 13 ++ > 12 files changed, 845 insertions(+), 47 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorFormAdd.vue > >diff --git a/Koha/REST/V1/Acquisitions/Vendors.pm b/Koha/REST/V1/Acquisitions/Vendors.pm >index 2b93fb28751..0747f5bbf43 100644 >--- a/Koha/REST/V1/Acquisitions/Vendors.pm >+++ b/Koha/REST/V1/Acquisitions/Vendors.pm >@@ -87,21 +87,34 @@ Controller function that handles adding a new Koha::Acquisition::Bookseller obje > sub add { > my $c = shift->openapi->valid_input or return; > >- my $vendor = Koha::Acquisition::Bookseller->new_from_api( $c->req->json ); >+ my $vendor = $c->req->json; >+ my $contacts = delete $vendor->{contacts}; >+ my $interfaces = delete $vendor->{interfaces}; >+ my $aliases = delete $vendor->{aliases}; >+ >+ my $vendor_to_store = Koha::Acquisition::Bookseller->new_from_api( $c->req->json ); > > return try { >- $vendor->store; >- $c->res->headers->location($c->req->url->to_string . '/' . $vendor->id ); >+ $vendor_to_store->store; >+ >+ foreach my $contact (@$contacts) { >+ $contact->{booksellerid} = $vendor_to_store->id; >+ Koha::Acquisition::Bookseller::Contact->new($contact)->store; >+ } >+ $vendor_to_store->aliases($aliases) if scalar($aliases) > 0; >+ $vendor_to_store->interfaces($interfaces) if scalar($interfaces) > 0; >+ >+ $c->res->headers->location( $c->req->url->to_string . '/' . $vendor_to_store->id ); > return $c->render( > status => 201, >- openapi => $c->objects->to_api($vendor), >+ openapi => $c->objects->to_api($vendor_to_store), > ); >- } >- catch { >+ } catch { > $c->unhandled_exception($_); > }; > } > >+ > =head3 update > > Controller function that handles updating a Koha::Acquisition::Bookseller object >diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl >index 520b977f78f..33b0b042b26 100755 >--- a/acqui/booksellers.pl >+++ b/acqui/booksellers.pl >@@ -62,6 +62,7 @@ use C4::Context; > > use Koha::Acquisition::Booksellers; > use Koha::Patrons; >+use Koha::Acquisition::Currencies; > > my $query = CGI->new; > my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user( >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue >index b26ff4e8b44..552be59f6b3 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue >@@ -94,11 +94,18 @@ export default { > > fetchConfig().then(() => { > this.loaded() >+ this.userPermissions = userPermissions >+ this.vendorStore.currencies = currencies >+ this.vendorStore.gstValues = gstValues.map(gv => { >+ return { >+ label: `${(gv.option * 100).toFixed(2)}%`, >+ value: gv.option, >+ } >+ }) > this.initialized = true > }) > }, > data() { >- this.userPermissions = userPermissions > return { > initialized: false, > } >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContacts.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContacts.vue >index 61a56e3e7d3..d02d2875ba7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContacts.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContacts.vue >@@ -1,5 +1,5 @@ > <template> >- <fieldset class="rows"> >+ <fieldset class="rows" v-if="display"> > <h2> > {{ $__("Contact") }} > </h2> >@@ -84,12 +84,215 @@ > </li> > </ol> > </fieldset> >+ <fieldset class="rows" v-else> >+ <legend>{{ $__("Contacts") }}</legend> >+ <fieldset >+ class="rows" >+ v-for="(contact, i) in vendor.contacts" >+ v-bind:key="i" >+ :id="`contact_${i}`" >+ > >+ <legend>{{ $__("Contact details") }}</legend> >+ <ol> >+ <li> >+ <label :for="`contact_${i}_name`" >+ >{{ $__("Contact name") }}:</label >+ > >+ <input :id="`contact_${i}_name`" v-model="contact.name" /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_position`" >+ >{{ $__("Position") }}:</label >+ > >+ <input >+ :id="`contact_${i}_position`" >+ v-model="contact.position" >+ /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_phone`" >+ >{{ $__("Phone") }}:</label >+ > >+ <input :id="`contact_${i}_phone`" v-model="contact.phone" /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_altphone`" >+ >{{ $__("Alternative phone") }}:</label >+ > >+ <input >+ :id="`contact_${i}_altphone`" >+ v-model="contact.altphone" >+ /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_fax`">{{ $__("Fax") }}:</label> >+ <input :id="`contact_${i}_fax`" v-model="contact.fax" /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_email`" >+ >{{ $__("Email") }}:</label >+ > >+ <input :id="`contact_${i}_email`" v-model="contact.email" /> >+ </li> >+ <li> >+ <label :for="`contact_${i}_notes`" >+ >{{ $__("Notes") }}:</label >+ > >+ <textarea >+ :id="`contact_${i}_notes`" >+ v-model="contact.notes" >+ cols="40" >+ rows="3" >+ /> >+ </li> >+ </ol> >+ <div style="display: flex"> >+ <div> >+ <fieldset class="rows"> >+ <legend>Acquisitions options</legend> >+ <ol class="radio"> >+ <li> >+ <label> >+ <input >+ v-if="contact.acqprimary" >+ type="checkbox" >+ :id="`contact_acqprimary_${i}`" >+ class="contact_acqprimary" >+ checked="checked" >+ v-model="contact.acqprimary" >+ /> >+ <input >+ v-else >+ type="checkbox" >+ :id="`contact_acqprimary_${i}`" >+ class="contact_acqprimary" >+ v-model="contact.acqprimary" >+ /> >+ {{ $__("Primary acquisitions contact") }} >+ </label> >+ </li> >+ <li> >+ <label> >+ <input >+ v-if="contact.orderacquisition" >+ type="checkbox" >+ :id="`contact_orderacquisition_${i}`" >+ class="contact_orderacquisition" >+ checked="checked" >+ v-model="contact.orderacquisition" >+ /> >+ <input >+ v-else >+ type="checkbox" >+ :id="`contact_orderacquisition_${i}`" >+ class="contact_orderacquisition" >+ v-model="contact.orderacquisition" >+ /> >+ {{ $__("Contact when ordering") }} >+ </label> >+ </li> >+ <li> >+ <label> >+ <input >+ v-if="contact.claimacquisition" >+ type="checkbox" >+ :id="`contact_claimacquisition_${i}`" >+ class="contact_claimacquisition" >+ checked="checked" >+ v-model="contact.claimacquisition" >+ /> >+ <input >+ v-else >+ type="checkbox" >+ :id="`contact_claimacqu isition_${i}`" >+ class="contact_claimacqu isition" >+ v-model="contact.claimacquisition" >+ /> >+ {{ $__("Contact about late orders") }} >+ </label> >+ </li> >+ </ol> >+ </fieldset> >+ </div> >+ <div> >+ <fieldset class="rows"> >+ <legend>Serials options</legend> >+ <ol class="radio"> >+ <li> >+ <label> >+ <input >+ v-if="contact.serialsprimary" >+ type="checkbox" >+ :id="`contact_serialsprimary_${i}`" >+ class="contact_serialsprimary" >+ checked="checked" >+ v-model="contact.serialsprimary" >+ /> >+ <input >+ v-else >+ type="checkbox" >+ :id="`contact_serialsprimary_${i}`" >+ class="contact_serialsprimary" >+ v-model="contact.serialsprimary" >+ /> >+ {{ $__("Primary serials contact") }} >+ </label> >+ </li> >+ <li> >+ <label> >+ <input >+ v-if="contact.claimissues" >+ type="checkbox" >+ :id="`contact_claimissues_${i}`" >+ class="contact_claimissues" >+ checked="checked" >+ v-model="contact.claimissues" >+ /> >+ <input >+ v-else >+ type="checkbox" >+ :id="`contact_claimissues_${i}`" >+ class="contact_claimissues" >+ v-model="contact.claimissues" >+ /> >+ {{ $__("Contact about late issues") }} >+ </label> >+ </li> >+ </ol> >+ </fieldset> >+ </div> >+ </div> >+ </fieldset> >+ <span class="btn btn-default" @click="addContact" >+ ><font-awesome-icon icon="plus" /> >+ {{ $__("Add new contact") }}</span >+ > >+ </fieldset> > </template> > > <script> > export default { > props: { > vendor: Object, >+ display: Boolean, >+ }, >+ methods: { >+ addContact() { >+ this.vendor.contacts.push({ >+ name: "", >+ position: "", >+ email: "", >+ phone: "", >+ notes: "", >+ altphone: "", >+ fax: "", >+ acqprimary: false, >+ orderacquisition: false, >+ claimacquisition: false, >+ serialsprimary: false, >+ claimissues: false, >+ }) >+ }, > }, > } > </script> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorDetails.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorDetails.vue >index 1795f5e8d89..eee83375b05 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorDetails.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorDetails.vue >@@ -1,5 +1,5 @@ > <template> >- <fieldset class="rows"> >+ <fieldset class="rows" v-if="display"> > <h2> > {{ $__("Vendor details") }} > </h2> >@@ -7,7 +7,7 @@ > <li> > <label>{{ $__("Type") }}:</label> > <span> >- {{ get_lib_from_av("vendor_types", vendor.type) }} >+ {{ get_lib_from_av("av_vendor_types", vendor.type) }} > </span> > </li> > <li> >@@ -65,24 +65,146 @@ > </li> > </ol> > </fieldset> >+ <fieldset class="rows" v-else> >+ <legend>{{ $__("Company details") }}</legend> >+ <ol> >+ <li> >+ <label for="vendor_name" class="required" >+ >{{ $__("Name") }}:</label >+ > >+ <input >+ id="vendor_name" >+ v-model="vendor.name" >+ :placeholder="$__('Vendor name')" >+ required >+ /> >+ <span class="required">{{ $__("Required") }}</span> >+ </li> >+ <li> >+ <label for="vendor_postal">{{ $__("Postal address") }}:</label> >+ <textarea >+ id="vendor_postal" >+ v-model="vendor.postal" >+ cols="40" >+ rows="3" >+ /> >+ </li> >+ <li> >+ <label for="vendor_physical" >+ >{{ $__("Physical address") }}:</label >+ > >+ <textarea >+ id="vendor_physical" >+ v-model="vendor.physical" >+ cols="40" >+ rows="3" >+ /> >+ </li> >+ <li> >+ <label for="vendor_phone">{{ $__("Phone") }}:</label> >+ <input id="vendor_phone" v-model="vendor.phone" /> >+ </li> >+ <li> >+ <label for="vendor_fax">{{ $__("Fax") }}:</label> >+ <input id="vendor_fax" v-model="vendor.fax" /> >+ </li> >+ <li> >+ <label for="vendor_website">{{ $__("Website") }}:</label> >+ <input id="vendor_website" v-model="vendor.url" /> >+ </li> >+ <li> >+ <label for="vendor_accountnumber" >+ >{{ $__("Account number") }}:</label >+ > >+ <input >+ id="vendor_accountnumber" >+ v-model="vendor.accountnumber" >+ /> >+ </li> >+ <li> >+ <label for="vendor_type">{{ $__("Vendor type") }}:</label> >+ <v-select >+ v-if="authorisedValues.vendor_types.length" >+ id="vendor_type" >+ v-model="vendor.type" >+ label="description" >+ :reduce="av => av.value" >+ :options="authorisedValues.vendor_types" >+ /> >+ <input v-else id="vendor_type" v-model="vendor.type" /> >+ </li> >+ <li> >+ <label for="vendor_aliases">{{ $__("Aliases") }}:</label> >+ <input id="vendor_aliases" v-model="newAlias" /> >+ <span class="aliasAction" @click="addAlias()" >+ ><i class="fa fa-plus"></i> {{ $__("Add") }}</span >+ > >+ <ol id="aliasList"> >+ <li >+ v-for="(item, i) in vendor.aliases" >+ :key="`${item}${i}`" >+ style="display: flex" >+ > >+ <label :for="`alias${i}`" >+ >{{ $__("Alias") + " " + (i + 1) }}:</label >+ > >+ <span :id="`alias${i}`">{{ item.alias }}</span> >+ <span class="aliasAction" @click="removeAlias(item)" >+ ><i class="fa fa-trash"></i> >+ {{ $__("Remove") }}</span >+ > >+ </li> >+ </ol> >+ </li> >+ </ol> >+ </fieldset> > </template> > > <script> > import { inject } from "vue" >+import { storeToRefs } from "pinia" > > export default { > props: { > vendor: Object, >+ display: Boolean, > }, > setup() { >- const AVStore = inject("AVStore") >- const { get_lib_from_av } = AVStore > >+ const AVStore = inject("AVStore") >+ const { get_lib_from_av, av_vendor_types } = AVStore > return { > get_lib_from_av, >+ av_vendor_types, >+ } >+ }, >+ data() { >+ return { >+ newAlias: "", > } > }, >+ methods: { >+ addAlias() { >+ if (!this.vendor.aliases) { >+ this.vendor.aliases = [] >+ } >+ this.vendor.aliases.push({ alias: this.newAlias }) >+ this.newAlias = "" >+ }, >+ removeAlias(e) { >+ this.vendor.aliases.splice(this.vendor.aliases.indexOf(e.alias), 1) >+ }, >+ }, > } > </script> > >-<style></style> >+<style scoped> >+.aliasAction { >+ cursor: pointer; >+ margin-left: 5px; >+ color: #006100; >+} >+#aliasList { >+ padding-left: 5em; >+} >+</style> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorFormAdd.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorFormAdd.vue >new file mode 100644 >index 00000000000..b4dc628553c >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorFormAdd.vue >@@ -0,0 +1,154 @@ >+<template> >+ <div v-if="!initialized">{{ $__("Loading") }}</div> >+ <div v-else id="vendor_add"> >+ <h2 v-if="vendor.id"> >+ {{ $__("Edit vendor #%s").format(vendor.id) }} >+ </h2> >+ <h2 v-else>{{ $__("New vendor") }}</h2> >+ <div> >+ <form @submit="onSubmit($event)"> >+ <VendorDetails :vendor="vendor" /> >+ <VendorContacts :vendor="vendor" /> >+ <VendorInterfaces :vendor="vendor" /> >+ <VendorOrderingInformation :vendor="vendor" /> >+ <fieldset class="action"> >+ <ButtonSubmit /> >+ <router-link >+ :to="{ name: 'VendorList' }" >+ role="button" >+ class="cancel" >+ >{{ $__("Cancel") }}</router-link >+ > >+ </fieldset> >+ </form> >+ </div> >+ </div> >+</template> >+ >+<script> >+import ButtonSubmit from "../ButtonSubmit.vue" >+import { setMessage } from "../../messages" >+import { APIClient } from "../../fetch/api-client.js" >+import VendorDetails from "./VendorDetails.vue" >+import VendorContacts from "./VendorContacts.vue" >+import VendorOrderingInformation from "./VendorOrderingInformation.vue" >+import VendorInterfaces from "./VendorInterfaces.vue" >+ >+export default { >+ data() { >+ return { >+ vendor: { >+ id: null, >+ name: "", >+ address1: "", >+ address2: "", >+ address3: "", >+ address4: "", >+ phone: "", >+ accountnumber: "", >+ type: "", >+ notes: "", >+ postal: "", >+ url: "", >+ active: false, >+ list_currency: null, >+ invoice_currency: null, >+ tax_rate: null, >+ gst: false, >+ list_includes_gst: false, >+ invoice_includes_gst: false, >+ discount: null, >+ deliverytime: null, >+ fax: "", >+ external_id: "", >+ aliases: [], >+ contacts: [], >+ interfaces: [], >+ }, >+ initialized: false, >+ } >+ }, >+ beforeRouteEnter(to, from, next) { >+ next(vm => { >+ if (to.params.vendor_id) { >+ vm.getVendor(to.params.vendor_id) >+ } else { >+ vm.initialized = true >+ } >+ }) >+ }, >+ methods: { >+ async getVendor(vendor_id) { >+ const client = APIClient.acquisition >+ client.vendors.get(vendor_id).then( >+ vendor => { >+ this.vendor = vendor >+ let physical = "" >+ vendor.address1 && (physical += vendor.address1 + "\n") >+ vendor.address2 && (physical += vendor.address2 + "\n") >+ vendor.address3 && (physical += vendor.address3 + "\n") >+ vendor.address4 && (physical += vendor.address4 + "\n") >+ this.vendor.physical = physical >+ this.initialized = true >+ }, >+ error => {} >+ ) >+ }, >+ onSubmit(e) { >+ e.preventDefault() >+ >+ const vendor = JSON.parse(JSON.stringify(this.vendor)) >+ >+ const vendorId = vendor.id >+ delete vendor.id >+ >+ if (vendor.physical) { >+ const addressLines = vendor.physical.split("\n") >+ if (addressLines.length > 4) { >+ addressLines.length = 4 >+ } >+ addressLines.forEach((line, i) => { >+ vendor[`address${i + 1}`] = line >+ }) >+ } >+ delete vendor.physical >+ >+ vendor.contacts = vendor.contacts.map( >+ ({ id, booksellerid, ...requiredProperties }) => >+ requiredProperties >+ ) >+ vendor.interfaces = vendor.interfaces.map( >+ ({ interface_id, vendor_id, ...requiredProperties }) => >+ requiredProperties >+ ) >+ >+ const client = APIClient.acquisition >+ if (vendorId) { >+ client.vendors.update(vendor, vendorId).then( >+ success => { >+ setMessage(this.$__("Vendor updated")) >+ this.$router.push({ name: "VendorList" }) >+ }, >+ error => {} >+ ) >+ } else { >+ client.vendors.create(vendor).then( >+ success => { >+ setMessage(this.$__("Vendor created")) >+ this.$router.push({ name: "VendorList" }) >+ }, >+ error => {} >+ ) >+ } >+ }, >+ }, >+ components: { >+ ButtonSubmit, >+ VendorDetails, >+ VendorContacts, >+ VendorOrderingInformation, >+ VendorInterfaces, >+ }, >+ name: "VendorFormAdd", >+} >+</script> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorInterfaces.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorInterfaces.vue >index f405431dee6..e04e46baa8f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorInterfaces.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorInterfaces.vue >@@ -1,5 +1,5 @@ > <template> >- <fieldset class="rows"> >+ <fieldset class="rows" v-if="display"> > <h2> > {{ $__("Interfaces") }} > </h2> >@@ -8,7 +8,7 @@ > <li> > <label>{{ $__("Type") }}:</label> > <span> >- {{ get_lib_from_av("vendor_interface_types", vi.type) }} >+ {{ get_lib_from_av("av_vendor_interface_types", vi.type) }} > </span> > </li> > <li v-if="vi.uri"> >@@ -43,12 +43,129 @@ > </li> > </ol> > </fieldset> >+ <fieldset class="rows" v-else> >+ <legend>{{ $__("Interfaces") }}</legend> >+ <fieldset >+ v-for="(vendorInterface, i) in vendor.interfaces" >+ v-bind:key="i" >+ class="rows" >+ :id="`vendor_interface_${i}`" >+ > >+ <legend> >+ {{ $__("Interface details") }} >+ <a href="#" @click.prevent="deleteInterface(i)" >+ ><i class="fa fa-trash"></i> >+ {{ $__("Remove this interface") }}</a >+ > >+ </legend> >+ <ol> >+ <li> >+ <label :for="`vendorInterface_${i}_name`" >+ >{{ $__("Name") }}:</label >+ > >+ <input >+ :id="`vendorInterface_${i}_name`" >+ v-model="vendorInterface.name" >+ /> >+ </li> >+ <li> >+ <label for="vendorInterface_type">{{ $__("Type") }}:</label> >+ <v-select >+ id="vendorInterface_type" >+ v-model="vendorInterface.type" >+ label="description" >+ :reduce="av => av.value" >+ :options="av_vendor_interface_types" >+ /> >+ </li> >+ <li> >+ <label :for="`vendorInterface_${i}_uri`" >+ >{{ $__("URI") }}:</label >+ > >+ <input >+ :id="`vendorInterface_${i}_uri`" >+ v-model="vendorInterface.uri" >+ /> >+ </li> >+ <li> >+ <label :for="`vendorInterface_${i}_login`" >+ >{{ $__("Login") }}:</label >+ > >+ <input >+ :id="`vendorInterface_${i}_login`" >+ v-model="vendorInterface.login" >+ /> >+ </li> >+ <li> >+ <label :for="`vendorInterface_${i}_password`" >+ >{{ $__("Password") }}:</label >+ > >+ <input >+ :id="`vendorInterface_${i}_password`" >+ v-model="vendorInterface.password" >+ /> >+ </li> >+ <li> >+ <label :for="`vendorInterface_${i}_accountemail`" >+ >{{ $__("Account email") }}:</label >+ > >+ <input >+ :id="`vendorInterface_${i}_accountemail`" >+ v-model="vendorInterface.account_email" >+ /> >+ </li> >+ <li> >+ <label :for="`vendorInterface_${i}_notes`" >+ >{{ $__("Notes") }}:</label >+ > >+ <textarea >+ :id="`vendorInterface_${i}_notes`" >+ v-model="vendorInterface.notes" >+ cols="40" >+ rows="3" >+ /> >+ </li> >+ </ol> >+ </fieldset> >+ <span class="btn btn-default" @click="addInterface" >+ ><font-awesome-icon icon="plus" /> >+ {{ $__("Add new interface") }}</span >+ > >+ </fieldset> > </template> > > <script> >+import { inject } from "vue" >+import { storeToRefs } from "pinia" >+ > export default { > props: { > vendor: Object, >+ display: Boolean, >+ }, >+ setup() { >+ const AVStore = inject("AVStore") >+ const { get_lib_from_av, av_vendor_interface_types } = AVStore >+ return { >+ get_lib_from_av, >+ av_vendor_interface_types, >+ } >+ }, >+ methods: { >+ addInterface() { >+ this.vendor.interfaces.push({ >+ type: "", >+ name: "", >+ uri: "", >+ login: "", >+ password: "", >+ account_email: "", >+ notes: "", >+ }) >+ }, >+ deleteInterface(interfaceIndex) { >+ this.vendor.interfaces.splice(interfaceIndex, 1) >+ }, > }, > } > </script> >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 e4d3416a583..9f3fe26e686 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 >@@ -3,7 +3,7 @@ > <div v-else id="vendors_list"> > <Toolbar> > <ToolbarButton >- :to="{ name: 'VendorList' }" >+ :to="{ name: 'VendorFormAdd' }" > icon="plus" > :title="$__('New vendor')" > /> >@@ -28,10 +28,9 @@ > import flatPickr from "vue-flatpickr-component" > import Toolbar from "../Toolbar.vue" > import ToolbarButton from "../ToolbarButton.vue" >-import { inject, ref, reactive } from "vue" >+import { inject, ref } from "vue" > import { APIClient } from "../../fetch/api-client.js" > import { storeToRefs } from "pinia" >-import { build_url } from "../../composables/datatables" > import KohaTable from "../KohaTable.vue" > > export default { >@@ -45,11 +44,6 @@ export default { > > const table = ref() > >- // const filters = reactive({ >- // by_expired: false, >- // max_expiration_date: "", >- // by_mine: false, >- // }) > return { > vendors, > get_lib_from_av, >@@ -58,7 +52,6 @@ export default { > setConfirmationDialog, > setMessage, > escape_str, >- // filters, > } > }, > data() { >@@ -69,7 +62,7 @@ export default { > tableOptions: { > columns: this.getTableColumns(), > options: { embed: "aliases,baskets,subscriptions" }, >- url: () => this.table_url(), >+ url: () => this.tableURL(), > add_filters: true, > filters_options: { > 1: [ >@@ -104,19 +97,20 @@ export default { > error => {} > ) > }, >- doShow: function ({ id }, dt, event) { >+ doShow({ id }, dt, event) { > event.preventDefault() > this.$router.push({ > name: "VendorShow", > params: { vendor_id: id }, > }) > }, >- doEdit: function ({ id }, dt, event) { >+ doEdit({ id }, dt, event) { > this.$router.push({ >- name: "Home", >+ name: "VendorFormAddEdit", >+ params: { vendor_id: id }, > }) > }, >- doDelete: function (vendor, dt, event) { >+ doDelete(vendor, dt, event) { > this.setConfirmationDialog( > { > title: this.$__( >@@ -143,15 +137,15 @@ export default { > } > ) > }, >- doSelect: function (vendor, dt, event) { >+ doSelect(vendor, dt, event) { > this.$emit("select-vendor", vendor.id) > this.$emit("close") > }, >- table_url: function () { >+ tableURL() { > let url = "/api/v1/acquisitions/vendors" > return url > }, >- getTableColumns: function () { >+ getTableColumns() { > const escape_str = this.escape_str > const get_lib_from_av = this.get_lib_from_av > >@@ -161,7 +155,7 @@ export default { > data: "me.name:me.id", > searchable: true, > orderable: true, >- render: function (data, type, row, meta) { >+ render(data, type, row, meta) { > return ( > '<a href="/cgi-bin/koha/vendors/' + > row.id + >@@ -176,7 +170,7 @@ export default { > data: "active", > searchable: true, > orderable: true, >- render: function (data, type, row, meta) { >+ render(data, type, row, meta) { > return escape_str( > row.active ? __("Active") : __("Inactive") > ) >@@ -202,7 +196,7 @@ export default { > data: "baskets", > searchable: false, > orderable: true, >- render: function (data, type, row, meta) { >+ render(data, type, row, meta) { > return row.baskets.length > ? '<a href="/cgi-bin/koha/vendors/' + > row.id + >@@ -219,7 +213,7 @@ export default { > data: "subscriptions", > searchable: false, > orderable: true, >- render: function (data, type, row, meta) { >+ render(data, type, row, meta) { > return row.subscriptions.length > ? '<a href="/cgi-bin/koha/serials/serials-search.pl?bookseller_filter=' + > row.name + >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorOrderingInformation.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorOrderingInformation.vue >index 60a3e621570..9a0a8037518 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorOrderingInformation.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorOrderingInformation.vue >@@ -1,5 +1,5 @@ > <template> >- <fieldset class="rows"> >+ <fieldset class="rows" v-if="display"> > <h2> > {{ $__("Ordering information") }} > </h2> >@@ -13,31 +13,31 @@ > <li> > <label>{{ $__("List prices are") }}:</label> > <span> >- {{ vendor.listprice }} >+ {{ vendor.list_currency }} > </span> > </li> > <li> > <label>{{ $__("Invoice prices are") }}:</label> > <span> >- {{ vendor.invoiceprice }} >+ {{ vendor.invoice_currency }} > </span> > </li> > <li v-if="vendor.tax_rate"> > <label>{{ $__("Tax number registered") }}:</label> > <span> >- {{ vendor.gstreg ? $__("Yes") : $__("No") }} >+ {{ vendor.gst ? $__("Yes") : $__("No") }} > </span> > </li> > <li v-if="vendor.tax_rate"> > <label>{{ $__("List item price includes tax") }}:</label> > <span> >- {{ vendor.listincgst ? $__("Yes") : $__("No") }} >+ {{ vendor.list_includes_gst ? $__("Yes") : $__("No") }} > </span> > </li> > <li v-if="vendor.tax_rate"> > <label>{{ $__("Invoice item price includes tax") }}:</label> > <span> >- {{ vendor.invoiceincgst ? $__("Yes") : $__("No") }} >+ {{ vendor.invoice_includes_gst ? $__("Yes") : $__("No") }} > </span> > </li> > <li> >@@ -62,14 +62,184 @@ > </li> > </ol> > </fieldset> >+ <fieldset class="rows" v-else> >+ <legend>{{ $__("Ordering information") }}</legend> >+ <ol> >+ <li> >+ <label for="activestatus">{{ $__("Vendor is") }}:</label> >+ <input >+ type="radio" >+ name="active" >+ id="activestatus_active" >+ :value="true" >+ v-model="vendor.active" >+ /> >+ <label class="radio" for="activestatus_active" >+ >{{ $__("Active") }} >+ </label> >+ <input >+ type="radio" >+ name="active" >+ id="activestatus_inactive" >+ :value="false" >+ v-model="vendor.active" >+ /> >+ <label class="radio" for="activestatus_inactive" >+ >{{ $__("Inactive") }} >+ </label> >+ </li> >+ <li> >+ <label for="list_currency">{{ $__("List prices are") }}:</label> >+ <v-select >+ id="list_currency" >+ v-model="vendor.list_currency" >+ label="currency" >+ :reduce="av => av.currency" >+ :options="currencies" >+ /> >+ </li> >+ <li> >+ <label for="invoice_currency" >+ >{{ $__("Invoice prices are") }}:</label >+ > >+ <v-select >+ id="invoice_currency" >+ v-model="vendor.invoice_currency" >+ label="currency" >+ :reduce="av => av.currency" >+ :options="currencies" >+ /> >+ </li> >+ <li> >+ <label for="gst">{{ $__("Tax number registered") }}:</label> >+ <input >+ type="radio" >+ name="gst" >+ id="gst_yes" >+ :value="true" >+ v-model="vendor.gst" >+ /> >+ <label class="radio" for="gst_yes">{{ $__("Yes") }} </label> >+ <input >+ type="radio" >+ name="gst" >+ id="gst_no" >+ :value="false" >+ v-model="vendor.gst" >+ /> >+ <label class="radio" for="gst_no">{{ $__("No") }} </label> >+ </li> >+ <li> >+ <label for="invoice_gst">{{ $__("Invoice prices") }}:</label> >+ <input >+ type="radio" >+ name="invoice_gst" >+ id="invoice_gst_yes" >+ :value="true" >+ v-model="vendor.invoice_includes_gst" >+ /> >+ <label class="radio" for="invoice_gst_yes" >+ >{{ $__("Include tax") }} >+ </label> >+ <input >+ type="radio" >+ name="invoice_gst" >+ id="invoice_gst_no" >+ :value="false" >+ v-model="vendor.invoice_includes_gst" >+ /> >+ <label class="radio" for="invoice_gst_no" >+ >{{ $__("Don't include tax") }} >+ </label> >+ </li> >+ <li> >+ <label for="list_gst">{{ $__("List prices") }}:</label> >+ <input >+ type="radio" >+ name="list_gst" >+ id="list_gst_yes" >+ :value="true" >+ v-model="vendor.list_includes_gst" >+ /> >+ <label class="radio" for="list_gst_yes" >+ >{{ $__("Include tax") }} >+ </label> >+ <input >+ type="radio" >+ name="list_gst" >+ id="list_gst_no" >+ :value="false" >+ v-model="vendor.list_includes_gst" >+ /> >+ <label class="radio" for="list_gst_no" >+ >{{ $__("Don't include tax") }} >+ </label> >+ </li> >+ <li> >+ <label for="tax_rate">{{ $__("Tax rate") }}:</label> >+ <v-select >+ id="tax_rate" >+ v-model="vendor.tax_rate" >+ label="label" >+ :reduce="av => av.value" >+ :options="gstValues" >+ /> >+ </li> >+ <li> >+ <label for="discount">{{ $__("Discount") }}: </label> >+ <input >+ type="text" >+ size="6" >+ id="discount" >+ name="discount" >+ v-model="vendor.discount" >+ /> >+ % >+ </li> >+ <li> >+ <label for="deliverytime">{{ $__("Delivery time") }}: </label> >+ <input >+ type="text" >+ size="6" >+ id="deliverytime" >+ name="deliverytime" >+ v-model="vendor.deliverytime" >+ /> >+ {{ $__("days") }} >+ </li> >+ <li> >+ <label for="notes">{{ $__("Notes") }}:</label> >+ <textarea >+ id="notes" >+ v-model="vendor.notes" >+ cols="40" >+ rows="3" >+ /> >+ </li> >+ </ol> >+ </fieldset> > </template> > > <script> >+import { inject } from "vue" >+import { storeToRefs } from "pinia" >+ > export default { > props: { > vendor: Object, >+ display: Boolean, >+ }, >+ setup() { >+ const vendorStore = inject("vendorStore") >+ const { currencies, gstValues } = storeToRefs(vendorStore) >+ >+ const AVStore = inject("AVStore") >+ const { get_lib_from_av } = AVStore >+ >+ return { >+ currencies, >+ gstValues, >+ } > }, > } > </script> >- >-<style></style> >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 2f4f7d8ddcb..e91d84731ee 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 >@@ -26,15 +26,16 @@ > </h1> > <div class="row"> > <div class="col-sm-6"> >- <VendorDetails :vendor="vendor" /> >- <VendorOrderingInformation :vendor="vendor" /> >+ <VendorDetails :vendor="vendor" :display="true" /> >+ <VendorOrderingInformation :vendor="vendor" :display="true" /> > <VendorInterfaces > :vendor="vendor" > v-if="vendor.interfaces.length > 0" >+ :display="true" > /> > </div> > <div class="col-sm-6"> >- <VendorContacts :vendor="vendor" /> >+ <VendorContacts :vendor="vendor" :display="true" /> > <VendorSubscriptions :vendor="vendor" /> > </div> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js >index 37c265f545e..ecc532630a9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js >@@ -22,6 +22,9 @@ export class AcquisitionAPIClient extends HttpClient { > endpoint: "vendors", > query, > params, >+ headers: { >+ "x-koha-embed": "aliases", >+ }, > }), > delete: id => > this.delete({ >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/acquisitions.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/acquisitions.js >index 0c9dc362ac1..33a9daf18be 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/acquisitions.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/acquisitions.js >@@ -3,6 +3,7 @@ import { markRaw } from "vue"; > import Home from "../components/Vendors/Home.vue"; > import VendorList from "../components/Vendors/VendorList.vue"; > import VendorShow from "../components/Vendors/VendorShow.vue"; >+import VendorFormAdd from "../components/Vendors/VendorFormAdd.vue"; > > import { $__ } from "../i18n"; > >@@ -36,6 +37,18 @@ export const routes = [ > component: markRaw(VendorShow), > title: $__("Show vendor"), > }, >+ { >+ path: "add", >+ name: "VendorFormAdd", >+ component: markRaw(VendorFormAdd), >+ title: $__("Add vendor"), >+ }, >+ { >+ path: "edit/:vendor_id", >+ name: "VendorFormAddEdit", >+ component: markRaw(VendorFormAdd), >+ title: $__("Edit vendor"), >+ }, > ], > }, > ], >-- >2.39.3 (Apple Git-146)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 38010
:
174119
|
174120
|
174121
|
174122
|
174123
|
174124
|
174125
|
174126
|
174128
|
174129
|
174130
|
174131
|
174132
|
174133
|
174134
|
174135
|
174136
|
174137
|
174138
|
174139
|
174140
|
174141
|
174142
|
174143
|
174144
|
174145
|
174146
|
174147
|
174148
|
174151
|
174152
|
174153
|
174154
|
174155
|
174156
|
174157
|
174158
|
174159
|
174160
|
174161
|
174162
|
174163
|
174164
|
174165
|
174166
|
174167
|
174168
|
174169
|
174170
|
174171
|
174172
|
174173
|
174174
|
174175
|
174176
|
174177
|
174178
|
174179
|
174194
|
174196
|
174197
|
174198
|
174199
|
174200
|
174201
|
174202
|
174203
|
174204
|
174205
|
174206
|
174207
|
174208
|
174209
|
174210
|
174211
|
174212
|
174213
|
174214
|
174215
|
174216
|
174217
|
174218
|
174220
|
174221
|
174222
|
174223
|
174224
|
174225
|
174226
|
174248
|
174266
|
174267
|
174269
|
174270
|
174273
|
174327
|
174328
|
174329
|
174330
|
174331
|
174332
|
174333
|
174334
|
174335
|
174336
|
174337
|
174338
|
174339
|
174340
|
174341
|
174342
|
174343
|
174344
|
174345
|
174346
|
174347
|
174348
|
174349
|
174350
|
174351
|
174352
|
174353
|
174354
|
174355
|
174356
|
174357
|
174358
|
174359
|
174360
|
174603