/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright © 2013 VillageReach * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses. For additional information contact info@OpenLMIS.org. */ package org.openlmis.distribution.service; import lombok.NoArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.collections.Transformer; import org.openlmis.core.domain.Facility; import org.openlmis.core.domain.Refrigerator; import org.openlmis.core.exception.DataException; import org.openlmis.core.service.FacilityService; import org.openlmis.core.service.MessageService; import org.openlmis.core.service.RefrigeratorService; import org.openlmis.distribution.domain.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.apache.commons.collections.CollectionUtils.collect; import static org.apache.commons.collections.CollectionUtils.select; /** * Exposes the services for handling FacilityDistribution entity. */ @Service @NoArgsConstructor public class FacilityDistributionService { @Autowired private FacilityService facilityService; @Autowired private RefrigeratorService refrigeratorService; @Autowired private EpiUseService epiUseService; @Autowired private FacilityVisitService facilityVisitService; @Autowired private DistributionRefrigeratorsService distributionRefrigeratorsService; @Autowired private EpiInventoryService epiInventoryService; @Autowired private MessageService messageService; @Autowired private VaccinationCoverageService vaccinationCoverageService; public Map<Long, FacilityDistribution> createFor(Distribution distribution) { Long deliveryZoneId = distribution.getDeliveryZone().getId(); Long programId = distribution.getProgram().getId(); Map<Long, FacilityDistribution> facilityDistributions = new HashMap<>(); List<Facility> facilities = facilityService.getAllForDeliveryZoneAndProgram(deliveryZoneId, programId); if (facilities.size() == 0) { throw new DataException(messageService.message("message.no.facility.available", distribution.getProgram().getName(), distribution.getDeliveryZone().getName())); } List<Refrigerator> distributionRefrigerators = refrigeratorService.getRefrigeratorsForADeliveryZoneAndProgram(deliveryZoneId, programId); List<TargetGroupProduct> targetGroupProducts = vaccinationCoverageService.getVaccinationProducts(); List<TargetGroupProduct> childrenTargetGroupProducts = new ArrayList<>(); List<TargetGroupProduct> adultTargetGroupProducts = new ArrayList<>(); filterTargetGroupProducts(targetGroupProducts, childrenTargetGroupProducts, adultTargetGroupProducts); List<ProductVial> productVials = vaccinationCoverageService.getProductVials(); List<ProductVial> childProductVials = new ArrayList<>(); List<ProductVial> adultProductVials = new ArrayList<>(); filterProductVials(productVials, childProductVials, adultProductVials); for (Facility facility : facilities) { facilityDistributions.put(facility.getId(), createDistributionData(facility, distribution, distributionRefrigerators, childrenTargetGroupProducts, adultTargetGroupProducts, childProductVials, adultProductVials)); } return facilityDistributions; } private void filterProductVials(List<ProductVial> productVials, List<ProductVial> childProductVials, List<ProductVial> adultProductVials) { CollectionUtils.select(productVials, new Predicate() { @Override public boolean evaluate(Object o) { return ((ProductVial) o).getChildCoverage(); } }, childProductVials); CollectionUtils.selectRejected(productVials, new Predicate() { @Override public boolean evaluate(Object o) { return ((ProductVial) o).getChildCoverage(); } }, adultProductVials); } private void filterTargetGroupProducts(List<TargetGroupProduct> targetGroupProducts, List<TargetGroupProduct> childrenTargetGroupProducts, List<TargetGroupProduct> adultTargetGroupProducts) { CollectionUtils.select(targetGroupProducts, new Predicate() { @Override public boolean evaluate(Object o) { return ((TargetGroupProduct) o).getChildCoverage(); } }, childrenTargetGroupProducts); CollectionUtils.selectRejected(targetGroupProducts, new Predicate() { @Override public boolean evaluate(Object o) { return ((TargetGroupProduct) o).getChildCoverage(); } }, adultTargetGroupProducts); } FacilityDistribution createDistributionData(final Facility facility, Distribution distribution, List<Refrigerator> refrigerators, List<TargetGroupProduct> childrenTargetGroupProducts, List<TargetGroupProduct> adultTargetGroupProducts, List<ProductVial> childProductVials, List<ProductVial> adultProductVials) { List<RefrigeratorReading> refrigeratorReadings = getRefrigeratorReadings(facility.getId(), refrigerators); FacilityVisit facilityVisit = new FacilityVisit(facility, distribution); facilityVisitService.save(facilityVisit); FacilityDistribution facilityDistribution = new FacilityDistribution(facilityVisit, facility, distribution, refrigeratorReadings, childrenTargetGroupProducts, adultTargetGroupProducts, childProductVials, adultProductVials); epiUseService.save(facilityDistribution.getEpiUse()); epiInventoryService.save(facilityDistribution.getEpiInventory()); vaccinationCoverageService.saveChildCoverage(facilityDistribution.getChildCoverage()); vaccinationCoverageService.saveAdultCoverage(facilityDistribution.getAdultCoverage()); return facilityDistribution; } public FacilityDistribution save(FacilityDistribution facilityDistribution) { facilityVisitService.save(facilityDistribution.getFacilityVisit()); if (facilityDistribution.getFacilityVisit().getVisited()) { epiInventoryService.save(facilityDistribution.getEpiInventory()); distributionRefrigeratorsService.save(facilityDistribution.getFacilityVisit().getFacilityId(), facilityDistribution.getRefrigerators()); epiUseService.save(facilityDistribution.getEpiUse()); } vaccinationCoverageService.save(facilityDistribution); return facilityDistribution; } public FacilityDistribution setSynced(FacilityDistribution facilityDistribution) { facilityVisitService.setSynced(facilityDistribution.getFacilityVisit()); return facilityDistribution; } private List<RefrigeratorReading> getRefrigeratorReadings(final Long facilityId, List<Refrigerator> refrigerators) { return (List<RefrigeratorReading>) collect(select(refrigerators, new Predicate() { @Override public boolean evaluate(Object o) { return ((Refrigerator) o).getFacilityId().equals(facilityId); } }), new Transformer() { @Override public Object transform(Object o) { return new RefrigeratorReading((Refrigerator) o); } }); } public Map<Long, FacilityDistribution> get(Distribution distribution) { Map<Long, FacilityDistribution> facilityDistributions = new HashMap<>(); List<FacilityVisit> unSyncedFacilities = facilityVisitService.getUnSyncedFacilities(distribution.getId()); for (FacilityVisit facilityVisit : unSyncedFacilities) { facilityDistributions.put(facilityVisit.getFacilityId(), getDistributionData(facilityVisit, distribution)); } return facilityDistributions; } private FacilityDistribution getDistributionData(FacilityVisit facilityVisit, Distribution distribution) { EpiUse epiUse = epiUseService.getBy(facilityVisit.getId()); List<Refrigerator> refrigerators = refrigeratorService.getRefrigeratorsForADeliveryZoneAndProgram(distribution.getDeliveryZone().getId(), distribution.getProgram().getId()); DistributionRefrigerators distributionRefrigerators = new DistributionRefrigerators(getRefrigeratorReadings(facilityVisit.getFacilityId(), refrigerators)); Facility facility = facilityService.getById(facilityVisit.getFacilityId()); EpiInventory epiInventory = epiInventoryService.getBy(facilityVisit.getId()); VaccinationFullCoverage coverage = vaccinationCoverageService.getFullCoverageBy(facilityVisit.getId()); VaccinationChildCoverage childCoverage = vaccinationCoverageService.getChildCoverageBy(facilityVisit.getId()); VaccinationAdultCoverage adultCoverage = vaccinationCoverageService.getAdultCoverageBy(facilityVisit.getId()); FacilityDistribution facilityDistribution = new FacilityDistribution(facilityVisit, epiUse, distributionRefrigerators, epiInventory, coverage, childCoverage, adultCoverage); facilityDistribution.setFacility(facility); return facilityDistribution; } }