How to create invoice for the shipped quantity of the items in the sales order.

define([‘N/search’, ‘N/record’], function(search, record) {

    function getInputData() {

        return search.create({

            type: “itemfulfillment”,

            filters: [

                [“type”, “anyof”, “ItemShip”],

                “AND”,

                [“status”, “anyof”, “ItemShip:C”],

                “AND”,

                [“taxline”, “is”, “F”],

                “AND”,

                [“shipping”, “is”, “F”],

                “AND”,

                [“cogs”, “is”, “F”],

                “AND”,

                [“createdfrom”, “anyof”, “2898721”],

                “AND”,

                [“mainline”,“is”,“T”],

                “AND”,

                [“createdfrom.status”,“noneof”,“SalesOrd:G”],

                “AND”,

                [“createdfrom.type”,“anyof”,“SalesOrd”]

            ],

            columns: [

                search.createColumn({ name: “createdfrom”, label: “Created From” }),

                search.createColumn({ name: “tranid”, label: “Document Number” }),

                search.createColumn({ name: “statusref”, label: “Status” }),

                search.createColumn({ name: “item”, label: “Item” }),

                search.createColumn({ name: “quantity”, label: “Quantity” }),

                search.createColumn({ name: “line”, label: “Line ID” }),

                search.createColumn({ name: “lineuniquekey”, label: “Line Unique Key” })

            ]

        });

    }

    function map(context) {

        let searchResult = JSON.parse(context.value);

        log.debug(“searchResult”,searchResult);

        let createdFrom = searchResult.values.createdfrom.value;

        context.write({

            key: createdFrom,

            value: searchResult

        });

    }

    function reduce(context) {

        let salesOrderId = context.key;

        let fulfillments = context.values.map(function(value) {

            return JSON.parse(value);

        });

   

        try {

            // Log the sales order ID we are transforming

            log.debug(‘Transforming Sales Order’, ‘Sales Order ID: ‘ + salesOrderId);

   

            let invoice = record.transform({

                fromType: record.Type.SALES_ORDER,

                fromId: salesOrderId,

                toType: record.Type.INVOICE

            });

   

            let invoiceLines = invoice.getLineCount({ sublistId: ‘item’ });

            log.debug(‘Invoice Line Count’, ‘Invoice Lines: ‘ + invoiceLines);

   

            // Load the sales order to access its lines

            let salesOrder = record.load({

                type: record.Type.SALES_ORDER,

                id: salesOrderId

            });

            let salesOrderLines = salesOrder.getLineCount({ sublistId: ‘item’ });

   

            // Object to store quantities based on order line

            let orderLineQuantities = {};

   

            // Sum quantities based on order lines encountered in item fulfillments

            for (let j = 0; j < fulfillments.length; j++) {

                let fulfillment = record.load({

                    type: record.Type.ITEM_FULFILLMENT,

                    id: fulfillments[j].id

                });

                let fulfillmentLines = fulfillment.getLineCount({ sublistId: ‘item’ });

   

                for (let k = 0; k < fulfillmentLines; k++) {

                    let orderline = fulfillment.getSublistValue({

                        sublistId: ‘item’,

                        fieldId: ‘orderline’,

                        line: k

                    });

   

                    let quantity = fulfillment.getSublistValue({

                        sublistId: ‘item’,

                        fieldId: ‘quantity’,

                        line: k

                    });

   

                    if (orderLineQuantities.hasOwnProperty(orderline)) {

                        // If order line already encountered, add quantity to existing sum

                        orderLineQuantities[orderline] += quantity;

                    } else {

                        // If order line encountered for the first time, initialize the sum

                        orderLineQuantities[orderline] = quantity;

                    }

   

                    // Add debug log to track quantities being accumulated

                    log.debug(‘Order Line: ‘ + orderline, ‘Quantity: ‘ + quantity + ‘, Accumulated Quantity: ‘ + orderLineQuantities[orderline]);

                }

            }

   

            // Set total quantity to the corresponding invoice line if order line matches

            for (let i = 0; i < invoiceLines; i++) {

                let invoiceLineId = invoice.getSublistValue({

                    sublistId: ‘item’,

                    fieldId: ‘orderline’,

                    line: i

                });

   

                // Check if the order line is found in the accumulated quantities

                if (orderLineQuantities.hasOwnProperty(invoiceLineId)) {

                    let totalQuantity = orderLineQuantities[invoiceLineId];

   

                    // Find the corresponding line in the Sales Order

                    for (let m = 0; m < salesOrderLines; m++) {

                        let salesOrderLineId = salesOrder.getSublistValue({

                            sublistId: ‘item’,

                            fieldId: ‘line’,

                            line: m

                        });

   

                        if (salesOrderLineId == invoiceLineId) {

                            // Get the value from the Sales Order line field

                            let salesOrderLineFieldValue = salesOrder.getSublistValue({

                                sublistId: ‘item’,

                                fieldId: ‘quantitybilled’, // Replace with the actual field ID from Sales Order

                                line: m

                            });

   

                            // Subtract this value from the total quantity

                            totalQuantity -= salesOrderLineFieldValue;

                            log.debug(‘Adjusted Quantity for Invoice Line’, ‘Original Quantity: ‘ + orderLineQuantities[invoiceLineId] + ‘, Sales Order Line Field Value: ‘ + salesOrderLineFieldValue + ‘, Adjusted Quantity: ‘ + totalQuantity);

                            break;

                        }

                    }

   

                    // Set the adjusted quantity on the Invoice line

                    invoice.setSublistValue({

                        sublistId: ‘item’,

                        fieldId: ‘quantity’,

                        line: i,

                        value: totalQuantity

                    });

                } else {

                    log.debug(‘No Match Found for Invoice Line’, ‘Removing Line’);

                    invoice.removeLine({

                        sublistId: ‘item’,

                        line: i

                    });

                }

            }

   

            log.debug(‘Before Save Invoice’, ‘Attempting to save invoice’);

            let invoiceId = invoice.save({ignoreMandatoryFields: true});

            log.debug(‘Invoice Created’, ‘Invoice ID: ‘ + invoiceId);

        } catch (e) {

            // Log detailed error message

            log.error(‘Error Transforming Sales Order to Invoice’, ‘Sales Order ID: ‘ + salesOrderId + ‘, Error: ‘ + e.name + ‘ – ‘ + e.message);

        }

    }

   

   

    function summarize(summary) {

        log.audit(‘Summary’, ‘Usage Consumed: ‘ + summary.usage);

        log.audit(‘Summary’, ‘Concurrency: ‘ + summary.concurrency);

        log.audit(‘Summary’, ‘Number of Yields: ‘ + summary.yields);

        summary.output.iterator().each(function(key, value) {

            log.audit(‘Reduce Result’, ‘Key: ‘ + key + ‘, Value: ‘ + value);

            return true;

        });

        if (summary.inputSummary.error) {

            log.error(‘Input Error’, summary.inputSummary.error);

        }

        summary.mapSummary.errors.iterator().each(function(key, error) {

            log.error(‘Map Error’, ‘Key: ‘ + key + ‘, Error: ‘ + error);

            return true;

        });

        summary.reduceSummary.errors.iterator().each(function(key, error) {

            log.error(‘Reduce Error’, ‘Key: ‘ + key + ‘, Error: ‘ + error);

            return true;

        });

    }

    return {

        getInputData: getInputData,

        map: map,

        reduce: reduce,

        summarize: summarize

    };

});

Leave a comment

Your email address will not be published. Required fields are marked *