// $HeadURL$
// $Id$
//
// Copyright © 2010 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.
package edu.harvard.med.screensaver.service.libraries;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.hibernate.Session;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import edu.harvard.med.screensaver.db.Criterion.Operator;
import edu.harvard.med.screensaver.db.DAOTransaction;
import edu.harvard.med.screensaver.db.Query;
import edu.harvard.med.screensaver.db.hqlbuilder.HqlBuilder;
import edu.harvard.med.screensaver.db.hqlbuilder.JoinType;
import edu.harvard.med.screensaver.model.BusinessRuleViolationException;
import edu.harvard.med.screensaver.model.activities.AdministrativeActivity;
import edu.harvard.med.screensaver.model.activities.AdministrativeActivityType;
import edu.harvard.med.screensaver.model.libraries.Copy;
import edu.harvard.med.screensaver.model.libraries.CopyUsageType;
import edu.harvard.med.screensaver.model.libraries.Library;
import edu.harvard.med.screensaver.model.libraries.LibraryType;
import edu.harvard.med.screensaver.model.libraries.Plate;
import edu.harvard.med.screensaver.model.libraries.PlateLocation;
import edu.harvard.med.screensaver.model.libraries.PlateSize;
import edu.harvard.med.screensaver.model.libraries.PlateStatus;
import edu.harvard.med.screensaver.model.screens.ScreenType;
import edu.harvard.med.screensaver.model.users.AdministratorUser;
import edu.harvard.med.screensaver.test.AbstractSpringPersistenceTest;
public class PlateUpdaterTest extends AbstractSpringPersistenceTest
{
@Autowired
protected PlateUpdater plateUpdater;
private AdministratorUser _admin;
private Copy _copyC;
private Copy _copyD;
@Override
public void setUp() throws Exception
{
super.setUp();
_admin = new AdministratorUser("Admin", "User");
genericEntityDao.persistEntity(_admin);
Library library = new Library(null, "lib", "lib", ScreenType.SMALL_MOLECULE, LibraryType.COMMERCIAL, 1, 6, PlateSize.WELLS_96);
_copyC = library.createCopy(null, CopyUsageType.LIBRARY_SCREENING_PLATES, "C");
_copyD = library.createCopy(null, CopyUsageType.LIBRARY_SCREENING_PLATES, "D");
genericEntityDao.persistEntity(library);
}
public void testPlateStatusUpdate()
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
Plate plate = _copyC.findPlate(1);
genericEntityDao.persistEntity(admin2);
plateUpdater.updatePlateStatus(plate, PlateStatus.NOT_CREATED, _admin, admin2, new LocalDate(2010, 1, 1));
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.NOT_CREATED, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Not specified' to 'Not created'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 1), activity.getDateOfActivity());
assertNull(updatedPlate.getPlatedActivity());
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate plate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
plateUpdater.updatePlateStatus(plate, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 2));
plateUpdater.updatePlateLocation(plate, new PlateLocation("W", "X", "Y", "Z"), _admin, admin2, new LocalDate(2010, 1, 2));
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.AVAILABLE, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Not created' to 'Available'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 2), activity.getDateOfActivity());
assertEquals(activity, updatedPlate.getPlatedActivity());
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate plate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
plateUpdater.updatePlateStatus(plate, PlateStatus.NOT_AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 3));
plateUpdater.updatePlateLocation(plate, new PlateLocation("W", "X", "Y", "Z"), _admin, admin2, new LocalDate(2010, 1, 3));
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.NOT_AVAILABLE, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Available' to 'Not available'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 3), activity.getDateOfActivity());
assertEquals("original plate status update activity maintained", new LocalDate(2010, 1, 2), updatedPlate.getPlatedActivity().getDateOfActivity());
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate plate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
plateUpdater.updatePlateLocation(plate, new PlateLocation("W", "X", "Y", "Z"), _admin, admin2, new LocalDate(2010, 1, 4));
plateUpdater.updatePlateStatus(plate, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 4));
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.AVAILABLE, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Not available' to 'Available'", activity.getComments());
assertEquals("original plate status update activity maintained", new LocalDate(2010, 1, 2), updatedPlate.getPlatedActivity().getDateOfActivity());
}
});
plateUpdater.updatePlateStatus(plate, PlateStatus.RETIRED, _admin, admin2, new LocalDate(2010, 1, 5));
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.RETIRED, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Available' to 'Retired'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 5), activity.getDateOfActivity());
assertEquals(activity, updatedPlate.getRetiredActivity());
}
});
plateUpdater.updatePlateStatus(plate, PlateStatus.DISCARDED, _admin, admin2, new LocalDate(2010, 1, 6));
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.DISCARDED, updatedPlate.getStatus());
assertEquals(genericEntityDao.reloadEntity(admin2), activity.getPerformedBy());
assertEquals(genericEntityDao.reloadEntity(_admin), activity.getCreatedBy());
assertEquals("Status changed from 'Retired' to 'Discarded'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 6), activity.getDateOfActivity());
assertEquals("extant retired date does not change when a retired plate is discarded, etc.",
new LocalDate(2010, 1, 5), updatedPlate.getRetiredActivity().getDateOfActivity());
assertNull(updatedPlate.getLocation());
AdministrativeActivity locationTransferActivity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_LOCATION_TRANSFER);
assertEquals(new LocalDate(2010, 1, 6), locationTransferActivity.getDateOfActivity());
assertTrue(locationTransferActivity.getComments().contains("plate no longer has a location due to change of status to " +
PlateStatus.DISCARDED));
}
});
}
public void testPlateStatusUpdateFromLost()
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
Plate plate = _copyC.findPlate(1);
genericEntityDao.persistEntity(admin2);
plateUpdater.updatePlateStatus(plate, PlateStatus.LOST, _admin, admin2, new LocalDate(2010, 1, 1));
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.LOST, updatedPlate.getStatus());
assertEquals("Status changed from 'Not specified' to 'Lost'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 1), activity.getDateOfActivity());
assertNull(updatedPlate.getPlatedActivity());
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate plate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
plateUpdater.updatePlateStatus(plate, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 2));
plateUpdater.updatePlateLocation(plate, new PlateLocation("W", "X", "Y", "Z"), _admin, admin2, new LocalDate(2010, 1, 2));
}
});
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate updatedPlate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity activity = updatedPlate.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_STATUS_UPDATE);
assertEquals(PlateStatus.AVAILABLE, updatedPlate.getStatus());
assertEquals("Status changed from 'Lost' to 'Available'", activity.getComments());
assertEquals(new LocalDate(2010, 1, 2), activity.getDateOfActivity());
assertEquals(activity, updatedPlate.getPlatedActivity());
}
});
}
// public void testInvalidPlateStatusUpdateFromNotCreatedToNotSpecified()
// {
// doTestInvalidStatusUpdate(PlateStatus.NOT_CREATED, PlateStatus.NOT_SPECIFIED);
// }
// public void testInvalidPlateStatusUpdateFromNotAvailableToNotSpecified()
// {
// doTestInvalidStatusUpdate(PlateStatus.NOT_AVAILABLE, PlateStatus.NOT_SPECIFIED);
// }
// public void testInvalidPlateStatusUpdateFromNotAvailableToNotCreated()
// {
// doTestInvalidStatusUpdate(PlateStatus.NOT_AVAILABLE, PlateStatus.NOT_CREATED);
// }
// public void testInvalidPlateStatusUpdateFromAvailableToNotSpecified()
// {
// doTestInvalidStatusUpdate(PlateStatus.AVAILABLE, PlateStatus.NOT_SPECIFIED);
// }
// public void testInvalidPlateStatusUpdateFromAvailableToNotCreated()
// {
// doTestInvalidStatusUpdate(PlateStatus.AVAILABLE, PlateStatus.NOT_CREATED);
// }
// public void testInvalidPlateStatusUpdateFromRetiredToNotSpecified()
// {
// doTestInvalidStatusUpdate(PlateStatus.RETIRED, PlateStatus.NOT_SPECIFIED);
// }
// public void testInvalidPlateStatusUpdateFromRetiredToNotCreated()
// {
// doTestInvalidStatusUpdate(PlateStatus.RETIRED, PlateStatus.NOT_CREATED);
// }
// public void testInvalidPlateStatusUpdateFromRetiredToNotAvailable()
// {
// doTestInvalidStatusUpdate(PlateStatus.RETIRED, PlateStatus.NOT_AVAILABLE);
// }
// public void testInvalidPlateStatusUpdateFromRetiredToAvailable()
// {
// doTestInvalidStatusUpdate(PlateStatus.RETIRED, PlateStatus.AVAILABLE);
// }
// public void testInvalidPlateStatusUpdateFromDiscardedToLost()
// {
// doTestInvalidStatusUpdate(PlateStatus.DISCARDED, PlateStatus.LOST);
// }
private void doTestInvalidStatusUpdate(final PlateStatus initialStatus, final PlateStatus invalidStatus)
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
Plate plate = _copyC.findPlate(1);
genericEntityDao.persistEntity(admin2);
plateUpdater.updatePlateStatus(plate, initialStatus, _admin, admin2, new LocalDate(2010, 1, 1));
plate = genericEntityDao.reloadEntity(_copyC.findPlate(1));
assertEquals(initialStatus, plate.getStatus());
try {
plateUpdater.updatePlateStatus(plate, invalidStatus, _admin, admin2, new LocalDate(2010, 1, 1));
fail("expected BusinessRuleViolationException");
}
catch (BusinessRuleViolationException e) {}
}
public void testPrimaryPlateStatus()
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
genericEntityDao.persistEntity(admin2);
plateUpdater.updatePlateStatus(_copyC.findPlate(1), PlateStatus.NOT_AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateStatus(_copyC.findPlate(2), PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateStatus(_copyC.findPlate(3), PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateStatus(_copyC.findPlate(4), PlateStatus.LOST, _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateStatus(_copyC.findPlate(5), PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateStatus(_copyC.findPlate(6), PlateStatus.NOT_CREATED, _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(PlateStatus.AVAILABLE, genericEntityDao.reloadEntity(_copyC).getPrimaryPlateStatus());
plateUpdater.updatePlateStatus(_copyC.findPlate(5), PlateStatus.LOST, _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals("primary plate status ties are broken by ordering of PlateStatus enum values",
PlateStatus.AVAILABLE, genericEntityDao.reloadEntity(_copyC).getPrimaryPlateStatus());
plateUpdater.updatePlateStatus(_copyC.findPlate(6), PlateStatus.LOST, _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(PlateStatus.LOST, genericEntityDao.reloadEntity(_copyC).getPrimaryPlateStatus());
}
public void testPrimaryPlateLocation()
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
genericEntityDao.persistEntity(admin2);
// set plates to a status that allows for a plate location
for (Plate plate : _copyC.getPlates().values()) {
plate.setStatus(PlateStatus.AVAILABLE);
}
plateUpdater.updatePlateLocation(_copyC.findPlate(1), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(2), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(3), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(4), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(5), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(6), new PlateLocation("R1", "F1", "S1", "B1"), _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(new PlateLocation("R1", "F1", "S1", "B1").toDisplayString(), genericEntityDao.reloadEntity(_copyC).getPrimaryPlateLocation().toDisplayString());
plateUpdater.updatePlateLocation(_copyC.findPlate(5), null, _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(new PlateLocation("R1", "F1", "S1", "B1").toDisplayString(), genericEntityDao.reloadEntity(_copyC).getPrimaryPlateLocation().toDisplayString());
plateUpdater.updatePlateLocation(_copyC.findPlate(2), new PlateLocation("R1", "F1", "S1", "B2"), _admin, admin2, new LocalDate(2010, 1, 1));
plateUpdater.updatePlateLocation(_copyC.findPlate(3), new PlateLocation("R1", "F1", "S1", "B2"), _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(new PlateLocation("R1", "F1", "S1", "B1").toDisplayString(), genericEntityDao.reloadEntity(_copyC).getPrimaryPlateLocation().toDisplayString());
plateUpdater.updatePlateLocation(_copyC.findPlate(4), new PlateLocation("R1", "F1", "S1", "B2"), _admin, admin2, new LocalDate(2010, 1, 1));
assertEquals(new PlateLocation("R1", "F1", "S1", "B2").toDisplayString(), genericEntityDao.reloadEntity(_copyC).getPrimaryPlateLocation().toDisplayString());
}
public void testPlatedDate()
{
final AdministratorUser admin2 = new AdministratorUser("Admin2", "User");
genericEntityDao.persistEntity(admin2);
Plate plate1 = _copyC.findPlate(1);
plateUpdater.updatePlateStatus(plate1, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 2, 2));
plate1 = genericEntityDao.reloadEntity(plate1, false, Plate.copy.to(Copy.library));
assertEquals(PlateStatus.AVAILABLE, plate1.getStatus());
assertEquals(new LocalDate(2010, 2, 2), plate1.getCopy().getDatePlated());
assertEquals(new LocalDate(2010, 2, 2), plate1.getCopy().getLibrary().getDateScreenable());
Plate plate2 = _copyC.findPlate(2);
plateUpdater.updatePlateStatus(plate2, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 3, 3));
plate2 = genericEntityDao.reloadEntity(plate2, false, Plate.copy.to(Copy.library));
assertEquals(PlateStatus.AVAILABLE, plate2.getStatus());
assertEquals(new LocalDate(2010, 3, 3), plate2.getCopy().getDatePlated());
assertEquals(new LocalDate(2010, 2, 2), plate2.getCopy().getLibrary().getDateScreenable());
Plate plate3 = _copyC.findPlate(3);
plateUpdater.updatePlateStatus(plate3, PlateStatus.AVAILABLE, _admin, admin2, new LocalDate(2010, 1, 1));
plate3 = genericEntityDao.reloadEntity(plate3, false, Plate.copy.to(Copy.library));
assertEquals(PlateStatus.AVAILABLE, plate3.getStatus());
assertEquals(new LocalDate(2010, 1, 1), plate3.getCopy().getDatePlated());
assertEquals(new LocalDate(2010, 1, 1), plate3.getCopy().getLibrary().getDateScreenable());
}
public void testPlateLocationUnspecifiedBin()
{
Map<Plate,PlateLocation> plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F1", "S1", PlateUpdater.NO_BIN));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F1", "S2", PlateUpdater.NO_BIN));
plateLocations.put(_copyC.findPlate(3), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyC.findPlate(4), new PlateLocation("R1", "F1", "S2", "B2"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(1),
_copyC.findPlate(3)),
"R1", "F1", "S1", null);
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(2),
_copyC.findPlate(4)),
"R1", "F1", "S2", null);
plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F1", "", "B1"));
assertIllegalUpdate(_admin, plateLocations, "bin name must be unique within a freezer");
}
// note that this method is not transactional, so each plate update is done within its own txn, but that's okay for testing purposes
private void updatePlateLocations(Map<Plate,PlateLocation> plateToNewLocation,
AdministratorUser recordedByAdmin,
AdministratorUser performedByAdmin,
LocalDate datePerformed)
{
boolean modified = false;
for (Map.Entry<Plate,PlateLocation> entry : plateToNewLocation.entrySet()) {
entry.getKey().setStatus(PlateStatus.AVAILABLE); // set to a status that allows for a plate location
modified |= plateUpdater.updatePlateLocation(entry.getKey(), entry.getValue(), recordedByAdmin, performedByAdmin, datePerformed);
}
plateUpdater.validateLocations();
}
public void testPlateLocationTransferActivityCreation()
{
AdministratorUser performedBy = new AdministratorUser("Admin2", "User");
genericEntityDao.persistEntity(performedBy);
Map<Plate,PlateLocation> plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F1", "S2", "B2"));
updatePlateLocations(plateLocations, _admin, performedBy, new LocalDate(2010, 1, 1));
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F2", "S1", "B1"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F2", "S2", "B2"));
updatePlateLocations(plateLocations, _admin, performedBy, new LocalDate(2010, 2, 2));
genericEntityDao.doInTransaction(new DAOTransaction() {
@Override
public void runTransaction()
{
Plate plate1 = genericEntityDao.reloadEntity(_copyC.findPlate(1));
AdministrativeActivity locationTransferActivity = plate1.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_LOCATION_TRANSFER);
assertEquals("Location changed from 'R1-F1-S1-B1' to 'R1-F2-S1-B1'",
locationTransferActivity.getComments());
Plate plate2 = genericEntityDao.reloadEntity(_copyC.findPlate(2));
locationTransferActivity = plate2.getLastUpdateActivityOfType(AdministrativeActivityType.PLATE_LOCATION_TRANSFER);
assertEquals("Location changed from 'R1-F1-S2-B2' to 'R1-F2-S2-B2'",
locationTransferActivity.getComments());
}
});
}
public void testPlateLocationUpdate()
{
Map<Plate,PlateLocation> plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyC.findPlate(3), new PlateLocation("R1", "F1", "S1", "B2"));
plateLocations.put(_copyC.findPlate(4), new PlateLocation("R1", "F1", "S1", "B2"));
plateLocations.put(_copyC.findPlate(5), new PlateLocation("R1", "F1", "S2", "B3"));
plateLocations.put(_copyC.findPlate(6), new PlateLocation("R1", "F1", "S2", "B3"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(1),
_copyC.findPlate(2),
_copyC.findPlate(3),
_copyC.findPlate(4),
_copyC.findPlate(5),
_copyC.findPlate(6)),
"R1", "F1", null, null);
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(1),
_copyC.findPlate(2),
_copyC.findPlate(3),
_copyC.findPlate(4)),
null, null, "S1", null);
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(5),
_copyC.findPlate(6)),
null, null, "S2", null);
assertPlatesInLocation(Sets.newHashSet(_copyC.findPlate(1)),
"R1", "F1", "S1", "B1");
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(1), new PlateLocation("R1", "F2", "S1", "B1"));
plateLocations.put(_copyD.findPlate(2), new PlateLocation("R1", "F2", "S1", "B1"));
plateLocations.put(_copyD.findPlate(3), new PlateLocation("R1", "F2", "S1", "B2"));
plateLocations.put(_copyD.findPlate(4), new PlateLocation("R1", "F2", "S1", "B2"));
plateLocations.put(_copyD.findPlate(5), new PlateLocation("R1", "F2", "S2", "B3"));
plateLocations.put(_copyD.findPlate(6), new PlateLocation("R1", "F2", "S2", "B3"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(1),
_copyD.findPlate(2),
_copyD.findPlate(3),
_copyD.findPlate(4),
_copyD.findPlate(5),
_copyD.findPlate(6)),
"R1", "F2", null, null);
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(1),
_copyD.findPlate(2),
_copyD.findPlate(3),
_copyD.findPlate(4)),
null, null, "S1", null);
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(5),
_copyD.findPlate(6)),
null, null, "S2", null);
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(1)),
"R1", "F2", "S1", "B1");
// move copyC to same freezer as copyD (F2)
plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F2", "S3", "B1"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F2", "S3", "B1"));
plateLocations.put(_copyC.findPlate(3), new PlateLocation("R1", "F2", "S3", "B2"));
plateLocations.put(_copyC.findPlate(4), new PlateLocation("R1", "F2", "S3", "B2"));
plateLocations.put(_copyC.findPlate(5), new PlateLocation("R1", "F2", "S4", "B3"));
plateLocations.put(_copyC.findPlate(6), new PlateLocation("R1", "F2", "S4", "B3"));
assertIllegalUpdate(_admin, plateLocations, "bin name must be unique within a freezer");
plateLocations = Maps.newHashMap();
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F2", "S3", "B4"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F2", "S3", "B4"));
plateLocations.put(_copyC.findPlate(3), new PlateLocation("R1", "F2", "S3", "B5"));
plateLocations.put(_copyC.findPlate(4), new PlateLocation("R1", "F2", "S3", "B5"));
plateLocations.put(_copyC.findPlate(5), new PlateLocation("R1", "F2", "S4", "B6"));
plateLocations.put(_copyC.findPlate(6), new PlateLocation("R1", "F2", "S4", "B6"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(Iterables.concat(_copyC.getPlates().values(),
_copyD.getPlates().values())),
"R1", "F2", null, null);
// move copyD to copyC's original freezer (F1)
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(1), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyD.findPlate(2), new PlateLocation("R1", "F1", "S1", "B1"));
plateLocations.put(_copyD.findPlate(3), new PlateLocation("R1", "F1", "S1", "B2"));
plateLocations.put(_copyD.findPlate(4), new PlateLocation("R1", "F1", "S1", "B2"));
plateLocations.put(_copyD.findPlate(5), new PlateLocation("R1", "F1", "S2", "B3"));
plateLocations.put(_copyD.findPlate(6), new PlateLocation("R1", "F1", "S2", "B3"));
// rename copyC bins back to 1...3
plateLocations.put(_copyC.findPlate(1), new PlateLocation("R1", "F2", "S1", "B1"));
plateLocations.put(_copyC.findPlate(2), new PlateLocation("R1", "F2", "S1", "B1"));
plateLocations.put(_copyC.findPlate(3), new PlateLocation("R1", "F2", "S1", "B2"));
plateLocations.put(_copyC.findPlate(4), new PlateLocation("R1", "F2", "S1", "B2"));
plateLocations.put(_copyC.findPlate(5), new PlateLocation("R1", "F2", "S2", "B3"));
plateLocations.put(_copyC.findPlate(6), new PlateLocation("R1", "F2", "S2", "B3"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyC.getPlates().values()), "R1", "F2", null, null);
assertPlatesInLocation(Sets.newHashSet(_copyD.getPlates().values()), "R1", "F1", null, null);
// move freezer F1 to room R2
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(1), new PlateLocation("R2", "F1", "S1", "B1"));
plateLocations.put(_copyD.findPlate(2), new PlateLocation("R2", "F1", "S1", "B1"));
plateLocations.put(_copyD.findPlate(3), new PlateLocation("R2", "F1", "S1", "B2"));
plateLocations.put(_copyD.findPlate(4), new PlateLocation("R2", "F1", "S1", "B2"));
plateLocations.put(_copyD.findPlate(5), new PlateLocation("R2", "F1", "S2", "B3"));
assertIllegalUpdate(_admin, plateLocations, "freezer name must be unique across all rooms");
plateLocations.put(_copyD.findPlate(6), new PlateLocation("R2", "F1", "S2", "B3"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyD.getPlates().values()), "R2", "F1", null, null);
// move copyD B1 to new freezer F3
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(1), new PlateLocation("R2", "F3", "S1", "B1"));
plateLocations.put(_copyD.findPlate(2), new PlateLocation("R2", "F3", "S1", "B1"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(1),
_copyD.findPlate(2)),
"R2", "F3", null, "B1");
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(3),
_copyD.findPlate(4),
_copyD.findPlate(5),
_copyD.findPlate(6)),
"R2", "F1", null, null);
// split copyD B1 into 2 bins, placing new bin on new shelf
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(2), new PlateLocation("R2", "F3", "S2", "B2"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(2)), "R2", "F3", "S2", "B2");
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(1), _copyD.findPlate(2)),
"R2", "F3", null, null);
// move copyD B3 to F1, S1, having all bins on same shelf in F1
plateLocations = Maps.newHashMap();
plateLocations.put(_copyD.findPlate(5), new PlateLocation("R2", "F1", "S1", "B3"));
plateLocations.put(_copyD.findPlate(6), new PlateLocation("R2", "F1", "S1", "B3"));
updatePlateLocations(plateLocations, _admin, _admin, new LocalDate());
assertPlatesInLocation(Sets.newHashSet(_copyD.findPlate(3),
_copyD.findPlate(4),
_copyD.findPlate(5),
_copyD.findPlate(6)),
"R2", "F1", "S1", null);
}
public void assertIllegalUpdate(AdministratorUser admin,
Map<Plate,PlateLocation> plateLocations,
String exceptionMessageSubstring)
{
try {
updatePlateLocations(plateLocations, admin, admin, new LocalDate());
fail("expected exception: " + exceptionMessageSubstring);
}
catch (BusinessRuleViolationException e) {
assertTrue(e.getMessage().contains(exceptionMessageSubstring));
}
}
private void assertPlatesInLocation(Set<Plate> plates, String room, String freezer, String shelf, String bin)
{
final HqlBuilder hql = new HqlBuilder();
hql.select("p");
hql.from(Plate.class, "p").from("p", Plate.location, "l", JoinType.INNER);
hql.whereIn("p", plates);
if (room != null) {
hql.where("l", "room", Operator.EQUAL, room);
}
if (freezer != null) {
hql.where("l", "freezer", Operator.EQUAL, freezer);
}
if (shelf != null) {
hql.where("l", "shelf", Operator.EQUAL, shelf);
}
if (bin != null) {
hql.where("l", "bin", Operator.EQUAL, bin);
}
Query<Plate> query = new Query<Plate>() {
@Override
public List<Plate> execute(Session session)
{
return hql.toQuery(session, true).list();
}
};
List<Plate> result = genericEntityDao.runQuery(query);
assertEquals("plates match location " + room + "-" + freezer + "-" + shelf + "-" + bin,
plates,
Sets.newHashSet(result));
}
}