diff --git a/src/main/java/uk/ac/sanger/sccp/stan/service/label/LabwareLabelDataService.java b/src/main/java/uk/ac/sanger/sccp/stan/service/label/LabwareLabelDataService.java index df0b9580..d9b48704 100644 --- a/src/main/java/uk/ac/sanger/sccp/stan/service/label/LabwareLabelDataService.java +++ b/src/main/java/uk/ac/sanger/sccp/stan/service/label/LabwareLabelDataService.java @@ -9,6 +9,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.function.Predicate; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -38,6 +39,7 @@ public LabwareLabelData getLabelData(Labware labware) { List content = labware.getSlots().stream() .sorted(slotOrder) .flatMap(slot -> slot.getSamples().stream()) + .distinct() .map(this::getContent) .collect(toList()); Set mediums = labware.getSlots().stream() @@ -425,12 +427,22 @@ public String prefix(LifeStage lifeStage) { public List getPlannedContent(List planActions, Comparator slotOrder) { return planActions.stream() + .filter(distinctPlanSection()) .sorted(Comparator.comparing(PlanAction::getDestination, slotOrder) .thenComparing(PlanAction::getId)) .map(this::getContent) .collect(toList()); } + /** + * Creates a filter to dedupe new sections. Doesn't filter out non-sections. + * @return a predicate to filter out plan actions creating the same section + */ + static Predicate distinctPlanSection() { + final Set keys = new HashSet<>(); + return pa -> (nullOrEmpty(pa.getNewSection()) || keys.add(new PlanActionKey(pa))); + } + public LabelContent getContent(PlanAction planAction) { BioState bs = planAction.getNewBioState(); if (bs==null) { @@ -468,4 +480,11 @@ public SimpleContent(Sample sample) { this(sample.getTissue(), sample.getSection()); } } + + /** The characteristics to dedupe the new section that will be created from a plan action */ + record PlanActionKey(Sample parentSample, String section) { + public PlanActionKey(PlanAction pa) { + this(pa.getSample(), pa.getNewSection()); + } + } } diff --git a/src/test/java/uk/ac/sanger/sccp/stan/service/label/TestLabwareLabelDataService.java b/src/test/java/uk/ac/sanger/sccp/stan/service/label/TestLabwareLabelDataService.java index cbd0459b..a5f94b7d 100644 --- a/src/test/java/uk/ac/sanger/sccp/stan/service/label/TestLabwareLabelDataService.java +++ b/src/test/java/uk/ac/sanger/sccp/stan/service/label/TestLabwareLabelDataService.java @@ -575,6 +575,32 @@ static Stream getContentArgs() { }).map(Arguments::of); } + @Test + void testDistinctPlanSection() { + Sample[] samples = EntityFactory.makeSamples(2); + List pas = List.of( + makePlanAction(1, samples[0], null), + makePlanAction(2, samples[0], null), + makePlanAction(3, samples[1], null), + makePlanAction(4, samples[0], "1a"), + makePlanAction(5, samples[0], "1a"), // this one gets filtered out + makePlanAction(6, samples[1], "1a"), + makePlanAction(7, samples[1], "2b") + ); + assertThat(pas.stream() + .filter(LabwareLabelDataService.distinctPlanSection()) + .map(PlanAction::getId) + ).containsExactly(1, 2, 3, 4, 6, 7); + } + + static PlanAction makePlanAction(int id, Sample sam, String newSection) { + PlanAction pa = new PlanAction(); + pa.setId(id); + pa.setSample(sam); + pa.setNewSection(newSection); + return pa; + } + private String tissueString(Tissue tissue) { String prefix = switch (tissue.getDonor().getLifeStage()) { case paediatric -> "P";