diff --git a/NEWS.md b/NEWS.md index c9d0b7284..f8c4194b0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,6 @@ +## 5.0.6 2021-11-12 +* ERM-1917 Duplicate title instance created on package import in Kiwi bugfest (incoming issn now maps to eissn in system) + ## 5.0.5 2021-11-10 * ERM-1917 Duplicate title instance created on package import in Kiwi bugfest diff --git a/service/gradle.properties b/service/gradle.properties index bb8600b45..ff3f06868 100644 --- a/service/gradle.properties +++ b/service/gradle.properties @@ -11,6 +11,6 @@ gradleWrapperVersion=5.4 # Application appName=mod-agreements -appVersion=5.0.5 +appVersion=5.0.6 dockerTagSuffix= dockerRepo=folioci diff --git a/service/grails-app/services/org/olf/TitleInstanceResolverService.groovy b/service/grails-app/services/org/olf/TitleInstanceResolverService.groovy index 866d2af35..ea0991b18 100644 --- a/service/grails-app/services/org/olf/TitleInstanceResolverService.groovy +++ b/service/grails-app/services/org/olf/TitleInstanceResolverService.groovy @@ -499,6 +499,37 @@ class TitleInstanceResolverService implements DataBinder{ identifiers?.findAll( { IdentifierSchema id -> class_one_namespaces?.contains( id.namespace.toLowerCase() ) })?.size() ?: 0 } + + // On the rare chance that we have `eissn` in our db (From before Kiwi namespace flattening) + // We attempt to map an incoming `issn` -> `eissn` in our DB + private String mapNamespaceToElectronic(final String incomingNs) { + String ouput; + switch (incomingNs.toLowerCase()) { + case 'issn': + ouput = 'eissn' + break; + case 'isbn': + ouput = 'eisbn' + default: + break; + } + } + + // On the rare chance that we have `pissn` in our db (From before Kiwi namespace flattening) + // We attempt to map an incoming `issn` -> `pissn` in our DB + private String mapNamespaceToPrint(final String incomingNs) { + String ouput; + switch (incomingNs.toLowerCase()) { + case 'issn': + ouput = 'pissn' + break; + case 'isbn': + ouput = 'pisbn' + default: + break; + } + } + /** * Being passed a map of namespace, value pair maps, attempt to locate any title instances with class 1 identifiers (ISSN, ISBN, DOI) */ @@ -532,9 +563,32 @@ class TitleInstanceResolverService implements DataBinder{ * We have to know that eissn == issn etc... Use namespaceMapping function */ - // TODO we have the possibility for Kiwi that an existing TI is in place with namespace eissn, since cleanup is a complicated matter - // For the time being, allow matching BOTH of `eissn` to `issn` (As per the story), but also `issn` to `eissn` in our db - final List id_matches = Identifier.executeQuery('select id from Identifier as id where id.value = :value and (id.ns.value = :mns or id.ns.value = :ns)',[value:id.value, ns:id.namespace, mns:namespaceMapping(id.namespace)], [max:2]) + /* NOTE: We have the possibility for Kiwi that an existing TI is in place with namespace eissn, + * since cleanup is a complicated matter. + * For the time being, allow matching BOTH of `eissn` -> `issn` (As per the story), + * but also `eissn` -> `eissn` AND `issn` -> `eissn` in our db. + * To allow for `eissn` -> `eissn` the (ns:id.namespace) case is sufficient. + * To allow for `issn` -> `eissn` we also need + */ + final List id_matches = Identifier.executeQuery(""" + SELECT id FROM Identifier AS id + WHERE + id.value = :value AND + ( + id.ns.value = :nsm OR + id.ns.value = :ns OR + id.ns.value = :ens OR + id.ns.value = :pns + )""".toString(), + [ + value:id.value, + ns:id.namespace.toLowerCase(), + nsm:namespaceMapping(id.namespace), + ens:mapNamespaceToElectronic(id.namespace), + pns:mapNamespaceToPrint(id.namespace) + ], + [max:2] + ) if (id_matches.size() > 1) { throw new RuntimeException("Multiple (${id_matches.size()}) class one matches found for identifier ${id.namespace}::${id.value}"); diff --git a/service/src/main/groovy/org/olf/export/KBart.groovy b/service/src/main/groovy/org/olf/export/KBart.groovy index 3098d9d1c..a98143c5e 100644 --- a/service/src/main/groovy/org/olf/export/KBart.groovy +++ b/service/src/main/groovy/org/olf/export/KBart.groovy @@ -215,7 +215,8 @@ public class KBart implements Serializable { return header as String[] } - // This method assumes it is being called on identifiers from within our database. Therefore any eissn or pissn will have been flattened to just issn + // This method assumes it is being called on identifiers from within our database. + // Therefore any eissn or pissn *should* have been flattened to just issn, but may not have been static String getIdentifierValue(Object identifiers) { if (identifiers) { Iterator iter = identifiers.iterator(); @@ -224,9 +225,17 @@ public class KBart implements Serializable { while (iter.hasNext()) { IdentifierOccurrence thisIdent = iter.next() Identifier ident = thisIdent.identifier - if (ident?.ns?.value == "issn") { + if ( + ident?.ns?.value == "issn" || + ident?.ns?.value == "eissn" || + ident?.ns?.value == "pissn" + ) { issn = ident.value - } else if (ident?.ns?.value == "isbn") { + } else if ( + ident?.ns?.value == "isbn" || + ident?.ns?.value == "eisbn" || + ident?.ns?.value == "pisbn" + ) { isbn = ident.value } else if (ident?.ns?.value == "doi") { doi = ident.value