source: trunk/grails-app/services/InventoryCsvService.groovy @ 436

Last change on this file since 436 was 436, checked in by gav, 10 years ago

Change InventoryItem to have a preferred and many alternate suppliers and manufacturers.
Remove reverse InventoryItem references from Supplier and Manufacture domain classes.
InventoryCsvService updated.

File size: 31.3 KB
Line 
1import grails.util.GrailsUtil
2import au.com.bytecode.opencsv.CSVWriter
3import au.com.bytecode.opencsv.CSVReader
4import org.apache.commons.lang.WordUtils
5
6/**
7 * Provides some csv import/export methods.
8 * Requires the opencsv jar to be available which is included in the grails-export plugin.
9 */
10class InventoryCsvService {
11
12    boolean transactional = false
13
14    def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
15
16    def sessionFactory
17    def propertyInstanceMap = org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP
18
19    /**
20    * Import inventory creating items as required.
21    * @param request The http request to run getFile against.
22    * Get file should return a csv format file containing the inventory as per template.
23    */
24    def importInventory(request) {
25        InventoryItem.withTransaction { status ->
26            def result = [:]
27
28            def kByteMultiplier = 1000
29            def fileMaxSize = 800 * kByteMultiplier
30            def logFileLink = g.link(controller: "appCore", action: "appLog") {"log"}
31
32            def multiPartFile = request.getFile('file')
33
34            InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
35            CSVReader reader = new CSVReader(sr)
36
37            def fail = { Map m ->
38                status.setRollbackOnly()
39                reader.close()
40                result.error = [ code: m.code, args: m.args ]
41                return result
42            }
43
44            if(!multiPartFile || multiPartFile.isEmpty())
45                return fail(code: "default.file.not.supplied")
46
47            if (multiPartFile.getSize() > fileMaxSize)
48                return fail(code: "default.file.over.max.size", args: [fileMaxSize/kByteMultiplier, "kB"])
49
50            //TODO: delete
51            def columnValue = ''
52            def columnIndex = 0
53            def numberOfColumns = 0
54
55            def line = []
56            def lineNumber = 0
57            def maxNumberOfColumns = 25
58            def inventoryParams = [:]
59            def inventoryProperties = ["name", "description", "comment", "unitsInStock", "reorderPoint", "recommendedReorderPoint",
60                                                        "unitOfMeasure", "estimatedUnitPriceAmount", "estimatedUnitPriceCurrency",
61                                                        "enableReorder", "inventoryLocation", "inventoryStore", "site",
62                                                        "inventoryGroup", "inventoryType", "averageDeliveryTime", "averageDeliveryPeriod",
63                                                        "suppliersPartNumber", "preferredSupplier", "alternateSuppliers",
64                                                        "manufacturersPartNumber", "preferredManufacturer", "alternateManufacturers",
65                                                        "alternateItems", "spareFor"]
66
67            def siteInstance
68            def alternateSupplierInstance
69            def preferredSupplierInstance
70            def supplierTypeInstance
71            def supplierTypeUnknown = SupplierType.get(1)
72            def spareForInstance
73            def alternateItemInstance
74            def preferredManufacturerInstance
75            def alternateManufacturerInstance
76            def manufacturerTypeInstance
77            def manufacturerTypeUnknown = ManufacturerType.get(1)
78            def inventoryTypeInstance
79            def unitOfMeasureInstance
80            def inventoryGroupInstance
81            def inventoryItemInstance
82            def inventoryStoreInstance
83            def inventoryLocationInstance
84            def averageDeliveryPeriodInstance
85
86            def tempPreferredSupplierItemAndType = ''
87            def tempPreferredSupplierItem = ''
88            def tempPreferredSupplierType = ''
89
90            def tempAlternateSuppliers = []
91            def tempSupplierItem = ''
92            def tempSupplierType = ''
93            def tempSupplierItemAndType = []
94
95            def tempPreferredManufacturerItemAndType = ''
96            def tempPreferredManufacturerItem = ''
97            def tempPreferredManufacturerType = ''
98
99            def tempAlternateManufacturers = []
100            def tempManufacturerItem = ''
101            def tempManufacturerType = ''
102            def tempManufacturerItemAndType = []
103
104            def tempSpareFor = []
105            def tempAlternateItems = []
106
107            def column = ''
108
109            def nextLine = {
110                    line = reader.readNext()
111                    lineNumber ++
112                    log.info "Processing line: " + lineNumber
113            }
114
115            def nextColumn = {
116
117                if( columnIndex < numberOfColumns ) {
118                        column = line[columnIndex].trim()
119                }
120                else {
121                    log.info "No more columns on line: " + lineNumber
122                    return false
123                }
124
125                columnIndex++
126                // Success.
127                return column
128            }
129
130            def parseInputList = {
131                if( (it == null) || (it.trim() == '') ) return []
132                return it.split(";").collect{it.trim()}
133            }
134
135            def parseItemAndType = {
136                return it.split("@").collect{it.trim()}
137            }
138
139            // Get first line.
140            nextLine()
141
142            // Check for header line 1.
143            if(line != templateHeaderLine1) {
144                log.error "Failed to find header line 1. "
145                log.error "Required: " + templateHeaderLine1.toString()
146                log.error "Supplied: " + line.toString()
147                return fail(code: "default.file.no.header")
148            }
149
150            log.info "Header line found."
151
152            // Prepare the first body line.
153            nextLine()
154
155            // Primary loop.
156            while(line) {
157
158                if(line.size() > maxNumberOfColumns) {
159                    log.error "Too many columns on line: " + lineNumber
160                    return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
161                }
162
163                // Ignore comment lines.
164                if(line.toString().toLowerCase().contains("comment")) {
165                    log.info "Comment line found."
166                    nextLine()
167                    continue
168                }
169
170                // Ignore example lines.
171                if(line.toString().toLowerCase().contains("example")) {
172                    log.info "Example line found."
173                    nextLine()
174                    continue
175                }
176
177                // Parse the line into the params map.
178                inventoryParams = [:]
179                line.eachWithIndex { it, j ->
180                    inventoryParams."${inventoryProperties[j]}" = it.trim()
181                }
182
183                // Debug
184                log.debug " Supplied params: "
185                log.debug inventoryParams
186
187                // Ignore blank lines.
188                if(inventoryParams.name == '') {
189                    log.info "No name found."
190                    nextLine()
191                    continue
192                }
193
194                /** Prepare the params and create supporting items as required. */
195
196                // Site
197                inventoryParams.site = WordUtils.capitalize(inventoryParams.site)
198                siteInstance = Site.findByName(inventoryParams.site)
199                if(!siteInstance) {
200                    siteInstance = new Site(name: inventoryParams.site)
201                    if(!siteInstance.save()) {
202                        log.error "Failed to create site on line: " + lineNumber
203                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
204                    }
205                }
206
207                // InventoryStore
208                inventoryParams.inventoryStore = WordUtils.capitalizeFully(inventoryParams.inventoryStore)
209                inventoryStoreInstance = InventoryStore.findByName(inventoryParams.inventoryStore)
210                if(!inventoryStoreInstance) {
211                    inventoryStoreInstance = new InventoryStore(name: inventoryParams.inventoryStore,
212                                                                                                site: siteInstance)
213                    if(!inventoryStoreInstance.save()) {
214                        log.error "Failed to create inventory store on line: " + lineNumber
215                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
216                    }
217                }
218
219                // InventoryLocation
220                inventoryParams.inventoryLocation = WordUtils.capitalize(inventoryParams.inventoryLocation)
221                inventoryLocationInstance = InventoryLocation.findByName(inventoryParams.inventoryLocation)
222                if(!inventoryLocationInstance) {
223                    inventoryLocationInstance = new InventoryLocation(name: inventoryParams.inventoryLocation,
224                                                                                                        inventoryStore: inventoryStoreInstance)
225                    if(!inventoryLocationInstance.save()) {
226                        log.error "Failed to create inventory location on line: " + lineNumber
227                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
228                    }
229                }
230
231                // InventoryGroup
232                inventoryParams.inventoryLocation = WordUtils.capitalizeFully(inventoryParams.inventoryLocation)
233                inventoryGroupInstance = InventoryGroup.findByName(inventoryParams.inventoryGroup)
234                if(!inventoryGroupInstance) {
235                    inventoryGroupInstance = new InventoryGroup(name: inventoryParams.inventoryGroup)
236                    if(!inventoryGroupInstance.save()) {
237                        log.error "Failed to create inventory group on line: " + lineNumber
238                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
239                    }
240                }
241
242                // InventoryType
243                inventoryParams.inventoryType = WordUtils.capitalizeFully(inventoryParams.inventoryType)
244                inventoryTypeInstance = InventoryType.findByName(inventoryParams.inventoryType)
245                if(!inventoryTypeInstance) {
246                    inventoryTypeInstance = new InventoryType(name: inventoryParams.inventoryType)
247                    if(!inventoryTypeInstance.save()) {
248                        log.error "Failed to create inventory type on line: " + lineNumber
249                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
250                    }
251                }
252
253                // UnitOfMeasure.
254                unitOfMeasureInstance = UnitOfMeasure.findByName(inventoryParams.unitOfMeasure)
255                if(!unitOfMeasureInstance) {
256                    unitOfMeasureInstance = new UnitOfMeasure(name: inventoryParams.unitOfMeasure)
257                    if(!unitOfMeasureInstance.save()) {
258                        log.error "Failed to create unit of measure on line: " + lineNumber
259                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
260                    }
261                }
262
263                // AverageDeliveryPeriod.
264                if(inventoryParams.averageDeliveryPeriod) {
265                    averageDeliveryPeriodInstance = Period.findByPeriod(inventoryParams.averageDeliveryPeriod)
266                    if(!averageDeliveryPeriodInstance) {
267                        log.error "Failed, not a valid delivery period on line: " + lineNumber
268                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
269                    }
270                }
271
272                // Preferred Manufacturer
273                if(inventoryParams.preferredManufacturer) {
274                    tempPreferredManufacturerItemAndType = parseItemAndType(inventoryParams.preferredManufacturer)
275                    tempPreferredManufacturerItem = WordUtils.capitalize(tempPreferredManufacturerItemAndType[0])
276
277                    preferredManufacturerInstance = Manufacturer.findByName(tempPreferredManufacturerItem)
278                    if(!preferredManufacturerInstance) {
279
280                        // Manufacturer Type.
281                        if(tempPreferredManufacturerItemAndType.size == 2) {
282                            tempPreferredManufacturerType = WordUtils.capitalizeFully(tempPreferredManufacturerItemAndType[1])
283                            manufacturerTypeInstance = ManufacturerType.findByName(tempPreferredManufacturerType)
284                        }
285                        else
286                            manufacturerTypeInstance = manufacturerTypeUnknown
287                        if(!manufacturerTypeInstance) {
288                            log.error "Failed to find preferred manufacturer type on line: " + lineNumber
289                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
290                        }
291
292                        preferredManufacturerInstance = new Manufacturer(name: tempPreferredManufacturerItem,
293                                                                                                            supplierType: manufacturerTypeInstance)
294                        if(!preferredManufacturerInstance.save()) {
295                            log.error "Failed to create preferred manufacturer on line: " + lineNumber
296                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
297                        }
298                    }
299                }
300                else
301                    preferredManufacturerInstance = null
302
303                // Alternate Manufacturers.
304                tempAlternateManufacturers = parseInputList(inventoryParams.manufacturers)
305                inventoryParams.manufacturers = []
306
307                for(tempManufacturer in tempAlternateManufacturers) {
308                    tempManufacturerItemAndType = parseItemAndType(tempManufacturer)
309                    tempManufacturerItem = WordUtils.capitalizeFully(tempManufacturerItemAndType[0])
310
311                    manufacturerInstance = Manufacturer.findByName(tempManufacturerItem)
312                    if(!manufacturerInstance) {
313
314                        // ManufacturerType.
315                        if(tempManufacturerItemAndType.size == 2) {
316                            tempManufacturerType = WordUtils.capitalizeFully(tempManufacturerItemAndType[1])
317                            manufacturerTypeInstance = ManufacturerType.findByName(tempManufacturerType)
318                        }
319                        else
320                            manufacturerTypeInstance = manufacturerTypeUnknown
321                        if(!manufacturerTypeInstance) {
322                            log.error "Failed to find manufacturer type on line: " + lineNumber
323                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
324                        }
325
326                        manufacturerInstance = new Manufacturer(name: tempManufacturerItem,
327                                                                                                manufacturerType: manufacturerTypeInstance)
328                        if(!manufacturerInstance.save()) {
329                            log.error "Failed to create manufacturers on line: " + lineNumber
330                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
331                        }
332                    }
333
334                    inventoryParams.manufacturers.add(manufacturerInstance)
335                }
336
337                // Preferred Supplier
338                if(inventoryParams.preferredSupplier) {
339                    tempPreferredSupplierItemAndType = parseItemAndType(inventoryParams.preferredSupplier)
340                    tempPreferredSupplierItem = WordUtils.capitalize(tempPreferredSupplierItemAndType[0])
341
342                    preferredSupplierInstance = Supplier.findByName(tempPreferredSupplierItem)
343                    if(!preferredSupplierInstance) {
344
345                        // SupplierType.
346                        if(tempPreferredSupplierItemAndType.size == 2) {
347                            tempPreferredSupplierType = WordUtils.capitalizeFully(tempPreferredSupplierItemAndType[1])
348                            supplierTypeInstance = SupplierType.findByName(tempPreferredSupplierType)
349                        }
350                        else
351                            supplierTypeInstance = supplierTypeUnknown
352                        if(!supplierTypeInstance) {
353                            log.error "Failed to find preferred supplier type on line: " + lineNumber
354                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
355                        }
356
357                        preferredSupplierInstance = new Supplier(name: tempPreferredSupplierItem,
358                                                                                            supplierType: supplierTypeInstance)
359                        if(!preferredSupplierInstance.save()) {
360                            log.error "Failed to create preferred supplier on line: " + lineNumber
361                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
362                        }
363                    }
364                }
365                else
366                    preferredSupplierInstance = null
367
368                // Alternate Suppliers.
369                tempAlternateSuppliers = parseInputList(inventoryParams.alternateSuppliers)
370                inventoryParams.alternateSuppliers = []
371
372                for(tempSupplier in tempAlternateSuppliers) {
373                    tempSupplierItemAndType = parseItemAndType(tempSupplier)
374                    tempSupplierItem = WordUtils.capitalizeFully(tempSupplierItemAndType[0])
375
376                    alternateSupplierInstance = Supplier.findByName(tempSupplierItem)
377                    if(!alternateSupplierInstance) {
378
379                        // SupplierType.
380                        if(tempSupplierItemAndType.size == 2) {
381                            tempSupplierType = WordUtils.capitalizeFully(tempSupplierItemAndType[1])
382                            supplierTypeInstance = SupplierType.findByName(tempSupplierType)
383                        }
384                        else
385                            supplierTypeInstance = supplierTypeUnknown
386                        if(!supplierTypeInstance) {
387                            log.error "Failed to find alternate supplier type on line: " + lineNumber
388                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
389                        }
390
391                        alternateSupplierInstance = new Supplier(name: tempSupplierItem,
392                                                                            supplierType: supplierTypeInstance)
393                        if(!alternateSupplierInstance.save()) {
394                            log.error "Failed to create alternate suppliers on line: " + lineNumber
395                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
396                        }
397                    }
398
399                    inventoryParams.suppliers.add(alternateSupplierInstance)
400                }
401
402                // AlternateItems.
403                tempAlternateItems = parseInputList(inventoryParams.alternateItems)
404                inventoryParams.alternateItems = []
405
406                for(tempAlternateItem in tempAlternateItems) {
407                    tempAlternateItem = WordUtils.capitalize(tempAlternateItem)
408                    alternateItemInstance = InventoryItem.findByName(tempAlternateItem)
409                    if(!alternateItemInstance) {
410                        alternateItemInstance = new InventoryItem(name: tempAlternateItem,
411                                                                                                description: "Generated from alternateItems during import, details may not be correct.",
412                                                                                                reorderPoint: 0,
413                                                                                                inventoryGroup: inventoryGroupInstance,
414                                                                                                inventoryType: inventoryTypeInstance,
415                                                                                                unitOfMeasure: unitOfMeasureInstance,
416                                                                                                inventoryLocation: inventoryLocationInstance)
417                        if(!alternateItemInstance.save()) {
418                            log.error "Failed to create alternateItems on line: " + lineNumber
419                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
420                        }
421                    }
422
423                    inventoryParams.alternateItems.add(alternateItemInstance)
424                }
425
426                // spareFor.
427                tempSpareFor = parseInputList(inventoryParams.spareFor)
428                inventoryParams.spareFor = []
429
430                for(asset in tempSpareFor) {
431
432                    asset = WordUtils.capitalize(asset)
433
434                    spareForInstance = Asset.findByName(asset)
435                    if(!spareForInstance) {
436                        log.error "Failed to find 'Spare For' asset on line: " + lineNumber
437                        return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
438                    }
439
440                    inventoryParams.spareFor.add(spareForInstance)
441                }
442
443                // Assign the retrieved or created instances to params.
444                inventoryParams.inventoryLocation = inventoryLocationInstance
445                inventoryParams.inventoryGroup = inventoryGroupInstance
446                inventoryParams.inventoryType = inventoryTypeInstance
447                inventoryParams.unitOfMeasure = unitOfMeasureInstance
448                inventoryParams.averageDeliveryPeriod = averageDeliveryPeriodInstance
449                inventoryParams.preferredSupplier = preferredSupplierInstance
450                inventoryParams.preferredManufacturer = preferredManufacturerInstance
451
452                // Name.
453                // Checked above for blank string.
454                inventoryParams.name = WordUtils.capitalize(inventoryParams.name)
455
456                // Description.
457                if(inventoryParams.description != '')
458                    inventoryParams.description = inventoryParams.description[0].toUpperCase() + inventoryParams.description[1..-1]
459
460                // Debug
461                log.debug "InventoryParams: "
462                log.debug inventoryParams
463
464                // Create new or update.
465                inventoryItemInstance = InventoryItem.findByName(inventoryParams.name)
466                if(inventoryItemInstance) {
467                    log.info "Updating existing item: " + inventoryItemInstance
468                    inventoryItemInstance.properties = inventoryParams
469                }
470                else {
471                    log.info "Creating new item: " + inventoryParams.name
472                    inventoryItemInstance = new InventoryItem(inventoryParams)
473                }
474
475                // Save inventoryItem.
476                if(inventoryItemInstance.hasErrors() || !inventoryItemInstance.save()) {
477                    log.error "Failed to create item on line: " + column + "(" + lineNumber + ")"
478                    log.debug inventoryItemInstance.errors
479                    return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
480                }
481
482                if(lineNumber % 100 == 0)
483                    cleanUpGorm()
484
485                if(!result.error) nextLine()
486            } //while(line)
487
488            // Success.
489            log.info "End of file."
490            reader.close()
491            return result
492
493        } //end withTransaction
494    } // end importInventory()
495
496    /**
497    * Build an inventory template csv file.
498    * This template can then be populated for import.
499    * @returns The template as a String in csv format.
500    */
501    def buildInventoryTemplate() {
502
503        StringWriter sw = new StringWriter()
504        CSVWriter writer = new CSVWriter(sw)
505
506        writeTemplateLines(writer)
507
508        writer.close()
509        return sw.toString()
510    }
511
512    private writeTemplateLines(writer) {
513        writer.writeNext(templateHeaderLine1 as String[])
514        writer.writeNext()
515        writer.writeNext("Comment: The header line is required.")
516        writer.writeNext("Comment: Required columns are marked with a (*) in the header line.")
517        writer.writeNext("Comment: Lists of items in a column must be separated by a semicolon (;), not a comma.")
518        writer.writeNext("Comment: The at symbol (@) is reserved for indicating supplier and manufacturer types.")
519        writer.writeNext("Comment: Identical and existing names will be considered as the same item.")
520        writer.writeNext("Comment: Lines containing 'comment' will be ignored.")
521        writer.writeNext("Comment: Lines containing 'example' will be ignored.")
522        writer.writeNext("Comment: This file must be saved as a CSV file before import.")
523        writer.writeNext()
524    }
525
526    /**
527    * Build an inventory example/test file.
528    * This test file can be imported to test the import and export methods.
529    * @returns The test file as a String in csv format.
530    */
531    def buildInventoryExample() {
532
533        StringWriter sw = new StringWriter()
534        CSVWriter writer = new CSVWriter(sw)
535
536        writeTemplateLines(writer)
537
538        // Requires creation of some of the base/group/type data.
539        writer.writeNext(["Split19", "19mm split pin", "Very usefull item.",
540                                        "1024", "0", "1",
541                                        "each", "5", "NZD",
542                                        "false", "BR4",
543                                        "Store #99", "Inventory Depot",
544                                        "Mechanical Stock",
545                                        "Consumable",
546                                        "7", "Week(s)",
547                                        "123", "Multi Supplier@Local",
548                                        "Multi Distributors1@OEM; Multi Distributors2@Local",
549                                        "321", "Master Manufacturer@OEM",
550                                        "Mega Manufacturer1@OEM;Mega Manufacturer2@Alternate",
551                                        "2204E-2RS", ""
552                                        ] as String[])
553
554        // Using existing base data.
555        writer.writeNext(["2204E-2RS", "Double Row Self Align Ball Bearing 2204E-2RS - Sealed - 20/47x18", "",
556                                        "4", "1", "9",
557                                        "each", "16.35", "USD",
558                                        "TRUE", "BR4",
559                                        "Store #99", "Inventory Depot",
560                                        "Mechanical Stock",
561                                        "Consumable",
562                                        "2", "Month(s)",
563                                        "456KL", "Multi Supplier",
564                                        "Multi Distributors1; Multi Distributors2",
565                                        "654OP", "Master Manufacturer",
566                                        "Mega Manufacturer1;Mega Manufacturer2",
567                                        "", ""
568                                        ] as String[])
569
570        writer.close()
571        return sw.toString()
572    }
573
574    /**
575    * Build complete inventory for export.
576    * @param inventoryItemList The list of inventory items to build.
577    * @returns The inventory as a String in csv format.
578    */
579    def buildInventory(List inventoryItemList) {
580
581        def sw = new StringWriter()
582        def writer = new CSVWriter(sw)
583
584        writeTemplateLines(writer)
585
586        //Rows
587        def row
588
589        inventoryItemList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { inventoryItem ->
590            row = []
591            row.add(inventoryItem.name)
592            row.add(inventoryItem.description)
593            row.add(inventoryItem.comment)
594            row.add(inventoryItem.unitsInStock)
595            row.add(inventoryItem.reorderPoint)
596            row.add(inventoryItem.recommendedReorderPoint)
597            row.add(inventoryItem.unitOfMeasure)
598            row.add(inventoryItem.estimatedUnitPriceAmount)
599            row.add(inventoryItem.estimatedUnitPriceCurrency)
600            row.add(inventoryItem.enableReorder)
601            row.add(inventoryItem.inventoryLocation)
602            row.add(inventoryItem.inventoryLocation.inventoryStore)
603            row.add(inventoryItem.inventoryLocation.inventoryStore.site)
604            row.add(inventoryItem.inventoryGroup)
605            row.add(inventoryItem.inventoryType)
606            row.add(inventoryItem.averageDeliveryTime)
607            row.add(inventoryItem.averageDeliveryPeriod)
608            row.add(inventoryItem.suppliersPartNumber)
609
610            if(inventoryItem.preferredSupplier)
611                row.add( inventoryItem.preferredSupplier.name + "@" + inventoryItem.preferredSupplier.supplierType )
612            else
613                row.add('')
614
615            row.add( inventoryItem.alternateSuppliers.sort { p1, p2 ->
616                p1.name.compareToIgnoreCase(p2.name)
617            }.collect { it.name + "@" + it.supplierType }.join(';') )
618
619            row.add(inventoryItem.manufacturersPartNumber)
620
621            if(inventoryItem.preferredManufacturer)
622                row.add( inventoryItem.preferredManufacturer.name + "@" + inventoryItem.preferredManufacturer.manufacturerType )
623            else
624                row.add('')
625
626            row.add(inventoryItem.alternateManufacturers.sort { p1, p2 ->
627                p1.name.compareToIgnoreCase(p2.name)
628            }.collect { it.name + "@" + it.manufacturerType }.join(';'))
629
630            row.add(inventoryItem.alternateItems.sort { p1, p2 ->
631                p1.name.compareToIgnoreCase(p2.name)
632            }.collect { it.name }.join(';') )
633
634            row.add(inventoryItem.spareFor.sort { p1, p2 ->
635                p1.name.compareToIgnoreCase(p2.name)
636            }.collect { it.name }.join(';'))
637
638            writer.writeNext(row as String[])
639        }
640
641        writer.close()
642        return sw.toString()
643    } // end buildInventory
644
645    private getTemplateHeaderLine1() {
646            ["Name*", "Description", "Comment", "Units In Stock", "Reorder Point*", "Recommended Reorder Point", "Unit Of Measure*",
647            "Estimated Unit Price", "Currency", "Enable Reorder", "Location*", "Store*", "Site*", "Group*", "Type*",
648            "Average Delivery Time", "Average Delivery Period", "Supplier's Part Number", "Preferred Supplier", "Alternate Suppliers",
649            "Manufacturer's Part Number", "Preferred Manufacturer", "Alternate Manufacturers", "Alternate Item", "Spare For"]
650    }
651
652    /**
653    * This cleans up the hibernate session and a grails map.
654    * For more info see: http://naleid.com/blog/2009/10/01/batch-import-performance-with-grails-and-mysql/
655    * The hibernate session flush is normal for hibernate.
656    * The map is apparently used by grails for domain object validation errors.
657    * A starting point for clean up is every 100 objects.
658    */
659    def cleanUpGorm() {
660        def session = sessionFactory.currentSession
661        session.flush()
662        session.clear()
663        propertyInstanceMap.get().clear()
664    }
665
666} // end class
Note: See TracBrowser for help on using the repository browser.