SUITE LET SAMPLE TO ADD ITEMS IN THE ALREADY EXISTING SALES ORDER LINES

Here is a sample suitelet code that can add item by scanning the QR code and add this item item in the sales order table.

/**
 * @NApiVersion 2.1
 * @NScriptType Suitelet
 */
define(['N/record', 'N/file', 'N/search', 'N/url'],
    /**
 * @param{record} record
 */
    (record, file, search, url) => {
        "use strict";
        const BACKGROUND_IMAGE_PATH = 'SuiteScripts/Jobin and Jismi IT ServicesLLP/CRYS-94 QR Code Scanning/layer.svg';
        const LOGO_FILE_PATH = 'SuiteScripts/Jobin and Jismi IT ServicesLLP/CRYS-94 QR Code Scanning/CT-Logo-900x214.png';
        const ITEM_HTML_PATH = "SuiteScripts/Jobin and Jismi IT ServicesLLP/CRYS-94 QR Code Scanning/jj_html_scan_item_qr_code_scanning_crys96.html";
        const SCRIPT_ID_UPDATE_SO = 'customscript_jj_sl_so_details_crys_192';
        const DEPLOY_ID_UPDATE_SO = 'customdeploy_jj_sl_so_details_crys_192';
        function getsalesOrder(salesOrderId) {
            try {
                let salesOrderSearchObj = search.create({
                    type: "salesorder",
                    filters: [
                            ["type", "anyof", "SalesOrd"],
                        "AND", ["internalid", "anyof", salesOrderId],
                        "AND", ["mainline", "is", "F"],
                        "AND", ["taxline", "is", "F"],
                        "AND", ["shipping", "is", "F"]
                        ],
                    columns: [
                            search.createColumn({ name: "item", label: "Item" }),
                            search.createColumn({ name: "rate", label: "Item Rate" }),
                            search.createColumn({ name: "quantity", label: "Quantity" }),
                            search.createColumn({ name: "amount", label: "Amount" }),
                            search.createColumn({ name: "taxcode", label: "Tax Item" }),
                            search.createColumn({ name: "taxgroup", join: "taxItem", label: "Tax Group" }),
                            search.createColumn({ name: "rate", join: "taxItem", label: "Rate" }),
                            search.createColumn({ name: "entity", label: "Customer Name" }),
                            search.createColumn({
                                name: "custentity_jj_cus_member_category",
                                join: "customerMain",
                                label: "Membership Category"
                             })
                            
                        ]
                });
                let results = [];
                let customerId = "", customerCategory = "";


                salesOrderSearchObj.run().each(result => {
                    results.push({
                        itemName: result.getValue({ name: "item" }),
                        itemRate: result.getValue({ name: "rate" }),
                        itemQuantity: result.getValue({ name: "quantity" }),
                        itemAmount: result.getValue({ name: "amount" }),
                        taxgroup: result.getText({ name: "taxcode" }),
                        taxrate: result.getText({ name: "taxgroup", join: "taxItem",}),
                    })
                    if (!customerId) {
                        customerId = result.getText("entity");
                        customerCategory = result.getText({ name: "custentity_jj_cus_member_category", join: "customerMain" });
                    }
                    return true;
                });
                return { customerId, customerCategory, items: results }; // Return customer ID and items
            } catch (error) {
                log.error('error @getsalesOrder', error)
                return { customerId: "", items: [] };
            }
        }
        function salesOrderDetailsPage(scriptContext, backgroundFileUrl, fullFileUrl, salesOrderdetails, itemhtmlFileUrl, scanningPageUrl, itemLine) {
            try {
                if(itemLine)
                {
                log.debug('itemLine',itemLine)
                }
                let salesOrderJson = JSON.stringify(salesOrderdetails.items || []);
                let customerId = salesOrderdetails.customerId || "N/A";
                let customerCategory = salesOrderdetails.customerCategory || "N/A";
                let htmlContent = `<!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <title>Sales Order Details</title>
                    <style>
                        body {
                            font-family: 'Montserrat', sans-serif;
                            margin: 0;
                            padding: 0;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            min-height: 100vh;
                            flex-direction: column;
                            background: url('${backgroundFileUrl.replace(/"/g, '"')}') no-repeat center center/cover;
                        }
        
                        .container {
                            width: 90%;
                            max-width: 1200px;
                            min-height: 80vh;
                            margin: auto;
                            padding: 40px;
                            border-radius: 10px;
                            background: rgba(220, 220, 220, 0.25);
                            box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
                        }
        
                        .logo {
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            width: 100%;
                            margin-bottom: 10px;
                        }
        
                        .logo img {
                            max-width: 180px;
                            height: auto;
                            object-fit: contain;
                        }
        
                        h2 {
                            text-align: center;
                            margin-bottom: 20px;
                            font-size: 2rem;
                        }
        
                        table {
                            width: 100%;
                            margin-bottom: 20px;
                            border: 2px solid black;
                        }
        
                        th, td {
                            border: 2px solid #ddd;
                            padding: 10px;
                            text-align: center;
                            vertical-align: middle;
                        }
        
                        th {
                            background-color: #007bff;
                            color: white;
                        }
        
                        button {
                            padding: 10px 15px;
                            border: none;
                            cursor: pointer;
                            font-size: 14px;
                            margin-top: 10px;
                            transition: all 0.3s ease-in-out;
                        }
        
                        .remove-btn {
                            background-color: red;
                            color: white;
                        }
        
                        .add-btn {
                            background-color: green;
                            color: white;
                        }
        
                        .save-btn {
                            background-color: #007bff;
                            color: white;
                        }
                    </style>
                </head>
                <body>
                    <div class="container">
                        <div class="logo">
                            <img src="${fullFileUrl.replace(/"/g, '"')}" alt="Company Logo">
                        </div>
                        <h2>Sales Order Details</h2>
                        <p><strong>Sales Order ID:</strong> <span id="salesOrderId"></span></p>
                        <p><strong>Customer Name:</strong> <span id="customerId">${customerId}</span></p>
                        <p><strong>Customer Category:</strong> <span id="customerCategory">${customerCategory}</span></p>
                        <table id="salesOrderTable">
                            <thead>
                                <tr>
                                    <th>Item Name</th>
                                    <th>Quantity</th>
                                    <th>Price</th>
                                    <th>Tax Group</th>
                                    <th>Tax Rate</th>
                                    <th>Action</th>
                                </tr>
                            </thead>
                            <tbody id="orderItems"></tbody>
                        </table>
                        <button class="add-btn" onclick="addNewItem()">+ Add Item</button>
                        <button class="save-btn" onclick="saveOrder()">Save</button>
                    </div>
                
                    <script>


                        
                        salesOrderId = new URLSearchParams(window.location.search).get("salesOrderId");
                        document.getElementById("salesOrderId").textContent = salesOrderId;
                        orderItems = ${salesOrderJson};
        
                        function renderOrderItems() {
                            let tableBody = document.getElementById("orderItems");
                            tableBody.innerHTML = "";
        
                            orderItems.forEach((item, index) => {
                                let row = `
                                <tr>
                                    <td>${item.itemName}</td>
                                    <td><input type="number" value="${item.itemQuantity}" min="1"></td>
                                    <td>${item.itemRate}</td>
                                    <td>${item.taxGroup}</td>
                                    <td>${item.taxRate}</td>
                                    <td><button class="remove-btn" onclick="removeItem(${index})">Remove</button></td>
                                </tr>`;
                                tableBody.innerHTML += row;
                            });
                        }
                        renderOrderItems();
        
                        function removeItem(index) {
                            orderItems.splice(index, 1);
                            renderOrderItems();
                        }
        
                        function itemscanning(fileUrl, suiteletUrl) {
                            try {
                                if (suiteletUrl) {
                                    fileUrl += "?suiteletUrl=" + encodeURIComponent(suiteletUrl);
                                }
                                let scanWindow = window.open(fileUrl, "_blank", "width=650, height=650, left=400");
                            } catch (e) {
                                console.error("Error in itemscanning:", e);
                            }
                        }
        
                        function addNewItem() {
                            itemscanning("${itemhtmlFileUrl}", "${scanningPageUrl}");
                        }
                        async function getSuiteletUrl() {
                            try {
                                let urlParams = new URLSearchParams(window.location.search);
                                let itemInternalId = urlParams.get("itemInternalId");
                                console.log('itemInternalId',itemInternalId)
                            } catch (error) {
                                console.error("Error fetching item:", error);
                            }
                        }
        
                        async function saveOrder() {
                            try {
                                let response = await fetch("/updateSalesOrder", {
                                    method: "POST",
                                    headers: { "Content-Type": "application/json" },
                                    body: JSON.stringify({ salesOrderId, items: orderItems })
                                });
        
                                let data = await response.json();
                                if (data.success) {
                                    alert("Sales Order Updated Successfully!");
                                    window.location.href = "/";
                                } else {
                                    alert("Failed to update Sales Order.");
                                }
                            } catch (error) {
                                console.error("Error saving order:", error);
                            }
                        }
        
                        getSuiteletUrl();
                        if(${itemLine}){
                        console.log('itemLine',${itemLine})
                        }           
                    </script>
                </body>
                </html>`;
        
                scriptContext.response.write(htmlContent);
            } catch (error) {
                log.error("Error @ salesOrderDetailsPage", error);
            }
        }
        


        function checkIfExternal(request) {
            try {
                let host = request.headers['host'];


                // Ensure host is defined before proceeding
                if (!host) {
                    throw new Error("Host header is undefined");
                }


                // NetSuite external URLs usually contain '.extforms.netsuite.com'
                return host.includes('.extforms.netsuite.com');
            } catch (error) {
                log.error("Error in checkIfExternal", error);
                return false; // Default to false in case of an error
            }
        }
        /**
        * Retrieves the full URL of a file given its path or ID.
        *
        * @param {string} filePath - The path or ID of the file to load.
        * @returns {string} The full URL of the file, or an empty string if an error occurs.Domain(filePath)
        */
        function getFileUrl(filePath) {
            try {
                // Load the file using its path or ID
                let fileObj = file.load({
                    id: filePath
                });


                // Retrieve the relative URL of the file
                let fileRelativeUrl = fileObj.url;


                // Use the `N / url` module to get the base domain dynamically
                let baseDomain = url.resolveDomain({ hostType: url.HostType.APPLICATION });


                // Construct and return the full file URL
                return 'https://' + baseDomain + fileRelativeUrl;


            } catch (error) {
                log.error("Error loading file", error);
                return '';
            }
        }
         /**
         * Retrieves the relative URL of a file without the domain.
         *
         * @param {string} filePath - The path or ID of the file to load.
         * @returns {string} The relative URL of the file, or an empty string if an error occurs.
         */
         function getFileUrlNoDomain(filePath) {
            try {
                // Load the file using its path or ID
                let fileObj = file.load({
                    id: filePath
                });
                // Retrieve the relative URL of the file
                let fileRelativeUrl = fileObj.url;
                return fileRelativeUrl;
            } catch (error) {
                log.error("Error loading file", error);
                return '';
            }
        }
        /**
         * Resolves the URL for a given script and deployment.
         *
         * @param {string} scriptId - The internal ID of the script.
         * @param {string} deploymentId - The internal ID of the script deployment.
         * @returns {string} The resolved URL for the script deployment.
         */
        function getResolvedUrl(scriptId, deploymentId, isExternal) {
        try {
            return url.resolveScript({
                scriptId: scriptId,
                deploymentId: deploymentId,
                returnExternalUrl: isExternal,
            });
        } catch (error) {
            log.error('error @getResolvedUrl',error)
        }
        }



        function getNewItem(itemInternalId, customerCategory) { 
            try {
                if (!itemInternalId) {
                    log.error("Error @getNewItem", "Item Internal ID is missing.");
                    return null;
                }
        
                let filter = [
                    ["type", "anyof", "InvtPart"], 
                    "AND", ["internalid", "anyof", itemInternalId]
                ];
        
                if (customerCategory) {
                    filter.push("AND", ["pricing.pricelevel", "anyof", 3]);
                } else {
                    filter.push("AND", ["pricing.pricelevel", "anyof", 1]);
                }
        
                let inventoryItemSearchObj = search.create({
                    type: "inventoryitem",
                    filters: filter,
                    columns: [
                        search.createColumn({ name: "internalid", label: "Internal ID" }),
                        search.createColumn({ name: "itemid", label: "Item Name" }),
                        search.createColumn({ name: "baseprice", label: "Base Price" }),
                        search.createColumn({ name: "unitprice", join: "pricing", label: "Unit Price" }),
                        search.createColumn({ name: "pricelevel", join: "pricing", label: "Price Level" })
                    ]
                });
        
                let searchResults = inventoryItemSearchObj.run().getRange({ start: 0, end: 1 });
                if (searchResults.length > 0) {
                    let result = searchResults[0];
                    return {
                        id: result.getValue({ name: "internalid" }),
                        name: result.getValue({ name: "itemid" }),
                        rate: result.getValue({ name: "unitprice", join: "pricing" }) || result.getValue({ name: "baseprice" }) || 0,
                        quantity: 1
                    };
                } else {
                    return null;
                }
            } catch (error) {
                log.error("Error @getNewItem", error);
                return null;
            }
        }
        


        /**
         * Defines the Suitelet script trigger point.
         * @param {Object} scriptContext
         * @param {ServerRequest} scriptContext.request - Incoming request
         * @param {ServerResponse} scriptContext.response - Suitelet response
         * @since 2015.2
         */
        const onRequest = (scriptContext) => {
            try {
                let isExternal = false;
                isExternal = checkIfExternal(scriptContext.request);
                log.debug('isExternal', isExternal);
                log.debug('script context', scriptContext.request.parameters)


                if (scriptContext.request.method === 'GET') {
                    let backgroundFileUrl = getFileUrl(BACKGROUND_IMAGE_PATH);
                    let fullFileUrl = getFileUrl(LOGO_FILE_PATH);
                    let salesOrder = scriptContext.request.parameters.salesOrderId;
                    let salesOrderdetails = getsalesOrder(salesOrder)
                    let itemhtmlFileUrl = getFileUrlNoDomain(ITEM_HTML_PATH);
                    let scanningPageUrl = getResolvedUrl('customscript_jj_sl_so_details_crys_192', 'customdeploy_jj_sl_so_details_crys_192', isExternal);
                    let itemLine = {}
                    
                    let params = scriptContext.request.parameters;
                    if ('PreRecId' in params) {
                        log.debug('removing PrerecId', params.PreRecId)
                        delete params.PreRecId;


                    }
                    let itemInternalId = scriptContext.request.parameters.itemInternalId;
                    log.debug('itemInternalId',itemInternalId);
                    if(itemInternalId)
                    {
                        let customerCategory = salesOrderDetailsPage.customerCategory                        
                        itemLine = getNewItem(itemInternalId, customerCategory);
                        itemLine = JSON.stringify(itemLine);
                        log.debug('itemLine',itemLine)
                        salesOrderDetailsPage(scriptContext, backgroundFileUrl, fullFileUrl, salesOrderdetails, itemhtmlFileUrl, scanningPageUrl, itemLine);
                    }
                    salesOrderDetailsPage(scriptContext, backgroundFileUrl, fullFileUrl, salesOrderdetails, itemhtmlFileUrl, scanningPageUrl, itemLine = null);
                }
            }
            catch (e) {
                log.error('Error in onRequest', e);
            }
        };
        
        return { onRequest }


    });

Leave a comment

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