SUITE LET DESIGN WITH HTML FOR GETTING SALES ORDERS

Here is sample suitelet that fetches the sales order Id or customer Id given and returns the sales order from the netsuite.

define(['N/search', 'N/url', 'N/file'],
    (search, url, file) => {
        "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 SCRIPT_ID_UPDATE_SO = 'customscript_jj_sl_so_details_crys_192';
        const DEPLOY_ID_UPDATE_SO = 'customdeploy_jj_sl_so_details_crys_192';


        function getSalesOrderDetails(customer, salesOrder) {
            try {
                let searchFilter = [
                    ["type", "anyof", "SalesOrd"],
                    // "AND",
                    // ["status", "anyof", "SalesOrd:G"],
                    "AND",
                    ["mainline", "is", "T"]
                ];


                if (customer) {
                    searchFilter.push("AND", ["name", "anyof", customer]);
                }
                else if (salesOrder) {
                    searchFilter.push("AND", ["internalid", "anyof", salesOrder]);
                }
                let salesorderSearchObj = search.create({
                    type: "salesorder",


                    filters: searchFilter,
                    columns:
                        [search.createColumn({ name: "internalid", label: "Internal ID" }),
                        search.createColumn({ name: "tranid", label: "Document Number" }),
                        search.createColumn({ name: "entity", label: "Name" }),
                        search.createColumn({ name: "statusref", label: "Status" }),
                        ]
                });
                let results = [];
                log.debug('filterArray', searchFilter)
                let searchResultCount = salesorderSearchObj.runPaged().count;
                log.debug("Sales Order Search Count", searchResultCount);


                salesorderSearchObj.run().each((result) => {
                    results.push({
                        salesOrderId: result.getValue({ name: "internalid" }),
                        salesOrderNo: result.getValue({ name: "tranid" }),
                        customerName: result.getText({ name: "entity" }),
                        status: result.getText({ name: "statusref" })
                    });
                    return true;
                });
                return results;
            } catch (error) {
                log.error('error @getSalesOrderDetails', e);
                return {};
            }
        }
        function salesOrderSelect(scriptContext, backgroundFileUrl, fullFileUrl, urlUpdateSO) {
            try {
                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 Update</title>    
                    <style>
                        body {
                            font-family: 'Montserrat', sans-serif;
                            margin: 0;
                            padding: 0;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            height: 100vh;
                            flex-direction: column;
                            background: url('${backgroundFileUrl.replace(/"/g, '"')}') no-repeat center center/cover;
                        }
                        
                        .container {
                            max-width: 600px;
                            width: 90%;
                            padding: 20px;
                            text-align: center;
                            border: 1px solid #ddd;
                            border-radius: 10px;
                            background: rgba(220, 220, 220, 0.25);
                            margin-bottom: 20px;
                        }
                        .results-container {
                            max-width: 900px;
                            width: 90%;
                            padding: 20px;
                            border: 1px solid #ddd;
                            border-radius: 10px;
                            background: rgba(220, 220, 220, 0.25);
                            text-align: center;
                            overflow-x: auto;
                        }
                        
                        /* Logo Styling */
                        .logo {
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            margin-bottom: 20px;
                        }
                        .logo img {
                            max-width: 180px; /* Ensures a max width for responsiveness */
                            height: auto; /* Maintains aspect ratio */
                            object-fit: contain;
                        }
        
                        h1 {
                            font-size: 1.8rem;
                            margin-bottom: 20px;
                        }
                        .form-group {
                            margin-bottom: 20px;
                        }
                        .input-group {
                            display: flex;
                            flex-direction: column;
                            align-items: flex-start;
                            margin-bottom: 15px;
                        }
                        label {
                            font-size: 1rem;
                            font-weight: bold;
                            margin-bottom: 5px;
                        }
                        input {
                            padding: 10px;
                            font-size: 16px;
                            border: 1px solid #999;
                            border-radius: 5px;
                            width: 100%;
                            box-sizing: border-box;
                        }
                        button {
                            padding: 10px 20px;
                            font-size: 16px;
                            border: none;
                            background-color: #007bff;
                            color: white;
                            cursor: pointer;
                            border-radius: 5px;
                            width: 100%;
                            box-sizing: border-box;
                        }
                        button:hover {
                            background-color: #0056b3;
                        }
                        #salesOrderList {
                            margin-top: 20px;
                            max-height: 400px;
                            overflow-y: auto;
                            box-sizing: border-box;
                        }
                        table {
                            width: 100%;
                            border-collapse: collapse;
                            font-family: Arial, sans-serif;
                            margin-top: 20px;
                            table-layout: auto;
                            min-width: 800px;
                        }
                        th, td {
                            border: 1px solid #ddd;
                            padding: 12px;
                            text-align: left;
                            white-space: nowrap;
                        }
                        th {
                            background-color: #4CAF50;
                            color: white;
                            font-size: 1rem;
                        }
                        tr:nth-child(even) {
                            background-color: #f2f2f2;
                        }
                        tr:hover {
                            background-color: #ddd;
                        }
                        a {
                            text-decoration: none;
                            color: #007bff;
                            font-weight: bold;
                        }
                        a:hover {
                            color: #0056b3;
                        }
                    </style>
                </head>
                <body>
                    <div class="container">
                        <!-- Logo Section -->
                        <div class="logo">
                            <img src="${fullFileUrl.replace(/"/g, '"')}" alt="Company Logo">
                        </div>
        
                        <!-- Search Form Container -->
                        <h1>Sales Order Updation</h1>
                        <div class="form-group">
                            <div class="input-group">
                                <label for="salesOrderId">Enter Sales Order ID:</label>
                                <input type="text" id="salesOrderId" placeholder="Enter Sales Order ID">
                            </div>
                            <div class="input-group">
                                <label for="customerId">Enter Customer ID:</label>
                                <input type="text" id="customerId" placeholder="Enter Customer ID">
                            </div>
                            <button id="fetchSalesOrders">SEARCH</button>
                        </div>
                    </div>
        
                    <!-- Results Container -->
                    <div class="results-container">
                        <h2>Search Results</h2>
                        <div id="salesOrderList"></div>
                    </div>
                    
                    <script>
                        document.addEventListener("DOMContentLoaded", function () {
                            document.getElementById("fetchSalesOrders").addEventListener("click", fetchSalesOrders);
                        });
                        let urlUpdateSO = "${urlUpdateSO}";
                        function fetchSalesOrders() {
                            let salesOrderId = document.getElementById("salesOrderId").value.trim();
                            let customerId = document.getElementById("customerId").value.trim();
                            let resultElement = document.getElementById("salesOrderList");
        
                            if (!salesOrderId && !customerId) {
                                resultElement.innerHTML = "<p style='color: red;'>⚠️ Please enter at least one search field</p>";
                                return;
                            }
        
                            fetch(window.location.href, {
                                method: "POST",
                                headers: { "Content-Type": "application/json" },
                                body: JSON.stringify({ salesOrderId, customerId })
                            })
                            .then(response => response.json())
                            .then(data => {
                                if (data.success && data.orders.length > 0) {
                                    let tableHtml = `
                                    <table>
                                    <tr>
                                        <th>No</th>
                                        <th>Sales Order No</th>
                                        <th>Customer Name</th>
                                        <th>Status</th>
                                        <th>Update</th>
                                    </tr>`;
                                    data.orders.forEach((order, index) => {
                                        tableHtml += `
                                            <tr>
                                                <td>${index + 1}</td>
                                                <td>${order.salesOrderNo}</td>
                                                <td>${order.customerName}</td>
                                                <td>${order.status}</td>
                                                <td><a href="${urlUpdateSO}&salesOrderId=${order.salesOrderId}" target="_blank">Update</a></td>
                                            </tr>`;
                                    });
        
                                    tableHtml += "</table>";
                                    resultElement.innerHTML = tableHtml;
        
                                    setTimeout(() => {
                                        window.scrollTo({ top: 0, behavior: 'smooth' });
                                        resultElement.scrollTop = 0;
                                    }, 100);
                                } else {
                                    resultElement.innerHTML = "<p style='color: red;'>❌ No Sales Orders Found</p>";
                                }
                            })
                            .catch(error => {
                                console.error("Error:", error);
                                resultElement.innerHTML = "<p style='color: red;'>❌ Error fetching Sales Orders</p>";
                            });
                        }
                    </script>
                </body>
                </html>`;
        
                scriptContext.response.write(htmlContent);
            } catch (e) {
                log.error('Error @ salesOrderSelect', e);
            }
        }
        
        
        /**
        * 
        * @param {*} request 
        * @returns 
        */
        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 '';
            }
        }
        /**
         * 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 resolveScriptUrl(scriptId, deploymentId, isExternal) {
            try {
                return url.resolveScript({
                    scriptId: scriptId,
                    deploymentId: deploymentId,
                    returnExternalUrl: isExternal,
                });
            } catch (error) {
               log.error('error @resolveScriptUrl',error) 
            }
            
        }
        /**
         * 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);
                let urlUpdateSO = resolveScriptUrl(SCRIPT_ID_UPDATE_SO, DEPLOY_ID_UPDATE_SO, isExternal);
                if (scriptContext.request.method === 'GET') {
                    let backgroundFileUrl = getFileUrl(BACKGROUND_IMAGE_PATH);
                    let fullFileUrl = getFileUrl(LOGO_FILE_PATH);
                    salesOrderSelect(scriptContext, backgroundFileUrl, fullFileUrl, urlUpdateSO);
                }
                else if (scriptContext.request.method === 'POST') {
                    log.debug('scriptContext', scriptContext.request.body);
                    let requestData = JSON.parse(scriptContext.request.body);  // Parse incoming JSON data
                    let salesOrders = getSalesOrderDetails(requestData.customerId, requestData.salesOrderId);
                    scriptContext.response.write(JSON.stringify({
                        success: true,
                        orders: salesOrders,
                        urlUpdateSO: urlUpdateSO
                    }));
                }
            }
            catch (e) {
                log.error('error @onRequest', e);
                scriptContext.response.write(JSON.stringify({
                    success: false,
                    message: e.message
                }));
            }
        };
        return { onRequest };
    });

Leave a comment

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