Map Reduce Script : Back Instock

Map Reduce script to “Send Email to the Customer when the item is back in stock and delete the record from customer record list”

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



BP-21 In stock verification - PDP

Date: 14/07/2021

Author: Rosemol

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')
             });
            // log.debug('templateFile', templateFile)

             var tplHtml = templateFile.getContents();
            // log.debug('tplHtml', tplHtml)

             renderer.templateContent = tplHtml;
            // log.debug('tplHtmlrenderer', renderer)

             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;
         log.debug("locationSearchObj result count", searchResultCount);
         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();
         log.debug('locationIds', locationIds);
         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;
      log.debug("customrecord_back_in_stockSearchObj result count", searchResultCount);

      return customrecord_back_in_stockSearchObj;

   }


   function map(mapContext) {
      var data = JSON.parse(mapContext.value);
      log.debug('datacheckkkkkkiiiiinnnnng', data)
      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);
         log.debug('current', current);
         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);
            // log.debug('imgURl', imgURl); 
         }



         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 *