Search in sources :

Example 26 with SubMonitor

use of eu.ggnet.dwoss.progress.SubMonitor in project dwoss by gg-net.

the class RedTapeCloserOperation method filterOpenStockTransactions.

/**
 * Filters out all {@link Document}'s with associated {@link StockUnit}'s on an open {@link StockTransaction}.
 * See {@link StockTransactionStatusType} and {@link StockTransaction#POSSIBLE_STATUS_TYPES} for details about open {@link StockTransaction}.
 * <p>
 * <p/>
 * @param documents the documents as reference
 * @param monitor   a optional monitor
 * @return all documents which are not on open transactions.
 */
private Set<Document> filterOpenStockTransactions(Set<Document> documents, IMonitor monitor) {
    SubMonitor m = SubMonitor.convert(monitor, documents.size());
    m.start();
    m.message(" filtere");
    for (Iterator<Document> it = documents.iterator(); it.hasNext(); ) {
        Document document = it.next();
        m.worked(1, " filtere " + document.getIdentifier());
        LogicTransaction lt = ltEao.findByDossierId(document.getDossier().getId());
        if (lt == null)
            continue;
        for (StockUnit stockUnit : lt.getUnits()) {
            if (!validator.validate(stockUnit).isEmpty() || stockUnit.isInTransaction() || stockUnit.getStock() == null) {
                it.remove();
                L.warn("Closing: The Dossier(id={},customerId={}) has the Unit(refurbhisId={})" + " which is in an invalid state (validation error,open StockTransaction), excluding Dossier from closing.", document.getDossier().getId(), document.getDossier().getCustomerId(), stockUnit.getRefurbishId());
                break;
            }
        }
    }
    m.finish();
    return documents;
}
Also used : SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) LogicTransaction(eu.ggnet.dwoss.stock.ee.entity.LogicTransaction) Document(eu.ggnet.dwoss.redtape.ee.entity.Document) StockUnit(eu.ggnet.dwoss.stock.ee.entity.StockUnit)

Example 27 with SubMonitor

use of eu.ggnet.dwoss.progress.SubMonitor in project dwoss by gg-net.

the class RedTapeCloserOperation method poluteReporting.

/**
 * Actually creating reportLines from the reportable documents.
 * For each position of a {@link Document} a {@link ReportLine} is created with all information supplied.
 * <p>
 * Exceptions are:
 * <ul>
 * <li>A {@link Document} with a {@link Condition#CANCELED} which is silently ignored</li>
 * <li>A {@link Document} with a {@link DocumentType#COMPLAINT} which sets all prices on the {@link ReportLine} to 0 and
 * <ul>
 * <li>If the {@link Document} has the {@link Condition#WITHDRAWN} or {@link Condition#REJECTED}, set {@link ReportLine#workflowStatus} to
 * {@link ReportLine.WorkflowStatus#DISCHARGED}</li>
 * <li>If the {@link Document} has the {@link Condition#ACCEPTED}, set {@link ReportLine#workflowStatus} to
 * {@link ReportLine.WorkflowStatus#CHARGED}</li>
 * <li>Otherwise set {@link ReportLine#workflowStatus} to {@link ReportLine.WorkflowStatus#UNDER_PROGRESS}</li>
 * </ul>
 * </li>
 * <li>A {@link Document} with a {@link DocumentType#CREDIT_MEMO} gets its prices inverted</li>
 * </ul>
 * <p/>
 * @param reportable the documents to create lines from
 * @param monitor    a optional monitor.
 * @return the amount of created lines.
 */
private int poluteReporting(Set<Document> reportable, Date reporting, IMonitor monitor) {
    WarrantyService warrantyService = null;
    if (!warrantyServiceInstance.isUnsatisfied()) {
        warrantyService = warrantyServiceInstance.get();
    }
    SubMonitor m = SubMonitor.convert(monitor, reportable.size() + 10);
    m.start();
    ReportLineEao reportLineEao = new ReportLineEao(reportEm);
    UniqueUnitEao uniqueUnitEao = new UniqueUnitEao(uuEm);
    ProductEao productEao = new ProductEao(uuEm);
    int amountCreate = 0;
    List<ReportLine> newLines = new ArrayList<>(reportable.size());
    for (Document document : reportable) {
        m.worked(1, "reported " + document.getIdentifier());
        // A canceled document must be closed, but must not create a reportline.
        if (document.getConditions().contains(Condition.CANCELED))
            continue;
        ReportLine l;
        for (Position position : document.getPositions().values()) {
            amountCreate++;
            l = new ReportLine();
            l.setActual(document.getActual());
            l.setAmount(position.getAmount());
            l.setBookingAccount(position.getBookingAccount().map(Ledger::getValue).orElse(-1));
            l.setCustomerId(document.getDossier().getCustomerId());
            l.setDescription(normalizeSpace(position.getDescription()));
            l.setDocumentId(document.getId());
            l.setDocumentIdentifier(document.getIdentifier());
            l.setDocumentType(document.getType());
            l.setDossierId(document.getDossier().getId());
            l.setDossierIdentifier(document.getDossier().getIdentifier());
            // TODO: We could use something else for a separator, but keep in mind that we want to avoid name, , , something.
            l.setInvoiceAddress(normalizeSpace(document.getInvoiceAddress().getDescription()));
            l.setName(normalizeSpace(position.getName()));
            l.setPositionType(position.getType());
            l.setPrice(position.getPrice());
            l.setReportingDate(reporting);
            l.setTax(position.getTax());
            // Set via Report afterwards
            l.setMarginPercentage(0);
            // Set via Report afterwards
            l.setPurchasePrice(0);
            UiCustomer c = customerService.asUiCustomer(document.getDossier().getCustomerId());
            if (c != null) {
                l.setCustomerCompany(c.getCompany());
                l.setCustomerName(c.toTitleNameLine());
                l.setCustomerEmail(c.getEmail());
            }
            // A Credit Memo gets its prices inverted
            if (document.getType() == DocumentType.CREDIT_MEMO) {
                l.setPrice(position.getPrice() * (-1));
            }
            // Special handling of complaints.
            if (document.getType() == DocumentType.COMPLAINT) {
                // A Complaint position has "tagging" effect, but shall never result in a plus or minus.
                l.setPrice(0);
                if (document.getConditions().contains(Condition.REJECTED) || document.getConditions().contains(Condition.WITHDRAWN)) {
                    l.setWorkflowStatus(ReportLine.WorkflowStatus.DISCHARGED);
                } else if (document.getConditions().contains(Condition.ACCEPTED)) {
                    l.setWorkflowStatus(ReportLine.WorkflowStatus.CHARGED);
                } else {
                    l.setWorkflowStatus(ReportLine.WorkflowStatus.UNDER_PROGRESS);
                }
            }
            // Extra information for Type Position
            if (position.getType() == PositionType.UNIT || position.getType() == PositionType.UNIT_ANNEX) {
                UniqueUnit uu = Objects.requireNonNull(uniqueUnitEao.findById(position.getUniqueUnitId()), "No UniqueUnit with id=" + position.getUniqueUnitId());
                Product p = uu.getProduct();
                if (uu.getContractor() == p.getTradeName().getManufacturer()) {
                    l.setContractorPartNo(p.getPartNo());
                    l.setContractorReferencePrice(p.getPrice(MANUFACTURER_COST));
                } else {
                    l.setContractorPartNo(p.getAdditionalPartNo(uu.getContractor()));
                    l.setContractorReferencePrice(p.getPrice(CONTRACTOR_REFERENCE));
                }
                l.setManufacturerCostPrice(p.getPrice(MANUFACTURER_COST));
                l.setContractor(uu.getContractor());
                l.setContractorReferencePrice(p.getPrice(CONTRACTOR_REFERENCE));
                if (Math.abs(l.getContractorReferencePrice()) < 0.001)
                    l.setContractorReferencePrice(p.getPrice(MANUFACTURER_COST));
                l.setMfgDate(uu.getMfgDate());
                l.setRefurbishId(uu.getRefurbishId());
                l.setSerial(uu.getSerial());
                l.setUniqueUnitId(uu.getId());
                l.setSalesChannel(uu.getSalesChannel());
                l.setPartNo(p.getPartNo());
                l.setProductBrand(p.getTradeName());
                l.setProductName(p.getName());
                l.setProductGroup(p.getGroup());
                l.setProductId(p.getId());
                l.setGtin(p.getGtin());
            // Extra Information for Type Product Batch
            } else if (position.getType() == PositionType.PRODUCT_BATCH) {
                Product p = Objects.requireNonNull(productEao.findById(position.getUniqueUnitProductId()), "No Product for id=" + position.getUniqueUnitProductId());
                l.setPartNo(p.getPartNo());
                l.setProductBrand(p.getTradeName());
                l.setProductGroup(p.getGroup());
                l.setProductName(p.getName());
                l.setProductId(p.getId());
                l.setGtin(p.getGtin());
                l.setUniqueUnitId(position.getUniqueUnitId());
                l.setSerial(position.getSerial());
                l.setRefurbishId(position.getRefurbishedId());
                if (warrantyService != null) {
                    // If this is no warranty Partno, this will return null ;-)
                    l.setContractor(warrantyService.warrantyContractor(p.getPartNo()));
                }
            }
            reportEm.persist(l);
            newLines.add(l);
        }
    }
    reportEm.flush();
    m.message("Updateing References");
    for (ReportLine newLine : newLines) {
        // Not Refs for Product_Batches or Versandkosten jet.
        if (newLine.getUniqueUnitId() < 1)
            continue;
        if (newLine.getPositionType() == PositionType.PRODUCT_BATCH) {
            // TODO: also evaluate the productId.
            newLine.addAll(reportLineEao.findBySerialAndPositionTypeAndDossierId(newLine.getSerial(), newLine.getPositionType(), newLine.getDossierId()));
        } else {
            newLine.addAll(reportLineEao.findUnitsAlike(newLine.getUniqueUnitId(), newLine.getDossierId()));
        }
    }
    updateSingleReferences(newLines);
    m.worked(5);
    m.finish();
    return amountCreate;
}
Also used : ReportLine(eu.ggnet.dwoss.report.ee.entity.ReportLine) Position(eu.ggnet.dwoss.redtape.ee.entity.Position) Ledger(eu.ggnet.dwoss.mandator.api.value.Ledger) SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Product(eu.ggnet.dwoss.uniqueunit.ee.entity.Product) ProductEao(eu.ggnet.dwoss.uniqueunit.ee.eao.ProductEao) WarrantyService(eu.ggnet.dwoss.mandator.api.service.WarrantyService) Document(eu.ggnet.dwoss.redtape.ee.entity.Document) UniqueUnitEao(eu.ggnet.dwoss.uniqueunit.ee.eao.UniqueUnitEao) UniqueUnit(eu.ggnet.dwoss.uniqueunit.ee.entity.UniqueUnit) ReportLineEao(eu.ggnet.dwoss.report.ee.eao.ReportLineEao) UiCustomer(eu.ggnet.dwoss.customer.opi.UiCustomer)

Example 28 with SubMonitor

use of eu.ggnet.dwoss.progress.SubMonitor in project dwoss by gg-net.

the class RedTapeCloserOperation method closeRedTape.

/**
 * Closes the Documents and it's dossiers. This simply sets {@link Document#closed} and {@link Dossier#closed} to true.
 * For information on reopening {@link Dossier}'s see {@link RedTapeWorkflow#refreshAndPrepare(de.dw.redtape.entity.Document, de.dw.redtape.entity.Document)
 * }.
 * <p/>
 * @param documents the documents to close
 * @param monitor   a optional monitor.
 * @return a container instance with dossierIds to be closed and/or reopened in sopo.
 */
private void closeRedTape(Set<Document> documents, IMonitor monitor) {
    SubMonitor m = SubMonitor.convert(monitor, documents.size());
    m.start();
    for (Document document : documents) {
        m.worked(1, " verbuche " + document.getIdentifier());
        document.setClosed(true);
        document.getDossier().setClosed(true);
    }
    m.finish();
}
Also used : SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Document(eu.ggnet.dwoss.redtape.ee.entity.Document)

Example 29 with SubMonitor

use of eu.ggnet.dwoss.progress.SubMonitor in project dwoss by gg-net.

the class RedTapeCloserOperation method findReportable.

/**
 * Discovers all Documents, which are in closing state.
 * <p>
 * Closing States are:
 * <table border="1" >
 * <thead>
 * <tr><th>Case</th><th>Document Type</th><th>PaymentMethod</th><th>Conditions</th><th>Directive</th></tr>
 * </thead>
 * <tbody>
 * <tr>
 * <td>1</td>
 * <td>{@link Type#ORDER}</td>
 * <td>*</td>
 * <td>{@link Condition#CANCELED}</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>2</td>
 * <td>{@link Type#INVOICE} overwrites {@link Type#ORDER}</td>
 * <td>{@link PaymentMethod#ADVANCE_PAYMENT}</td>
 * <td>{@link Condition#PAID} &amp; ( {@link Condition#SENT} | {@link Condition#PICKED_UP} )</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>3</td>
 * <td>{@link Type#INVOICE} overwrites {@link Type#ORDER}</td>
 * <td>{@link PaymentMethod#CASH_ON_DELIVERY}</td>
 * <td>{@link Condition#SENT}</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>4</td>
 * <td>{@link Type#INVOICE} overwrites {@link Type#ORDER}</td>
 * <td>{@link PaymentMethod#DIRECT_DEBIT}</td>
 * <td>{@link Condition#SENT} | {@link Condition#PICKED_UP}</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>5</td>
 * <td>{@link Type#INVOICE} overwrites {@link Type#ORDER}</td>
 * <td>{@link PaymentMethod#INVOICE}</td>
 * <td>{@link Condition#SENT} | {@link Condition#PICKED_UP}</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>6</td>
 * <td>{@link Type#ANNULATION_INVOICE} | {@link Type#CREDIT_MEMO}</td>
 * <td>*</td>
 * <td>*</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>7</td>
 * <td>{@link Type#COMPLAINT}</td>
 * <td>*</td>
 * <td>*</td>
 * <td>*</td>
 * </tr>
 * <tr>
 * <td>8</td>
 * <td>{@link Type#CAPITAL_ASSET} | {@link Type#RETURNS}</td>
 * <td>*</td>
 * <td>{@link Condition#PICKED_UP}</td>
 * <td>{@link Directive#NONE}</td>
 * </tr>
 * </tbody>
 * </table>
 * Comments:
 * <ul>
 * <li>A canceled order will be closed, but not reported.</li>
 * <li>A complaint is a very special case, which might be closed two times. See {@link  RedTapeWorkflow#refreshAndPrepare(de.dw.redtape.entity.Document, de.dw.redtape.entity.Document)
 * }</li>
 * </ul>
 * <p>
 * @param monitor a optional monitor.
 * @return all documents, which are in a closing state.
 */
private Set<Document> findReportable(IMonitor monitor) {
    SubMonitor m = SubMonitor.convert(monitor);
    m.start();
    m.message(" lade offene Vorgänge");
    List<Dossier> openDossiers = new DossierEao(redTapeEm).findByClosed(false);
    m.worked(5);
    m.setWorkRemaining(openDossiers.size());
    Set<Document> closeable = new HashSet<>();
    for (Dossier dossier : openDossiers) {
        m.worked(1, " selecting " + dossier.getIdentifier());
        // Check if there is only an order.
        if (dossier.getActiveDocuments().size() == 1 && dossier.getActiveDocuments(DocumentType.ORDER).size() == 1) {
            Document doc = dossier.getActiveDocuments(DocumentType.ORDER).get(0);
            if (doc.getConditions().contains(CANCELED))
                closeable.add(doc);
            L.debug("Filtered not reportable {}, cause: canceled order", doc.getDossier().getIdentifier());
            // Shortcut: If there is only an order, that is not canceled. we do not close it. If it is canceled, we close it.
            continue;
        }
        // Check the Closing State. Every closable document is removed from the copied collection.
        // If the collection is empty at the end, the dossier can be closed, meaning we remove all cases that we consider closing state.
        List<Document> activeDocuments = new ArrayList<>(dossier.getActiveDocuments());
        for (Iterator<Document> it = activeDocuments.iterator(); it.hasNext(); ) {
            Document document = it.next();
            Set<Condition> conditions = document.getConditions();
            if (document.isClosed()) {
                it.remove();
            // At this point a ORDER is never the only Document, therfore we safly ignore it.
            // All Repayments get reported on creation.
            } else if (document.getType() == DocumentType.ORDER || document.getType() == DocumentType.ANNULATION_INVOICE || document.getType() == DocumentType.CREDIT_MEMO) {
                it.remove();
            } else if (document.getType() == DocumentType.INVOICE) {
                switch(dossier.getPaymentMethod()) {
                    case ADVANCE_PAYMENT:
                        if (conditions.contains(PAID) && (conditions.contains(SENT) || conditions.contains(PICKED_UP)))
                            it.remove();
                        break;
                    case CASH_ON_DELIVERY:
                        if (conditions.contains(SENT))
                            it.remove();
                        break;
                    case DIRECT_DEBIT:
                        if (conditions.contains(SENT) || conditions.contains(PICKED_UP))
                            it.remove();
                        break;
                    case INVOICE:
                        if (conditions.contains(SENT) || conditions.contains(PICKED_UP))
                            it.remove();
                        break;
                }
            } else if (document.getType() == DocumentType.CAPITAL_ASSET || document.getType() == DocumentType.RETURNS) {
                if (conditions.contains(PICKED_UP))
                    it.remove();
            } else if (document.getType() == DocumentType.COMPLAINT) {
                // A Complaint gets allways closed. See RedTapeWorkflow.refreshAndPrepare() for the reopening conditions.
                it.remove();
            }
        // TODO: There might be a special case, that someone made the CreditMemo on the Invoice, but had a Complait before.
        // We should cleanup this also. See: http://overload.ahrensburg.gg-net.de/jira/browse/DW-831
        }
        // Empty means, all documents in a dossier are either closed or in a closing state, expect Blocks and orders.
        if (activeDocuments.isEmpty()) {
            for (Document document : dossier.getActiveDocuments()) {
                // The Order part is never Reported.
                if (document.getType() == DocumentType.ORDER)
                    continue;
                // Should never happen, no concept jet.
                if (document.getType() == DocumentType.BLOCK)
                    continue;
                // Don't close it twice
                if (document.isClosed())
                    continue;
                closeable.add(document);
            }
        } else if (L.isDebugEnabled()) {
            List<String> shorts = new ArrayList<>();
            String identifier = activeDocuments.get(0).getIdentifier();
            for (Document document : activeDocuments) {
                shorts.add(document.toTypeConditions());
            }
            L.debug("Filtered not reportable {}, cause: Not closeable documents: {}", identifier, shorts);
        }
    }
    m.finish();
    return closeable;
}
Also used : Condition(eu.ggnet.dwoss.redtape.ee.entity.Document.Condition) SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) Document(eu.ggnet.dwoss.redtape.ee.entity.Document) Dossier(eu.ggnet.dwoss.redtape.ee.entity.Dossier) DossierEao(eu.ggnet.dwoss.redtape.ee.eao.DossierEao)

Example 30 with SubMonitor

use of eu.ggnet.dwoss.progress.SubMonitor in project dwoss by gg-net.

the class SageExporterOperation method toXml.

/**
 * Exports the all Documents in the Range as the specified XML lines.
 * <p/>
 * @param start the starting date
 * @param end   the ending date
 * @return an Xml document, ready for import in GS Office.
 */
@Override
@AutoLogger
public FileJacket toXml(Date start, Date end) {
    SubMonitor m = monitorFactory.newSubMonitor("GS Buchhalter Export", 100);
    m.start();
    m.message("Loading Invoices");
    DocumentEao documentEao = new DocumentEao(redTapeEm);
    List<Document> documents = new ArrayList<>();
    documents.addAll(documentEao.findDocumentsBetweenDates(start, end, INVOICE, CREDIT_MEMO, ANNULATION_INVOICE));
    L.info("Loaded {} amount of documents", documents.size());
    m.worked(10);
    Map<Document, UiCustomer> customerInvoices = new HashMap<>();
    m.setWorkRemaining(documents.size() * 2);
    for (Document document : documents) {
        m.worked(1, "Handling Invoice " + document.getIdentifier());
        customerInvoices.put(document, customerService.asUiCustomer(document.getDossier().getCustomerId()));
    }
    m.message("Generating Outfile");
    try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
        SageExporterEngine exporter = new SageExporterEngine(out, customerInvoices, config);
        exporter.execute(m);
        m.finish();
        return new FileJacket("Buchungsaetze DW " + mandator.getCompany().getName() + " von " + DATE_FORMAT.format(start) + " bis " + DATE_FORMAT.format(end), ".xml", out.toByteArray());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : SageExporterEngine(eu.ggnet.dwoss.redtape.ee.sage.SageExporterEngine) DocumentEao(eu.ggnet.dwoss.redtape.ee.eao.DocumentEao) SubMonitor(eu.ggnet.dwoss.progress.SubMonitor) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Document(eu.ggnet.dwoss.redtape.ee.entity.Document) FileJacket(eu.ggnet.dwoss.util.FileJacket) UiCustomer(eu.ggnet.dwoss.customer.opi.UiCustomer) AutoLogger(eu.ggnet.dwoss.common.log.AutoLogger)

Aggregations

SubMonitor (eu.ggnet.dwoss.progress.SubMonitor)63 UniqueUnitEao (eu.ggnet.dwoss.uniqueunit.ee.eao.UniqueUnitEao)23 UniqueUnit (eu.ggnet.dwoss.uniqueunit.ee.entity.UniqueUnit)21 FileJacket (eu.ggnet.dwoss.util.FileJacket)18 Document (eu.ggnet.dwoss.redtape.ee.entity.Document)16 Product (eu.ggnet.dwoss.uniqueunit.ee.entity.Product)14 StockUnitEao (eu.ggnet.dwoss.stock.ee.eao.StockUnitEao)12 File (java.io.File)12 StockUnit (eu.ggnet.dwoss.stock.ee.entity.StockUnit)11 UiCustomer (eu.ggnet.dwoss.customer.opi.UiCustomer)9 ProductEao (eu.ggnet.dwoss.uniqueunit.ee.eao.ProductEao)8 MonitorFactory (eu.ggnet.dwoss.progress.MonitorFactory)7 Inject (javax.inject.Inject)7 Test (org.junit.Test)7 PriceEngineResult (eu.ggnet.dwoss.price.engine.PriceEngineResult)6 DocumentEao (eu.ggnet.dwoss.redtape.ee.eao.DocumentEao)6 CCalcDocument (eu.ggnet.lucidcalc.CCalcDocument)6 CFormat (eu.ggnet.lucidcalc.CFormat)6 CSheet (eu.ggnet.lucidcalc.CSheet)6 STable (eu.ggnet.lucidcalc.STable)6