class AssetSubItemService {

    boolean transactional = false

    /**
    * Determines and returns sorted list of possible parent items.
    * @param assetSubItemInstance The instance to prepare the list for.
    * @returns A list of the possible parentItems.
    */
    def possibleParentItems(assetSubItemInstance) {
        def criteria = AssetSubItem.createCriteria()
        def possibleParentItems = criteria.list() {
            and {
                eq('isActive', true)
                ne('id', assetSubItemInstance.id)
                assetSubItemInstance.subItems.each() { notEqual('id', it.id) }
                }
        }
        possibleParentItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
    }

    def delete(params) {
        AssetSubItem.withTransaction { status ->
            def result = [:]

            def fail = { Map m ->
                status.setRollbackOnly()
                if(result.assetSubItemInstance && m.field)
                    result.assetSubItemInstance.errors.rejectValue(m.field, m.code)
                result.error = [ code: m.code, args: ["AssetSubItem", params.id] ]
                return result
            }

            result.assetSubItemInstance = AssetSubItem.get(params.id)

            if(!result.assetSubItemInstance)
                return fail(code:"default.not.found")

            for(subItem in result.assetSubItemInstance.subItems) {
                if(subItem.maintenanceActions)
                    fail(code:"maintenanceActions.still.associated.subItem")
            }

            if(result.error)
                return result

            if(result.assetSubItemInstance.maintenanceActions)
                return fail(code:"maintenanceActions.still.associated")

            if(result.assetSubItemInstance.assets)
                return fail(code:"assetSubItem.assets.associated")

            // 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.assetSubItemInstance.delete()
            return result //Success.

        } // withTransaction
    }

    def create(params) {
        def result = [:]
        def fail = { Map m ->
            result.error = [ code: m.code, args: ["AssetSubItem", params.id] ]
            return result
        }

        result.assetSubItemInstance = new AssetSubItem()
        result.assetSubItemInstance.properties = params

        // pass in an asset to link to if provided.
        if(params.asset?.id)
            result.assetInstance = Asset.get(params.asset.id)

        // success
        return result
    }

    def save(params) {
        AssetSubItem.withTransaction { status ->
            def result = [:]

            def fail = { Map m ->
                status.setRollbackOnly()
                if(result.assetSubItemInstance && m.field)
                    result.assetSubItemInstance.errors.rejectValue(m.field, m.code)
                result.error = [ code: m.code, args: ["AssetSubItem", params.id] ]
                return result
            }

            result.assetSubItemInstance = new AssetSubItem(params)

            if(params.asset?.id) {
                result.assetInstance = Asset.get(params.asset.id)

                if(!result.assetInstance)
                    return fail(code:"assetSubItem.asset.not.found")
            }

            if(result.assetSubItemInstance.hasErrors() || !result.assetSubItemInstance.save(flush: true))
                return fail(code:"default.create.failure")

            if(result.assetInstance)
                result.assetInstance.addToAssetSubItems(result.assetSubItemInstance)

            // Success.
            return result

        } //end withTransaction
    } // save()

} // end class