package com.lemans.ds.qualitycontrol import com.lemans.services.LemansManager import grails.transaction.Transactional import javax.mail.internet.InternetAddress import javax.mail.internet.MimeMessage @Transactional @SuppressWarnings(['AssignCollectionUnique']) class PartReviewManagerService extends LemansManager { def qcChangeLogService def qcRejectionLogService def jiraContext def jiraDigiQCUserName def jiraDigiQCPassword def jiraDigiQCPartEpic def temporaryMediaPath def hiddenChangeLogEmail def mailSender private static final String QC_LOGS_QUERY = ''' SELECT changeLogId FROM qc.vwChangeLog cl WITH(NOLOCK) INNER JOIN qc.Config c WITH(NOLOCK) ON cl.configId = c.configId AND c.parentEntity = 'Part' WHERE cl.parentEntityId = :partNumber AND cl.approvalStatusId = 13001 ''' Map approveByChangeLogIds(List logIds, String username, Integer qcChangeGroupId = null) { List changeLogIds = logIds?.unique() log.error("ChangeLogs Approving: ${changeLogIds}") if (hasChangeLogsWithStatus(changeLogIds, [13002])) { [messages: [[type: 'error', text: 'Some or All of the changes have already been approved, please refresh to get the latest changes']]] } else { qcChangeLogService.approveOrDeclineChangeLog(changeLogIds, 13002, username) //Approved List parentEntityIds = qcChangeLogService.getParentEntityIds(changeLogIds) if (13002 && qcChangeLogService.hasAllChangeLogsApproved(parentEntityIds)) { parentEntityIds.collect { String partNumber -> qcChangeLogService.deleteQCPriorityFlag(partNumber, 'Part', username) } } qcRejectionLogService.insertOrUpdateMessage(changeLogIds, '', '', username, 'Part', qcChangeGroupId, 'A') if (ifAllChangeLogsApproved(changeLogIds) && qcChangeGroupId !=null) { qcRejectionLogService.insertOrUpdateMessage(changeLogIds, '', '', username, 'Part', null) } } } Map approveByPartNumber(String partNumber, String username) { List changeLogIds = sql().rows([partNumber: partNumber], QC_LOGS_QUERY)*.changeLogId if (changeLogIds) { approveByChangeLogIds(changeLogIds, username) qcChangeLogService.deleteQCPriorityFlag(partNumber, 'Part', username) return [:] } else { return [messages: [[type: 'error', text: 'partNumber has no changes to be approved']]] } } Map approveByPartNumberAndEmail(String partNumber, String username) { List changeLogIds = sql().rows([partNumber: partNumber], QC_LOGS_QUERY)*.changeLogId if (changeLogIds) { approveByChangeLogIds(changeLogIds, username) qcChangeLogService.deleteQCPriorityFlag(partNumber, 'Part', username) sendEmail(partNumber, changeLogIds, username) } } private void sendEmail(String partNumber, List changeLogIds, String username) { MimeMessage mimeMessage = createMessage(partNumber, changeLogIds, username) mailSender.send(mimeMessage) } MimeMessage createMessage(String partNumber, List changeLogIds, String username) { MimeMessage mimeMessage = mailSender.createMimeMessage() mimeMessage.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(hiddenChangeLogEmail)) mimeMessage.from = new InternetAddress('services-mail@parts-unltd.com') mimeMessage.subject = "Auto Approve Change Logs not visible on Page for partNumber $partNumber Requested by user $username" mimeMessage.setContent changeLogIds.join(', ').toString(), 'text/html' mimeMessage } def declineByChangeLogIds(Map payload, String username) { List changeLogIds = payload.changeLogIds?.unique() log.error("ChangeLogs Declining: ${changeLogIds}") if (hasChangeLogsWithStatus(changeLogIds, [13002])) { [messages: [[type: 'error', text: 'Some or All of the changes have already been approved, please refresh to get the latest changes']]] } else { JiraTicketResponse response = createJira(payload, username) qcChangeLogService.approveOrDeclineChangeLog(changeLogIds, 13003, username) //Declined List parentIds = qcChangeLogService.getParentEntityIds(changeLogIds) parentIds.each { parentId -> if(qcChangeLogService.isApprovedOrRejected(parentId)) { qcChangeLogService.deleteQCPriorityFlag(parentId as String, 'Part', username) } } qcRejectionLogService.insertOrUpdateMessage(changeLogIds, response.key ?: "", payload.description.toString(), username, 'Part', payload.qcChangeGroupId as Integer) response.error ? response.toErrorMap() : response.toResponseMap() } } def createJira(Map payload, String username) { List partReviewUsers = [] List watchers = [] if(payload.changeLogIds) { partReviewUsers = partReviewUsersByChangeLogIds(payload.changeLogIds?.unique()) watchers = partReviewUsers.collect { it.changedBy ? it.changedBy.tokenize('\\')[1] : null }.findAll { it != null } } else if(payload.partNumber) { partReviewUsers = partReviewUsersByPartNumber(payload.partNumber) } String assignee = partReviewUsers ? (partReviewUsers[0]?.categorySpecialist ?: 'unassigned') : 'unassigned' JiraTicket jiraTicket = new JiraTicket(jiraContext, jiraDigiQCUserName, jiraDigiQCPassword, jiraDigiQCPartEpic, temporaryMediaPath).with { it.assignee = assignee reporter = username.tokenize('\\')[1] it.watchers = watchers description = payload.description ?: '' media = payload.media summary = this.summary(partReviewUsers ? partReviewUsers[0] : null) it } return jiraTicket.create() } private String summary(Map partInfo) { if (partInfo) { "${partInfo.qualifiedCategoryName ?: ''} - ${partInfo.primaryProductId ?: ''} - ${partInfo.partNumber ?: ''}" } else { 'Quality Control Rejected' } } private List partReviewUsersByChangeLogIds(List changeLogIds) { if (changeLogIds) { String query = """ SELECT DISTINCT p.partNumber, p.qualifiedCategoryName, p.primaryProductId, categorySpecialist = cs.userName, qc.changedBy FROM qc.vwChangeLog qc WITH(NOLOCK) INNER JOIN dbo.vwPart p WITH(NOLOCK) ON p.partNumber = qc.parentEntityId LEFT OUTER JOIN dbo.Category c WITH(NOLOCK) ON c.categoryId = p.categoryId AND c.dateDeleted IS NULL LEFT OUTER JOIN dbo.CategorySpecialist cs WITH(NOLOCK) ON cs.categoryId = c.parentCategoryId AND cs.dateDeleted IS NULL WHERE qc.changeLogId IN (${changeLogIds.join(', ')}) """ sql().rows(query) } } private List partReviewUsersByPartNumber(String partNumber) { String query = """ SELECT DISTINCT p.partNumber, p.qualifiedCategoryName, p.primaryProductId, categorySpecialist = cs.userName FROM dbo.vwPart p WITH(NOLOCK) LEFT OUTER JOIN dbo.Category c WITH(NOLOCK) ON c.categoryId = p.categoryId AND c.dateDeleted IS NULL LEFT OUTER JOIN dbo.CategorySpecialist cs WITH(NOLOCK) ON cs.categoryId = c.parentCategoryId AND cs.dateDeleted IS NULL WHERE p.partNumber = '${partNumber}' """ sql().rows(query) } private boolean hasChangeLogsWithStatus(List changeLogIds, List statuses) { if (changeLogIds) { String query = """ SELECT count(cl.changeLogId) as count FROM qc.vwChangeLog cl WITH(NOLOCK) WHERE cl.changeLogId IN (${changeLogIds.join(', ')}) AND cl.approvalStatusId IN (${statuses.join(', ')}) """ sql().firstRow(query)?.count } } private boolean ifAllChangeLogsApproved(List changeLogIds) { List parentEntityIds = qcChangeLogService.getParentEntityIds(changeLogIds) return qcChangeLogService.hasAllChangeLogsApproved(parentEntityIds) } }