package org.celllife.idart.misc.task; import java.util.Date; import java.util.List; import model.manager.DrugManager; import model.manager.StockManager; import org.apache.log4j.Logger; import org.celllife.idart.database.hibernate.Drug; import org.celllife.idart.database.hibernate.Stock; import org.celllife.idart.database.hibernate.StockAdjustment; import org.celllife.idart.database.hibernate.StockLevel; import org.celllife.idart.database.hibernate.StockTake; import org.celllife.idart.database.hibernate.util.HibernateUtil; import org.celllife.idart.database.hibernate.util.TransactionalCommand; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.hibernate.Session; public class RecalculateSockTask implements IdartTask { private static Logger log = Logger.getLogger(RecalculateSockTask.class); private boolean adjustNegaiveLevels = false; private StockTake stockTake; @Override public boolean init(String[] args) { if (args.length > 0){ if (args[0].equals("-adjust")){ adjustNegaiveLevels = true; } else { return false; } } return true; } @Override public void run(final IProgressMonitor monitor) throws TaskException { Session session = HibernateUtil.getNewSession(); if (adjustNegaiveLevels){ new TransactionalCommand(session) { @Override protected void executeInTransaction() { openStockTake(getSession()); } }.run(); } List<Drug> allDrugs = DrugManager.getAllDrugs(session); monitor.beginTask("Updating stock levels for all stock", allDrugs.size()); for (final Drug drug : allDrugs) { monitor.setTaskName("Update stock levels for " + drug.getName()); List<Stock> stockForDrug = StockManager.getAllStockForDrug(session, drug); for (final Stock stock : stockForDrug) { if (monitor.isCanceled()){ throw new OperationCanceledException("Stock level calculation cancelled"); } new TransactionalCommand(session) { @Override protected void executeInTransaction() { monitor.subTask("Calculating for batch " + stock.getBatchNumber()); StockLevel sl = StockManager.updateStockLevel(getSession(), stock); if (sl == null){ return; } if ((sl.getFullContainersRemaining() < 0 || sl.getLoosePillsRemaining() < 0) && adjustNegaiveLevels){ int unitsRemaining = drug.getPackSize() * sl.getFullContainersRemaining() + sl.getLoosePillsRemaining(); log.info("Creating adjustment for batch " + stock.getBatchNumber() + " for drug " + drug.getName() + ": " + unitsRemaining); StockAdjustment st = new StockAdjustment(); st.setAdjustedValue(unitsRemaining); st.setCaptureDate(new Date()); st.setNotes("Zero negative stock level"); st.setStock(stock); st.setStockCount(0); st.setStockTake(stockTake); getSession().save(st); StockManager.updateStockLevel(getSession(), stock); } } }.run(); monitor.internalWorked(1.0/stockForDrug.size()); } } if (adjustNegaiveLevels){ new TransactionalCommand(session) { @Override protected void executeInTransaction() { closeStockTake(getSession()); } }.run(); } monitor.done(); } private void closeStockTake(Session session) { stockTake.setEndDate(new Date()); stockTake.setOpen(false); session.saveOrUpdate(stockTake); } private void openStockTake(Session session) { stockTake = new StockTake(); stockTake.setOpen(true); stockTake.setStartDate(new Date()); stockTake.setStockTakeNumber("Zero negative stock: " + new Date()); session.save(stockTake); } @Override public String getHelpText() { String help = "This task recalculates ALL the iDART stock levels" + " based on the amounts received, dispensed, destroyed" + ", returned and adjusted.\nIt can also create a stock take" + " and adjust any negative levels to zero if required.\n\n"; help += " Optional arguments:\n"; help += " -adjust: if this argument is passed then a stock take" + " will be created and negative stock levels will be adjusted to zero.\n" + " Once complete it is possible to view the stock take report" + " by going to the reports screen.\n"; help += " Usage example:\n"; help += " go.bat recalculateStock -adjust (Windows)\n"; help += " ./go.sh recalculateStock -adjust (Linux)\n"; return help; } @Override public String getDescription() { return "Recalculate iDART stock levels"; } }