{"ok":true,"commandType":"transfer-purchase-order-to-purchase-invoice","module":"Purchase","mode":"write","summary":"Transfer purchase order to purchase invoice, optionally assigning item batches and batch expiry.","payloadSchema":{"fromDocNo":"required source PO number","docNo":"optional target PI number; omit for AutoCount numbering","docDate":"optional target date YYYY-MM-DD","lines":"optional batch assignments only: [{sourceDtlKey, batchNo, batchExpiryDate?}]. Read DtlKey from get-purchase-order or read-purchase-order-lines first. batchno aliases batchNo. No itemCode/qty/price overrides; omitted lines retain native transfer values. Batch-enabled full transfers reject POs with prior or pending transferred quantities to prevent duplicate transfer.","batchAllocations":"optional non-empty array [{sourceDtlKey, qty, batchNo, batchExpiryDate?}]; only explicitly allocated rows transfer. Positive source-UOM quantities, repeated sourceDtlKey allowed for batch splits. Cannot combine with lines. Read actual source DtlKey and available quantity first. Requires local-mvp-2026.09.29.01 or later installed on the selected connector; older builds may ignore this field and full-transfer.","createMissingBatches":"optional boolean, default false; create missing ItemCode + BatchNo through SDK; requires update-item policy permission","updateExistingBatchExpiry":"optional boolean, default false; explicitly permit changing shared batch master expiry; requires update-item policy permission","saveAsDraft":"optional boolean; native SDK draft save when supported by the account book"},"examplePayload":{"fromDocNo":"PO-000001","docDate":"2026-06-29","createMissingBatches":false,"updateExistingBatchExpiry":false,"lines":[{"sourceDtlKey":12345,"batchNo":"BATCH-001"}]},"examples":[],"payloadEnums":{},"requiredPayloadFields":["fromDocNo"],"conditionalPayloadRules":{},"notes":"Requires local-mvp-2026.09.29.01 or later installed on the selected connector; publishing the download does not install it. Older builds may ignore batchAllocations and full-transfer; never trial against an older or unconfirmed build. Legacy mode without batchAllocations uses native PO FullDetails transfer. lines is NOT a selection or partial-quantity list; legacy mode still transfers all available source lines with optional single-batch assignments. batchAllocations cannot combine with lines and transfers only explicitly allocated rows; repeated sourceDtlKey splits a source row across batches. Each qty is positive in the source UOM; remaining = Qty - (TransferedQty + PendingTransferredQty) / Rate because those PO counters use smallest-UOM units. Native TSM 22-check acceptance passed for native PO linkage, source price/tax and saved totals, BOX Rate10 draft reservation, simple percent and prorated fixed discount, and 8% tax. No itemCode/UOM/price/tax/total overrides. Guards reject compound discounts, serial items, item packages and FOC allocations. Proportional DiscountAmt/SubTotal/Tax checks apply per-row and per-source aggregate tolerance 0.01 within each request; larger rounding drift rejects. Read actual sourceDtlKey and source quantities with read-purchase-order-lines filtered by docNo or get-purchase-order. createMissingBatches=true permits missing batches; lines[].batchExpiryDate or batchAllocations[].batchExpiryDate uses YYYY-MM-DD. updateExistingBatchExpiry=true explicitly permits shared Item Master expiry changes, not just this PI. Both flags require update-item policy permission; omit expiry to preserve it. Expiry conflicts and ambiguous mappings reject. Response includes writeVerification, batchMasterVerification, linkageVerified, sourceQuantityVerification and totalsVerified after fresh reload. Batch master and PI use separate SDK saves: inspect stage, batchMasterChanges and saved on failure (null means unknown), and read back before retrying; a duplicate-PI failure with a retained batch commit was verified. Sequential stale-reader native proof PASS: second stale PI aborted and was absent; truly simultaneous external-writer atomicity remains unproven. No connector SQL writes or source deletion/recreation. Native acceptance is bounded to tested cases, not every account book or discount/tax expression.","nativePayload":{"supported":false,"sections":[{"name":"Master","fields":[]},{"name":"Details","fields":[]},{"name":"KnockOffDetails","fields":[]},{"name":"TransferDetails","fields":[]},{"name":"PaymentDetails","fields":[]},{"name":"Options","fields":[]}]}}