diff --git a/grails-app/services/au/org/ala/collectory/DataImportService.groovy b/grails-app/services/au/org/ala/collectory/DataImportService.groovy index 055b7c15..0b74343a 100644 --- a/grails-app/services/au/org/ala/collectory/DataImportService.groovy +++ b/grails-app/services/au/org/ala/collectory/DataImportService.groovy @@ -150,7 +150,8 @@ class DataImportService { if (file.getName().startsWith(EML_FILE)) { //open the XML file that contains the EML details for the GBIF resource def xml = new XmlSlurper().parseText(zipFile.getInputStream(file).getText("UTF-8")) - contacts = emlImportService.extractContactsFromEml(xml, dataResource) + def result = emlImportService.extractContactsFromEml(xml, dataResource) + contacts = result.contacts } } } diff --git a/grails-app/services/au/org/ala/collectory/EmlImportService.groovy b/grails-app/services/au/org/ala/collectory/EmlImportService.groovy index b82dffbd..5fabfdd5 100644 --- a/grails-app/services/au/org/ala/collectory/EmlImportService.groovy +++ b/grails-app/services/au/org/ala/collectory/EmlImportService.groovy @@ -115,6 +115,7 @@ class EmlImportService { def extractContactsFromEml(eml, dataResource){ def contacts = [] + def primaryContacts = [] emlFields.each { name, accessor -> def val = accessor(eml) @@ -123,10 +124,10 @@ class EmlImportService { } } - //add a contacts... + //add contacts... if (eml.dataset.creator){ eml.dataset.creator.each { - def contact = addContact(it) + def contact = addOrUpdateContact(it) if (contact){ contacts << contact } @@ -137,36 +138,77 @@ class EmlImportService { && eml.dataset.metadataProvider.electronicMailAddress != eml.dataset.creator.electronicMailAddress){ eml.dataset.metadataProvider.each { - def contact = addContact(it) + def contact = addOrUpdateContact(it) if (contact){ contacts << contact } } } - contacts + // Add additional contacts + if (eml.dataset.contact){ + eml.dataset.contact.each { + def contact = addOrUpdateContact(it) + if (contact){ + contacts << contact + primaryContacts << contact + } + } + } + + if (eml.dataset.associatedParty){ + eml.dataset.associatedParty.each { + def contact = addOrUpdateContact(it) + if (contact){ + contacts << contact + } + } + } + + [contacts: contacts, primaryContacts: primaryContacts] } - private def addContact(emlElement){ - def contact = Contact.findByEmail(emlElement.electronicMailAddress) - if (!contact){ + private def addOrUpdateContact(emlElement) { + def contact = null + if (emlElement.electronicMailAddress && !emlElement.electronicMailAddress.isEmpty()) { + String email = emlElement.electronicMailAddress.text().trim() + contact = Contact.findByEmail(email) + } else if (emlElement.individualName.givenName && emlElement.individualName.surName) { + contact = Contact.findByFirstNameAndLastName(emlElement.individualName.givenName, emlElement.individualName.surName) + } else if (emlElement.individualName.surName) { + // surName is mandatory + contact = Contact.findByLastName(emlElement.individualName.surName) + } + + // Create the contact if it doesn't exist and it's a individualName with email or surName + // to prevent empty contacts (e.g. with emlElement.organizationName only) + boolean hasEmail = emlElement?.electronicMailAddress?.text()?.trim()?.isEmpty() == false + boolean hasName = emlElement?.individualName?.surName?.text()?.trim()?.isEmpty() == false + + if (!contact && (hasEmail || hasName)) { contact = new Contact() - contact.firstName = emlElement.individualName.givenName - contact.lastName = emlElement.individualName.surName - contact.email = emlElement.electronicMailAddress - contact.setUserLastModified(collectoryAuthService.username()) - Contact.withTransaction { - if (contact.validate()) { - contact.save(flush: true, failOnError: true) - return contact - } else { - contact.errors.each { - log.error("Problem creating contact: " + it) - } - return null + } else { + return null + } + + // Update the contact details + contact.firstName = emlElement.individualName.givenName + contact.lastName = emlElement.individualName.surName + // some email has leading/trailing spaces causing the email constrain regexp to fail, lets trim + contact.email = emlElement.electronicMailAddress.text().trim() + contact.setUserLastModified(collectoryAuthService.username()) + Contact.withTransaction { + if (contact.validate()) { + contact.save(flush: true, failOnError: true) + return contact + } else { + contact.errors.each { + log.error("Problem creating contact: " + it) } + return null } } + contact } } diff --git a/grails-app/services/au/org/ala/collectory/IptService.groovy b/grails-app/services/au/org/ala/collectory/IptService.groovy index 97dae984..ad96c8be 100644 --- a/grails-app/services/au/org/ala/collectory/IptService.groovy +++ b/grails-app/services/au/org/ala/collectory/IptService.groovy @@ -119,12 +119,16 @@ class IptService { } } - def emails = old.getContacts().collect { it.contact.email } - //sync contacts update.contacts.each { contact -> - if (!emails.contains(contact.email)) { - old.addToContacts(contact, null, false, true, collectoryAuthService.username()) + def existingContact = old.getContacts().find { + (it.contact.email && !it.contact.email.isEmpty() && it.contact.email == contact.email) || + (it.contact.firstName == contact.firstName && it.contact.lastName == contact.lastName) + } + if (!existingContact) { + // Add new contact + boolean isPrimaryContact = update.primaryContacts.contains(contact) + old.addToContacts(contact, null, false, isPrimaryContact, collectoryAuthService.username()) } } } @@ -142,7 +146,8 @@ class IptService { DataResource.withTransaction { update.resource.save(flush: true, failOnError: true) update.contacts.each { contact -> - update.resource.addToContacts(contact, null, false, true, collectoryAuthService.username()) + boolean isPrimaryContact = update.primaryContacts.contains(contact) + update.resource.addToContacts(contact, null, false, isPrimaryContact, collectoryAuthService.username()) } } activityLogService.log username, admin, Action.CREATE, "Created new IPT data resource for provider " + provider.uid + " with uid " + update.resource.uid + " for dataset " + update.resource.websiteUrl @@ -203,11 +208,14 @@ class IptService { resource.isShareableWithGBIF = isShareableWithGBIF def contacts = [] + def primaryContacts = [] if (eml != null && eml != "") { - contacts = retrieveEml(resource, eml) + def result = retrieveEml(resource, eml) + contacts = result.contacts + primaryContacts = result.primaryContacts } - [resource: resource, contacts: contacts] + [resource: resource, contacts: contacts, primaryContacts: primaryContacts] } /**