Add PO, Comments, Expected delivery date, office hours in checkout page

We have to add some new fields on the checkout page. The requirement of the task is shown below.

Update the checkout page by providing the following fields.

  • Input field for adding Purchase order number.
  • Input field for adding Comments during order process
  • A static text field for displaying Office hours.
  • Input field for adding Expected delivery date.

All data entered during checkout will be stored in respective fields within the sales order for easy reference.

Solution

  • The PO (Purchase order number) field is default in SCA. When the checkbox to show the PO field on the checkout is checked on the website setup, it will display on the checkout page and the value will be stored in the corresponding field. We just made the field mandatory.
  • Created two fields in the so record named ‘EXPECTED DELIVERY DATE’ and ‘COMMENTS (CONFIRMATION NUMBER)’.
  • The office hours field is made configurable from config record and its value is no need to save to the SO record.
  • The description under the Expected delivery date field on the website is also configurable. We can set the expected delivery date to two days from today on the field and its value will be saved to ‘EXPECTED DELIVERY DATE’ field in the SO record.
  • The comments field value needs to be saved memo field in the SO where the label of the field is ‘CONFIRMATION NUMBER’. And also, the field is standard field in the SO record, so we can’t directly save the value to the SO record. When SO is created, the confirmation number is saved to the field by default.
  • So we created a new field in the SO record named ‘COMMENTS (CONFIRMATION NUMBER)’. The value from the CONFIRMATION NUMBER (memo) will be set to the new field and the comments we have given from the webstore while placing the order will be saved to the CONFIRMATION NUMBER field.

Entrypoint file

 var checkout = container.getComponent('Checkout');
                this.opcrendered = false;
                var self = this;
                if (checkout) {
                    checkout.on("afterShowContent", function () {
                        checkout.getCurrentStep().then(function (step) {
                            if ((step.url == "opc" && !self.opcrendered)) {
                                checkout.addModuleToStep({
                                    step_url: 'opc',
                                    module: {
                                        id: 'checkoutFieldsView',
                                        index: 7,
                                        classname: 'JJ.CheckoutPageUpdate.checkoutfields.View'
                                    }
                                });
                                self.opcrendered = true
                            }
                        })
                    })
                }
                _.extend(OrderWizardModulePaymentMethodPurchaseNumber.prototype, {
                    template: jj_order_wizard_paymentmethod_purchasenumber_module_tpl,
                    // To make the po field mandatory
                    submit: function () {
                        var poNumber = this.$('[name=purchase-order-number]').val() || '';
                        var poErrorMessage = document.getElementById('purchase-history-error-message');
                        if (poNumber.trim() === '') {
                            var errorMessage = Utils.translate('Purchase Order Number is mandatory. Please fill it.');
                            var global_view_message = new GlobalViewsMessageView({
                                message: errorMessage,
                                type: 'error',
                                closable: true
                            });
                            this.$('#purchase-history-error-message')
                                .empty()
                                .append(global_view_message.render().$el.html());
                            return jQuery.Deferred().reject();  // Prevent form submission                           
                        } else {
                            poErrorMessage.innerHTML = ''; // Clear the error message
                            this.wizard.model.set('purchasenumber', poNumber);
                            return jQuery.Deferred().resolve(); // Allow form submission
                        }
                    }
                });
                _.extend(WizardView.prototype, {
                    getContext: _.wrap(WizardView.prototype.getContext, function (fn) {
                        var context = fn.apply(this, _.toArray(arguments).slice(1));
                        try {
                            var cart = container.getComponent('Cart');
                            var selectedExpDate = this.wizard.selectedExpDate;
                            var commentsOnOrder = this.wizard.commentsOnOrder;


                            if (!!commentsOnOrder) {
                                var data = {
                                    fieldId: "custbody_comments",
                                    type: "string",
                                    value: commentsOnOrder
                                }
                                cart.setTransactionBodyField(data).then(function () {
                                    console.log(data.fieldId + ' was set to ' + data.value);
                                }).fail(function (error) {
                                    console.log("error@commentsOnOrder", error);
                                });
                            }


                            if (!!selectedExpDate) {
                                var inputDateString = selectedExpDate;
                                var parts = inputDateString.split('-');
                                var year = parseInt(parts[0], 10);
                                var month = parseInt(parts[1], 10) - 1; // Months are 0-indexed in JavaScript
                                var day = parseInt(parts[2], 10);
                                // Create a Date object
                                var date = new Date(year, month, day);
                                var dateinfo = {
                                    fieldId: "custbody_exp_del_date",
                                    type: "date",
                                    value: date
                                }
                                cart.setTransactionBodyField(dateinfo).then(function () {
                                    console.log(dateinfo.fieldId + ' was set to ' + dateinfo.value);
                                }).fail(function (error) {
                                    console.log("error@selectedExpDate", error);
                                });
                            }
                        } catch (e) {
                            console.log("error@WizardViewcontext", e);
                        }
                        return context;
                    })
                });


                _.extend(OrderWizardModuleConfirmation.prototype, {
                    getContext: _.wrap(OrderWizardModuleConfirmation.prototype.getContext, function getContext(fn) {
                        var context = fn.apply(this, _.toArray(arguments).slice(1));
                        try {
                            var orderId = this.model.get('confirmation').get('internalid');
                            this.memoModel = new CheckoutPageUpdateSS2Model({ id: orderId });
                            this.memoModel.fetch({
                            }).done(function (result) {
                                console.log("return confirm memofield", result);
                            });
                        } catch (e) {
                            console.log("err@OrderWizardModuleConfirmation", e);
                        }
                        return context;
                    })
                });

View file

return WizardModule.extend({


            template: jj_checkoutpageupdate_checkoutfields_tpl


            , events: {
                'change [data-action="save-comments"]': "saveComments",
                'change [data-action="save-date"]': "setDeliveryDate",
            }
            , setDeliveryDate: function setDeliveryDate() {
                try {
                    const dateInput = document.getElementById('selected-date');
                    const selectedDate = dateInput.value;
                    this.wizard.selectedExpDate = selectedDate;
                } catch (error) {
                    console.log('error@error', error);
                }
            }
            , saveComments: function () {
                try {
                    const dataInput = document.getElementById('comments-on-order');
                    const commentsOnOrder = dataInput.value;
                    this.wizard.commentsOnOrder = commentsOnOrder;
                } catch (error) {
                    console.log("err@saveValue", e);
                }
            }


            , getContext: function getContext() {


                var deliveryDateDesc = SC.CONFIGURATION.get('checkoutfields.deliverydatedesc');
                var officeHoursInfo = SC.CONFIGURATION.get('checkoutfields.officehoursinfo');
                var date = this.wizard.selectedExpDate;
                var today = new Date();
                var yyyy = today.getFullYear();
                var mm = String(today.getMonth() + 1).padStart(2, '0');
                var dd = String(today.getDate() + 3).padStart(2, '0');
                var minDate = `${yyyy}-${mm}-${dd}`;
                return {
                    startDate: minDate,
                    date: date,
                    deliveryDateDesc: deliveryDateDesc,
                    officeHoursInfo: officeHoursInfo
                };
            }
        });

Template file

1. Template for the new fields

<div class="order-wizard-add-date-and-comments-module">
  <!-- Section for expected delivery date -->
  <div class="order-wizard-add-date-section">
    <h3 class="order-wizard-delivery-date-module-title">
      {{translate 'Expected Delivery Date'}}
    </h3>
    <br>
    <p class="order-wizard-address-module-message-show">{{translate deliveryDateDesc}}</p>
    <br>
    <input class="list-header-view-delivery-body-input" id="selected-date" name="selected-date" type="date"
      placeholder="Date" data-start-date="{{startDate}}" autocomplete="off" data-format="yyyy-mm-dd" value="{{date}}"
      data-action="save-date" data-todayhighlight="true" />
  </div>
  <!-- Section for comments -->
  <div class="order-wizard-add-comments-section">
    <h3 class="order-wizard-add-comments-module-title">
      {{translate 'Add Comments Here'}}
    </h3>


    <div class="order-wizard-add-comments-module-row">
      <textarea class="order-wizard-add-comments-module-values {{text}}" id="comments-on-order" name="addcomments"
        placeholder="Write your comments here" data-action="save-comments"></textarea>
    </div>
  </div>


  <!-- Section for office hours text -->
  <div class="order-wizard-office-hours-section">
    <h3 class="order-wizard-office-hours-module-title">
      {{translate 'Office Hours'}}
    </h3>


    <div class="office-hours-section">
      {{#if officeHoursInfo}}
      {{{officeHoursInfo}}}
      {{else}}
      <p>
        Our office hours for inquiries and communications are:
        <br>
        Monday to Friday: 9:00 AM - 5:00 PM
        <br>
        Saturday: 10:00 AM - 2:00 PM
        <br>
        Sunday: Closed
      </p>
      {{/if}}
    </div>
  </div>
</div>

2. Purchase order template for validation

<div class="order-wizard-paymentmethod-purchasenumber-module">
    <h3 class="order-wizard-paymentmethod-purchasenumber-module-title">
        {{translate 'Purchase Order Number'}}
    </h3>
    <div class="order-wizard-paymentmethod-purchasenumber-module-row">
        <label for="purchase-order-number" id="order-wizard-paymentmethod-purchasenumber"
            class="order-wizard-paymentmethod-purchasenumber-module-purchase-order-label">
            {{translate 'Enter Purchase Order Number'}} <span
                class="order-wizard-paymentmethod-purchasenumber-module-purchase-order-optional"> {{ translate
                '(Required)' }} </span>
        </label>
        <input type="text" name="purchase-order-number" id="purchase-order-number"
            class="order-wizard-paymentmethod-purchasenumber-module-purchase-order-value" value="{{purchaseNumber}}">
    </div>
    <!-- Add the error message container -->
    <div id="purchase-history-error-message" class="order-wizard-paymentmethod-purchasenumber-error-message"></div>
</div>


{{!----
The context variables for this template are not currently documented. Use the {{log this}} helper to view the context
variables in the Console of your browser's developer tools.


----}}

Suitescript file

define(['N/record'],function (record) {
    "use strict";


    function saveOrderDetails(context) {
        try {


            var OrderId = context.request.parameters ? (context.request.parameters.internalid) : null;
            var salesOrder = record.load({
                type: record.Type.SALES_ORDER,
                id: OrderId,
                isDynamic: true // Set to true if you need to interact with sublist data
            });
            var currentMemo = salesOrder.getValue('custbody_comments');
            var oldMemo = salesOrder.getValue('memo');
            salesOrder.setValue({
                fieldId: 'memo',
                value: currentMemo
            });
            salesOrder.setValue({
                fieldId: 'custbody_comments',
                value: oldMemo
            });
            var id = salesOrder.save();
        } catch (error) {
            log.error('Error fetching order details', error);
        }
        return context.response.write(JSON.stringify({ salesorder: OrderId }));
    }
    return {
        service: saveOrderDetails
    };
});

Leave a comment

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