Set the Delivery Status of the Lines a Document Was Made From
This Groovy script writes a delivery status of your choice onto the lines a document was made from. When you save, say, an invoice made from a sales order, each order line that the invoice draws on gets the status you picked, such as Loaded or Delivering.
Recommended pattern
This script is not tied to any customer's setup. You can paste it as it is and control it entirely through its parameters.
| Class name | EASetDeliveryStatusInFromDocLines |
| Script | EASetDeliveryStatusInFromDocLines.groovy |
| Runs on | Any supply chain document made from another document. Usually PostCommit. |
| Uses | Parameter 2 and Parameter 3. Leave Parameter 1 empty. |
| Shipped as | Source to paste. It is not built into the system. |
When to use it
Sales lines and delivery document lines carry a Delivery Status column. The built-in EAUpdateDeliveryStatusFromSalesDocToFromDoc copies a line's own status back to the line it came from, one level up. This script is for the other common need: a fixed milestone.
Suppose the warehouse builds a stock issue from each sales invoice, and the invoice itself was made from a sales order. The sales team wants every order line to show Loaded the moment the stock issue is saved. Attach this script to the stock issue with Parameter 2 set to Loaded and Parameter 3 set to SalesOrder. The script walks from each issue line to its invoice line and on to the order line, and stamps that one.
How it works
- It reads the parameters. Parameter 2 is the status to set. When it is empty, the status is Delivering. Parameter 3 is the document type to stop at. When it is empty, that is Sales Invoice.
- It follows each line back. For every line of the document being saved, the script finds the line it was made from. It uses the line's own origin document when there is one, and the document's From Document otherwise.
- It keeps climbing until the type matches. If the source line belongs to a document of the type in Parameter 3, that is the line it changes. If not, it looks at where that line came from, and so on up the chain. A line with no source, or a chain that never reaches that type, is skipped without a message.
- It sets the status on the source line. The source document is changed directly, in the same save. It is not re-saved through its own screen, so its own entity flows and validations do not run.
Deleting the document does not undo the status
The script only sets a status. Deleting the document, or removing a line from it, leaves the source lines with the status the script gave them. Change them back by hand if needed.
Setting it up
- Open Administration → Display Customization → Entity Flow and create a flow whose target type is the document that should trigger the change (for example Stock Issue).
- In the Details grid, add a line with Target Action set to PostCommit, and paste the whole script into its Groovy Script column. Leave Class Name empty: it is filled in when you save.
- Fill in the parameters:
| Parameter | Title shown after saving | What to enter |
|---|---|---|
| Parameter 1 | Not used - leave empty | Nothing. |
| Parameter 2 | Status To Change To (NotDelivered, PartialDelivered, Delivered, Cancelled, Delivering, Loaded, Other1, Other2, Other3), default is Delivering | One of the listed values, spelt exactly as shown. Leave it empty for Delivering. |
| Parameter 3 | Document Type To change status in, default is SalesInvoice | The entity type of the document whose lines should change, for example SalesOrder. Leave it empty for SalesInvoice. |
- Save the flow. Class Name now shows the script's class name, the line's Description explains what it does, and each parameter shows its title.
Parameter 3 must name a document whose lines have a delivery status
Sales documents (orders, invoices and the like) and the delivery document have a Delivery Status on their lines. Naming a type whose lines have none, such as a stock issue, makes the flow fail when the document is saved.
Example
A sales order SO-163 has ten lines. An invoice is made from it for two of those lines, and the flow above runs on the invoice with Parameter 2 = Loaded and Parameter 3 = SalesOrder. After the invoice is saved, those two order lines show Loaded in Delivery Status. The other eight lines keep their old status, because the invoice draws nothing from them.
The script
package com.namasoft.modules.supplychain.domain.utils.plugnplay.groovy
import com.namasoft.common.utilities.ObjectChecker
import com.namasoft.infra.domainbase.datafields.LongTextDF
import com.namasoft.infra.domainbase.datafields.enums.EntityTypeDF
import com.namasoft.infra.domainbase.entity.base.EntityAction
import com.namasoft.infra.domainbase.entitytype.EntityTypeUtil
import com.namasoft.infra.domainbase.util.Result
import com.namasoft.modules.basic.domain.primitives.DeliveryStatus
import com.namasoft.modules.supplychain.domain.details.BasicSCDocumentLine
import com.namasoft.modules.supplychain.domain.details.HasDeliveryStatus
import com.namasoft.modules.supplychain.domain.entities.BasicSCDocument
import com.namasoft.modules.supplychain.domain.entities.SalesInvoice
class EASetDeliveryStatusInFromDocLines implements EntityAction<BasicSCDocument> {
@Override
Result doAction(BasicSCDocument object, LongTextDF... parameters) {
DeliveryStatus status = DeliveryStatus.Delivering();
if (ObjectChecker.isNotEmptyOrNull(parameters[1]))
status = DeliveryStatus.fromString(parameters[1].getPrimitiveValue());
Class klass = SalesInvoice.class;
if (ObjectChecker.isNotEmptyOrNull(parameters[2]))
klass = EntityTypeUtil.getEntityClassFromType(EntityTypeDF.fromDataField(parameters[2]));
for (final BasicSCDocumentLine detail in object.getDetails()) {
def parentLine = object.fetchParentLine(detail, klass);
if (parentLine != null) {
HasDeliveryStatus l = parentLine.getY();
l.setDelivStatus(status);
}
}
return Result.createSuccessResult();
}
@Override
String describe() {
return "Sets the delivery status of the lines this document was made from. For each line, the script follows the line's " +
"source line up the chain of from-documents until it reaches a document of the type in parameter 3 (default SalesInvoice), " +
"and sets that line's delivery status to the value in parameter 2 (default Delivering). Lines with no source line are skipped. " +
"The type in parameter 3 must be a document whose lines have a delivery status, such as a sales document or a delivery document. " +
"Parameter 1 is not used.";
}
@Override
List<String> columnNames() {
return Arrays.asList("Not used - leave empty",
"Status To Change To (NotDelivered, PartialDelivered, Delivered, Cancelled, Delivering, Loaded, Other1, Other2, Other3), default is Delivering",
"Document Type To change status in, default is SalesInvoice");
}
}Related
- EAGroovyAction: how Groovy scripts are attached to entity flows.
- EAUpdateDeliveryStatusFromSalesDocToFromDoc: the built-in action that copies a line's own delivery status one level up.