/**
* Provides a data service to create base and demo data.
*/
class  CreateDataService {

    def authenticateService
    boolean transactional = false

/*******************************************
Start of Group methods.
Generally use these methods to create data.
*******************************************/

    /**
    * Always call this at startup to ensure admin access.
    */
    def ensureAdminAccess() {
        if(!Authority.findByAuthority("ROLE_AppAdmin") ) {
            println "ROLE_AppAdmin not found, calling createAdminAuthority()."
            createAdminAuthority()
        }
        if(!Person.findByloginName("admin") ) {
            println "LoginName 'admin' not found, calling createAdminPerson()."
            createAdminPerson()
        }
    }

    /**
    * Create the base data required for the application to function.
    */
    def createBaseData() {
        println "Creating base data..."
        // Person and Utils
        createBaseAuthorities()
        createBasePersonGroups()
        createBasePersons()
        createBaseUnitsOfMeasure()
        createBasePeriods()
        // Tasks
        createBaseTaskStatus()
        createBaseTaskPriorities()
        createBaseTaskTypes()
        createBaseEntryTypes()
        createBaseModificationTypes()
        // Inventory
        createBaseInventoryTypes()
        createBaseMaintenancePolicies()
        // Assets
        createBaseAssetExtenededAttributeTypes()

    }

    /**
    * Create demo data for some example sites.
    */
    def createDemoData() {
        println "Creating demo data..."
        // Person and Utils
        createDemoPersons()
        createDemoSites()
        createDemoDepartments()
        // Tasks
        createDemoTaskGroups() /// @todo: Perhaps this should be BaseData?
        createDemoTasks()
        createDemoEntries()
        createDemoAssignedPersons()
        createDemoTaskRecurringSchedules()
        // Inventory
        createDemoInventoryStores()  /// @todo: Perhaps a 'createQuickStartData' method?
        createDemoStoreLocations()
        createDemoInventoryGroups() /// @todo: Perhaps a 'createQuickStartData' method?
        createDemoInventoryItems()
        createDemoStoredItems()
        // Assets
        createDemoLifePlan()
        createDemoTaskProcedure()
        createDemoMaintenanceActions()
        createDemoSystemSections()
        createDemoAssetTypes()
        createDemoAssemblies()
        createDemoSubAssemblies()
        createDemoComponentItems()
        createDemoAssets()
        createDemoAssetExtenedAttributes()
    }

/******************
Start of Person
*******************/

    def createAdminAuthority() {
        def authInstance

        authInstance = new Authority(description:"Application Admin, not required for daily use! Grants full admin access to the application.",
                                        authority:"ROLE_AppAdmin")
        saveAndTest(authInstance)
    }

    def createBaseAuthorities() {

        def authInstance

        authInstance = new Authority(description:"Business manager, grants full management access.",
                                        authority:"ROLE_Manager")
        saveAndTest(authInstance)

        authInstance = new Authority(description:"Application User, all application users need this base role to allow login.",
                                        authority:"ROLE_AppUser")
        saveAndTest(authInstance)
    }

    void createBasePersonGroups() {
        //TypeOfPersonGroup
        def personGroupTypeInstance
            personGroupTypeInstance = new PersonGroupType(name:"Team")
        saveAndTest(personGroupTypeInstance)
            personGroupTypeInstance = new PersonGroupType(name:"Contractor")
        saveAndTest(personGroupTypeInstance)
            personGroupTypeInstance = new PersonGroupType(name:"ProjectTeam")
        saveAndTest(personGroupTypeInstance)

        //PersonGroup
        def personGroupInstance
            personGroupInstance = new PersonGroup(personGroupType:PersonGroupType.get(1),
                            name:"Electrical")
        saveAndTest(personGroupInstance)
            personGroupInstance = new PersonGroup(personGroupType:PersonGroupType.get(1),
                            name:"Mechanical")
        saveAndTest(personGroupInstance)
            personGroupInstance = new PersonGroup(personGroupType:PersonGroupType.get(1),
                            name:"Production")
        saveAndTest(personGroupInstance)
            personGroupInstance = new PersonGroup(personGroupType:PersonGroupType.get(2),
                            name:"Kewl AirCon Guys")
        saveAndTest(personGroupInstance)
            personGroupInstance = new PersonGroup(personGroupType:PersonGroupType.get(3),
                            name:"gnuMims")
        saveAndTest(personGroupInstance)
    }

    def createAdminPerson() {
        //Person
        def passClearText = "pass"
        def passwordEncoded = authenticateService.encodePassword(passClearText)
        def personInstance

        //Person #1
        personInstance = new Person(loginName:"admin",
                                    firstName:"Admin",
                                    lastName:"Powers",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"admin@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(1))
    }

    def createBasePersons() {
        //Person
        def passClearText = "pass"
        def passwordEncoded = authenticateService.encodePassword(passClearText)
        def personInstance

        //Person #1 is admin.

        //Person #2
        personInstance = new Person(loginName:"manager",
                                    firstName:"Demo",
                                    lastName:"Manager",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"manager@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(2))
        personInstance.addToAuthorities(Authority.get(3))
        personInstance.addToPersonGroups(PersonGroup.get(5))

        //Person #3
        personInstance = new Person(loginName:"user",
                                    firstName:"Demo",
                                    lastName:"User",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"user@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(3))
        personInstance.addToPersonGroups(PersonGroup.get(1))
    }

    def createDemoPersons() {
        //Person
        def passClearText = "pass"
        def passwordEncoded = authenticateService.encodePassword(passClearText)
        def personInstance

        //Person #4
        personInstance = new Person(loginName:"craig",
                                    firstName:"Craig",
                                    lastName:"SuperSparky",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"user@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(3))
        personInstance.addToPersonGroups(PersonGroup.get(1))

        //Person #5
        personInstance = new Person(loginName:"john",
                                    firstName:"John",
                                    lastName:"SuperFitter",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"user@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(3))
        personInstance.addToPersonGroups(PersonGroup.get(2))

        //Person #6
        personInstance = new Person(loginName:"mann",
                                    firstName:"Production",
                                    lastName:"Mann",
                                    pass:passClearText,
                                    password:passwordEncoded,
                                    email:"user@example.com")
        saveAndTest(personInstance)
        personInstance.addToAuthorities(Authority.get(3))
        personInstance.addToPersonGroups(PersonGroup.get(3))
    }

/***********************
START OF UTILITIES
***********************/

    def createDemoSites() {
        //Site
        def siteInstance

        siteInstance = new Site(name: "Creek Mill")
        saveAndTest(siteInstance)

        siteInstance = new Site(name: "Jasper Street Depot")
        saveAndTest(siteInstance)

        siteInstance = new Site(name: "River Press")
        saveAndTest(siteInstance)
    }

    def createDemoDepartments() {

        //Department
        def departmentInstance

        //Department #1
        departmentInstance = new Department(name: "Print Centre",
                                                                                    site: Site.get(1))
        saveAndTest(departmentInstance)

        //Department #2
        departmentInstance = new Department(name: "Pulp Mill 2",
                                                                                    site: Site.get(2))
        saveAndTest(departmentInstance)
    }

    def createBaseUnitsOfMeasure() {

        //UnitOfMeasure
        def unitOfMeasureInstance

        //UnitOfMeasure #1
        unitOfMeasureInstance = new UnitOfMeasure(name: "each")
        saveAndTest(unitOfMeasureInstance)

        //UnitOfMeasure #2
        unitOfMeasureInstance = new UnitOfMeasure(name: "meter(s)")
        saveAndTest(unitOfMeasureInstance)

        //UnitOfMeasure #3
        unitOfMeasureInstance = new UnitOfMeasure(name: "box(es)")
        saveAndTest(unitOfMeasureInstance)

        //UnitOfMeasure #4
        unitOfMeasureInstance = new UnitOfMeasure(name: "litre(s)")
        saveAndTest(unitOfMeasureInstance)

        //UnitOfMeasure #5
        unitOfMeasureInstance = new UnitOfMeasure(name: "kilogram(s)")
        saveAndTest(unitOfMeasureInstance)
    }

    def createBasePeriods() {

        //Period
        def periodInstance

        //Period #1
        periodInstance = new Period(period: "Day(s)")
        saveAndTest(periodInstance)

        //Period #2
        periodInstance = new Period(period: "Week(s)")
        saveAndTest(periodInstance)

        //Period #3
        periodInstance = new Period(period: "Month(s)")
        saveAndTest(periodInstance)

        //Period #4
        periodInstance = new Period(period: "Year(s)")
        saveAndTest(periodInstance)
    }

/*********************
START OF TASK
*********************/

    def createDemoTaskGroups() {
        //TaskGroup
        def taskGroupInstance

        taskGroupInstance = new TaskGroup(name:"Engineering Activites",
                                                                            description:"Engineering daily activities")
        saveAndTest(taskGroupInstance)

        taskGroupInstance = new TaskGroup(name:"Production Activites",
                                                                            description:"Production daily activities")
        saveAndTest(taskGroupInstance)

        taskGroupInstance = new TaskGroup(name:"New Projects",
                                                                            description:" ")
        saveAndTest(taskGroupInstance)
    }

    def createBaseTaskStatus() {

        //TaskStatus
        def taskStatusInstance

        taskStatusInstance = new TaskStatus(name:"Not Started")
        saveAndTest(taskStatusInstance)

        taskStatusInstance = new TaskStatus(name:"In Progress")
        saveAndTest(taskStatusInstance)

        taskStatusInstance = new TaskStatus(name:"Completed")
        saveAndTest(taskStatusInstance)
    }

    def createBaseTaskPriorities() {

        //TaskPriority
        def taskPriorityInstance

        taskPriorityInstance = new TaskPriority(name:"Normal")
        saveAndTest(taskPriorityInstance)

        taskPriorityInstance = new TaskPriority(name:"Low")
        saveAndTest(taskPriorityInstance)

        taskPriorityInstance = new TaskPriority(name:"High")
        saveAndTest(taskPriorityInstance)

        taskPriorityInstance = new TaskPriority(name:"Immediate")
        saveAndTest(taskPriorityInstance)
    }

    def createBaseTaskTypes() {

        //TaskType
        def taskTypeInstance

        taskTypeInstance = new TaskType(name:"Unscheduled Breakin")
        saveAndTest(taskTypeInstance)

        taskTypeInstance = new TaskType(name:"Preventative Maintenance")
        saveAndTest(taskTypeInstance)

        taskTypeInstance = new TaskType(name:"Project")
        saveAndTest(taskTypeInstance)

        taskTypeInstance = new TaskType(name:"Turnaround")
        saveAndTest(taskTypeInstance)

        taskTypeInstance = new TaskType(name:"Production Run")
        saveAndTest(taskTypeInstance)
    }

    def createDemoTasks() {

        //Task
        def taskInstance

        //Task #1
        taskInstance = new Task(taskGroup:TaskGroup.findByName("Engineering Activites"),
                 taskStatus:TaskStatus.findByName("Not Started"),
                 taskPriority:TaskPriority.get(2),
                 taskType:TaskType.get(1),
                 leadPerson:Person.get(2),
                 description:"Check specific level sensor",
                 comment:"Has been noted as problematic, try recalibrating.",
                targetStartDate:new Date())
        saveAndTest(taskInstance)

        //Task #2
        taskInstance = new Task(taskGroup:TaskGroup.findByName("Engineering Activites"),
                taskStatus:TaskStatus.findByName("Not Started"),
                taskPriority:TaskPriority.get(2),
                taskType:TaskType.get(1),
                leadPerson:Person.get(5),
                description:"Some follow-up work",
                comment:"Some help required",
                targetStartDate:new Date()+1,
                parentTask: Task.get(1))
        saveAndTest(taskInstance)

        //Task #3
        taskInstance = new Task(taskGroup:TaskGroup.findByName("Engineering Activites"),
                taskStatus:TaskStatus.findByName("Not Started"),
                taskPriority:TaskPriority.get(2),
                taskType:TaskType.get(1),
                leadPerson:Person.get(5),
                description:"A Sub Task can be created by setting the Parent Task value",
                comment:"Some help required",
                targetStartDate:new Date()-1,
                parentTask: Task.get(1))
        saveAndTest(taskInstance)

        //Task #4
        taskInstance = new Task(taskGroup:TaskGroup.findByName("Engineering Activites"),
                 taskStatus:TaskStatus.findByName("Not Started"),
                 taskPriority:TaskPriority.get(2),
                 taskType:TaskType.get(1),
                 leadPerson:Person.get(4),
                 description:"Replace sensor at next opportunity.",
                 comment:"Nothing else has worked.",
                targetStartDate:new Date()+7,
                parentTask: Task.get(1))
        saveAndTest(taskInstance)

        //Task #5
        taskInstance = new Task(taskGroup:TaskGroup.findByName("Production Activites"),
                 taskStatus:TaskStatus.findByName("Not Started"),
                 taskPriority:TaskPriority.get(2),
                 taskType:TaskType.get(5),
                 leadPerson:Person.get(6),
                 description:"Production Report",
                 comment:"Production report for specific production run or shift",
                targetStartDate:new Date()-7)
        saveAndTest(taskInstance)

        //Task #6
        taskInstance = new Task(taskGroup:TaskGroup.findByName("New Projects"),
                 taskStatus:TaskStatus.findByName("Not Started"),
                 taskPriority:TaskPriority.get(2),
                 taskType:TaskType.get(3),
                 leadPerson:Person.get(1),
                 description:"Make killer CMMS app",
                 comment:"Use Grails and get a move on!",
                targetStartDate:new Date()-6)
        saveAndTest(taskInstance)
    }

    def createBaseEntryTypes() {

        //EntryType
        def entryTypeInstance

        entryTypeInstance = new EntryType(name:"Fault")
        saveAndTest(entryTypeInstance)

        entryTypeInstance = new EntryType(name:"WorkDone")
        saveAndTest(entryTypeInstance)

        entryTypeInstance = new EntryType(name:"Production Note")
        saveAndTest(entryTypeInstance)

        entryTypeInstance = new EntryType(name:"Work Request")
        saveAndTest(entryTypeInstance)
    }

    def createDemoEntries() {

        //Entry
        def entryInstance

        //Entry #1
        entryInstance = new Entry(enteredBy: Person.get(3),
                                                    task: Task.get(1),
                                                    entryType: EntryType.findByName("Fault"),
                                                    comment: "This level sensor is causing us trouble.",
                                                    durationMinute: 20)
        saveAndTest(entryInstance)

        //Entry #2
        entryInstance = new Entry(enteredBy: Person.get(4),
                                                    task: Task.get(1),
                                                    entryType: EntryType.findByName("WorkDone"),
                                                    comment: "Cleaned sensor, see how it goes.",
                                                    durationMinute: 30)
        saveAndTest(entryInstance)

        //Entry #3
        entryInstance = new Entry(enteredBy: Person.get(4),
                                                    task: Task.get(1),
                                                    entryType: EntryType.findByName("WorkDone"),
                                                    comment: "Checked up on it later and sensor is dropping out intermittently, created subTask to replace sensor.",
                                                    durationMinute: 20)
        saveAndTest(entryInstance)
    }

    def createBaseModificationTypes() {

        //ModificationType
        def taskModificationTypeInstance
        taskModificationTypeInstance = new TaskModificationType(name:"Created").save()
        taskModificationTypeInstance = new TaskModificationType(name:"Completed").save()
        taskModificationTypeInstance = new TaskModificationType(name:"Closed").save()
        taskModificationTypeInstance = new TaskModificationType(name:"Altered").save()
        taskModificationTypeInstance = new TaskModificationType(name:"TargetDateModified").save()
        taskModificationTypeInstance = new TaskModificationType(name:"ScheduledDateModified").save()
        taskModificationTypeInstance = new TaskModificationType(name:"DescriptionModified").save()
        taskModificationTypeInstance = new TaskModificationType(name:"AssignedToModified").save()
        taskModificationTypeInstance = new TaskModificationType(name:"NameModified").save()
    }

    def createDemoAssignedPersons() {

        //AssignedPerson
        def assignedPersonInstance

        //AssignedPerson #1
        assignedPersonInstance = new AssignedPerson(person: Person.get(4),
                                                                                        task: Task.get(1),
                                                                                        estimatedHour: 1,
                                                                                        estimatedMinute: 20)
        saveAndTest(assignedPersonInstance)

        //AssignedPerson #2
        assignedPersonInstance = new AssignedPerson(person: Person.get(5),
                                                                                        task: Task.get(1),
                                                                                        estimatedHour: 3,
                                                                                        estimatedMinute: 30)
        saveAndTest(assignedPersonInstance)
    }

    def createDemoTaskRecurringSchedules() {

        //TaskRecurringSchedule
        def taskRecurringScheduleInstance

        //TaskRecurringSchedule #1
        taskRecurringScheduleInstance = new TaskRecurringSchedule(task: Task.get(1),
                                                                                                    recurEvery: 1,
                                                                                                    recurPeriod: Period.get(1),
                                                                                                    startDate: new Date(),
                                                                                                    generateAhead: 1,
                                                                                                    generateAheadPeriod: Period.get(1),
                                                                                                    taskDuration: 1,
                                                                                                    taskDurationPeriod: Period.get(1))
        saveAndTest(taskRecurringScheduleInstance)

        //TaskRecurringSchedule #2
        taskRecurringScheduleInstance = new TaskRecurringSchedule(task: Task.get(2),
                                                                                                    recurEvery: 1,
                                                                                                    recurPeriod: Period.get(1),
                                                                                                    startDate: new Date(),
                                                                                                    generateAhead: 1,
                                                                                                    generateAheadPeriod: Period.get(1),
                                                                                                    taskDuration: 1,
                                                                                                    taskDurationPeriod: Period.get(1))
        saveAndTest(taskRecurringScheduleInstance)
    }

/*************************
START OF INVENTORY
**************************/

    def createDemoInventoryStores() {

        //InventoryStore
        def inventoryStoreInstance

        inventoryStoreInstance = new InventoryStore(site: Site.get(1), name: "Store #1")
        saveAndTest(inventoryStoreInstance)

        inventoryStoreInstance = new InventoryStore(site: Site.get(2), name: "Store #2")
        saveAndTest(inventoryStoreInstance)
    }

    def createDemoStoreLocations() {

        //StoreLocation
        def storeLocation

        storeLocation = new StoreLocation(inventoryStore: InventoryStore.get(1), bin: "A1-2")
        saveAndTest(storeLocation)

        storeLocation = new StoreLocation(inventoryStore: InventoryStore.get(1), bin: "C55")
        saveAndTest(storeLocation)
    }

    def createDemoInventoryGroups() {

        //InventoryGroup
        def inventoryGroupInstance

        //InventoryGroup #1
        inventoryGroupInstance = new InventoryGroup(name: "Misc")
        saveAndTest(inventoryGroupInstance)

        //InventoryGroup #2
        inventoryGroupInstance = new InventoryGroup(name: "Electrical")
        saveAndTest(inventoryGroupInstance)

        //InventoryGroup #3
        inventoryGroupInstance = new InventoryGroup(name: "Mechanical")
        saveAndTest(inventoryGroupInstance)

        //InventoryGroup #4
        inventoryGroupInstance = new InventoryGroup(name: "Production")
        saveAndTest(inventoryGroupInstance)
    }

    def createBaseInventoryTypes() {

        //InventoryType
        def inventoryTypeInstance

        inventoryTypeInstance = new InventoryType(name: "Consumable")
        saveAndTest(inventoryTypeInstance)

        inventoryTypeInstance = new InventoryType(name: "Repairable")
        saveAndTest(inventoryTypeInstance)
    }

    def createDemoInventoryItems() {

        //InventoryItem
        def inventoryItemInstance

        //InventoryItem #1
        inventoryItemInstance = new InventoryItem(inventoryGroup: InventoryGroup.get(1),
                                                                                    inventoryType: InventoryType.get(1),
                                                                                    unitOfMeasure: UnitOfMeasure.get(2),
                                                                                    name: "J-Rope",
                                                                                    description: "Twine wound J-Rope",
                                                                                    reorderPoint: 0)
        saveAndTest(inventoryItemInstance)

        //InventoryItem #2
        inventoryItemInstance = new InventoryItem(inventoryGroup: InventoryGroup.get(1),
                                                                                    inventoryType: InventoryType.get(1),
                                                                                    unitOfMeasure: UnitOfMeasure.get(2),
                                                                                    name: "L-Rope",
                                                                                    description: "Twine wound L-Rope",
                                                                                    alternateItems: InventoryItem.get(1),
                                                                                    reorderPoint: 0)
        saveAndTest(inventoryItemInstance)

        //InventoryItem #3
        inventoryItemInstance = new InventoryItem(inventoryGroup: InventoryGroup.get(3),
                                                                                    inventoryType: InventoryType.get(1),
                                                                                    unitOfMeasure: UnitOfMeasure.get(1),
                                                                                    name: "2305-2RS",
                                                                                    description: "Bearing 25x62x24mm double row self aligning ball",
                                                                                    reorderPoint: 2)
        saveAndTest(inventoryItemInstance)

        //InventoryItem #4
        inventoryItemInstance = new InventoryItem(inventoryGroup: InventoryGroup.get(2),
                                                                                    inventoryType: InventoryType.get(1),
                                                                                    unitOfMeasure: UnitOfMeasure.get(1),
                                                                                    name: "L1592-K10",
                                                                                    description: "10kW contactor",
                                                                                    reorderPoint: 0)
        saveAndTest(inventoryItemInstance)

        //InventoryItem #5
        inventoryItemInstance = new InventoryItem(inventoryGroup: InventoryGroup.get(3),
                                                                                    inventoryType: InventoryType.get(1),
                                                                                    unitOfMeasure: UnitOfMeasure.get(1),
                                                                                    name: "6205-ZZ",
                                                                                    description: "Bearing 25x52x15mm single row ball shielded",
                                                                                    reorderPoint: 2)
        saveAndTest(inventoryItemInstance)
    }

    def createDemoStoredItems() {

        //StoredItem
        def storedItemInstance

        //StoredItem #1
        storedItemInstance = new StoredItem(inventoryItem: InventoryItem.get(1),
                                                                            storeLocation: StoreLocation.get(1),
                                                                            quantity: 8)
        saveAndTest(storedItemInstance)

        //StoredItem #2
        storedItemInstance = new StoredItem(inventoryItem: InventoryItem.get(1),
                                                                            storeLocation: StoreLocation.get(2),
                                                                            quantity: 4)
        saveAndTest(storedItemInstance)

        //StoredItem #3
        storedItemInstance = new StoredItem(inventoryItem: InventoryItem.get(2),
                                                                            storeLocation: StoreLocation.get(1),
                                                                            quantity: 2)
        saveAndTest(storedItemInstance)

        //StoredItem #4
        storedItemInstance = new StoredItem(inventoryItem: InventoryItem.get(3),
                                                                            storeLocation: StoreLocation.get(1),
                                                                            quantity: 2)
        saveAndTest(storedItemInstance)

        //StoredItem #5
        storedItemInstance = new StoredItem(inventoryItem: InventoryItem.get(4),
                                                                            storeLocation: StoreLocation.get(1),
                                                                            quantity: 30)
        saveAndTest(storedItemInstance)
    }

/*******************
START OF ASSET
*******************/

    def createDemoLifePlan() {

        //LifePlan
        def lifeplanInstance

        lifeplanInstance = new LifePlan(name: "Initial Plan")
        saveAndTest(lifeplanInstance)
    }

    def createBaseMaintenancePolicies() {

        //MaintenancePolicy
        def maintenancePolicyInstance

        //MaintenancePolicy #1
        maintenancePolicyInstance = new MaintenancePolicy(name: "Fixed Time")
        saveAndTest(maintenancePolicyInstance)

        //MaintenancePolicy #2
        maintenancePolicyInstance = new MaintenancePolicy(name: "Condition Based Online")
        saveAndTest(maintenancePolicyInstance)

        //MaintenancePolicy #3
        maintenancePolicyInstance = new MaintenancePolicy(name: "Condition Based Offline")
        saveAndTest(maintenancePolicyInstance)

        //MaintenancePolicy #4
        maintenancePolicyInstance = new MaintenancePolicy(name: "Design Out")
        saveAndTest(maintenancePolicyInstance)

        //MaintenancePolicy #5
        maintenancePolicyInstance = new MaintenancePolicy(name: "Operate To Failure")
        saveAndTest(maintenancePolicyInstance)
    }

    def createDemoTaskProcedure() {

        //TaskProcedure
        def taskProcedureInstance

        taskProcedureInstance = new TaskProcedure(name: "Daily check")
        saveAndTest(taskProcedureInstance)
        taskProcedureInstance.addToTasks(Task.get(1))
    }

    def createDemoMaintenanceActions() {

        //MaintenanceAction
        def maintenanceActionInstance

        //MaintenanceAction #1
        maintenanceActionInstance = new MaintenanceAction(description: "Check all E-stops, activate E-stops S1-S12 and ensure machine cannot run",
                                                                                                        procedureStepNumber: 1,
                                                                                                        maintenancePolicy: MaintenancePolicy.get(1),
                                                                                                        taskProcedure: TaskProcedure.get(1))
        saveAndTest(maintenanceActionInstance)

        //MaintenanceAction #2
        maintenanceActionInstance = new MaintenanceAction(description: "Do more pushups",
                                                                                                        procedureStepNumber: 2,
                                                                                                        maintenancePolicy: MaintenancePolicy.get(1),
                                                                                                        taskProcedure: TaskProcedure.get(1))
        saveAndTest(maintenanceActionInstance)

        //MaintenanceAction #3
        maintenanceActionInstance = new MaintenanceAction(description: "Ok just one more pushup",
                                                                                                        procedureStepNumber: 3,
                                                                                                        maintenancePolicy: MaintenancePolicy.get(1),
                                                                                                        taskProcedure: TaskProcedure.get(1))
        saveAndTest(maintenanceActionInstance)
    }

    def createDemoSystemSections() {

        //SystemSection
        def systemSectionInstance

        //SystemSection #1
        systemSectionInstance = new SystemSection(name: "Press Section",
                                                                                    site: Site.get(1),
                                                                                    department: Department.get(1))
        saveAndTest(systemSectionInstance)

        //SystemSection #2
        systemSectionInstance = new SystemSection(name: "RO System",
                                                                                    site: Site.get(2),
                                                                                    department: Department.get(2))
        saveAndTest(systemSectionInstance)

        //SystemSection #3
        systemSectionInstance = new SystemSection(name: "Auxilliray Section",
                                                                                    site: Site.get(1),
                                                                                    department: Department.get(1))
        saveAndTest(systemSectionInstance)
    }

    def createDemoAssetTypes() {

        //AssetType
        def assetTypeInstance

        //AssetType #1
        assetTypeInstance = new AssetType(name: "Print Unit")
        saveAndTest(assetTypeInstance)

        //AssetType #2
        assetTypeInstance = new AssetType(name: "Reactor Tower")
        saveAndTest(assetTypeInstance)
    }

    def createDemoAssemblies() {

        //Assembly
        def assemblyInstance

        //Assembly #1
        assemblyInstance = new Assembly(name: "Print Couple",
                                                                        assetType: AssetType.get(1))
        saveAndTest(assemblyInstance)
//        assemblyInstance.addToMaintenanceActions(MaintenanceAction.get(1))

        //Assembly #2
        assemblyInstance = new Assembly(name: "Agitator",
                                                                        assetType: AssetType.get(2))
        saveAndTest(assemblyInstance)
    }

    def createDemoSubAssemblies() {

        //SubAssembly
        def subAssemblyInstance

        //SubAssembly #1
        subAssemblyInstance = new SubAssembly(name: "Cylinder",
                                                                                    assembly: Assembly.get(1))
        saveAndTest(subAssemblyInstance)

         //SubAssembly #2
        subAssemblyInstance = new SubAssembly(name: "Gearmotor",
                                                                                    assembly: Assembly.get(2))
        saveAndTest(subAssemblyInstance)
    }

    def createDemoComponentItems() {

        //ComponentItem
        def componentItemInstance

        //ComponentItem #1
        componentItemInstance = new ComponentItem(name: "Bearing",
                                                                                            subAssembly: SubAssembly.get(1))
        saveAndTest(componentItemInstance)

         //ComponentItem #2
        componentItemInstance = new ComponentItem(name: "Drive shaft oil seal",
                                                                                            subAssembly: SubAssembly.get(2))
        saveAndTest(componentItemInstance)
    }

    def createDemoAssets() {

        //Asset
        def assetInstance

        //Asset #1
        assetInstance = new Asset(name: "Print Unit 22",
                                                        assetType: AssetType.get(1),
                                                        systemSection: SystemSection.get(1))
        saveAndTest(assetInstance)
//        assetInstance.addToMaintenanceActions(MaintenanceAction.get(1))

        //Asset #2
        assetInstance = new Asset(name: "Print Unit 21",
                                                        assetType: AssetType.get(1),
                                                        systemSection: SystemSection.get(1))
        saveAndTest(assetInstance)

        //Asset #3
        assetInstance = new Asset(name: "Print Unit 23",
                                                        assetType: AssetType.get(1),
                                                        systemSection: SystemSection.get(1))
        saveAndTest(assetInstance)

        //Asset #4
        assetInstance = new Asset(name: "RO 1",
                                                        assetType: AssetType.get(2),
                                                        systemSection: SystemSection.get(2))
        saveAndTest(assetInstance)
    }

    def createBaseAssetExtenededAttributeTypes() {

        //AssetExtendedAttributeType
        def assetExtendedAttributeInstanceType

        //AssetExtendedAttributeType #1
        assetExtendedAttributeInstanceType = new AssetExtendedAttributeType(name: "Model Number")
        saveAndTest(assetExtendedAttributeInstanceType)

        //AssetExtendedAttributeType #2
        assetExtendedAttributeInstanceType = new AssetExtendedAttributeType(name: "Purchase Cost")
        saveAndTest(assetExtendedAttributeInstanceType)

        //AssetExtendedAttributeType #3
        assetExtendedAttributeInstanceType = new AssetExtendedAttributeType(name: "Serial Number")
        saveAndTest(assetExtendedAttributeInstanceType)

        //AssetExtendedAttributeType #4
        assetExtendedAttributeInstanceType = new AssetExtendedAttributeType(name: "Manufactured Date")
        saveAndTest(assetExtendedAttributeInstanceType)

        //AssetExtendedAttributeType #5
        assetExtendedAttributeInstanceType = new AssetExtendedAttributeType(name: "Location Description")
        saveAndTest(assetExtendedAttributeInstanceType)
    }

    def createDemoAssetExtenedAttributes() {

        //AssetExtendedAttribute
        def assetExtendedAttributeInstance

        //AssetExtendedAttribute #1
        assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "PU Mark 2",
                                                                                                                    asset: Asset.get(1),
                                                                                                                    assetExtendedAttributeType: AssetExtendedAttributeType.get(1))
        saveAndTest(assetExtendedAttributeInstance)

        //AssetExtendedAttribute #2
        assetExtendedAttributeInstance = new AssetExtendedAttribute(value: "On the far side of Tank 5",
                                                                                                                    asset: Asset.get(1),
                                                                                                                    assetExtendedAttributeType: AssetExtendedAttributeType.get(5))
        saveAndTest(assetExtendedAttributeInstance)
    }


/****************************************
Call this function instead of .save()
*****************************************/
    private boolean saveAndTest(object) {
        if(!object.save()) {
//             DemoDataSuccessful = false
            println "'${object}' failed to save!"
            println object.errors
            return false
        }
        return true
    }
}
