package com.medenterprise.app.supplystore.ejb; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.*; import javax.persistence.*; import com.medenterprise.supplystore.entity.*; import java.util.ArrayList; @Stateless public class EntityController implements EntityControllerLocal { @PersistenceContext(unitName = "supply-store") private EntityManager em; public void persist(Object entity) { HashMap fieldMap = new HashMap(); try { for (Field f : entity.getClass().getDeclaredFields()) { if (f.isAnnotationPresent(OwnedEntity.class)) { EntityFieldReflector reflector = new EntityFieldReflector(entity, f); Object owned = reflector.get(); if (owned != null) { fieldMap.put(f, owned); } reflector.set(null); } } em.persist(entity); em.flush(); Object id = getId(entity); for (Field f : fieldMap.keySet()) { EntityFieldReflector reflector = new EntityFieldReflector(entity, f); Object owned = fieldMap.get(f); for (Method m : owned.getClass().getMethods()) { if (m.isAnnotationPresent(OwnerIdSetter.class)) { m.invoke(owned, id); } } owned = update(owned); em.flush(); reflector.set(owned); } } catch (Exception ex) { Logger.getLogger(EntityController.class.getName()).log(Level.SEVERE, null, ex); } } public T merge(T entity) { return (T) em.merge(entity); } private Object getId(Object entity) { for (Field f : entity.getClass().getDeclaredFields()) { if (f.isAnnotationPresent(Id.class)) { EntityFieldReflector reflector = new EntityFieldReflector(entity, f); return reflector.get(); } } return null; } public void remove(Object entity) { Object mergedEntity = em.merge(entity); em.remove(mergedEntity); } public void refresh(Object entity) { em.refresh(entity); } public void remove(Class entityClass, int id) { try { Object entity = em.find(entityClass, id); if (entity != null) { em.remove(entity); } } catch (Exception ex) { throw new EJBException(ex); } } public T update(T entity) { try { Object id = getId(entity); if (id == null) { persist(entity); return entity; } } catch (Exception ex) { Logger.getLogger(EntityController.class.getName()).log(Level.SEVERE, null, ex); } return (T) em.merge(entity); } public T find(Class entityClass, int id) { return (T) em.find(entityClass, id); } public List getList(Class entityClass) { Query query = em.createNamedQuery(entityClass.getSimpleName() + ".list"); return query.getResultList(); } public int getCount(Class entityClass) { Query query = em.createNamedQuery(entityClass.getSimpleName() + ".count"); return ((Long) query.getSingleResult()).intValue(); } public List lookByGTIN(String gtin) { Query query = em.createNamedQuery("InventoryItem.lookByGTIN"); query.setParameter("gtin", '%' + gtin.toLowerCase() + '%'); return query.getResultList(); } public List findByName(String name) { Query query = em.createNamedQuery("InventoryItem.findByName"); query.setParameter("name", '%' + name.toLowerCase() + '%'); return query.getResultList(); } public List getReceiveInventoryItems(Integer vendorId, Integer categoryId) { Query query = em.createNamedQuery("InventoryItem.getReceiveItems"); query.setParameter(1, categoryId); query.setParameter(2, vendorId); query.setParameter(3, vendorId); query.setParameter(4, vendorId); return query.getResultList(); } public List getDistributionInventoryItems(Integer categoryId) { Query query = em.createNamedQuery("InventoryItem.getDistributionItems"); query.setParameter("categoryId", categoryId); return query.getResultList(); } public List findByCategory(Class entityClass, Integer categoryId) { Query query = em.createNamedQuery(entityClass.getSimpleName() + ".findByCategoryId"); query.setParameter("categoryId", categoryId); return query.getResultList(); } public List findByVendorCategory(Integer vendorId, Integer categoryId, boolean showDiscontinued) { Query query = em.createNamedQuery("InventoryItem.findByVendorCategory"); // query.setParameter("vendorId", vendorId); query.setParameter(1, showDiscontinued); query.setParameter(2, categoryId); query.setParameter(3, vendorId); query.setParameter(4, vendorId); query.setParameter(5, vendorId); return query.getResultList(); } public List findByReorderLevel(Integer vendorId, boolean showDiscontinued) { Query query = em.createNamedQuery("InventoryItem.findByReorderLevel"); query.setParameter(1, showDiscontinued); query.setParameter(2, vendorId); query.setParameter(3, vendorId); query.setParameter(4, vendorId); return query.getResultList(); } public List findNotUsed() { Query query = em.createNamedQuery("InventoryItem.findNotUsed"); return query.getResultList(); } public List getBatch(Class entityClass, int batchSize, int firstItem) { Query query = em.createNamedQuery(entityClass.getSimpleName() + ".list"); query.setMaxResults(batchSize); query.setFirstResult(firstItem); return query.getResultList(); } public Order saveOrder(Order order) { List list = order.getItemList(); order.setItemList(null); if (order.getId() == null) { em.persist(order); em.flush(); } for (OrderItem item : list) { if (item.getOrder() == null) { item.setOrder(order); em.persist(item); } else { em.merge(item); } } order.setItemList(list); return em.merge(order); } @Override public PurchaseOrder savePurchaseOrder(PurchaseOrder purchaseOrder) { purchaseOrder.updateTotalAmount(); List list = purchaseOrder.getItemList(); // Execution of this statement modified suddenly modified "list" varaible purchaseOrder.setItemList(null); // List list = new ArrayList(); // list.addAll(purchaseOrder.getItemList()); if (purchaseOrder.getId() == null) { em.persist(purchaseOrder); em.flush(); } for (PurchaseOrderItem item : list) { if (item.getOrder() == null) { item.setOrder(purchaseOrder); em.persist(item); } else { em.merge(item); } } purchaseOrder.setItemList(list); for (PurchaseOrderItem item : purchaseOrder.getItemList()) { changeUnitsOnOrder(item.getInventoryItem().getId(), item.getQuantity()); } return em.merge(purchaseOrder); } public int changeUnitsOnOrder(Integer inventoryItemId, Integer quantity) { Query query = em.createNamedQuery("InventoryItem.changeUnitsOnOrder"); query.setParameter("id", inventoryItemId); query.setParameter("quantity", quantity); return query.executeUpdate(); } public int clearItemsFromAggregation(Integer inventoryItemId) { Query query = em.createNamedQuery("InventoryItem.clearItemsFromAggregation"); query.setParameter("id", inventoryItemId); return query.executeUpdate(); } public List findMyOrders(Integer userId, Date fromDate, Date toDate, Integer siteId, Integer customerId, Integer statusId) { Query query = em.createNamedQuery("Order.myOrders"); query.setParameter("userId", userId); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("siteId", siteId); query.setParameter("customerId", customerId); query.setParameter("statusId", statusId); return query.getResultList(); } public List findOrders(Date fromDate, Date toDate, Integer siteId, Integer customerId, Integer statusId) { Query query = em.createNamedQuery("Order.orders"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("siteId", siteId); query.setParameter("customerId", customerId); query.setParameter("statusId", statusId); return query.getResultList(); } public List findPurchaseOrders(Date fromDate, Date toDate, Integer vendorId, Integer statusId) { Query query = em.createNamedQuery("PurchaseOrder.orders"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("vendorId", vendorId); query.setParameter("statusId", statusId); return query.getResultList(); } public InventoryItem findInventoryItemByGTIN(String gtin) { Query query = em.createNamedQuery("InventoryItem.findByGTIN"); query.setParameter("gtin", gtin); try { return (InventoryItem) query.getSingleResult(); } catch (NoResultException ex) { return null; } } public List findInventoryItemByProduct(Product product) { Query query = em.createNamedQuery("InventoryItem.findByProduct"); query.setParameter("product", product); return query.getResultList(); } public InventoryItem findInventoryItemByProductUnit(Product product, Unit unit) { Query query = em.createNamedQuery("InventoryItem.findByProductUnit"); query.setParameter("product", product); query.setParameter("unit", unit); try { return (InventoryItem) query.getSingleResult(); } catch (NoResultException ex) { return null; } } public List findPrescriptionItemByProductId(Integer productId) { Query query = em.createNamedQuery("InventoryItem.findPrescriptionByProductId"); query.setParameter("productId", productId); return query.getResultList(); } public InventoryItem findProviderPrescriptionItemByProductId(Integer productId) { Query query = em.createNamedQuery("InventoryItem.findProviderPrescriptionByProductId"); query.setParameter("productId", productId); try { return (InventoryItem) query.getSingleResult(); } catch (NoResultException ex) { return null; } } public Invoice saveInvoice(Invoice invoice) { int quantity; int remains; int unitsRate; int currentQty; InventoryItem inventoryItem; List list = invoice.getItemList(); invoice.setItemList(null); em.persist(invoice); em.flush(); for (InvoiceItem item : list) { item.setInvoice(invoice); em.persist(item); unitsRate = unitsConversionRate(item.getInventoryItem().getUnit(), item.getUnit()); if (unitsRate > 1) { inventoryItem = find(InventoryItem.class, item.getInventoryItem().getId()); currentQty = inventoryItem.getUnitsInStock() * unitsRate + inventoryItem.getRemains(); currentQty = currentQty - item.getQuantity(); quantity = currentQty / unitsRate; remains = currentQty % unitsRate; inventoryItem.setUnitsInStock(quantity); inventoryItem.setRemains(remains); em.merge(inventoryItem); } else { changeUnitsInStock(item.getInventoryItem().getId(), -item.getQuantity()); } } invoice.setItemList(list); return em.merge(invoice); } public int unitsConversionRate(Unit vendorUnit, Unit catalogUnit) { if (catalogUnit == null || vendorUnit.equals(catalogUnit)) { return 1; } else { return vendorUnit.getQuantity(); } } public int changeUnitsInStock(Integer inventoryItemId, Integer quantity) { Query query = em.createNamedQuery("InventoryItem.changeUnitsInStock"); query.setParameter("id", inventoryItemId); query.setParameter("quantity", quantity); return query.executeUpdate(); } public int changeReceived(Integer orderId, Integer inventoryItemId, Integer quantity) { Query query = em.createNamedQuery("PurchaseOrderItem.changeReceived"); query.setParameter("orderId", orderId); query.setParameter("inventoryItemId", inventoryItemId); query.setParameter("quantity", quantity); return query.executeUpdate(); } @Override public List findInvoices(Date fromDate, Date toDate, Integer siteId, Integer customerId, Integer statusId, String productName, String identifier) { Query query; List products; Product product; if (productName != null && !productName.isEmpty()) { query = em.createNamedQuery("Product.search"); query.setParameter("name", '%' + productName.toLowerCase() + '%'); products = query.getResultList(); if (products.isEmpty()) { return null; } product = products.get(0); query = em.createNamedQuery("Invoice.findByProduct"); query.setParameter("product", product); } else { if (identifier != null && !identifier.isEmpty()) { query = em.createNamedQuery("Invoice.findByIdentifier"); query.setParameter("identifier", identifier); } else { query = em.createNamedQuery("Invoice.invoices"); } } query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("siteId", siteId); query.setParameter("customerId", customerId); query.setParameter("statusId", statusId); return query.getResultList(); } public CustomerReturn saveCustomerReturn(CustomerReturn customerReturn) { List list = customerReturn.getItemList(); customerReturn.setItemList(null); em.persist(customerReturn); em.flush(); for (CustomerReturnItem item : list) { item.setCustomerReturn(customerReturn); em.persist(item); changeUnitsInStock(item.getInventoryItem().getId(), item.getQuantity()); } customerReturn.setItemList(list); return em.merge(customerReturn); } public List findCustomerReturns(Date fromDate, Date toDate, Integer siteId, Integer customerId) { Query query = em.createNamedQuery("CustomerReturn.returns"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("siteId", siteId); query.setParameter("customerId", customerId); return query.getResultList(); } public PackingSlip savePackingSlip(PackingSlip packingSlip) { InventoryItem inventoryItem; List list = packingSlip.getItemList(); packingSlip.setItemList(null); em.persist(packingSlip); em.flush(); for (PackingSlipItem item : list) { item.setPackingSlip(packingSlip); if (item.getIdentifier() != null && item.getInventoryItem() != null) { inventoryItem = new InventoryItem(); inventoryItem.setVendorId(packingSlip.getVendor().getId()); inventoryItem.setGtin(item.getIdentifier()); inventoryItem.setIdentifier(item.getIdentifier()); inventoryItem.setProduct(item.getInventoryItem().getProduct()); inventoryItem.setUnit(item.getInventoryItem().getUnit()); inventoryItem.setUnitsInStock(0); inventoryItem.setRemains(0); inventoryItem.setUnitsOnOrder(0); inventoryItem.setReorderLevel(0); inventoryItem.setLastUnitCost(item.getUnitCost()); inventoryItem.setAverageUnitCost(item.getUnitCost()); em.persist(inventoryItem); em.flush(); item.setInventoryItem(inventoryItem); } em.persist(item); if (item.getInventoryItem().getAggregationId() == null) { changeUnitsInStock(item.getInventoryItem().getId(), item.getQuantity()); } else { changeUnitsInStock(item.getInventoryItem().getAggregationId(), item.getQuantity()); } if (packingSlip.getOrderId() != null) { try { new Integer(packingSlip.getOrderId()); changeReceived(Integer.valueOf(packingSlip.getOrderId()), item.getInventoryItem().getId(), item.getQuantity()); } catch (NumberFormatException ex) { } } } packingSlip.setItemList(list); return em.merge(packingSlip); } public List findPackingSlips(Date fromDate, Date toDate, Integer vendorId) { Query query = em.createNamedQuery("PackingSlip.packingSlips"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("vendorId", vendorId); return query.getResultList(); } public Return saveReturn(Return reTurn) { List list = reTurn.getItemList(); reTurn.setItemList(null); em.persist(reTurn); em.flush(); for (ReturnItem item : list) { item.setReturn(reTurn); em.persist(item); changeUnitsInStock(item.getInventoryItem().getId(), -item.getQuantity()); } reTurn.setItemList(list); return em.merge(reTurn); } public List findReturns(Date fromDate, Date toDate, Integer vendorId) { Query query = em.createNamedQuery("Return.returns"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); query.setParameter("vendorId", vendorId); return query.getResultList(); } public InventoryItem adjustInventory(InventoryItemAdjustment adjustItem) { InventoryItem inventoryItem = adjustItem.getInventoryItem(); inventoryItem.setUnitsInStock(adjustItem.getNewQuantity()); inventoryItem.setRemains(adjustItem.getNewRemains()); try { em.persist(adjustItem); } catch (Exception ex) { Logger.getLogger(EntityController.class.getName()).log(Level.SEVERE, null, ex); return inventoryItem; } return em.merge(inventoryItem); } public InventoryItem saveAggregationItem(InventoryItem aggregationItem, List elementList) { int quantity = 0; int remains = 0; for (InventoryItem item : elementList) { quantity = quantity + item.getUnitsInStock(); remains = remains + item.getRemains(); } aggregationItem.setUnitsInStock(quantity); aggregationItem.setRemains(remains); em.persist(aggregationItem); em.flush(); for (InventoryItem item : elementList) { item.setAggregationId(aggregationItem.getId()); item.setUnitsInStock(0); item.setRemains(0); em.merge(item); } return aggregationItem; } public InventoryWriteoff saveInventoryWriteoff( InventoryWriteoff inventoryWriteoff) { List list = inventoryWriteoff.getItemList(); inventoryWriteoff.setItemList(null); em.persist(inventoryWriteoff); em.flush(); for (InventoryWriteoffItem item : list) { item.setInventoryWriteoff(inventoryWriteoff); em.persist(item); changeUnitsInStock(item.getInventoryItem().getId(), -item.getQuantity()); } inventoryWriteoff.setItemList(list); return em.merge(inventoryWriteoff); } public List findInventoryWriteoff( Date fromDate, Date toDate) { Query query = em.createNamedQuery("InventoryWriteoff.findByDateRange"); query.setParameter("fromDate", fromDate); query.setParameter("toDate", toDate); return query.getResultList(); } }