/* * 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.core.service; import com.google.common.base.Predicate; import lombok.NoArgsConstructor; import org.openlmis.core.domain.*; import org.openlmis.core.exception.DataException; import org.openlmis.core.repository.FacilityRepository; import org.openlmis.core.repository.ProgramProductRepository; import org.openlmis.core.repository.ProgramRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.List; import static com.google.common.collect.Iterables.all; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Lists.newArrayList; import static org.apache.commons.lang3.StringUtils.trimToEmpty; import static org.apache.commons.lang3.StringUtils.trimToNull; /** * Exposes the services for handling ProgramProduct entity. */ @Component @NoArgsConstructor public class ProgramProductService { @Autowired private ProgramProductRepository programProductRepository; @Autowired private ProgramService programService; @Autowired private ProductService productService; @Autowired private ProgramRepository programRepository; @Autowired private FacilityRepository facilityRepository; @Autowired private ProductCategoryService categoryService; @Autowired private FacilityApprovedProductService facilityApprovedProductService; public Long getIdByProgramIdAndProductId(Long programId, Long productId) { return programProductRepository.getIdByProgramIdAndProductId(programId, productId); } public void updateProgramProductPrice(ProgramProductPrice programProductPrice) { programProductPrice.validate(); ProgramProduct programProduct = programProductPrice.getProgramProduct(); ProgramProduct programProductWithId = programProductRepository.getByProgramAndProductCode(programProduct); if (programProductWithId == null) throw new DataException("programProduct.product.program.invalid"); programProduct.setId(programProductWithId.getId()); programProduct.setModifiedBy(programProductPrice.getModifiedBy()); programProduct.setModifiedDate(programProductPrice.getModifiedDate()); programProductRepository.updateCurrentPrice(programProduct); programProductRepository.updatePriceHistory(programProductPrice); } public void save(ProgramProduct programProduct) { validateAndSetProductCategory(programProduct); if (programProduct.getId() == null) { boolean globalProductStatus = productService.isActive(programProduct.getProduct().getCode()); if (globalProductStatus && programProduct.getActive()) programService.setFeedSendFlag(programProduct.getProgram(), true); } else { ProgramProduct existingProgramProduct = programProductRepository.getById(programProduct.getId()); if (existingProgramProduct.getProduct().getActive() && (existingProgramProduct.getActive() != programProduct.getActive())) { programService.setFeedSendFlag(programProduct.getProgram(), true); } } programProductRepository.save(programProduct); } public void saveAndLogPriceChange(ProgramProduct programProduct){ ProgramProduct existingProgramProduct = null; if (programProduct.getId() != null) { existingProgramProduct = programProductRepository.getById(programProduct.getId()); } save(programProduct); if( ( existingProgramProduct == null && programProduct.getActive() ) || (existingProgramProduct != null && programProduct.getCurrentPrice().compareTo( existingProgramProduct.getCurrentPrice()) != 0)){ programProductRepository.save(programProduct); // now log the price change if it has to be logged. logPriceChange(programProduct); } } private void logPriceChange(ProgramProduct programProduct) { ProgramProductPrice priceChange = new ProgramProductPrice(); priceChange.setProgramProduct( programProduct ); priceChange.setPricePerDosage( programProduct.getCurrentPrice() ); this.updateProgramProductPrice( priceChange ); } public ProgramProduct getByProgramAndProductCode(ProgramProduct programProduct) { return programProductRepository.getByProgramAndProductCode(programProduct); } public ProgramProductPrice getProgramProductPrice(ProgramProduct programProduct) { populateProgramProductIds(programProduct); return programProductRepository.getProgramProductPrice(programProduct); } private void populateProgramProductIds(ProgramProduct programProduct) { Long programId = programService.getIdForCode(programProduct.getProgram().getCode()); Long productId = productService.getIdForCode(programProduct.getProduct().getCode()); programProduct.setId(programProductRepository.getIdByProgramIdAndProductId(programId, productId)); } public List<ProgramProduct> getByProgram(Program program) { return programProductRepository.getByProgram(program); } public List<ProgramProduct> getByProductCode(String productCode) { return programProductRepository.getByProductCode(productCode); } public List<ProgramProduct> getProgramProductsBy(String programCode, String facilityTypeCode) { FacilityType facilityType = new FacilityType(); if ((facilityTypeCode = trimToNull(facilityTypeCode)) != null) { facilityType = facilityRepository.getFacilityTypeByCode(new FacilityType(facilityTypeCode)); } return programProductRepository.getProgramProductsBy(programRepository.getIdByCode(trimToEmpty(programCode)), facilityType.getCode()); } public List<ProgramProduct> getNonFullSupplyProductsForProgram(Program program) { return programProductRepository.getNonFullSupplyProductsForProgram(program); } private void validateAndSetProductCategory(ProgramProduct programProduct) { ProductCategory category = programProduct.getProductCategory(); if (category == null) return; String categoryCode = category.getCode(); if (categoryCode == null || categoryCode.isEmpty()) return; Long categoryId = categoryService.getProductCategoryIdByCode(category.getCode()); if (categoryId == null) { throw new DataException("error.reference.data.invalid.product"); } category.setId(categoryId); } public List<ProgramProduct> getActiveByProgram(Long programId) { return programProductRepository.getActiveByProgram(programId); } public ProgramProduct getByProgramAndProductId(Long programId, Long productId) { return programProductRepository.getByProgramAndProductId(programId, productId); } public List<ProgramProduct> search(String searchParam, Pagination pagination, String column) { if (column.equalsIgnoreCase("Program")) { return programProductRepository.searchByProgram(searchParam, pagination); } return programProductRepository.searchByProduct(searchParam, pagination); } public List<ProgramProduct> getUnapprovedProgramProducts(Long facilityTypeId, Long programId) { final List<ProgramProduct> allProgramProducts = getByProgram(new Program(programId)); final List<FacilityTypeApprovedProduct> approvedProducts = facilityApprovedProductService.getAllBy(facilityTypeId, programId, "", new Pagination()); Iterable<ProgramProduct> programProducts = filter(allProgramProducts, new Predicate<ProgramProduct>() { @Override public boolean apply(ProgramProduct programProduct) { return isApproved(programProduct, approvedProducts); } }); return newArrayList(programProducts); } private boolean isApproved(final ProgramProduct programProduct, List<FacilityTypeApprovedProduct> approvedProducts) { return all(approvedProducts, new Predicate<FacilityTypeApprovedProduct>() { @Override public boolean apply(final FacilityTypeApprovedProduct approvedProduct) { return !programProduct.getId().equals( approvedProduct.getProgramProduct().getId()); } }); } public Integer getTotalSearchResultCount(String searchParam, String column) { if (column.equalsIgnoreCase("Program")) { return programProductRepository.getTotalSearchResultCount(searchParam); } return productService.getTotalSearchResultCount(searchParam); } @Transactional public void saveAll(List<ProgramProduct> programProducts, Product product) { for (ProgramProduct programProduct : programProducts) { programProduct.setProduct(product); programProduct.setCreatedBy(product.getCreatedBy()); programProduct.setModifiedBy(product.getModifiedBy()); save(programProduct); } } public void insertISA(ProgramProductISA isa) { programProductRepository.insertISA(isa); } public void updateISA(ProgramProductISA isa) { programProductRepository.updateISA(isa); } }