...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Info | ||
---|---|---|
| ||
This article was written for a connector used with the separate Pack & Ship Extension (OnPrem or Per-Tenant). Mobile WMS - Implementing a new Shipping Provider Connector |
Use this event to
...
Create "Transport Orders" (or similar) in 3rd party Shipping App
Description
This event is triggered prior to a Warehouse Shipment being posted. You may use the event to:
...
/// <remarks>
/// Redirected from standard event OnAfterCheckWhseShptLine to new local event for more accessible "interface" (all neccessary events in Codeunit MOS Pack API)
/// </remarks>
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOS Pack API", 'OnPostPackingOnBeforePostWarehouseShipment', '', false, false)]
local procedure OnPostPackingOnBeforePostWarehouseShipment(var WhseShptHeader: Record "Warehouse Shipment Header"; var WhseShptLine: Record "Warehouse Shipment Line")
begin
end;
Example - Create Transport Order, Transport Order Packages and mark untransferred License Plates as now already Transferred to Shipping
...
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOS Pack API", 'OnPostPackingOnBeforePostWarehouseShipment', '', false, false)]
local procedure OnPostPackingOnBeforePostWarehouseShipment(var WhseShptHeader: Record "Warehouse Shipment Header"; var WhseShptLine: Record "Warehouse Shipment Line")
begin
UpdateQuantityToTransport(WhseShptLine);
if HasQuantityToTransport(WhseShptLine) then
CreateTransportOrder(WhseShptHeader); // May append to existing transport order
end;
local procedure UpdateQuantityToTransport(var _WhseShptLine: Record "Warehouse Shipment Line"): Boolean
var
WhseShptLine2: Record "Warehouse Shipment Line";
begin
// Simple implementation: Assuming everything is for ShipIt (currently not checking package + package type exists and is asociated to IDYS)
WhseShptLine2.Copy(_WhseShptLine);
if WhseShptLine2.FindSet() then
repeat
if WhseShptLine2."Qty. To Ship" <> 0 then begin
WhseShptLine2."IDYS Quantity To Send" := WhseShptLine2."Qty. To Ship";
WhseShptLine2.Modify(true);
end;
until WhseShptLine2.Next() = 0;
end;
local procedure HasQuantityToTransport(var _WhseShptLine: Record "Warehouse Shipment Line"): Boolean
var
WhseShptLine2: Record "Warehouse Shipment Line";
begin
WhseShptLine2.Copy(_WhseShptLine);
WhseShptLine2.SetFilter("IDYS Quantity To Send", '>0');
exit(not WhseShptLine2.IsEmpty());
end;
local procedure CreateTransportOrder(var _WhseShptHeader: Record "Warehouse Shipment Header")
var
IdysActionManagement: Codeunit "IDYS Action Management";
begin
IdysActionManagement.WhseShipmtHdr_CreateTransportOrder(_WhseShptHeader);
end;
/// <summary>
/// For each new transport order line created, transfer untransferred license plates to the transport order.
/// May transfer many or zero LP's (especially if all lines was transferred in a prior call to the event).
/// </summary>
[EventSubscriber(ObjectType::Codeunit, Codeunit::"IDYS Publisher", 'OnAfterCreateTransportOrderLine', '', true, true)]
local procedure OnAfterCreateTransportOrderLine(var TransportOrderLine: Record "IDYS Transport Order Line")
var
MobSessionData: Codeunit "MOB SessionData";
begin
if IsNullGuid(MobSessionData.GetPostingMessageId()) then
exit; // Not posting from Mobile WMS
InsertPackagesForTransportOrderLine(TransportOrderLine);
end;
internal procedure InsertPackagesForTransportOrder(_TransportOrderNo: Code[20]) _PackagesInserted: Integer
var
TransportOrderLine: Record "IDYS Transport Order Line";
begin
Clear(_PackagesInserted);
TransportOrderLine.Reset();
TransportOrderLine.SetRange("Transport Order No.", _TransportOrderNo);
if TransportOrderLine.FindSet() then
repeat
_PackagesInserted := _PackagesInserted + InsertPackagesForTransportOrderLine(TransportOrderLine);
until TransportOrderLine.Next() = 0;
exit(_PackagesInserted);
end;
/// <summary>
/// Insert all untransferred packages from all shipments related to a transport order line
/// </summary>
local procedure InsertPackagesForTransportOrderLine(_TransportOrderLine: Record "IDYS Transport Order Line") _PackagesInserted: Integer
var
WhseShipmentNo: Code[20];
begin
Clear(_PackagesInserted);
if _TransportOrderLine."Source Document Table No." = Database::"Sales Header" then begin
_TransportOrderLine.TestField("Source Document Type", 1); // 1 = Sales Order
_TransportOrderLine.TestField("Source Document No."); // Sales Order No
_TransportOrderLine.TestField("Source Document Line No."); // Sales Order No
// Transport order line source document table no. 36 -> whse. shipment line source type 37
WhseShipmentNo := GetWhseShipmentNoBySourceLine(Database::"Sales Line", _TransportOrderLine."Source Document Type", _TransportOrderLine."Source Document No.", _TransportOrderLine."Source Document Line No.");
_PackagesInserted := InsertPackagesForWarehouseShipment(WhseShipmentNo, _TransportOrderLine."Transport Order No.");
end;
exit(_PackagesInserted);
end;
/// <summary>
/// Insert all untransferred packages from a warehouse shipment
/// </summary>
local procedure InsertPackagesForWarehouseShipment(_FromWhseShipmentNo: Code[20]; _ToTransportOrderNo: Code[20]) _PackagesInserted: Integer
var
TransportOrderPackage: Record "IDYS Transport Order Package";
UntransferredLicensePlate: Record "MOS License Plate";
UntransferredLicensePlate2: Record "MOS License Plate";
PackageType: Record "MOS Package Type";
MosPackRegister: Codeunit "MOS WMS Pack Adhoc Reg-PostPck";
NextLineNo: Integer;
PackageTypeCode: Code[50];
begin
Clear(_PackagesInserted);
MosPackRegister.FilterUntransferredLicensePlatesForWarehouseShipment(_FromWhseShipmentNo, UntransferredLicensePlate);
if UntransferredLicensePlate.FindSet() then
repeat
if IsShippingProvider(UntransferredLicensePlate."Package Type") then begin
//
// First package only
//
if _PackagesInserted = 0 then begin
// Determine NextLineNo
TransportOrderPackage.LockTable();
TransportOrderPackage.Reset();
TransportOrderPackage.SetRange("Transport Order No.", _ToTransportOrderNo);
if TransportOrderPackage.FindLast() then
NextLineNo := TransportOrderPackage."Line No." + 10000
else
NextLineNo := 10000;
end;
//
// Any package
//
Evaluate(PackageTypeCode, UntransferredLicensePlate."Package Type");
PackageType.Get(PackageTypeCode);
TransportOrderPackage.Init();
TransportOrderPackage.Validate("Transport Order No.", _ToTransportOrderNo);
TransportOrderPackage.Validate("Line No.", NextLineNo);
NextLineNo := NextLineNo + 10000;
TransportOrderPackage.Validate("Package Type Code", PackageType."Shipping Provider Package Type");
if UntransferredLicensePlate.Weight <> 0 then
TransportOrderPackage.Validate(Weight, UntransferredLicensePlate.Weight);
if UntransferredLicensePlate.Height <> 0 then
TransportOrderPackage.Validate(Height, UntransferredLicensePlate.Height);
if UntransferredLicensePlate.Width <> 0 then
TransportOrderPackage.Validate(Width, UntransferredLicensePlate.Width);
if UntransferredLicensePlate.Length <> 0 then
TransportOrderPackage.Validate(Length, UntransferredLicensePlate.Length);
TransportOrderPackage.Insert(true);
_PackagesInserted := _PackagesInserted + TransportOrderPackage.Quantity;
UntransferredLicensePlate2 := UntransferredLicensePlate;
UntransferredLicensePlate2."Transferred to Shipping" := true;
UntransferredLicensePlate2.Modify(); // Do no modify record used for iteration due to next cursorplacement
end;
until UntransferredLicensePlate.Next() = 0;
exit(_PackagesInserted);
end;
/// <summary>
/// Collect all Whse Shipment No's related to a source (from open and posted warehouse shipments)
/// </summary>
local procedure CollectShipItTransportOrderNosByWhseShipment(_WhseShipmentNo: Code[20]; var _TransportOrderNos: Dictionary of [Code[20], Code[20]])
var
WhseShipmentLine: Record "Warehouse Shipment Line";
PostedWhseShipmentLine: Record "Posted Whse. Shipment Line";
begin
// From open Warehouse Shipment
WhseShipmentLine.Reset();
WhseShipmentLine.SetCurrentKey("No.", "Source Type", "Source SubType", "Source No.", "Source Line No.");
WhseShipmentLine.SetRange("No.", _WhseShipmentNo);
if WhseShipmentLine.FindSet() then
repeat
WhseShipmentLine.SetRange("Source Type", WhseShipmentLine."Source Type");
WhseShipmentLine.SetRange("Source Subtype", WhseShipmentLine."Source Subtype");
WhseShipmentLine.SetRange("Source No.", WhseShipmentLine."Source No.");
WhseShipmentLine.SetRange("Source Line No.", WhseShipmentLine."Source Line No.");
WhseShipmentLine.FindLast();
CollectShipItTransportOrderNosBySource(WhseShipmentLine."Source Type", WhseShipmentLine."Source Subtype", WhseShipmentLine."Source No.", WhseShipmentLine."Source Line No.", _TransportOrderNos);
WhseShipmentLine.SetRange("Source Type");
WhseShipmentLine.SetRange("Source Subtype");
WhseShipmentLine.SetRange("Source No.");
WhseShipmentLine.SetRange("Source Line No.");
until WhseShipmentLine.Next() = 0;
// From posted Warehouse Shipment
PostedWhseShipmentLine.Reset();
PostedWhseShipmentLine.SetCurrentKey("Whse. Shipment No.", "Source Type", "Source SubType", "Source No.", "Source Line No.");
PostedWhseShipmentLine.SetRange("Whse. Shipment No.", _WhseShipmentNo);
if PostedWhseShipmentLine.FindSet() then
repeat
PostedWhseShipmentLine.SetRange("Source Type", PostedWhseShipmentLine."Source Type");
PostedWhseShipmentLine.SetRange("Source Subtype", PostedWhseShipmentLine."Source Subtype");
PostedWhseShipmentLine.SetRange("Source No.", PostedWhseShipmentLine."Source No.");
PostedWhseShipmentLine.SetRange("Source Line No.", PostedWhseShipmentLine."Source Line No.");
PostedWhseShipmentLine.FindLast();
CollectShipItTransportOrderNosBySource(PostedWhseShipmentLine."Source Type", PostedWhseShipmentLine."Source Subtype", PostedWhseShipmentLine."Source No.", PostedWhseShipmentLine."Source Line No.", _TransportOrderNos);
PostedWhseShipmentLine.SetRange("Source Type");
PostedWhseShipmentLine.SetRange("Source Subtype");
PostedWhseShipmentLine.SetRange("Source No.");
PostedWhseShipmentLine.SetRange("Source Line No.");
until PostedWhseShipmentLine.Next() = 0;
end;
/// <summary>
/// Collect all ShipIt Transport Order No's related to a source (from open or posted warehouse shipment line)
/// </summary>
local procedure CollectShipItTransportOrderNosBySource(_SourceDocumentTableNo: Integer; _SourceDocumentType: Integer; _SourceDocumentNo: Code[20]; _SourceDocumentLineNo: Integer; var _TransportOrderNos: Dictionary of [Code[20], Code[20]])
var
TransportOrderLine: Record "IDYS Transport Order Line";
MosPackRegister: Codeunit "MOS WMS Pack Adhoc Reg-PostPck";
SourceDocumentHeaderTableNo: Integer;
begin
// Transport Order Lines are linked to header tables, not line tables
// Convert line table no. to header table no.
SourceDocumentHeaderTableNo := MosPackRegister.GetHeaderTableNo(_SourceDocumentTableNo);
TransportOrderLine.Reset();
TransportOrderLine.SetCurrentKey("Source Document Table No.", "Source Document Type", "Source Document No.", "Source Document Line No.", "Transport Order No.");
TransportOrderLine.SetRange("Source Document Table No.", SourceDocumentHeaderTableNo);
TransportOrderLine.SetRange("Source Document Type", _SourceDocumentType);
TransportOrderLine.SetRange("Source Document No.", _SourceDocumentNo);
TransportOrderLine.SetRange("Source Document Line No.", _SourceDocumentLineNo);
if TransportOrderLine.FindSet() then
repeat
TransportOrderLine.SetRange("Transport Order No.", TransportOrderLine."Transport Order No.");
TransportOrderLine.FindLast();
if _TransportOrderNos.Add(TransportOrderLine."Transport Order No.", TransportOrderLine."Transport Order No.") then;
TransportOrderLine.SetRange("Transport Order No.");
until TransportOrderLine.Next() = 0;
end;
/// <summary>
/// Get the single Whse Shipment No. related to a source line no. (from open or posted warehouse shipment)
/// Assuming a source line can only have a single associated whse. shipment line
/// </summary>
local procedure GetWhseShipmentNoBySourceLine(_SourceType: Integer; _SourceSubType: Integer; _SourceNo: Code[20]; _SourceLineNo: Integer): Code[20]
var
WhseShipmentLine: Record "Warehouse Shipment Line";
PostedWhseShipmentLine: Record "Posted Whse. Shipment Line";
begin
WhseShipmentLine.Reset();
WhseShipmentLine.SetCurrentKey("Source Type", "Source SubType", "Source No.", "Source Line No.", "No.");
WhseShipmentLine.SetRange("Source Type", _SourceType);
WhseShipmentLine.SetRange("Source Subtype", _SourceSubType);
WhseShipmentLine.SetRange("Source No.", _SourceNo);
WhseShipmentLine.SetRange("Source Line No.", _SourceLineNo);
if WhseShipmentLine.FindFirst() then
exit(WhseShipmentLine."No.");
PostedWhseShipmentLine.Reset();
PostedWhseShipmentLine.SetCurrentKey("Source Type", "Source SubType", "Source No.", "Source Line No.", "No.");
PostedWhseShipmentLine.SetRange("Source Type", _SourceType);
PostedWhseShipmentLine.SetRange("Source Subtype", _SourceSubType);
PostedWhseShipmentLine.SetRange("Source No.", _SourceNo);
PostedWhseShipmentLine.SetRange("Source Line No.", _SourceLineNo);
if PostedWhseShipmentLine.FindFirst() then
exit(PostedWhseShipmentLine."No.");
exit('');
end;
Version History
Version | Changes |
---|---|
MOS1.0.0 | Introduced |
...