Bug 32030: ERM - Add vendor to license

ALTER TABLE erm_agreement_licenses DROP FOREIGN KEY erm_licenses_ibfk_1;
ALTER TABLE erm_agreement_licenses DROP FOREIGN KEY erm_licenses_ibfk_2;
ALTER TABLE erm_agreement_licenses ADD CONSTRAINT `erm_agreement_licenses_ibfk_1` FOREIGN KEY (`agreement_id`) REFERENCES `erm_agreements` (`agreement_id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE erm_agreement_licenses ADD CONSTRAINT `erm_agreement_licenses_ibfk_2` FOREIGN KEY (`license_id`) REFERENCES `erm_licenses` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE erm_licenses ADD COLUMN vendor_id INT(11) DEFAULT NULL AFTER license_id;
ALTER TABLE erm_licenses ADD CONSTRAINT `erm_licenses_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;

Signed-off-by: Jonathan Field <jonathan.field@ptfs-europe.com>

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Jonathan Druart 2022-07-28 10:30:55 +02:00 committed by Tomas Cohen Arazi
parent 646a1ede2b
commit fccf6acc04
Signed by: tomascohen
GPG key ID: 0A272EA1B2F3C15F
13 changed files with 145 additions and 22 deletions

View file

@ -23,6 +23,7 @@ use MIME::Types;
use Koha::Database;
use Koha::DateUtils qw( dt_from_string );
use Koha::Exceptions;
use Koha::Acquisition::Bookseller;
use base qw(Koha::Object);
@ -257,6 +258,19 @@ sub agreement_packages {
return Koha::ERM::EHoldings::Package::Agreements->_new_from_dbic($packages_agreements_rs);
}
=head3 vendor
Return the vendor for this agreement
=cut
sub vendor {
my ( $self ) = @_;
my $vendor_rs = $self->_result->vendor;
return unless $vendor_rs;
return Koha::Acquisition::Bookseller->_new_from_dbic($vendor_rs);
}
=head2 Internal methods
=head3 _type

View file

@ -21,6 +21,8 @@ use Koha::Database;
use base qw(Koha::Object);
use Koha::Acquisition::Bookseller;
=head1 NAME
Koha::ERM::License - Koha ERM License Object class
@ -31,6 +33,19 @@ Koha::ERM::License - Koha ERM License Object class
=cut
=head3 vendor
Return the vendor for this license
=cut
sub vendor {
my ( $self ) = @_;
my $vendor_rs = $self->_result->vendor;
return unless $vendor_rs;
return Koha::Acquisition::Bookseller->_new_from_dbic($vendor_rs);
}
=head2 Internal methods
=head3 _type

View file

@ -64,6 +64,11 @@ properties:
description: documents
items:
$ref: erm_agreement_document.yaml
vendor:
description: Information about the vendor
type:
- object
- "null"
additionalProperties: false
required:

View file

@ -5,6 +5,11 @@ properties:
type: integer
description: internally assigned license identifier
readOnly: true
vendor_id:
description: foreign key to aqbooksellers
type:
- integer
- "null"
name:
description: name of the license
type: string
@ -33,6 +38,12 @@ properties:
- "null"
format: date
description: End of the license
vendor:
description: Information about the vendor
type:
- object
- "null"
additionalProperties: false
required:
- license_id

View file

@ -14,6 +14,11 @@
name: license_id
required: false
type: integer
- description: Case insensitive search on agreement vendor_id
in: query
name: vendor_id
required: false
type: integer
- description: Case insensitive search on license name
in: query
name: name

View file

@ -97,12 +97,14 @@ return {
$dbh->do(q{
CREATE TABLE `erm_licenses` (
`license_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`vendor_id` INT(11) DEFAULT NULL COMMENT 'foreign key to aqbooksellers',
`name` VARCHAR(255) NOT NULL COMMENT 'name of the license',
`description` LONGTEXT DEFAULT NULL COMMENT 'description of the license',
`type` VARCHAR(80) NOT NULL COMMENT 'type of the license',
`status` VARCHAR(80) NOT NULL COMMENT 'current status of the license',
`started_on` DATE COMMENT 'start of the license',
`ended_on` DATE COMMENT 'end of the license',
CONSTRAINT `erm_licenses_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
PRIMARY KEY(`license_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
});
@ -117,8 +119,8 @@ return {
`physical_location` VARCHAR(80) DEFAULT NULL COMMENT 'physical location of the license',
`notes` mediumtext DEFAULT NULL COMMENT 'notes about this license',
`uri` varchar(255) DEFAULT NULL COMMENT 'URI of the license',
CONSTRAINT `erm_licenses_ibfk_1` FOREIGN KEY (`agreement_id`) REFERENCES `erm_agreements` (`agreement_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_licenses_ibfk_2` FOREIGN KEY (`license_id`) REFERENCES `erm_licenses` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_agreement_licenses_ibfk_1` FOREIGN KEY (`agreement_id`) REFERENCES `erm_agreements` (`agreement_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_agreement_licenses_ibfk_2` FOREIGN KEY (`license_id`) REFERENCES `erm_licenses` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(`agreement_license_id`),
UNIQUE KEY `erm_agreement_licenses_uniq` (`agreement_id`, `license_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View file

@ -2830,12 +2830,14 @@ CREATE TABLE `erm_agreement_user_roles` (
DROP TABLE IF EXISTS `erm_licenses`;
CREATE TABLE `erm_licenses` (
`license_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`vendor_id` INT(11) DEFAULT NULL COMMENT 'foreign key to aqbooksellers',
`name` VARCHAR(255) NOT NULL COMMENT 'name of the license',
`description` LONGTEXT DEFAULT NULL COMMENT 'description of the license',
`type` VARCHAR(80) NOT NULL COMMENT 'type of the license',
`status` VARCHAR(80) NOT NULL COMMENT 'current status of the license',
`started_on` DATE COMMENT 'start of the license',
`ended_on` DATE COMMENT 'end of the license',
CONSTRAINT `erm_licenses_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
PRIMARY KEY(`license_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@ -2852,8 +2854,8 @@ CREATE TABLE `erm_agreement_licenses` (
`physical_location` VARCHAR(80) DEFAULT NULL COMMENT 'physical location of the license',
`notes` mediumtext DEFAULT NULL COMMENT 'notes about this license',
`uri` varchar(255) DEFAULT NULL COMMENT 'URI of the license',
CONSTRAINT `erm_licenses_ibfk_1` FOREIGN KEY (`agreement_id`) REFERENCES `erm_agreements` (`agreement_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_licenses_ibfk_2` FOREIGN KEY (`license_id`) REFERENCES `erm_licenses` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_agreement_licenses_ibfk_1` FOREIGN KEY (`agreement_id`) REFERENCES `erm_agreements` (`agreement_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `erm_agreement_licenses_ibfk_2` FOREIGN KEY (`license_id`) REFERENCES `erm_licenses` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(`agreement_license_id`),
UNIQUE KEY `erm_agreement_licenses_uniq` (`agreement_id`, `license_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View file

@ -332,6 +332,7 @@ export default {
apiUrl += '/' + agreement.agreement_id
}
delete agreement.agreement_id
delete agreement.vendor
agreement.is_perpetual = agreement.is_perpetual ? true : false
if (agreement.vendor_id == "") {

View file

@ -32,12 +32,8 @@
<a
:href="`/cgi-bin/koha/acqui/booksellers.pl?booksellerid=${agreement.vendor_id}`"
>
{{
vendors.find(
(e) => e.id == agreement.vendor_id
).name
}}</a
>
{{ agreement.vendor.name }}
</a>
</span>
</li>
<li>
@ -303,19 +299,14 @@
</template>
<script>
import { useVendorStore } from "../../stores/vendors"
import { useAVStore } from "../../stores/authorised_values"
import { fetchAgreement } from "../../fetch"
import { storeToRefs } from "pinia"
export default {
setup() {
const format_date = $date
const patron_to_html = $patron_to_html
const vendorStore = useVendorStore()
const { vendors } = storeToRefs(vendorStore)
const AVStore = useAVStore()
const { get_lib_from_av } = AVStore
@ -323,7 +314,6 @@ export default {
format_date,
patron_to_html,
get_lib_from_av,
vendors,
}
},
data() {

View file

@ -21,6 +21,30 @@
/>
<span class="required">{{ $t("Required") }}</span>
</li>
<li>
<label for="license_vendor_id"
>{{ $t("Vendor") }}:</label
>
<select
id="license_vendor_id"
v-model="license.vendor_id"
>
<option value=""></option>
<option
v-for="vendor in vendors"
:key="vendor.vendor_id"
:value="vendor.id"
:selected="
vendor.id == license.vendor_id
? true
: false
"
>
{{ vendor.name }}
</option>
</select>
</li>
<li>
<label for="license_description"
>{{ $t("Description") }}:
@ -121,6 +145,7 @@
<script>
import flatPickr from 'vue-flatpickr-component'
import { useVendorStore } from "../../stores/vendors"
import { useAVStore } from "../../stores/authorised_values"
import { setMessage, setError } from "../../messages"
import { fetchLicense } from '../../fetch'
@ -129,6 +154,8 @@ import { storeToRefs } from "pinia"
export default {
setup() {
const vendorStore = useVendorStore()
const { vendors } = storeToRefs(vendorStore)
const AVStore = useAVStore()
const {
av_license_types,
@ -136,6 +163,7 @@ export default {
} = storeToRefs(AVStore)
return {
vendors,
av_license_types,
av_license_statuses,
}
@ -147,6 +175,7 @@ export default {
license: {
license_id: null,
name: '',
vendor_id: null,
description: '',
type: '',
status: '',
@ -190,6 +219,11 @@ export default {
apiUrl += '/' + license.license_id
}
delete license.license_id
delete license.vendor
if (license.vendor_id == "") {
license.vendor_id = null
}
license.started_on = license.started_on ? $date_to_rfc3339(license.started_on) : null
license.ended_on = license.ended_on ? $date_to_rfc3339(license.ended_on) : null

View file

@ -12,6 +12,7 @@
<script>
import Toolbar from "./LicensesToolbar.vue"
import { createVNode, render } from 'vue'
import { useVendorStore } from "../../stores/vendors"
import { useAVStore } from "../../stores/authorised_values"
import { storeToRefs } from "pinia"
import { fetchLicenses } from "../../fetch"
@ -19,6 +20,9 @@ import { useDataTable } from "../../composables/datatables"
export default {
setup() {
const vendorStore = useVendorStore()
const { vendors } = storeToRefs(vendorStore)
const AVStore = useAVStore()
const { get_lib_from_av, map_av_dt_filter } = AVStore
@ -26,6 +30,7 @@ export default {
useDataTable(table_id)
return {
vendors,
get_lib_from_av,
map_av_dt_filter,
table_id,
@ -67,6 +72,15 @@ export default {
let default_search = this.$route.query.q
let table_id = this.table_id
window['vendors'] = this.vendors.map(e => {
e['_id'] = e['id']
e['_str'] = e['name']
return e
})
let vendors_map = this.vendors.reduce((map, e) => {
map[e.id] = e
return map
}, {})
let avs = ['av_license_types', 'av_license_statuses']
avs.forEach(function (av_cat) {
window[av_cat] = map_av_dt_filter(av_cat)
@ -98,6 +112,16 @@ export default {
return ""
}
},
{
title: __("Vendor"),
data: "vendor_id",
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
return row.vendor_id != undefined ? escape_str(vendors_map[row.vendor_id].name) : ""
}
},
{
title: __("Description"),
data: "description",
@ -189,8 +213,9 @@ export default {
})
},
preDrawCallback: function (settings) {
$("#" + table_id).find("thead th").eq(2).attr('data-filter', 'av_license_types')
$("#" + table_id).find("thead th").eq(3).attr('data-filter', 'av_license_statuses')
$("#" + table_id).find("thead th").eq(1).attr('data-filter', 'vendors')
$("#" + table_id).find("thead th").eq(3).attr('data-filter', 'av_license_types')
$("#" + table_id).find("thead th").eq(4).attr('data-filter', 'av_license_statuses')
}
}, license_table_settings, 1)

View file

@ -25,6 +25,16 @@
{{ license.name }}
</span>
</li>
<li>
<label>{{ $t("Vendor") }}:</label>
<span v-if="license.vendor_id">
<a
:href="`/cgi-bin/koha/acqui/booksellers.pl?booksellerid=${license.vendor_id}`"
>
{{ license.vendor.name }}
</a>
</span>
</li>
<li>
<label>{{ $t("Description") }}:</label>
<span>
@ -72,7 +82,6 @@
<script>
import { useAVStore } from "../../stores/authorised_values"
import { storeToRefs } from "pinia"
import { fetchLicense } from "../../fetch"
export default {
@ -92,6 +101,8 @@ export default {
license: {
license_id: null,
name: '',
vendor_id: null,
vendor: null,
description: '',
type: '',
status: '',

View file

@ -7,7 +7,7 @@ export const fetchAgreement = async function (agreement_id) {
await fetch(apiUrl, {
headers: {
"x-koha-embed":
"periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package",
"periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor",
},
})
.then(checkError)
@ -42,7 +42,11 @@ export const fetchLicense = async function (license_id) {
if (!license_id) return;
const apiUrl = "/api/v1/erm/licenses/" + license_id;
let license;
await fetch(apiUrl)
await fetch(apiUrl, {
headers: {
"x-koha-embed": "vendor",
},
})
.then(checkError)
.then(
(result) => {
@ -58,7 +62,11 @@ export const fetchLicense = async function (license_id) {
export const fetchLicenses = async function () {
const apiUrl = "/api/v1/erm/licenses";
let licenses;
await fetch(apiUrl)
await fetch(apiUrl, {
headers: {
"x-koha-embed": "vendor.name",
},
})
.then(checkError)
.then(
(result) => {