Search in sources :

Example 36 with Product

use of eu.ggnet.dwoss.uniqueunit.ee.entity.Product in project dwoss by gg-net.

the class PriceCoreOperationIT method testStore.

@Test
public void testStore() {
    stockGenerator.makeStocksAndLocations(2);
    receiptGenerator.makeUniqueUnits(20, true, false);
    // Estimate all Units
    List<PriceEngineResult> pers = priceCore.loadAndCalculate(null);
    final double fixedUnitPrice = 100;
    final double fixedProductPrice = 50;
    String fixedPriceRefurbishId = pers.get(0).getRefurbishedId();
    pers.get(0).setCustomerPrice(100);
    pers.get(0).setRetailerPrice(100);
    pers.get(0).setUnitPriceFixed(PriceEngineResult.Change.SET);
    String fixedPartNo = pers.get(3).getManufacturerPartNo();
    pers.get(3).setCustomerPrice(50);
    pers.get(3).setRetailerPrice(50);
    pers.get(3).setManufacturerPartPriceFixed(PriceEngineResult.Change.SET);
    priceCore.store(pers, "via test", "testuser", null);
    UniqueUnit uniqueUnit = uniqueUnitAgent.findUnitByIdentifierEager(Identifier.REFURBISHED_ID, fixedPriceRefurbishId);
    assertEquals(fixedUnitPrice, uniqueUnit.getPrice(PriceType.CUSTOMER), 0.001);
    assertEquals(fixedUnitPrice, uniqueUnit.getPrice(PriceType.RETAILER), 0.001);
    assertTrue("Unit should contain Flage PriceFixed" + uniqueUnit.getFlags(), uniqueUnit.getFlags().contains(UniqueUnit.Flag.PRICE_FIXED));
    for (PriceHistory priceHistory : uniqueUnit.getPriceHistory()) {
        assertTrue(priceHistory.getComment().contains("unitfix"));
        assertEquals(fixedUnitPrice, priceHistory.getPrice(), 0.001);
        assertTrue(priceHistory.getType() == PriceType.CUSTOMER || priceHistory.getType() == PriceType.RETAILER);
    }
    Product product = uniqueUnitAgent.findProductByPartNoEager(fixedPartNo);
    assertEquals(fixedProductPrice, product.getPrice(PriceType.CUSTOMER), 0.001);
    assertEquals(fixedProductPrice, product.getPrice(PriceType.RETAILER), 0.001);
    assertTrue(product.getFlags().contains(Product.Flag.PRICE_FIXED));
    for (PriceHistory priceHistory : product.getPriceHistory()) {
        assertTrue(priceHistory.getComment().contains("productfix"));
        assertEquals(fixedProductPrice, priceHistory.getPrice(), 0.001);
        assertTrue(priceHistory.getType() == PriceType.CUSTOMER || priceHistory.getType() == PriceType.RETAILER);
    }
}
Also used : UniqueUnit(eu.ggnet.dwoss.uniqueunit.ee.entity.UniqueUnit) PriceEngineResult(eu.ggnet.dwoss.price.engine.PriceEngineResult) Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product) PriceHistory(eu.ggnet.dwoss.uniqueunit.ee.entity.PriceHistory) Test(org.junit.Test)

Example 37 with Product

use of eu.ggnet.dwoss.uniqueunit.ee.entity.Product in project dwoss by gg-net.

the class ReceiptGeneratorOperation method makeUniqueUnits.

/**
 * Generates an amount of UniquUnits and receipts them.
 *
 * @param amount               the amount to generate.
 * @param generateSalesChannel
 * @param generatePrice        if true a random customer and retailer price is set
 * @return the generated and receipted UniquUnits.
 */
// TODO: Create more Shipments on multiple contractors.
public List<UniqueUnit> makeUniqueUnits(int amount, boolean generateSalesChannel, boolean generatePrice) {
    final int minProducts = 5;
    final int maxProducts = 450;
    int amountProducts = (amount / 25);
    if (amountProducts <= minProducts)
        amountProducts = minProducts;
    if (amountProducts >= maxProducts)
        amountProducts = maxProducts;
    L.info("Generating {} Units", amount);
    SubMonitor m = monitorFactory.newSubMonitor("Generating " + amount + " Units", amount);
    m.start();
    List<ProductSpec> productSpecs = makeProductSpecs(amountProducts, generatePrice);
    List<UniqueUnit> units = new ArrayList<>();
    Stock stock = findOrMakeStock();
    TradeName contractor = new ArrayList<>(contractors.all()).get(R.nextInt(contractors.all().size()));
    Shipment shipment = new Shipment("TEST-SHIPMENT-" + R.nextInt(10), contractor, TradeName.ACER, Shipment.Status.OPENED);
    stockEm.persist(shipment);
    StockTransaction transaction = stockTransactionEmo.requestRollInPrepared(stock.getId(), "SampleGenerator", "Rollin via make UniqueUnits");
    L.debug("Transaction prepared {}", transaction);
    for (int i = 0; i < amount; i++) {
        ProductSpec productSpec = productSpecs.get(R.nextInt(productSpecs.size()));
        Product product = uniqueUnitAgent.findById(Product.class, productSpec.getProductId());
        UniqueUnit unit = unitGenerator.makeUniqueUnit(contractor, product);
        m.worked(1, "created SopoNr " + unit.getRefurbishId());
        if (generatePrice) {
            int price = R.nextInt(1000) + 1;
            unit.setPrice(PriceType.CUSTOMER, price, "Generated by ReceiptGeneratorOperation.makeUniqueUnits()");
            unit.setPrice(PriceType.RETAILER, price * 1.08, "Generated by ReceiptGeneratorOperation.makeUniqueUnits()");
        }
        if (generateSalesChannel)
            unit.setSalesChannel(R.nextBoolean() ? SalesChannel.CUSTOMER : SalesChannel.RETAILER);
        unitProcessor.receipt(unit, product, shipment, transaction, ReceiptOperation.SALEABLE, "SampleGenerator", "Generator");
        // Ad the now persisted instance.
        units.add(uniqueUnitAgent.findUnitByIdentifierEager(REFURBISHED_ID, unit.getRefurbishId()));
    }
    stockTransactionProcessor.rollIn(Arrays.asList(transaction), "JUnit");
    m.finish();
    return units;
}
Also used : SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Shipment(eu.ggnet.dwoss.stock.ee.entity.Shipment) Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product) ProductSpec(eu.ggnet.dwoss.spec.ee.entity.ProductSpec) UniqueUnit(eu.ggnet.dwoss.uniqueunit.ee.entity.UniqueUnit) Stock(eu.ggnet.dwoss.stock.ee.entity.Stock) StockTransaction(eu.ggnet.dwoss.stock.ee.entity.StockTransaction)

Example 38 with Product

use of eu.ggnet.dwoss.uniqueunit.ee.entity.Product in project dwoss by gg-net.

the class ReceiptGeneratorOperation method makeWarrantyProduct.

public void makeWarrantyProduct(String partNumber) {
    Product p = new Product();
    p.setPartNo(partNumber);
    p.setTradeName(TradeName.ACER);
    p.setName("Garantieerweiterung auf 2 Jahre, Seriennummer: ");
    p.setDescription("Mit dem Kauf der Garantieerweiterung wird bestätigt, " + "dass die angegebene e-mail Addresse für die Aktivierung ausschließlich an die 123 weitergegeben wird." + " Seriennummer des Gerätes: ");
    p.setGroup(COMMENTARY);
    uuEm.persist(p);
}
Also used : Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product)

Example 39 with Product

use of eu.ggnet.dwoss.uniqueunit.ee.entity.Product in project dwoss by gg-net.

the class ContractorPricePartNoImporterOperation method fromContractorXls.

// Manufacturer PartNo | EAN | Name | Contractor Reference Price | ContractorPartNo <br />
/**
 * 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 Reply<Void> 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, Double.class).addColumn(4, String.class);
    List<ContractorImport> imports = reader.read(inFile.toTemporaryFile(), ContractorImport.class);
    List<String> errors = reader.getErrors();
    List<String> info = new ArrayList<>();
    // here for size, needed down below
    List<ReportLine> missingContractorPartNo = reportLineEao.findMissingContractorPartNo(contractor);
    m.worked(5);
    m.setWorkRemaining((int) (imports.size() + imports.size() * 0.5 + missingContractorPartNo.size()));
    int databaseLines = 0;
    int updatedGtin = 0;
    int newPrices = 0;
    int updatedPrices = 0;
    int updatedContractorPartNo = 0;
    Map<Product, SortedSet<ContractorImport>> importable = new HashMap<>();
    for (ContractorImport ci : imports) {
        m.worked(1, "Preparing and Sorting (" + ci.manufacturerPartNo + ")");
        if (!ci.hasManufacturerPartNoOrGtin()) {
            errors.add("No ManufacturerPartNo or EAN found for " + ci);
            continue;
        }
        Product p = null;
        // First, try finding it via gtin
        if (ci.hasValidGtin())
            p = productEao.findByGtin(Long.parseLong(ci.gtin));
        // Second try finding it via the partNo field raw
        if (p == null && !StringUtils.isBlank(ci.manufacturerPartNo))
            p = productEao.findByPartNo(ci.manufacturerPartNo);
        if (p == null) {
            // Third, try it by regex matching of part no patterns
            // Todo: implement more partno patterns an use them here, or add the type of import to this method.
            Matcher matcher = AcerRules.PART_NO_PATTERN.matcher(ci.manufacturerPartNo);
            if (matcher.find())
                p = productEao.findByPartNo(matcher.group());
        }
        if (p == null) {
            errors.add("No UniqueUnit.Product Entity found for PartNo " + ci.manufacturerPartNo + " bzw. Gtin " + ci.gtin + ", Ignoring");
            continue;
        }
        databaseLines++;
        if (importable.containsKey(p)) {
            // sorting based on product
            importable.get(p).add(ci);
        } else {
            SortedSet<ContractorImport> set = new TreeSet<>(Comparator.comparing(ContractorImport::getReferencePrice));
            set.add(ci);
            importable.put(p, set);
        }
    }
    // update size
    m.setWorkRemaining(missingContractorPartNo.size() + importable.size());
    for (Entry<Product, SortedSet<ContractorImport>> entry : importable.entrySet()) {
        Product p = entry.getKey();
        // only us the importline with the lowest price.
        ContractorImport ci = entry.getValue().first();
        m.worked(1, "Importing " + ProductFormater.toDetailedName(p));
        if (p.getGtin() == 0 && ci.hasValidGtin()) {
            // Optional set of gtin, if it is missing.
            p.setGtin(Long.parseLong(ci.gtin));
            updatedGtin++;
        }
        if (ci.getReferencePrice() > 0.01 && !TwoDigits.equals(p.getPrice(CONTRACTOR_REFERENCE), ci.getReferencePrice())) {
            // If price is valid and not equal, set it.
            double oldPrice = p.getPrice(CONTRACTOR_REFERENCE);
            if (p.hasPrice(CONTRACTOR_REFERENCE))
                updatedPrices++;
            else
                newPrices++;
            p.setPrice(CONTRACTOR_REFERENCE, ci.getReferencePrice(), "Import by " + arranger);
            info.add(ProductFormater.toDetailedName(p) + " added/updated contractor reference price from " + oldPrice + " to " + ci.getReferencePrice());
        } else {
            errors.add(ci + " hat keinen Preis");
        }
        if (ci.hasValidContractorPartNo(contractor)) {
            // If partNo is valid, set it.
            String contractorPartNo = ci.toNormalizeContractorPart(contractor);
            if (!contractorPartNo.equals(p.getAdditionalPartNo(contractor))) {
                info.add(ProductFormater.toDetailedName(p) + " added/updated contractor partno from " + p.getAdditionalPartNo(contractor) + " to " + contractorPartNo);
                p.setAdditionalPartNo(contractor, contractorPartNo);
                updatedContractorPartNo++;
            }
        } else {
            errors.add(ci.violationMessagesOfContractorPartNo(contractor));
        }
    }
    uuEm.flush();
    // Also update existing report lines, which have unset values.
    // TODO: This should happen from the report component on needed basis or as event call. not here.
    m.message("Updateing existing Reportlines");
    int updatedReportLinePartNo = 0;
    int updatedReportLineReferencePrice = 0;
    int updatedReportLineGtin = 0;
    for (ReportLine line : missingContractorPartNo) {
        Product product = uuEm.find(Product.class, line.getProductId());
        m.worked(1, "Updating ReportLine: " + line.getId());
        String head = "ReportLine(id=" + line.getId() + ") of " + ProductFormater.toDetailedName(product);
        String msg = "";
        if (product.getAdditionalPartNo(contractor) != null) {
            line.setContractorPartNo(product.getAdditionalPartNo(contractor));
            msg += " contractorPartNo:" + line.getContractorPartNo();
            updatedReportLinePartNo++;
        }
        if (product.hasPrice(CONTRACTOR_REFERENCE) && line.getContractorReferencePrice() == 0) {
            line.setContractorReferencePrice(product.getPrice(CONTRACTOR_REFERENCE));
            msg += " contractorReferencePrice:" + line.getContractorReferencePrice();
            updatedReportLineReferencePrice++;
        }
        if (product.getGtin() != line.getGtin()) {
            line.setGtin(product.getGtin());
            msg += " gtin:" + line.getGtin();
            updatedReportLineGtin++;
        }
        if (StringUtils.isBlank(msg)) {
            errors.add(head + ", no updateable values found in product.");
        } else {
            info.add(head + " updated " + msg);
        }
    }
    String summary = "Zeilen, mit gefunden (db)Artikeln: " + databaseLines + " (Entweder über PartNo oder Gtin)\n" + "GTIN/EAN aktuallisiert: " + updatedGtin + "\n" + "Neue Preise hinterlegt: " + newPrices + "\n" + "Preise aktualisiert: " + updatedPrices + "\n" + "Lieferantenartikelnummer aktualisiert: " + updatedContractorPartNo + "\n" + "Report-Fehlende GTIN/Preise/Artikelnummern Zeilen: " + missingContractorPartNo.size() + "\n" + "Report-GTIN/EAN aktuallisiert: " + updatedReportLineGtin + "\n" + "Report-Preise aktualisiert: " + updatedReportLineReferencePrice + "\n" + "Report-Lieferantenartikelnummer aktualisiert: " + updatedReportLinePartNo;
    StringBuilder details = new StringBuilder();
    if (!info.isEmpty()) {
        details.append("Infos\n-----\n");
        info.forEach((i) -> details.append(i).append("\n"));
    }
    details.append("-----------------\nFehler/Nicht importierbar\n-----------------\n");
    errors.forEach((error) -> details.append(error).append("\n"));
    m.finish();
    if (updatedGtin + newPrices + updatedPrices + updatedContractorPartNo == 0)
        return Reply.failure(summary, details.toString());
    else
        return Reply.success(null, summary, details.toString());
}
Also used : JExcelLucidCalcReader(eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader) ReportLine(eu.ggnet.dwoss.report.ee.entity.ReportLine) Matcher(java.util.regex.Matcher) SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product) ProductEao(eu.ggnet.dwoss.uniqueunit.ee.eao.ProductEao) ReportLineEao(eu.ggnet.dwoss.report.ee.eao.ReportLineEao) JExcelLucidCalcReader(eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader) LucidCalcReader(eu.ggnet.lucidcalc.LucidCalcReader)

Example 40 with Product

use of eu.ggnet.dwoss.uniqueunit.ee.entity.Product in project dwoss by gg-net.

the class ContractorPricePartNoImporterOperation method fromManufacturerXls.

@Override
public Reply<Void> 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 databaseLines = 0;
    int newPrices = 0;
    int updatedPrices = 0;
    for (ManufacturerImport mi : imports) {
        m.worked(1);
        if (partNoSupport != null && !partNoSupport.isValid(mi.partNo)) {
            errors.add(partNoSupport.violationMessages(mi.partNo));
            continue;
        }
        if (mi.costPrice == null || mi.costPrice <= 0.01) {
            errors.add("PartNo " + mi.costPrice + " hat keinen Preis");
            continue;
        }
        m.message("Importing (" + mi.partNo + ")");
        Product p = productEao.findByPartNo(mi.partNo);
        if (p == null) {
            errors.add("No UniqueUnit Entity for PartNo " + mi.partNo);
            continue;
        }
        databaseLines++;
        if (mi.getCostPrice() > 0.01 && !TwoDigits.equals(mi.getCostPrice(), p.getPrice(MANUFACTURER_COST))) {
            if (p.hasPrice(MANUFACTURER_COST))
                updatedPrices++;
            else
                newPrices++;
            p.setPrice(PriceType.MANUFACTURER_COST, mi.costPrice, "Import by " + arranger);
        }
    }
    m.finish();
    String summary = "Zeilen, mit gefunden (db)Artikeln: " + databaseLines + " \n" + "Neue Preise hinterlegt: " + newPrices + "\n" + "Preise aktualisiert: " + updatedPrices;
    StringBuilder details = new StringBuilder();
    for (Object error : errors) {
        details.append(error.toString()).append("\n");
    }
    m.finish();
    if (newPrices + updatedPrices == 0)
        return Reply.failure(summary, details.toString());
    else
        return Reply.success(null, summary, details.toString());
}
Also used : JExcelLucidCalcReader(eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader) SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product) ProductEao(eu.ggnet.dwoss.uniqueunit.ee.eao.ProductEao) JExcelLucidCalcReader(eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader) LucidCalcReader(eu.ggnet.lucidcalc.LucidCalcReader) PartNoSupport(eu.ggnet.dwoss.rules.partno.PartNoSupport)

Aggregations

Product (eu.ggnet.dwoss.uniqueunit.ee.entity.Product)50 UniqueUnit (eu.ggnet.dwoss.uniqueunit.ee.entity.UniqueUnit)29 Test (org.junit.Test)16 SubMonitor (eu.ggnet.dwoss.progress.SubMonitor)13 StockUnit (eu.ggnet.dwoss.stock.ee.entity.StockUnit)11 ProductEao (eu.ggnet.dwoss.uniqueunit.ee.eao.ProductEao)11 UniqueUnitEao (eu.ggnet.dwoss.uniqueunit.ee.eao.UniqueUnitEao)9 ProductSpec (eu.ggnet.dwoss.spec.ee.entity.ProductSpec)8 StockUnitEao (eu.ggnet.dwoss.stock.ee.eao.StockUnitEao)5 LogicTransaction (eu.ggnet.dwoss.stock.ee.entity.LogicTransaction)5 PriceType (eu.ggnet.dwoss.uniqueunit.ee.entity.PriceType)5 java.util (java.util)5 Stock (eu.ggnet.dwoss.stock.ee.entity.Stock)4 StockTransaction (eu.ggnet.dwoss.stock.ee.entity.StockTransaction)4 CategoryProduct (eu.ggnet.dwoss.uniqueunit.ee.entity.CategoryProduct)4 UnitCollection (eu.ggnet.dwoss.uniqueunit.ee.entity.UnitCollection)4 JExcelLucidCalcReader (eu.ggnet.lucidcalc.jexcel.JExcelLucidCalcReader)4 PriceEngineResult (eu.ggnet.dwoss.price.engine.PriceEngineResult)3 TradeName (eu.ggnet.dwoss.rules.TradeName)3 CustomerMetaData (eu.ggnet.dwoss.customer.opi.CustomerMetaData)2