Search in sources :

Example 6 with Boxable

use of uk.ac.bbsrc.tgac.miso.core.data.Boxable in project miso-lims by miso-lims.

the class DefaultBoxService method updateBoxableLocation.

@Override
public void updateBoxableLocation(Boxable boxable) throws IOException {
    BoxableId boxableId = new BoxableId(boxable.getEntityType(), boxable.getId());
    Boxable managedOriginal = boxStore.getBoxable(boxableId);
    if (boxable.getBox() == null && managedOriginal.getBox() == null) {
        return;
    }
    if ((boxable.getBox() != null && managedOriginal.getBox() != null && boxable.getBox().getId() == managedOriginal.getBox().getId() && boxable.getBoxPosition().equals(managedOriginal.getBoxPosition()))) {
        // Note: for new items, boxable.box.boxPosition[boxable.boxPosition] may not match boxable.boxPosition because it doesn't (and we
        // don't want it to) cascade update. boxable.boxPosition stays as it is because Hibernate won't overwrite the changes you've made to
        // the object with the current session. boxable.box should be a refreshed object with the correct, persisted boxPositions though.
        BoxPosition temp = managedOriginal.getBox().getBoxPositions().get(managedOriginal.getBoxPosition());
        if (temp != null && temp.getBoxableId().equals(boxableId)) {
            return;
        }
    }
    if (managedOriginal.getBox() != null) {
        Box box = get(managedOriginal.getBox().getId());
        box.getBoxPositions().remove(managedOriginal.getBoxPosition());
        addBoxContentsChangeLog(managedOriginal.getBox(), String.format("Removed %s (%s) from %s", managedOriginal.getAlias(), managedOriginal.getName(), managedOriginal.getBoxPosition()));
        box.setChangeDetails(authorizationManager.getCurrentUser());
        boxStore.save(box);
    }
    if (boxable.getBox() != null) {
        Box managedNew = boxStore.get(boxable.getBox().getId());
        addBoxContentsChangeLog(managedNew, String.format("Added %s (%s) to %s", boxable.getAlias(), boxable.getName(), boxable.getBoxPosition()));
        managedNew.getBoxPositions().put(boxable.getBoxPosition(), new BoxPosition(managedNew, boxable.getBoxPosition(), boxable.getEntityType(), boxable.getId()));
        managedNew.setChangeDetails(authorizationManager.getCurrentUser());
        boxStore.save(managedNew);
    }
}
Also used : BoxableId(uk.ac.bbsrc.tgac.miso.core.data.BoxableId) Boxable(uk.ac.bbsrc.tgac.miso.core.data.Boxable) Box(uk.ac.bbsrc.tgac.miso.core.data.Box) BoxPosition(uk.ac.bbsrc.tgac.miso.core.data.BoxPosition)

Example 7 with Boxable

use of uk.ac.bbsrc.tgac.miso.core.data.Boxable in project miso-lims by miso-lims.

the class DefaultBoxService method update.

@Override
public long update(Box box) throws IOException {
    box.setChangeDetails(authorizationManager.getCurrentUser());
    if (box.getStorageLocation() != null) {
        box.setStorageLocation(storageLocationService.get(box.getStorageLocation().getId()));
    } else {
        box.setStorageLocation(null);
    }
    loadChildEntities(box);
    Box managed = boxStore.get(box.getId());
    logStorageChange(box, managed);
    validateChange(box, managed);
    applyChanges(box, managed);
    StringBuilder message = new StringBuilder();
    // get persisted version of new box contents before change
    List<BoxableId> ids = box.getBoxPositions().values().stream().map(BoxPosition::getBoxableId).collect(Collectors.toList());
    Map<BoxableId, BoxableView> oldOccupants = boxStore.getBoxableViewsByIdList(ids).stream().collect(Collectors.toMap(view -> new BoxableId(view.getEntityType(), view.getId()), Functions.identity()));
    // Process additions/moves
    Set<BoxPosition> movedWithinBox = Sets.newHashSet();
    List<BoxableView> movedFromOtherBoxes = new ArrayList<>();
    for (Map.Entry<String, BoxPosition> entry : box.getBoxPositions().entrySet()) {
        BoxPosition managedPos = managed.getBoxPositions().get(entry.getKey());
        BoxPosition newPos = entry.getValue();
        if (managedPos != null && newPos.getBoxableId().equals(managedPos.getBoxableId())) {
            // Unchanged
            continue;
        }
        if (message.length() > 0) {
            message.append("\n");
        }
        BoxableView oldOccupant = oldOccupants.get(newPos.getBoxableId());
        if (oldOccupant.getBoxId() != null) {
            if (oldOccupant.getBoxId().longValue() == box.getId()) {
                // Moved within same box
                message.append(String.format("Relocated %s (%s) from %s to %s", oldOccupant.getAlias(), oldOccupant.getName(), oldOccupant.getBoxPosition(), entry.getKey()));
                movedWithinBox.add(newPos);
            } else {
                // Moved from a different box
                Box oldBox = get(oldOccupant.getBoxId());
                addBoxContentsChangeLog(oldBox, String.format("Removed %s (%s) from %s to %s (%s)", oldOccupant.getAlias(), oldOccupant.getName(), oldOccupant.getBoxPosition(), managed.getAlias(), managed.getName()));
                message.append(String.format("Moved %s (%s) from %s (%s) to %s", oldOccupant.getAlias(), oldOccupant.getName(), oldOccupant.getBoxAlias(), oldOccupant.getBoxName(), entry.getKey()));
                movedFromOtherBoxes.add(oldOccupant);
            }
        } else {
            message.append(String.format("Added %s (%s) to %s", oldOccupant.getAlias(), oldOccupant.getName(), entry.getKey()));
        }
    }
    // Process removals
    List<BoxableId> removedIds = new ArrayList<>();
    List<BoxableId> movedWithinBoxIds = movedWithinBox.stream().map(BoxPosition::getBoxableId).collect(Collectors.toList());
    for (Map.Entry<String, BoxPosition> entry : managed.getBoxPositions().entrySet()) {
        if (box.getBoxPositions().keySet().contains(entry.getKey()) && box.getBoxPositions().get(entry.getKey()).getBoxableId().equals(entry.getValue().getBoxableId())) {
            // Already handled. Only checking for removals at this point
            continue;
        }
        removedIds.add(entry.getValue().getBoxableId());
    }
    List<BoxableView> removed = boxStore.getBoxableViewsByIdList(removedIds);
    for (BoxableView v : removed) {
        if (!movedWithinBoxIds.contains(new BoxableId(v.getEntityType(), v.getId()))) {
            if (message.length() > 0) {
                message.append("\n");
            }
            message.append(String.format("Removed %s (%s) from %s", v.getAlias(), v.getName(), v.getBoxPosition()));
        }
    }
    for (BoxableView v : movedFromOtherBoxes) {
        boxStore.removeBoxableFromBox(v);
    }
    movedWithinBox.forEach(bp -> managed.getBoxPositions().remove(bp.getPosition()));
    removed.forEach(boxable -> managed.getBoxPositions().remove(boxable.getBoxPosition()));
    if (!movedWithinBox.isEmpty() || !removed.isEmpty()) {
        boxStore.save(managed);
    }
    for (String pos : box.getBoxPositions().keySet()) {
        if (!managed.getBoxPositions().containsKey(pos) || !managed.getBoxPositions().get(pos).getBoxableId().equals(box.getBoxPositions().get(pos).getBoxableId())) {
            managed.getBoxPositions().put(pos, new BoxPosition(managed, pos, box.getBoxPositions().get(pos).getBoxableId()));
        }
    }
    if (message.length() > 0) {
        addBoxContentsChangeLog(managed, message.toString());
    }
    managed.setChangeDetails(authorizationManager.getCurrentUser());
    return boxStore.save(managed);
}
Also used : BoxChangeLog(uk.ac.bbsrc.tgac.miso.core.data.impl.changelog.BoxChangeLog) AuthorizationManager(uk.ac.bbsrc.tgac.miso.core.security.AuthorizationManager) BoxSizeService(uk.ac.bbsrc.tgac.miso.core.service.BoxSizeService) PaginationFilter(uk.ac.bbsrc.tgac.miso.core.util.PaginationFilter) Date(java.util.Date) BoxableId(uk.ac.bbsrc.tgac.miso.core.data.BoxableId) Autowired(org.springframework.beans.factory.annotation.Autowired) MisoNamingException(uk.ac.bbsrc.tgac.miso.core.exception.MisoNamingException) ArrayList(java.util.ArrayList) Value(org.springframework.beans.factory.annotation.Value) ChangeLog(uk.ac.bbsrc.tgac.miso.core.data.ChangeLog) Service(org.springframework.stereotype.Service) Box(uk.ac.bbsrc.tgac.miso.core.data.Box) LocationUnit(uk.ac.bbsrc.tgac.miso.core.data.impl.StorageLocation.LocationUnit) LimsUtils(uk.ac.bbsrc.tgac.miso.core.util.LimsUtils) Map(java.util.Map) NamingScheme(uk.ac.bbsrc.tgac.miso.core.service.naming.NamingScheme) NamingSchemeHolder(uk.ac.bbsrc.tgac.miso.core.service.naming.NamingSchemeHolder) BoxStore(uk.ac.bbsrc.tgac.miso.persistence.BoxStore) ValidationError(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationError) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) Functions(com.google.common.base.Functions) BoxStorageAmount(uk.ac.bbsrc.tgac.miso.core.data.impl.StorageLocation.BoxStorageAmount) StorageLocationService(uk.ac.bbsrc.tgac.miso.core.service.StorageLocationService) Collection(java.util.Collection) Set(java.util.Set) DeletionStore(uk.ac.bbsrc.tgac.miso.core.store.DeletionStore) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) BoxableView(uk.ac.bbsrc.tgac.miso.core.data.impl.view.box.BoxableView) BoxService(uk.ac.bbsrc.tgac.miso.core.service.BoxService) Sets(com.google.common.collect.Sets) Consumer(java.util.function.Consumer) BoxPosition(uk.ac.bbsrc.tgac.miso.core.data.BoxPosition) List(java.util.List) Boxable(uk.ac.bbsrc.tgac.miso.core.data.Boxable) ValidationUtils(uk.ac.bbsrc.tgac.miso.service.impl.ValidationUtils) TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) ChangeLogService(uk.ac.bbsrc.tgac.miso.core.service.ChangeLogService) BoxUseService(uk.ac.bbsrc.tgac.miso.core.service.BoxUseService) PaginatedDataSource(uk.ac.bbsrc.tgac.miso.core.util.PaginatedDataSource) StorageLocation(uk.ac.bbsrc.tgac.miso.core.data.impl.StorageLocation) Transactional(org.springframework.transaction.annotation.Transactional) BarcodableReferenceService(uk.ac.bbsrc.tgac.miso.core.service.BarcodableReferenceService) ArrayList(java.util.ArrayList) Box(uk.ac.bbsrc.tgac.miso.core.data.Box) BoxableId(uk.ac.bbsrc.tgac.miso.core.data.BoxableId) BoxableView(uk.ac.bbsrc.tgac.miso.core.data.impl.view.box.BoxableView) BoxPosition(uk.ac.bbsrc.tgac.miso.core.data.BoxPosition) Map(java.util.Map)

Example 8 with Boxable

use of uk.ac.bbsrc.tgac.miso.core.data.Boxable in project miso-lims by miso-lims.

the class DefaultTransferService method validateItems.

private <T extends Boxable, U extends TransferItem<T>> void validateItems(Transfer transfer, Transfer beforeChange, Function<Transfer, Set<U>> getItems, List<ValidationError> errors) throws IOException {
    Set<U> items = getItems.apply(transfer);
    Set<U> beforeChangeItems = beforeChange == null ? null : getItems.apply(beforeChange);
    if (items.stream().anyMatch(item -> Boolean.FALSE.equals(item.isQcPassed()) && LimsUtils.isStringEmptyOrNull(item.getQcNote()))) {
        errors.add(new ValidationError("items", ERROR_QC_NOTE_REQUIRED));
    }
    if (beforeChange != null && !authorizationManager.isAdminUser() && transfer.getSenderGroup() != null && !authorizationManager.isGroupMember(transfer.getSenderGroup()) && (items.size() != beforeChangeItems.size() || items.stream().anyMatch(item -> beforeChangeItems.stream().noneMatch(beforeItem -> beforeItem.getItem().getId() == item.getItem().getId())))) {
        errors.add(new ValidationError("items", ERROR_UNAUTHORIZED_ITEM_MODIFY));
    }
    if (!authorizationManager.isAdminUser()) {
        if (beforeChange == null) {
            if (transfer.getRecipientGroup() != null && !authorizationManager.isGroupMember(transfer.getRecipientGroup())) {
                if (items.stream().anyMatch(item -> item.isQcPassed() != null || item.getQcNote() != null)) {
                    errors.add(new ValidationError("items", ERROR_UNAUTHORIZED_QC));
                }
                if (items.stream().anyMatch(item -> item.isReceived() != null)) {
                    errors.add(new ValidationError("items", ERROR_UNAUTHORIZED_RECEIPT));
                }
            }
        } else {
            if (!authorizationManager.isGroupMember(transfer.getRecipientGroup()) && items.stream().anyMatch(item -> {
                U beforeChangeItem = beforeChangeItems.stream().filter(before -> before.getItem().getId() == item.getItem().getId()).findFirst().orElse(null);
                return beforeChangeItem != null && isChanged(item, beforeChangeItem);
            })) {
                errors.add(new ValidationError("items", "Only administrators and members of the recipient group can mark receipt and QC results"));
            }
        }
    }
    if (transfer.isDistribution() && items.stream().anyMatch(item -> !Boolean.TRUE.equals(item.isReceived()))) {
        errors.add(new ValidationError("items", ERROR_DISTRIBUTION_NOT_RECEIVED));
    }
    if (transfer.getSenderLab() != null) {
        if (items.stream().map(TransferItem::getItem).anyMatch(item -> item.getTransferViews().stream().anyMatch(itemTransfer -> itemTransfer.isReceipt() && (!transfer.isSaved() || itemTransfer.getId() != transfer.getId())))) {
            errors.add(new ValidationError("items", ERROR_MULTIPLE_RECEIPT));
        }
    } else if (transfer.getRecipient() != null && items.stream().map(TransferItem::getItem).anyMatch(item -> item.getTransferViews().stream().anyMatch(itemTransfer -> itemTransfer.isDistribution() && (!transfer.isSaved() || itemTransfer.getId() != transfer.getId())))) {
        errors.add(new ValidationError("items", ERROR_MULTIPLE_DISTRIBUTION));
    }
}
Also used : Date(java.util.Date) Autowired(org.springframework.beans.factory.annotation.Autowired) AbstractBoxPosition(uk.ac.bbsrc.tgac.miso.core.data.AbstractBoxPosition) GroupService(uk.ac.bbsrc.tgac.miso.core.service.GroupService) BigDecimal(java.math.BigDecimal) Project(uk.ac.bbsrc.tgac.miso.core.data.Project) Sample(uk.ac.bbsrc.tgac.miso.core.data.Sample) Box(uk.ac.bbsrc.tgac.miso.core.data.Box) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) SampleService(uk.ac.bbsrc.tgac.miso.core.service.SampleService) TransferNotification(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferNotification) Set(java.util.Set) DeletionStore(uk.ac.bbsrc.tgac.miso.core.store.DeletionStore) Objects(java.util.Objects) List(java.util.List) TransferPool(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferPool) Boxable(uk.ac.bbsrc.tgac.miso.core.data.Boxable) PoolService(uk.ac.bbsrc.tgac.miso.core.service.PoolService) ChangeLogService(uk.ac.bbsrc.tgac.miso.core.service.ChangeLogService) TransferLibrary(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferLibrary) AbstractSaveService(uk.ac.bbsrc.tgac.miso.service.AbstractSaveService) SaveDao(uk.ac.bbsrc.tgac.miso.persistence.SaveDao) TransferChangeLog(uk.ac.bbsrc.tgac.miso.core.data.impl.changelog.TransferChangeLog) TransferItem(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferItem) User(com.eaglegenomics.simlims.core.User) AuthorizationManager(uk.ac.bbsrc.tgac.miso.core.security.AuthorizationManager) TransferNotificationService(uk.ac.bbsrc.tgac.miso.core.service.TransferNotificationService) TransferService(uk.ac.bbsrc.tgac.miso.core.service.TransferService) ProviderService(uk.ac.bbsrc.tgac.miso.core.service.ProviderService) Function(java.util.function.Function) Supplier(java.util.function.Supplier) LibraryAliquotService(uk.ac.bbsrc.tgac.miso.core.service.LibraryAliquotService) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Lab(uk.ac.bbsrc.tgac.miso.core.data.Lab) LibraryAliquot(uk.ac.bbsrc.tgac.miso.core.data.impl.LibraryAliquot) LibraryAliquotBoxPosition(uk.ac.bbsrc.tgac.miso.core.data.impl.boxposition.LibraryAliquotBoxPosition) LabService(uk.ac.bbsrc.tgac.miso.core.service.LabService) Service(org.springframework.stereotype.Service) Group(com.eaglegenomics.simlims.core.Group) LimsUtils(uk.ac.bbsrc.tgac.miso.core.util.LimsUtils) BiConsumer(java.util.function.BiConsumer) Library(uk.ac.bbsrc.tgac.miso.core.data.Library) ValidationError(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationError) PoolBoxPosition(uk.ac.bbsrc.tgac.miso.core.data.impl.boxposition.PoolBoxPosition) SampleBoxPosition(uk.ac.bbsrc.tgac.miso.core.data.impl.boxposition.SampleBoxPosition) Iterator(java.util.Iterator) LibraryService(uk.ac.bbsrc.tgac.miso.core.service.LibraryService) IOException(java.io.IOException) BoxService(uk.ac.bbsrc.tgac.miso.core.service.BoxService) Consumer(java.util.function.Consumer) TransferLibraryAliquot(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferLibraryAliquot) LibraryBoxPosition(uk.ac.bbsrc.tgac.miso.core.data.impl.boxposition.LibraryBoxPosition) TransferStore(uk.ac.bbsrc.tgac.miso.persistence.TransferStore) Transfer(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.Transfer) TransferSample(uk.ac.bbsrc.tgac.miso.core.data.impl.transfer.TransferSample) Transactional(org.springframework.transaction.annotation.Transactional) Pool(uk.ac.bbsrc.tgac.miso.core.data.Pool) ValidationError(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationError)

Aggregations

Boxable (uk.ac.bbsrc.tgac.miso.core.data.Boxable)8 Box (uk.ac.bbsrc.tgac.miso.core.data.Box)4 BoxableId (uk.ac.bbsrc.tgac.miso.core.data.BoxableId)4 IOException (java.io.IOException)3 BoxPosition (uk.ac.bbsrc.tgac.miso.core.data.BoxPosition)3 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2 List (java.util.List)2 Set (java.util.Set)2 Consumer (java.util.function.Consumer)2 Test (org.junit.Test)2 Autowired (org.springframework.beans.factory.annotation.Autowired)2 Service (org.springframework.stereotype.Service)2 Transactional (org.springframework.transaction.annotation.Transactional)2 AbstractDAOTest (uk.ac.bbsrc.tgac.miso.AbstractDAOTest)2 AuthorizationManager (uk.ac.bbsrc.tgac.miso.core.security.AuthorizationManager)2 BoxService (uk.ac.bbsrc.tgac.miso.core.service.BoxService)2 ChangeLogService (uk.ac.bbsrc.tgac.miso.core.service.ChangeLogService)2 ValidationError (uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationError)2 ValidationException (uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException)2