package com.lemans.ds.fitment import com.lemans.services.LemansManager import grails.transaction.Transactional import java.sql.Timestamp import java.util.stream.Collectors /** * Created by vramisetti on 6/12/2017. */ @Transactional class PartFitmentManagerService extends LemansManager { def partService def partFitmentService def modelYearService def qcChangeLogService /** * Create part fitments * * @param values * @param username * * @return Map containing errors */ Map createFitments(Map values, String username) { List errors = [] String partNumber = values.partNumber List modelYearIds = ((List) values.modelYearIds).parallelStream().distinct().collect(Collectors.toList()) List validModelYears = modelYearService.findValidModelYearIds(modelYearIds)?.modelYearId List invalidModelYearIds = modelYearIds.parallelStream().filter { s -> !validModelYears.contains(s) }.collect(Collectors.toList()) if (invalidModelYearIds) { errors << "Invalid model year's found $invalidModelYearIds" } if (!partService.partWithPartNumberExists(partNumber)) { errors << 'Invalid part' } if (!errors) { List modelYearIdsToBeCreated = modelIdsToBeCreated(partNumber, modelYearIds) if (modelYearIdsToBeCreated) { Timestamp now = new Timestamp(new Date().time) sql().withBatch(50, FITMENT_INSERT_SQL) { stmt -> modelYearIdsToBeCreated.each { Integer modelYearId -> stmt.addBatch([modelYearId: modelYearId, partNumber: partNumber, footnote: values.footNote ?: null, now: now, username: username]) } } List createdPartFitmentIds = createdPartFitmentsByModelYearIdsAndPartNumber(modelYearIdsToBeCreated, partNumber, now) log.debug("createdPartFitmentIds $createdPartFitmentIds") qcChangeLogService.createAndLogForQC('Part', partNumber, 'PartFitment', createdPartFitmentIds, now, username) qcChangeLogService.findAndDeleteChangeLogs('PartFitment', [partNumber], username) } } [errors: errors] } private List modelIdsToBeCreated(String partNumber, List modelYearIds) { List existingModelYearIds = partFitmentService.findFitmentsByPartNumberAndModelYearIds(partNumber, modelYearIds, 'modelYearId')*.modelYearId modelYearIds.parallelStream() .filter { s -> !existingModelYearIds.contains(s) } .collect(Collectors.toList()) } /** * Update partFitment * * @param partNumber * @param fitmentId * @param username * * @return Map containing errors */ PartFitment updateFitment(String partNumber, Integer fitmentId, Map input, String username) { PartFitment partFitment = PartFitment.findByPartNumberAndIdAndDateDeletedIsNull(partNumber, fitmentId) if (partFitment) { applyValuesToDomain(input, partFitment) saveOrDiscardDomain(partFitment, username) qcChangeLogService.updateAndLogForQC('Part', partNumber, 'PartFitment', partFitment, username) } partFitment } /** * Delete partFitment * * @param partNumber * @param fitmentId * @param username * * @return Map containing errors */ Map deleteFitment(String partNumber, Integer fitmentId, String username) { List partFitment = partFitmentService.findFitmentsByPartNumberAndPartFitmentIds(partNumber, [fitmentId]) deleteFitments(partNumber, partFitment ?: [], username) } /** * Delete partFitments * * @param values Map containing partNumber and partFitmentIds * @param username * * @return Map containing errors */ Map deleteMultipleFitments(Map values, String username) { List partFitment if(!values.partFitmentIds && values.modelYearIds) { values.partFitmentIds = partFitmentService.findFitmentsByPartNumberAndModelYearIds(values.partNumber, values.modelYearIds)*.partFitmentId } partFitment = partFitmentService.findFitmentsByPartNumberAndPartFitmentIds(values.partNumber, values.partFitmentIds) deleteFitments(values.partNumber, partFitment ?: [], username) } /** * Create Fitment position * * @param values.positions * @param partFitmentIds * @param username */ void assignFitmentPositions(Map values, List partFitmentIds, String username) { Timestamp now = new Timestamp(new Date().time) if (values?.replacePositions == true) { deletePartFitmentPositions(values.partNumber, new Timestamp(new Date().time), username, partFitmentIds) } if(values?.positions) { Map fitmentPositions = partFitmentPositionsByPositionAndFitment(values?.positions, partFitmentIds) List filtered = [] sql().withBatch(50, FITMENT_POSITION_INSERT_SQL) { stmt -> values?.positions.each { Integer position -> List fitments = fitmentPositions[position]*.partFitmentId partFitmentIds.each { Integer partFitmentId -> if (!(partFitmentId in fitments)) { filtered << partFitmentId stmt.addBatch([partFitmentId: partFitmentId, positionTypeId: position, now: now, username: username]) } } } } List createdFitmentPositionIds = createdPartFitmentPositionsByPositionAndFitment(values?.positions, partFitmentIds, now)*.partFitmentPositionId qcChangeLogService.createAndLogForQC('Part', values.partNumber, 'PartFitmentPosition', createdFitmentPositionIds, now, username) } qcChangeLogService.findAndDeleteChangeLogs('PartFitmentPosition', [values.partNumber], username) } PartFitmentTentative updateTentativeFitment(Integer partFitmentTentativeId, Map values, String username) { PartFitmentTentative partFitmentTentative = PartFitmentTentative.findByIdAndDateDeletedIsNull(partFitmentTentativeId) if (partFitmentTentative) { applyValuesToDomain(values, partFitmentTentative) saveOrDiscardDomain(partFitmentTentative, username) } partFitmentTentative } void deleteTentativeFitments(String partNumber, List modelYearIds, String username) { sql().executeUpdate(""" UPDATE partFitmentTentative SET dateDeleted = ?, deletedBy = ? WHERE modelYearId IN (${ modelYearIds.join(',') }) AND partNumber = '${partNumber}' AND dateDeleted IS NULL """, [new Timestamp(new Date().time), username]) } void deleteTentativeFitment(Integer partTentativeFitmentId, String username) { sql().executeUpdate(""" UPDATE partFitmentTentative SET dateDeleted = ?, deletedBy = ? WHERE partFitmentTentativeId = '${partTentativeFitmentId}' AND dateDeleted IS NULL """, [new Timestamp(new Date().time), username]) } private Map partFitmentPositionsByPositionAndFitment(List positionTypeIds, List partFitmentsIds) { String query = """SELECT partFitmentId, positionTypeId FROM PartFitmentPosition WITH(NOLOCK) WHERE positionTypeId IN (${positionTypeIds.join(', ')}) AND partFitmentId IN (${partFitmentsIds.join(', ')}) AND dateDeleted IS NULL""" sql().rows(query).groupBy { it.positionTypeId } } private List createdPartFitmentPositionsByPositionAndFitment(List positionTypeIds, List partFitmentsIds, Timestamp now) { String query = """SELECT partFitmentPositionId FROM PartFitmentPosition WITH(NOLOCK) WHERE positionTypeId IN (${positionTypeIds.join(', ')}) AND partFitmentId IN (${partFitmentsIds.join(', ')}) AND dateCreated = :dateCreated""" sql().rows([dateCreated: now], query) } private List deletedPartFitmentPositionsByFitmentId(List partFitmentsIds, Timestamp now) { String query = """SELECT partFitmentPositionId FROM PartFitmentPosition WITH(NOLOCK) WHERE dateDeleted = :dateDeleted AND partFitmentId IN (${partFitmentsIds.join(', ')})""" sql().rows([dateDeleted: now], query)*.partFitmentPositionId } private List deletedPartFitmentPositionsByFitmentId(List partFitmentsIds, Timestamp now, List positions) { String query = """SELECT partFitmentPositionId FROM PartFitmentPosition WITH(NOLOCK) WHERE dateDeleted = :dateDeleted AND partFitmentId IN (${partFitmentsIds.join(', ')}) AND positionTypeId IN (${positions?.join(', ')})""" sql().rows([dateDeleted: now], query)*.partFitmentPositionId } private List createdPartFitmentsByModelYearIdsAndPartNumber(List modelYearIds, String partNumber, Timestamp now) { String query = """SELECT partFitmentId FROM PartFitment WITH(NOLOCK) WHERE dateCreated = :dateCreated AND partNumber = :partNumber AND modelYearId IN (${modelYearIds.join(', ')})""" sql().rows([partNumber: partNumber, dateCreated: now], query)?.partFitmentId } private Map deleteFitments(String partNumber, List partFitments, String username) { List partFitmentIds = partFitments*.partFitmentId if (partFitments) { Timestamp now = new Timestamp(new Date().time) deletePartFitments(partNumber, now, username, partFitmentIds) deletePartFitmentPositions(partNumber, now, username, partFitmentIds) } [errors: []] } private void deletePartFitments(String partNumber, Timestamp now, String username, List partFitmentIds) { sql().executeUpdate([now: now, username: username], deleteFitmentsSql(partFitmentIds)) qcChangeLogService.deleteAndLogForQC('Part', partNumber, 'PartFitment', partFitmentIds, now, username) } void deletePartFitmentPositions(String partNumber, Timestamp now, String username, List partFitmentIds) { sql().executeUpdate([now: now, username: username], deleteFitmentPositionSql(partFitmentIds)) List fitmentPositionIds = deletedPartFitmentPositionsByFitmentId(partFitmentIds, now) qcChangeLogService.deleteAndLogForQC('Part', partNumber, 'PartFitmentPosition', fitmentPositionIds, now, username) } void deletePartFitmentPositions(String partNumber, Timestamp now, String username, List partFitmentIds, List positions) { sql().executeUpdate([now: now, username: username], deleteFitmentPositionSql(partFitmentIds, positions)) List fitmentPositionIds = deletedPartFitmentPositionsByFitmentId(partFitmentIds, now, positions) qcChangeLogService.deleteAndLogForQC('Part', partNumber, 'PartFitmentPosition', fitmentPositionIds, now, username) } private static final String FITMENT_INSERT_SQL = ''' INSERT INTO PartFitment (modelYearId, partNumber, footnote, dateCreated, createdBy, lastUpdated, lastUpdatedBy) VALUES (:modelYearId, :partNumber, :footnote, :now, :username, :now, :username) ''' /* private static final String FITMENT_UPDATE_SQL = ''' UPDATE PartFitment SET footnote = :footnote, modelReleaseTypeId = :modelReleaseTypeId, lastUpdated = :now, lastUpdatedBy = :username WHERE partNumber = :partNumber AND partFitmentId = :partFitmentId '''*/ private static final String FITMENT_POSITION_INSERT_SQL = ''' INSERT INTO PartFitmentPosition (partFitmentId, positionTypeId, dateCreated, createdBy, lastUpdated, lastUpdatedBy) values (:partFitmentId, :positionTypeId, :now, :username, :now, :username) ''' private String deleteFitmentPositionSql(List partFitmentIds) { "UPDATE PartFitmentPosition SET dateDeleted = :now, deletedBy = :username WHERE partFitmentId IN (${partFitmentIds.join(', ')}) AND dateDeleted IS NULL" } private String deleteFitmentPositionSql(List partFitmentIds, List positions) { "UPDATE PartFitmentPosition SET dateDeleted = :now, deletedBy = :username WHERE partFitmentId IN (${partFitmentIds?.join(', ')}) AND positionTypeId IN (${positions?.join(', ')}) AND dateDeleted IS NULL" } private String deleteFitmentsSql(List partFitmentIds) { "UPDATE PartFitment SET dateDeleted = :now, deletedBy = :username WHERE partFitmentId IN (${partFitmentIds.join(', ')})" } }