import org.apache.commons.lang.WordUtils class AssetService { boolean transactional = false def sessionFactory def assetSubItemService /** * Determines and returns a possible list of asset sub items. * @returns A list of the possible assetSubItems. */ def possibleAssetSubItems() { def criteria = AssetSubItem.createCriteria() def possibleAssetSubItems = criteria.list() { and { eq('isActive', true) isNull("parentItem") } } } /** * Determines and returns a list of assemblies for an asset. * This is purely a 'load from database' type method since a new hibernateSession is used. * @params Asset to get the subItems for. * @returns A list of the assemblies. */ def getAssemblies(Asset asset) { def assemblies = [] // Database efficiency: // The asset is configured to batch fetch assetSubItems which // in turn are configured to batch fetch subItems. Asset.withNewSession { Asset.get(asset.id).assetSubItems.each { assemblies.addAll(it.subItems) } } assemblies.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } return assemblies } def delete(params) { Asset.withTransaction { status -> def result = [:] def fail = { Map m -> status.setRollbackOnly() if(result.assetInstance && m.field) result.assetInstance.errors.rejectValue(m.field, m.code) result.error = [ code: m.code, args: ["Asset", params.id] ] return result } result.assetInstance = Asset.get(params.id) if(!result.assetInstance) return fail(code:"default.not.found") if(result.assetInstance.maintenanceActions) return fail(code:"maintenanceActions.still.associated") // Remove orphan assetSubItems. def assetSubItems = new ArrayList(result.assetInstance.assetSubItems) // avoid ConcurrentModificationException. def r for(assetSubItem in assetSubItems) { result.assetInstance.removeFromAssetSubItems(assetSubItem) if(!assetSubItem.assets && !assetSubItem.parentItem) { r = assetSubItemService.delete(id: assetSubItem.id) if(r.error) { log.debug r.error fail(code:"asset.subItems.delete.failure") break } } } if(result.error) return result // Success. // We have handled all the foreign keys so the delete should go forward. // Can't flush here due to cascading from Section and Site. // And without flush there is no point it trying to catch the dao.DataIntegrityViolationException // since that will only happen after leaving the transaction. result.assetInstance.delete() return result } // end withTransaction } // end delete() def create(params) { def result = [:] def fail = { Map m -> result.error = [ code: m.code, args: ["Asset", params.id] ] return result } result.assetInstance = new Asset() result.assetInstance.properties = params // success return result } def copy(params) { def result = [:] def fail = { Map m -> result.error = [ code: m.code, args: ["Asset", params.id] ] return result } result.assetToCopy = Asset.get(params.assetToCopy?.id) if(!result.assetToCopy) return fail(code: "asset.copy.asset.required") result.assetInstance = new Asset(name: result.assetToCopy.name, description: result.assetToCopy.description, comment: result.assetToCopy.comment, section: result.assetToCopy.section) result.assetInstance.properties = params // success return result } def save(params) { def result = [:] def fail = { Map m -> if(result.assetInstance && m.field) result.assetInstance.errors.rejectValue(m.field, m.code) result.error = [ code: m.code, args: ["Asset", params.id] ] return result } result.assetInstance = new Asset(params) use(WordUtils) { result.assetInstance.name = result.assetInstance.name.capitalize() result.assetInstance.description = result.assetInstance.description.capitalize() } if(result.assetInstance.hasErrors() || !result.assetInstance.save(flush: true)) return fail(code:"default.create.failure") // success return result } def saveCopy(params) { Asset.withTransaction { status -> def result = [:] def fail = { Map m -> status.setRollbackOnly() if(result.assetInstance && m.field) result.assetInstance.errors.rejectValue(m.field, m.code) result.error = [ code: m.code, args: ["Asset", params.id] ] return result } result.assetToCopy = Asset.get(params.assetToCopy?.id) if(!result.assetToCopy) return fail(code:"default.not.found") if(!params.copyMethod) fail(code:"asset.copy.method.required") result.assetInstance = new Asset(params) if(result.assetInstance.hasErrors() || !result.assetInstance.save()) return fail(code:"default.create.failure") def assetSubItemInstance1 // Copy subItems from level 2 and bellow. def copyAssetSubItem = { assetSubItemToCopy, parentItem -> def nextCount = AssetSubItem.count() + 1 def baseName = assetSubItemToCopy.name.split('\\(id:')[0] def name = baseName +'(id:'+nextCount+')' def assetSubItemInstance = new AssetSubItem(name: name, description: assetSubItemToCopy.description, parentItem: parentItem) if(assetSubItemInstance.hasErrors() || !assetSubItemInstance.save()) return fail(code:"asset.copy.subItem.create.failure") def i = 0 for(assetSubItem in assetSubItemToCopy.subItems) { call(assetSubItem, assetSubItemInstance) // Protect against endless recurrsion. i++ if(i > 100) fail(code:"asset.copy.subItem.too.many.failure") // Stop if an error is flagged. if(result.error) break } } //copyAssetSubItem // Copy the 1st level of subItems. def copyAssetSubItem1 = { assetSubItemToCopy -> def nextCount = AssetSubItem.count() + 1 def baseName = assetSubItemToCopy.name.split('\\(id:')[0] def name = baseName +'(id:'+nextCount+')' assetSubItemInstance1 = new AssetSubItem(name: name, description: assetSubItemToCopy.description, asset: result.assetInstance) if(assetSubItemInstance1.hasErrors() || !assetSubItemInstance1.save()) return fail(code:"asset.copy.subItem.create.failure") result.assetInstance.addToAssetSubItems(assetSubItemInstance1) def i = 0 for(assetSubItem in assetSubItemToCopy.subItems) { copyAssetSubItem(assetSubItem, assetSubItemInstance1) // Protect against endless recurrsion. i++ if(i > 100) fail(code:"asset.copy.subItem.too.many.failure") // Stop if an error is flagged. if(result.error) break } } //copyAssetSubItem1 def linkAssetSubItem = { assetSubItemToLink -> result.assetInstance.addToAssetSubItems(assetSubItemToLink) } def i = 0 for(assetSubItem in result.assetToCopy.assetSubItems) { if(params.copyMethod == "copy") copyAssetSubItem1(assetSubItem) else linkAssetSubItem(assetSubItem) // Protect against endless recurrsion. i++ if(i > 100) fail(code:"asset.copy.subItem.too.many.failure") // Stop if an error is flagged. if(result.error) break } // Success or not. return result } // end withTransaction } // end saveCopySrvce /** * Create recommended extended attributes for all assets. */ def createRecommendedExtendedAttributes() { def result = [:] def hibernateSession = sessionFactory.currentSession def assets = Asset.list() def locationDescription = ExtendedAttributeType.findByName("Location Description") def ecr = ExtendedAttributeType.findByName("ecr") def assetNumber = ExtendedAttributeType.findByName("Asset Number") def assetCondition = ExtendedAttributeType.findByName("Asset Condition") def maintenancePercentComplete = ExtendedAttributeType.findByName("Maintenance % Completion") def registrationRequired = ExtendedAttributeType.findByName("Registration Required") def registrationExpiryDate = ExtendedAttributeType.findByName("Registration Expiry Date") def regulatoryRequirement = ExtendedAttributeType.findByName("Regulatory Requirement") def riskLevel = ExtendedAttributeType.findByName("Risk Level") def safeWorkProcedure = ExtendedAttributeType.findByName("Safe Work Procedure") for(asset in assets) { def attributeTypes = asset.assetExtendedAttributes.collect {it.extendedAttributeType} //AssetExtendedAttribute def assetExtendedAttributeInstance if(!attributeTypes.contains(locationDescription)) { //AssetExtendedAttribute #1 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: locationDescription) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(ecr)) { //AssetExtendedAttribute #2 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: ecr) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(assetNumber)) { //AssetExtendedAttribute #3 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: assetNumber) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(assetCondition)) { //AssetExtendedAttribute #4 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: assetCondition) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(maintenancePercentComplete)) { //AssetExtendedAttribute #5 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "TBA", asset: asset, extendedAttributeType: maintenancePercentComplete) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(registrationRequired)) { //AssetExtendedAttribute #6 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: registrationRequired) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(registrationExpiryDate)) { //AssetExtendedAttribute #7 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType:registrationExpiryDate) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(regulatoryRequirement)) { //AssetExtendedAttribute #8 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: regulatoryRequirement) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(riskLevel)) { //AssetExtendedAttribute #9 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: riskLevel) assetExtendedAttributeInstance.save() } if(!attributeTypes.contains(safeWorkProcedure)) { //AssetExtendedAttribute #10 assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "Not Specified", asset: asset, extendedAttributeType: safeWorkProcedure) assetExtendedAttributeInstance.save() } hibernateSession.flush() } // for // Success. return result } // createRecommendedExtendedAttributes() } // end class