Skip to content

Collect a Purchase Invoice's Stock Receipts From Its Car Receipts ​

This Groovy script fills the Stock Documents grid of a purchase invoice. It takes the Car Receipts that were made from the same document as the invoice, and lists every stock receipt that was made from those Car Receipts.

Recommended pattern

This script is not tied to any customer's setup. It takes no parameters, so you can paste it as it is.

Class nameEACollectStockReceiptsByFromDoc
ScriptEACollectStockReceiptsByFromDoc.groovy
Runs onPurchase Invoice, on Pre Update Calculated Fields.
UsesNo parameters. Leave Parameter 1 empty.
Shipped asSource to paste. It is not built into the system.

When to use it ​

In the car business, goods do not go straight from the purchase document into stock. Cars arrive first on a Car Receipt (cars → Car Inventory → Car Receipt), which records the chassis and the accessories that came with each car. The stock receipt that actually puts the car into the warehouse is made from that Car Receipt.

When the purchase invoice is then made from the same purchase document, its Stock Documents grid should list those stock receipts, so the invoice and the goods it pays for are linked. The system does not find them by itself, because they hang one level away from the invoice: under the Car Receipts, not under the invoice's own From Document. This script walks that extra step.

How it works ​

  1. It finds the Car Receipts whose From Document is the invoice's From Document.
  2. It finds the stock receipts whose From Document is one of those Car Receipts.
  3. It rewrites the Stock Documents grid to hold exactly those stock receipts: rows already in the grid are overwritten in order, missing rows are added, and rows left over are removed. Each row takes the stock receipt and its date.

The grid is replaced, not added to

Whatever was in Stock Documents before the save is overwritten. When no stock receipt is found, the grid is emptied. Run the flow only on the invoices that follow this Car Receipt chain, using its book, term or criteria.

Setting it up ​

  1. Open Administration → Display Customization → Entity Flow and create a flow with Target Type set to Purchase Invoice.
  2. In the Details grid, add a line with the action Pre Update Calculated Fields, and paste the whole script from the file above into Groovy Script. Leave Class Name empty: it is filled in when you save.
  3. Leave every parameter empty. After saving, Parameter 1 shows the title Not used - leave empty.
  4. Save the flow. Class Name now shows com.namasoft.modules.srvcenter.domain.utils.EACollectStockReceiptsByFromDoc.

Example ​

A Car Purchase Invoice has one Car Receipt made from it, and two stock receipts were made from that Car Receipt. A purchase invoice is then created with the Car Purchase Invoice as its From Document. When it is saved, its Stock Documents grid holds the two stock receipts, each with its own date. A purchase invoice with no From Document keeps its grid as it was.

The script ​

groovy
package com.namasoft.modules.srvcenter.domain.utils

import com.namasoft.common.fieldids.NotGeneratedFields
import com.namasoft.common.utilities.CollectionsUtility
import com.namasoft.common.utilities.ObjectChecker
import com.namasoft.infra.domainbase.common.criteria.CriteriaBuilder
import com.namasoft.infra.domainbase.datafields.LongTextDF
import com.namasoft.infra.domainbase.datafields.UniqueIDDF
import com.namasoft.infra.domainbase.entity.base.EntityAction
import com.namasoft.infra.domainbase.persistence.repos.ListPageMatchingParameters
import com.namasoft.infra.domainbase.persistence.repos.Persister
import com.namasoft.infra.domainbase.util.Result
import com.namasoft.modules.srvcenter.domain.entities.SIReceipt
import com.namasoft.modules.supplychain.domain.entities.AbsPurchaseInvoice
import com.namasoft.modules.supplychain.domain.entities.StockReceipt
import com.namasoft.modules.supplychain.domain.utils.InvoiceStockLine

import java.util.stream.Collectors

public class EACollectStockReceiptsByFromDoc implements EntityAction<AbsPurchaseInvoice> {
    @Override
    Result doAction(AbsPurchaseInvoice doc, LongTextDF... parameters) {
        Result result = Result.createAccumulatingResult();
        if (ObjectChecker.isEmptyOrNull(doc.getFromDoc()))
            return result;
        List<SIReceipt> receipts = Persister.listPageMatching(SIReceipt.class, ListPageMatchingParameters.create().criteria(CriteriaBuilder.create().field(NotGeneratedFields.fromDoc + ".id").equal(doc.getFromDoc().getId())));
        List<UniqueIDDF> receiptsIds = receipts.stream().map({ R -> R.getId() }).collect(Collectors.toList());
        List<StockReceipt> stockReceipts = new ArrayList<>();
        if (ObjectChecker.isNotEmptyOrNull(receiptsIds))
            stockReceipts = Persister.listPageMatching(StockReceipt.class, ListPageMatchingParameters.create().criteria(CriteriaBuilder.create().field(NotGeneratedFields.fromDoc + ".id").in(receiptsIds)));
        CollectionsUtility.makeSecondSameSize(stockReceipts, doc.getStockDocs(), { -> doc.createNewInvoiceStockLine() });
        for (int i = 0; i < stockReceipts.size(); i++) {
            InvoiceStockLine line = doc.getStockDocs().get(i);
            StockReceipt receipt = stockReceipts.get(i);
            line.updateStockDoc(receipt);
            line.setValueDate(receipt.getValueDate());
        }
        return result;
    }

    @Override
    String describe() {
        return "Purchase invoice: fills the Stock Documents grid with the stock receipts that were made from the Car Receipts " +
                "of the invoice's from-doc. Rows already in the grid are overwritten, extra rows are removed, and each row takes the receipt and its date. " +
                "Parameter 1 is not used.";
    }

    @Override
    List<String> columnNames() {
        return Arrays.asList("Not used - leave empty");
    }
}