/* * Copyright (C) 2014 GG-Net GmbH - Oliver Günther * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.ggnet.dwoss.price.imex; import eu.ggnet.dwoss.rules.TradeName; import java.io.Serializable; import java.util.*; import javax.ejb.Stateless; import javax.inject.Inject; import javax.persistence.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.ggnet.lucidcalc.LucidCalcReader; import eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader; import eu.ggnet.dwoss.progress.MonitorFactory; import eu.ggnet.dwoss.progress.SubMonitor; import eu.ggnet.dwoss.report.assist.Reports; import eu.ggnet.dwoss.report.eao.ReportLineEao; import eu.ggnet.dwoss.report.entity.ReportLine; import eu.ggnet.dwoss.rules.partno.PartNoSupport; import eu.ggnet.dwoss.uniqueunit.assist.UniqueUnits; import eu.ggnet.dwoss.uniqueunit.eao.ProductEao; import eu.ggnet.dwoss.uniqueunit.entity.PriceType; import eu.ggnet.dwoss.uniqueunit.entity.Product; import eu.ggnet.dwoss.util.FileJacket; import lombok.Value; import static eu.ggnet.dwoss.uniqueunit.entity.PriceType.CONTRACTOR_REFERENCE; /** * Importer implementation. * <p> * @author oliver.guenther */ @Stateless public class ContractorPricePartNoImporterOperation implements ContractorPricePartNoImporter { // Must be Public for JExcelReader @Value public static class ManufacturerImport implements Serializable { private final String partNo; private final Double costPrice; } // Must be Public for JExcelReader @Value public static class ContractorImport implements Serializable { private final String contractorPartNo; private final String manufacturerPartNo; private final String name1; private final String name2; private final Double referencePrice; } private final static Logger L = LoggerFactory.getLogger(ContractorPricePartNoImporterOperation.class); @Inject @Reports private EntityManager reportEm; @Inject @UniqueUnits private EntityManager uuEm; @Inject private MonitorFactory monitorFactory; @Override public ImportResult fromManufacturerXls(TradeName contractorManufacturer, FileJacket inFile, String arranger) { if ( !contractorManufacturer.isManufacturer() ) throw new RuntimeException(contractorManufacturer + " is not a Manufacturer"); final SubMonitor m = monitorFactory.newSubMonitor(contractorManufacturer.getName() + " Costpreise importieren", 100); m.start().message("Reading File"); ProductEao productEao = new ProductEao(uuEm); LucidCalcReader reader = new JExcelLucidCalcReader(); reader.addColumn(0, String.class).addColumn(1, Double.class); List<ManufacturerImport> imports = reader.read(inFile.toTemporaryFile(), ManufacturerImport.class); List<String> errors = reader.getErrors(); m.worked(5); m.setWorkRemaining(imports.size()); L.info("Imports: {}", imports); PartNoSupport partNoSupport = contractorManufacturer.getPartNoSupport(); int validSize = 0; int importedSize = 0; for (ManufacturerImport partNoPrice : imports) { m.worked(1); if ( partNoSupport != null && !partNoSupport.isValid(partNoPrice.partNo) ) { errors.add(partNoSupport.violationMessages(partNoPrice.partNo)); continue; } if ( partNoPrice.costPrice == null || partNoPrice.costPrice <= 0.01 ) { errors.add("PartNo " + partNoPrice.costPrice + " hat keinen Preis"); continue; } validSize++; m.message("Importing (" + partNoPrice.partNo + ")"); Product p = productEao.findByPartNo(partNoPrice.partNo); if ( p == null ) { errors.add("No UniqueUnit Entity for PartNo " + partNoPrice.partNo); continue; } p.setPrice(PriceType.MANUFACTURER_COST, partNoPrice.costPrice, arranger); importedSize++; } m.finish(); return new ImportResult(imports.size(), validSize, importedSize, importedSize, errors); } /** * See {@link ContractorPricePartNoImporter#fromContractorXls(de.dw.rules.TradeName, de.dw.util.FileJacket, java.lang.String) }. * <p/> * @param inFile the inFile * @param arranger the arranger * @return */ @Override public ImportResult fromContractorXls(TradeName contractor, FileJacket inFile, String arranger) { final SubMonitor m = monitorFactory.newSubMonitor(contractor + " Preise und Artikelnummern importieren", 100); m.start(); m.message("Reading File"); ProductEao productEao = new ProductEao(uuEm); ReportLineEao reportLineEao = new ReportLineEao(reportEm); LucidCalcReader reader = new JExcelLucidCalcReader(); reader.addColumn(0, String.class).addColumn(1, String.class).addColumn(2, String.class).addColumn(3, String.class).addColumn(4, Double.class); List<ContractorImport> imports = reader.read(inFile.toTemporaryFile(), ContractorImport.class); List<String> errors = reader.getErrors(); m.worked(5); m.setWorkRemaining(imports.size() + 100); int validSize = 0; int importAbleSize = 0; int importedSize = 0; PartNoSupport support = contractor.getPartNoSupport(); for (ContractorImport contractorImport : imports) { m.worked(1, "Importing (" + contractorImport.manufacturerPartNo + ")"); // HINT: It would be much better to validate the import class and put the validation there, but the support comes afterwards. String contractorPartNo = contractorImport.contractorPartNo; if ( support != null ) { contractorPartNo = support.normalize(contractorPartNo); if ( !support.isValid(contractorPartNo) ) { errors.add(support.violationMessages(contractorPartNo)); continue; } } if ( contractorImport.manufacturerPartNo == null ) { errors.add("ManufacturerPartNo is null of" + contractorImport); continue; } if ( contractorImport.referencePrice == null || contractorImport.referencePrice <= 0.01 ) { errors.add("PartNo " + contractorImport + " hat keinen Preis"); continue; } // Some validation of the manufacturer part no would also be nice. validSize++; Product p = productEao.findByPartNo(contractorImport.manufacturerPartNo); if ( p == null ) { errors.add("No UniqueUnit Entity for PartNo " + contractorImport.manufacturerPartNo + ", Ignoring"); continue; } importAbleSize++; if ( contractorPartNo.equals(p.getAdditionalPartNo(contractor)) && p.getPrice(PriceType.CONTRACTOR_REFERENCE) > 0 ) continue; importedSize++; p.setAdditionalPartNo(contractor, contractorPartNo); p.setPrice(CONTRACTOR_REFERENCE, contractorImport.referencePrice, "Import by " + arranger); } uuEm.flush(); // Also update existing report lines, which have unset values. List<ReportLine> missingContractorPartNo = reportLineEao.findMissingContractorPartNo(contractor); m.setWorkRemaining(missingContractorPartNo.size()); m.message("Updateing existing Reportlines"); for (ReportLine line : missingContractorPartNo) { Product product = uuEm.find(Product.class, line.getProductId()); m.worked(1, "Updating ReportLine:" + line.getId()); if ( product.getAdditionalPartNo(contractor) != null ) line.setContractorPartNo(product.getAdditionalPartNo(contractor)); if ( product.getPrice(CONTRACTOR_REFERENCE) > 0.01 ) line.setContractorReferencePrice(product.getPrice(CONTRACTOR_REFERENCE)); } m.finish(); return new ImportResult(imports.size(), validSize, importAbleSize, importedSize, errors); } }