In stock verification

Description

We need to create a script that sends an email to the customer who clicks on the “Notify when item is in stock” button when the item is back in stock. The Custom record created when the button is clicked will be removed after sending the email

/**
 * @NApiVersion 2.x
 * @NScriptType MapReduceScript
 * @NModuleScope SameAccount
 */
/****************************************************************************



BP-21 In stock verification - PDP

Date: 14/07/2021

Author: Jobin & Jismi IT Services LLP

Script Description : Send Email to the Customer when the item is back in stock and delete the record from customer record list

Date created : 14 July 2021

 

REVISION HISTORY

 

Revision 1.0 14/07/2021 md: Create

 

****************************************************************************/
define(
   [
      'N/email',
      'N/runtime',
      'N/search',
      'N/error',
      'N/log',
      'N/record',
      'N/render',
      'N/file',
      './underscore.custom'

   ], function (
      email,
      runtime,
      search,
      error,
      log,
      record,
      render,
      file,
      _
   ) {
   var Utils = {
      record: 'customrecord_back_in_stock',
      getSku: function (values) {
         var parent = values['GROUP(parent.CUSTRECORD_BACK_ITEM)'];
         var child = values['GROUP(custrecord_back_item)'];        
         if (parent && parent.text !== '- None -') {
            parent = parent.text;
          //  log.debug("parentsubsku",child.text.split(":")[1])
            return child.text.split(":")[1];
         } else {           
            return values['GROUP(custrecord_back_item)'].text;
         }
      },
      baseUrl: function (site) {
         if (site.value === Utils.getParameterByKey('custscript_bp_id')) {
            return Utils.getParameterByKey('custscript_bp_url');
         }
      },
      getParameterByKey: function getParameterByKey(key) {
         var script = runtime.getCurrentScript();
         return script.getParameter({ name: key });
      },
      renderHTML: function renderHTML(items, customer, site) {
         try {

            // log.debug('renderHTMLsgfg', { items: items, customer: customer, site: site })

             var renderer = render.create();
             renderer.addCustomDataSource({
                 format: render.DataSource.JSON,
                 alias: 'ITEMS',
                 data: JSON.stringify({ items: _.isArray(items) ? items : [items] })
             });

             renderer.addCustomDataSource({
                 format: render.DataSource.JSON,
                 alias: 'CUSTOMER',
                 data: JSON.stringify(customer)
             });

             renderer.addCustomDataSource({
                 format: render.DataSource.JSON,
                 alias: 'SITE',
                 data: JSON.stringify(site)
             });

             log.debug('renderer', renderer)

             var templateFile = file.load({
                 id: Utils.getParameterByKey('custscript_template')
             });
            
            var tplHtml = templateFile.getContents();
            
            renderer.templateContent = tplHtml;
            
            return renderer.renderAsString();
         } catch (e) {
             log.error('renderHTML', e)
         }
     },
      sendEmail: function sendEmail(items, customer, site) {
         try {
           // var body = 'Hello,\n' + "These items are now back in stock"
            email.send({
               author: Utils.getParameterByKey('custscript_email_author'),
               recipients: customer.id,
               subject: site.name + Utils.getParameterByKey('custscript_email_subject'),
               body: Utils.renderHTML(items, customer, site),
               relatedRecords: {
                   entityId: customer.id
               }
            });
         } catch (e) {
            log.error('sendEmail', e)
         }

      },
      getWebstoreAvailableLocations: function getWebstoreAvailableLocations() {
         // get all the locations that expose stock to the webstore
         var locations = [];
         var locationSearchObj = search.create({
            type: 'location',
            filters: [
               ['isinactive', 'is', 'F'],
               'AND',
               ['makeinventoryavailablestore', 'is', 'T']
            ],
            columns: [
               search.createColumn({ name: "internalid", label: "Internal ID" })
            ]
         });
         var searchResultCount = locationSearchObj.runPaged().count;
         locationSearchObj.run().each(function (result) {
            locations.push(result.getValue('internalid'));
         
            return true;
         });

        // log.debug('locations', locations);
         return locations.join(',');
      }

   };

   function getInputData() {
      var locationIds;
      var isLocationsActivated = runtime.isFeatureInEffect({ feature: 'locations' });
     // log.debug('isLocationsActivated', isLocationsActivated);

      var filters = [
         ["isinactive", "is", "F"],
         "AND",
         ["custrecord_back_sent", "is", "F"],
         "AND",
         ["custrecord_back_site", "anyof", "3"],
         "AND",
         ['custrecord_back_item.isonline', 'is', 'T'],
         'AND',
         ["custrecord_back_item.locationquantityavailable", "isnotempty", ""]
      ];
      var columns = [
         search.createColumn({
            name: "custrecord_back_customer",
            summary: "GROUP",
            label: "Customer"
         }),
         search.createColumn({
            name: "custrecord_back_item",
            summary: "GROUP",
            label: "Item"
         }),
         search.createColumn({
            name: "custrecord_back_site",
            summary: "GROUP",
            label: "Site"
         }),
         search.createColumn({
            name: "custrecord_back_sent",
            summary: "GROUP",
            label: "Sent"
         }),
         search.createColumn({
            name: "internalid",
            summary: "GROUP",
            label: "Internal ID"
         }),
         search.createColumn({
            name: "custrecord_back_language",
            summary: "GROUP",
            label: "Language"
         }),
         search.createColumn({
            name: "custrecord_back_locale",
            summary: "GROUP",
            label: "Locale"
         }),
         search.createColumn({
            name: "displayname",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "Display Name"
         }),
         search.createColumn({
            name: "storedisplayname",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "Store Display Name"
         }),
         search.createColumn({
            name: "urlcomponent",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "URL Component"
         }),
         search.createColumn({
            name: "parent",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "Parent"
         }),
         search.createColumn({
            name: "internalid",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "Internal ID"
         }),
         search.createColumn({
            name: "custrecord_back_item_parent",
            summary: "GROUP",
            label: "Item Parent"
         }),
         search.createColumn({
            name: "urlcomponent",
            join: "CUSTRECORD_BACK_ITEM_PARENT",
            summary: "GROUP",
            label: "URL Component"
         }),
         search.createColumn({
            name: "custrecord_back_currency",
            summary: "GROUP",
            label: "Currency"
         }),
         search.createColumn({
            name: "firstname",
            join: "CUSTRECORD_BACK_CUSTOMER",
            summary: "GROUP",
            label: "First Name"
         }),
         search.createColumn({
            name: "lastname",
            join: "CUSTRECORD_BACK_CUSTOMER",
            summary: "GROUP",
            label: "Last Name"
         }),
         search.createColumn({
            name: "custitem_item_image",
            join: "CUSTRECORD_BACK_ITEM",
            summary: "GROUP",
            label: "Item_Image"
         })
      ]

      if (isLocationsActivated) {
         locationIds = Utils.getWebstoreAvailableLocations();
         filters.push(
            'AND',
            ['custrecord_back_item.inventorylocation', 'anyof', locationIds],
            'AND',
            ["sum(custrecord_back_item.locationquantityavailable)", "greaterthan", "0"]
         );
         columns.push(
            search.createColumn({
               name: "locationquantityavailable",
               join: "CUSTRECORD_BACK_ITEM",
               summary: "SUM",
               label: "Location Available"
            })
         )
      } else {
         filters.push(
            'AND',
            ["sum(custrecord_back_item.quantityavailable)", "greaterthan", "0"]
         );
         columns.push(
            search.createColumn({
               name: "quantityavailable",
               join: "CUSTRECORD_BACK_ITEM",
               summary: "SUM",
               label: "Available"
            })
         )
      }
      var customrecord_back_in_stockSearchObj = search.create({
         type: Utils.record,
         filters: filters,
         columns: columns
      });
    
      var searchResultCount = customrecord_back_in_stockSearchObj.runPaged().count;
      
      return customrecord_back_in_stockSearchObj;

   }


   function map(mapContext) {
      var data = JSON.parse(mapContext.value);
      var values = data.values;
      var recordSubs = {
         firstname: values['GROUP(firstname.CUSTRECORD_BACK_CUSTOMER)'],
         lastname: values['GROUP(lastname.CUSTRECORD_BACK_CUSTOMER)'],
         internalid: values['GROUP(internalid)'].value,
         customerid: values['GROUP(custrecord_back_customer)'].value,
         item: values['GROUP(custrecord_back_item)'],
         currency: values['GROUP(custrecord_back_currency)'],
         locale: values['GROUP(custrecord_back_locale)'],
         language: values['GROUP(custrecord_back_language)'],
         site: values['GROUP(custrecord_back_site)'],
         email: values['GROUP(custrecord_back_email)'],
         sent: values['GROUP(custrecord_back_sent)'],
         displayname: values['GROUP(displayname.CUSTRECORD_BACK_ITEM)'],
         storedisplayname: values['GROUP(storedisplayname.CUSTRECORD_BACK_ITEM)'],
         urlcomponent: values['GROUP(urlcomponent.CUSTRECORD_BACK_ITEM)'],
         parentItem: values['GROUP(custrecord_back_item_parent)'],
         parentUrl: values['GROUP(urlcomponent.custrecord_back_item_parent)'],
         sku: Utils.getSku(values),
         imgURl: values['GROUP(custitem_item_image.CUSTRECORD_BACK_ITEM)']
      };
          
      mapContext.write(recordSubs.site.id + '|' + recordSubs.customerid, recordSubs);
   }

   function reduce(reduceContext) {
       //send email for record
     // log.debug('reduceContext', reduceContext);
      var reduceValues = reduceContext.values;
      var itemsBp = [];
      var subscriptionsIds = [];
      var bpDetails;

      _.each(reduceContext.values, function(value) {
        
         var current = JSON.parse(value);
         var urlComponent = '';
         var displayName = current.storedisplayname;
         var imgURl = "http://bp.sca-jobinandjismi.ml/alphalifecare website Item Images/no_image_available.jpeg";

         if (current.parentItem && current.parentItem.value && current.parentUrl) {
            urlComponent = current.parentUrl === '- None -' ? Utils.baseUrl(current.site) + 'product/' + current.Item.value :
               Utils.baseUrl(current.site) + '/' + current.urlcomponent
         } else {
            urlComponent = current.urlcomponent === '- None -' ?
               Utils.baseUrl(current.site) + 'product/' + current.item.value :
               Utils.baseUrl(current.site) + '/' + current.urlcomponent;
         }
         if (!displayName || (displayName === '- None -')) {
            displayName = current.displayName;
         }
           if (!displayName || (displayName === '- None -')) {
                    displayName = current.sku;
                }
         if (current.imgURl != null && current.imgURl != '' && current.imgURl != "" && current.imgURl != undefined) {
            var imgFile = file.load({
               id: current.imgURl.value
            });

            imgURl = Utils.baseUrl(current.site) + '/alphalifecare website Item Images/' + encodeURIComponent(imgFile.name);
            
         }



         if (current.site.value === Utils.getParameterByKey('custscript_bp_id')) {
            bpDetails = current;
            itemsBp.push({ //item
               internalid: current.item,
               sku: current.sku,
               displayname: displayName,
               urlcomponent: urlComponent,
               imgURl: imgURl
            });
         }
           log.debug('itemsBp', itemsBp);
         subscriptionsIds.push(current.internalid);
        
      });

      if (itemsBp.length > 0) {
         log.debug('itemsBp', {
            itemsBp: itemsBp,
            customer: { // customer
               id: bpDetails.customerid,
               firstname: bpDetails.firstname === '- None -' ? '' : bpDetails.firstname,
               lastname: bpDetails.lastname === '- None -' ? '' : bpDetails.lastname
            },
            site: { //site
               name: bpDetails.site.text,
               baseUrl: Utils.baseUrl(bpDetails.site),

            }
         })
         Utils.sendEmail(
            itemsBp, { // customer
            id: bpDetails.customerid,
            firstname: bpDetails.firstname === '- None -' ? '' : bpDetails.firstname,
            lastname: bpDetails.lastname === '- None -' ? '' : bpDetails.lastname
         }, { //site
            name: bpDetails.site.text,
            baseUrl: Utils.baseUrl(bpDetails.site),

         }
         );
      }

      reduceContext.write('sentEmail', {
         subscriptionId: subscriptionsIds
     });
   }


   function summarize(summarizeContext) {
      var errorMessage = '';
    if (summarizeContext.inputSummary.error) {
         errorMessage += summarizeContext.inputSummary.error + '\n';
        // log.error('Input Error', summarizeContext.inputSummary.error);
     }
     summarizeContext.mapSummary.errors.iterator().each(function(key, error) {
       //  log.error('Map Error for key: ' + key, error);
         errorMessage += 'Map Error for key: ' + key + '\n' + error + '\n';
     });
     summarizeContext.reduceSummary.errors.iterator().each(function(key, error) {
         //log.error('Reduce Error for key: ' + key, error);
         errorMessage += 'Reduce Error for key: ' + key + '\n' + error + '\n';
     });

     // mark as sent if no errors
     if (errorMessage === '') {
         summarizeContext.output.iterator().each(function(key, value) {
             value = JSON.parse(value);
             _.each(value.subscriptionId, function(id) {
                 log.debug('update email sent for -->', JSON.stringify(id));
                 
                 record.delete({
                  type: Utils.record,
                  id: id
                 })

               //   record.submitFields({
               //       type: Utils.record,
               //       id: id,
               //       values: {
               //           'custrecord_back_sent': 'F'
               //       }
               //   });
             });

             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 *