Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/89 use inventory snapshot for dashboard widgets #142

Merged
4 changes: 2 additions & 2 deletions application.properties
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#Grails Metadata file
#Mon Aug 31 12:18:51 CDT 2015
#Mon Apr 18 20:15:11 CDT 2016
app.buildDate=02 Feb 2012 11\:17\:30 PM
app.buildNumber=1
app.context=/openboxes
app.grails.version=1.3.9
app.name=openboxes
app.revisionNumber=11160
app.servlet.version=2.4
app.version=0.7.7
app.version=0.7.8
plugins.barcode4j=0.2.1
plugins.bubbling=2.1.4
plugins.clickstream=0.2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.pih.warehouse.core.Location
import org.pih.warehouse.core.User
import org.pih.warehouse.shipping.Shipment
import org.pih.warehouse.shipping.ShipmentItem
import org.springframework.web.multipart.MultipartFile

// import java.util.Date

Expand Down Expand Up @@ -472,6 +473,86 @@ class OrderController {
}
}

def downloadOrderItems = {
def orderInstance = Order.get(params.id)
if (!orderInstance) {
flash.message = "${warehouse.message(code: 'default.not.found.message', args: [warehouse.message(code: 'order.label', default: 'Order'), params.id])}"
redirect(action: "list")
//render(text: 'Unable to find purchase order found', status: 404)

}
else {

def date = new Date();
response.setHeader("Content-disposition", "attachment; filename='PO${orderInstance.orderNumber}-${orderInstance?.description?.encodeAsHTML()}-${date.format("MM-dd-yyyy")}.csv'")
response.contentType = "text/csv"
def csv = ""

csv += "${warehouse.message(code:'product.productCode.label')}," +
"${warehouse.message(code:'product.name.label')}," +
"${warehouse.message(code:'product.vendorCode.label')}," +
"${warehouse.message(code:'orderItem.quantity.label')}," +
"${warehouse.message(code:'product.unitOfMeasure.label')}," +
"${warehouse.message(code:'orderItem.unitPrice.label')}," +
"${warehouse.message(code:'orderItem.totalPrice.label')}," +
"\n"

def totalPrice = 0.0

orderInstance?.listOrderItems()?.each { orderItem ->
totalPrice += orderItem.totalPrice()?:0

String quantityString = formatNumber(number:orderItem?.quantity, maxFractionDigits: 1, minFractionDigits: 1)
String unitPriceString = formatNumber(number:orderItem?.unitPrice, maxFractionDigits: 4, minFractionDigits: 2)
String totalPriceString = formatNumber(number:orderItem?.totalPrice(), maxFractionDigits: 2, minFractionDigits: 2)

csv += "${orderItem?.product?.productCode}," +
"${StringEscapeUtils.escapeCsv(orderItem?.product?.name)}," +
"${orderItem?.product?.vendorCode?:''}," +
"${quantityString}," +
"${orderItem?.product?.unitOfMeasure?:'EA'}," +
"${StringEscapeUtils.escapeCsv(unitPriceString)}," +
"${StringEscapeUtils.escapeCsv(totalPriceString)}" +
"\n"
}
render csv

}
}

def importOrderItems = {
def orderInstance = Order.get(params.id)
if (!orderInstance) {
flash.message = "${warehouse.message(code: 'default.not.found.message', args: [warehouse.message(code: 'order.label', default: 'Order'), params.id])}"
redirect(action: "list")
}
else {

try {
MultipartFile multipartFile = request.getFile('fileContents')
if (multipartFile.empty) {
flash.message = "File cannot be empty. Please select a packing list to import."
redirect(action: "show", id: params.id)
return;
}
List lineItems = orderService.parseOrderItems(multipartFile.inputStream)
log.info "Line items: " + lineItems

if (orderService.importOrderItems(params.id, lineItems)) {
flash.message = "Successfully imported ${lineItems?.size()} order line items. "

} else {
flash.message = "Failed to import packing list items due to an unknown error."
}
} catch (Exception e) {
log.error("Failed to import packing list due to the following error: " + e.message, e)
flash.message = "Failed to import packing list due to the following error: " + e.message
}
}
redirect(action: "show", id: params.id)
}


def upload = {
def orderInstance = Order.get(params.id)
if (!orderInstance) {
Expand Down Expand Up @@ -531,9 +612,24 @@ class OrderController {


}

}


def rollbackOrderStatus = {

def orderInstance = Order.get(params.id)
if (!orderInstance) {
flash.message = "${warehouse.message(code: 'default.not.found.message', args: [warehouse.message(code: 'order.label', default: 'Order'), params.id])}"
redirect(action: "list")
}
else {
orderService.rollbackOrderStatus(params.id)

}
redirect(action: "show", id: params.id)

}




Expand Down
4 changes: 2 additions & 2 deletions grails-app/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ default.browseByTag.label = Browse by attribute
default.browseByType.label = Browse by type
default.button.add.label = Add
default.button.addItem.label = Add Item
default.button.back.label = Back
default.button.back.label = << Back
default.button.cancel.label = Cancel
default.button.change.label = Change
default.button.clear.label = Clear
Expand All @@ -268,7 +268,7 @@ default.button.find.label = Find
default.button.finish.label = Finish
default.button.import.label = Import
default.button.move.label = Move
default.button.next.label = Next
default.button.next.label = Next >>
default.button.notSupported.message = This feature is not currently supported.
default.button.previous.label = Previous
default.button.review.label = Review
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
**/
package org.pih.warehouse.core

import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException
import org.apache.commons.lang.RandomStringUtils
import org.hibernate.ObjectNotFoundException
import org.pih.warehouse.inventory.Transaction
Expand Down Expand Up @@ -138,13 +139,20 @@ class IdentifierService {
def products = Product.findAll("from Product as p where productCode is null or productCode = ''")
products.each { product ->
try {
println "Assigning identifier to product " + product.id + " " + product.name
product.productCode = generateProductIdentifier()
if (!product.merge(flush: true, validate: false)) {
println product.errors
def productCode = generateProductIdentifier()
println "Assigning identifier ${productCode} to product " + product.id + " " + product.name

// Check to see if there's already a product with that product code
if (!Product.findByProductCode(productCode)) {
product.productCode = productCode
if (!product.merge(flush: true, validate: false)) {
println product.errors
}
}
} catch (MySQLIntegrityConstraintViolationException e) {
log.warn ("Unable to assign identifier due to constraint violation: " + e.message, e)
} catch (Exception e) {
println("Unable to assign identifier to product with ID " + product?.id + ": " + e.message)
log.warn("Unable to assign identifier to product with ID " + product?.id + ": " + e.message, e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2078,7 +2078,7 @@ class InventoryService implements ApplicationContextAware {
inventoryItem.lotNumber = lotNumber
inventoryItem.expirationDate = expirationDate;
inventoryItem.product = product
inventoryItem.save()
inventoryItem.save(flush:true)
}
return inventoryItem

Expand Down Expand Up @@ -3171,18 +3171,15 @@ class InventoryService implements ApplicationContextAware {
Integer maxSize = inventoryItemKeys.size()

if (n > maxSize) {
throw new RuntimeException("You cannot request more items than are available at this location [requested=${n},available=${maxSize}].")
n = maxSize
//throw new RuntimeException("You cannot request more items than are available at this location [requested=${n},available=${maxSize}].")
}

Random random = new Random()
def randomIntegerList = []
(1..n).each {
println "n: " + n
println "maxSize: " + maxSize
def randomIndex = random.nextInt(maxSize)
println "randomIndex: " + randomIndex
def inventoryItem = inventoryItemKeys.get(randomIndex)
println "lotNumber: " + inventoryItem.lotNumber
inventoryItems << inventoryItem
}
return inventoryItems;
Expand Down Expand Up @@ -4030,7 +4027,6 @@ class InventoryService implements ApplicationContextAware {

// Get the inventory levels for all products at the given location
def inventoryLevelMap = InventoryLevel.findAllByInventory(location.inventory)?.groupBy { it.product }
//log.info inventoryLevelMap

// Group entries by generic product
genericProductMap = entries.inject([:].withDefault { [
Expand Down
Loading