package edu.ualberta.med.biobank.common.action.scanprocess;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Map;
import edu.ualberta.med.biobank.common.action.ActionContext;
import edu.ualberta.med.biobank.common.action.exception.ActionException;
import edu.ualberta.med.biobank.common.action.scanprocess.data.ShipmentProcessInfo;
import edu.ualberta.med.biobank.common.action.scanprocess.result.CellProcessResult;
import edu.ualberta.med.biobank.common.action.scanprocess.result.ScanProcessResult;
import edu.ualberta.med.biobank.common.action.specimen.SpecimenIsUsedInDispatchAction;
import edu.ualberta.med.biobank.common.util.ItemState;
import edu.ualberta.med.biobank.common.util.RowColPos;
import edu.ualberta.med.biobank.model.ActivityStatus;
import edu.ualberta.med.biobank.model.Center;
import edu.ualberta.med.biobank.model.Specimen;
public class DispatchCreateProcessAction extends ServerProcessAction {
private static final long serialVersionUID = 1L;
private ShipmentProcessInfo data;
public DispatchCreateProcessAction(ShipmentProcessInfo data,
Integer currentWorkingCenterId,
Map<RowColPos, CellInfo> cells,
boolean isRescanMode, Locale locale) {
super(currentWorkingCenterId, cells, isRescanMode, locale);
this.data = data;
}
public DispatchCreateProcessAction(ShipmentProcessInfo data,
Integer currentWorkingCenterId,
CellInfo cell,
Locale locale) {
super(currentWorkingCenterId, cell, locale);
this.data = data;
}
/**
* Process of a map of cells
*/
@Override
protected ScanProcessResult getScanProcessResult(
Map<RowColPos, CellInfo> cells, boolean isRescanMode)
throws ActionException {
ScanProcessResult res = new ScanProcessResult();
res.setResult(cells, createProcess(cells));
return res;
}
/**
* Process of only one cell
*/
@Override
protected CellProcessResult getCellProcessResult(CellInfo cell)
throws ActionException {
CellProcessResult res = new CellProcessResult();
ShipmentProcessInfo dispatchData = data;
Center sender = null;
if (dispatchData.getSenderId() != null) {
sender =
actionContext.load(Center.class, dispatchData.getSenderId());
}
processCellDipatchCreateStatus(cell, sender,
dispatchData.isErrorIfAlreadyAdded());
res.setResult(cell);
return res;
}
/**
* Processing for the create mode
*
* @param cells
* @return
* @throws Exception
*/
private CellInfoStatus createProcess(Map<RowColPos, CellInfo> cells) {
CellInfoStatus currentScanState = CellInfoStatus.EMPTY;
ShipmentProcessInfo dispatchData = data;
Center sender = null;
if (dispatchData.getSenderId() != null) {
sender =
(Center) session.load(Center.class, dispatchData.getSenderId());
}
if (dispatchData.getPallet(session) == null) {
for (CellInfo cell : cells.values()) {
processCellDipatchCreateStatus(cell, sender, false);
currentScanState = currentScanState.mergeWith(cell.getStatus());
}
} else {
for (int row = 0; row < dispatchData
.getPalletRowCapacity(actionContext); row++) {
for (int col = 0; col < dispatchData
.getPalletColCapacity(actionContext); col++) {
RowColPos rcp = new RowColPos(row, col);
CellInfo cell = cells.get(rcp);
Specimen expectedSpecimen = dispatchData
.getSpecimen(session, row, col);
if (expectedSpecimen != null) {
if (cell == null) {
cell = new CellInfo(row, col, null, null);
cells.put(rcp, cell);
}
cell.setExpectedSpecimenId(expectedSpecimen.getId());
}
if (cell != null) {
processCellDipatchCreateStatus(cell, sender, false);
currentScanState = currentScanState.mergeWith(cell
.getStatus());
}
}
}
}
return currentScanState;
}
/**
* Process one cell for create mode param checkAlreadyAdded if set to true,
* will set the Cell as error if is already added, otherwise the status will
* only be 'already added' (this status is used while scanning: the color
* will be different)
*/
private CellInfoStatus processCellDipatchCreateStatus(CellInfo scanCell,
Center sender, boolean checkAlreadyAdded) {
Specimen expectedSpecimen = null;
if (scanCell.getExpectedSpecimenId() != null) {
expectedSpecimen = actionContext.load(Specimen.class,
scanCell.getExpectedSpecimenId());
}
String value = scanCell.getValue();
if (value == null) { // no specimen scanned
scanCell.setStatus(CellInfoStatus.MISSING);
scanCell.setInformation(MessageFormat.format(Messages.getString(
"ScanAssign.scanStatus.specimen.missing", locale), //$NON-NLS-1$
expectedSpecimen.getInventoryId()));
scanCell.setTitle("?"); //$NON-NLS-1$
} else {
Specimen foundSpecimen = searchSpecimen(session, value);
if (foundSpecimen == null) {
// not in database
scanCell.setStatus(CellInfoStatus.ERROR);
scanCell.setInformation(Messages.getString(
"DispatchProcess.scanStatus.specimen.notfound", locale)); //$NON-NLS-1$
} else {
if (expectedSpecimen != null
&& !foundSpecimen.equals(expectedSpecimen)) {
// Position taken
scanCell.setStatus(CellInfoStatus.ERROR);
scanCell
.setInformation(Messages
.getString(
"ScanAssign.scanStatus.specimen.positionTakenError", locale)); //$NON-NLS-1$
scanCell.setTitle("!"); //$NON-NLS-1$
} else {
scanCell.setSpecimenId(foundSpecimen.getId());
if (expectedSpecimen != null
|| data.getPallet(session) == null) {
checkCanAddSpecimen(scanCell, foundSpecimen,
sender, checkAlreadyAdded);
} else {
// should not be there
scanCell.setStatus(CellInfoStatus.ERROR);
scanCell.setTitle(foundSpecimen.getCollectionEvent()
.getPatient().getPnumber());
scanCell
.setInformation(Messages
.getString(
"DispatchProcess.create.specimen.anotherPallet", locale)); //$NON-NLS-1$
}
}
}
}
return scanCell.getStatus();
}
/**
* Check at creation
*
* @param cell
* @param specimen
* @param sender
* @param checkAlreadyAdded
* @throws Exception
*/
private void checkCanAddSpecimen(CellInfo cell, Specimen specimen,
Center sender, boolean checkAlreadyAdded) {
if (specimen.getId() == null) {
cell.setStatus(CellInfoStatus.ERROR);
cell.setInformation(""); //$NON-NLS-1$
} else if (specimen.getActivityStatus() != ActivityStatus.ACTIVE) {
cell.setStatus(CellInfoStatus.ERROR);
cell.setInformation(MessageFormat.format(Messages.getString(
"DispatchProcess.create.specimen.status", locale), //$NON-NLS-1$
specimen.getInventoryId()));
} else if (!specimen.getCurrentCenter().equals(sender)) {
cell.setStatus(CellInfoStatus.ERROR);
cell.setInformation(MessageFormat.format(Messages.getString(
"DispatchProcess.create.specimen.currentCenter", locale), //$NON-NLS-1$
specimen.getInventoryId(), specimen.getCurrentCenter()
.getNameShort(), sender.getNameShort()));
} else {
Map<Integer, ItemState> currentSpecimenIds = data
.getCurrentDispatchSpecimenIds();
boolean alreadyInShipment = currentSpecimenIds != null
&& currentSpecimenIds.get(specimen.getId()) != null;
if (checkAlreadyAdded && alreadyInShipment) {
cell.setStatus(CellInfoStatus.ERROR);
cell.setInformation(MessageFormat.format(Messages.getString(
"DispatchProcess.create.specimen.alreadyAdded", locale), //$NON-NLS-1$
specimen.getInventoryId()));
} else if (new SpecimenIsUsedInDispatchAction(specimen.getId())
.run(actionContext).isTrue()) {
cell.setStatus(CellInfoStatus.ERROR);
cell.setInformation(MessageFormat.format(
Messages
.getString(
"DispatchProcess.create.specimen.inNotClosedDispatch", locale), //$NON-NLS-1$
specimen.getInventoryId()));
} else {
if (alreadyInShipment)
cell.setStatus(CellInfoStatus.IN_SHIPMENT_ADDED);
else
cell.setStatus(CellInfoStatus.FILLED);
cell.setTitle(specimen.getCollectionEvent().getPatient()
.getPnumber());
cell.setSpecimenId(specimen.getId());
}
}
}
@Override
public boolean isAllowed(ActionContext context) throws ActionException {
// FIXME add dispatch create permission
return true;
}
}