Display ‘Eligible For Return’ or ‘Not Eligible For Return’ products in return authoraization based on custom condition.

Description: We can use this solution to show the products as ‘Eligible for Return’ or ‘Not Eligible for Return’ with custom conditions like personalized product and order date. and made customers only return eligible items.

JavaScript:

_.extend(ReturnAuthorizationFormView.ReturnAuthorizationFormView.prototype, {
          template: jj_return_authorization_form_tpl,
          //initListHeader function is updated as needed for the returnable items
          initListHeader: function() {
            try {
              const LINES = this.getReturnableItems();
              this.listHeader = new ListHeaderView({
                view: this,
                application: this.application,
                hideFilterExpandable: true,
                collection: LINES,
                selectable: true
              });
              if (LINES.length === 1) {
                this.selectAll();
              }
              return this;
            } catch (error) {
              console.error('Error @ initListHeader', error);
            }
          },
          //updating childviews as based on the returnable items.
          childViews: _.extend(ReturnAuthorizationFormView.ReturnAuthorizationFormView.prototype.childViews, {
            'Returnable.Lines.Collection': function () {
              try {
                let returnableItems = this.getReturnableItems();
                return new BackboneCollectionView({
                  collection: returnableItems,
                  childView: TransactionLineViewsCellSelectableActionableNavigableView,
                  viewsPerRow: 1,
                  childViewOptions: {
                    SummaryView: ReturnAuthorizationFormItemSummaryView,
                    ActionsView: ReturnAuthorizationFormItemActionsView,
                    actionsOptions: {
                      activeLinesLength: returnableItems.length ? this.getActiveLines().length || 0 : 0,
                      reasons: this.reasons
                    },
                    application: this.application,
                    navigable: !this.application.isStandalone,
                    actionType: 'return-line'
                  }
                });
              } catch (error) {
                console.error('Error @ Returnable.Lines.Collection', error);
              }
            },
            'Invalid.Lines.Collection': function () {
              try {
                let defaultInvalidLines = this.createdFromModel.get('invalidLines');
                let nonReturnableItems = this.getNonReturnableItems();
                let previousReturns = this.createdFromModel.get('returnauthorizations');
                let returnCollection = [];
                _.each(previousReturns.models, returns => _.each(returns.lines, item => returnCollection.push(item)));
                _.each(defaultInvalidLines.models, item => {
                  _.each(returnCollection, returnLine => {
                    if (returnLine && returnLine.item.itemid === item.get('item').get('itemid')) {
                      item.set('nonReturnReason', Configuration.get('Returns.returnedReason') ? Configuration.get('Returns.returnedReason'): 'Item has associated returns')
                    }
                  })
                })
                let invalidLines = [...defaultInvalidLines.models, ...nonReturnableItems];
                _.each(invalidLines, line => {
                  if (!line.get('nonReturnReason')) {
                    line.set('nonReturnReason', Configuration.get('Returns.nonFullfilledReason') ? Configuration.get('Returns.nonFullfilledReason'): 'Item needs to be fullfilled for return')
                  }
                })
                return new BackboneCollectionView({
                  collection: invalidLines,
                  childView: TransactionLineViewsCellNavigableView,
                  viewsPerRow: 1,
                  childViewOptions: {
                    navigable: !this.application.isStandalone,
                    detail1Title: Utils.translate('Qty:'),
                    detail1: 'quantity',
                    detail2Title: Utils.translate('Unit price'),
                    detail2: 'rate_formatted',
                    detail3Title: Utils.translate('Amount:'),
                    detail3: 'total_formatted'
                  }
                });
              } catch (error) {
                console.error('Error @ Invalid.Lines.Collection', error);
              }
            }
          }),
          //getReturnableItems function is used to get only retunable items.
          getReturnableItems: function () {
            try {
              let itemsCollection = this.getLines();
              let itemFullfillments = this.createdFromModel.get('fulfillments').models;
              let returnableItems = _.filter(itemsCollection.models, item => {
                let hasFullfillment = _.find(itemFullfillments, fullfillment => {
                  return _.find(fullfillment.lines, line=> line.internalid === item.id)
                })
                let orderDate = new Date(hasFullfillment.date);
                let currentDate = new Date();
                orderDate.setDate(orderDate.getDate() + 40);
                let personalizedOptions = _.filter(item.get('options').models, option => {
                  return (
                    (option.get('cartOptionId') === 'custcol_jj_ptc_395_personalisesaying' && option.get('value').internalid !== '') ||
                    (option.get('cartOptionId') === 'custcol_jj_ptc_395_personalisefont' && option.get('value').internalid !== '')
                  )
                })
                return personalizedOptions.length === 0 && currentDate <= orderDate
              })
              return returnableItems;
            } catch (error) {
              console.error('Error @ getReturnableItems', error);
            }
          },
          // getNonReturnableItems function is used to get Non-returnable items.
          getNonReturnableItems: function () {
            try {
              let itemsCollection = this.getLines();
              let itemFullfillments = this.createdFromModel.get('fulfillments').models;
              let nonReturnableItems = _.filter(itemsCollection.models, item => {
                let hasFullfillment = _.find(itemFullfillments, fullfillment => {
                  return _.find(fullfillment.lines, line=> line.internalid === item.id)
                })
                let orderDate = new Date(hasFullfillment.date);
                let currentDate = new Date();
                orderDate.setDate(orderDate.getDate() + 40);
                let personalizedOptions = _.filter(item.get('options').models, option => {
                  return (
                    (option.get('cartOptionId') === 'custcol_jj_ptc_395_personalisesaying' && option.get('value').internalid !== '') ||
                    (option.get('cartOptionId') === 'custcol_jj_ptc_395_personalisefont' && option.get('value').internalid !== '')
                  )
                })
                if (personalizedOptions.length > 0) {
                  item.set('nonReturnReason', Configuration.get('Returns.monogramReason') ? Configuration.get('Returns.monogramReason') : 'Product is customaized by monogram')
                } else if (currentDate > orderDate) {
                  item.set('nonReturnReason', Configuration.get('Returns.shippReason') ? Configuration.get('Returns.shippReason') : 'Item was shippid more than 35 days ago')
                }
                return personalizedOptions.length > 0 || currentDate > orderDate;
              })
              return nonReturnableItems;
            } catch (error) {
              console.error('Error @ getNonReturnableItems', error);
            }
          },
          //updated the setLinefunctions to effect only to returnable items.
          setLines: function(attributes) {
            try {
              _.each(this.getReturnableItems(), function(line) {
                line.set(attributes);
              });
              return this;
            } catch (error) {
              console.error('Error @ setLines', error);
            }
          },
          getContext: _.wrap(ReturnAuthorizationFormView.ReturnAuthorizationFormView.prototype.getContext, function (fn) {
            try {
              let context = fn.apply(this, _.toArray(arguments).slice(0));
              let defaultInvalidLines = this.createdFromModel.get('invalidLines');
              let nonReturnableItems = this.getNonReturnableItems();
              context.itemsToReturnLength = (this.getReturnableItems()).length;
              context.hasItemsToReturn = context.itemsToReturnLength !== 0;
              context.itemsToReturnLengthGreaterThan1 = (this.getReturnableItems()).length > 1;
              context.showInvalidLines = (defaultInvalidLines.models.length + nonReturnableItems.length) > 0;
              context.invalidLinesLength = (defaultInvalidLines.models.length + nonReturnableItems.length);
              context.activeLinesLength = context.itemsToReturnLength ? context.activeLinesLength : 0;
              context.hasAtLeastOneActiveLine = context.itemsToReturnLength ? context.hasAtLeastOneActiveLine : 0;
              return context;
            } catch (error) {
              console.error('Error @ GetContext', error);
            }
          })
        })

Template:

{{#if showBackToAccount}}
  <a href="/" class="return-authorization-form-button-back">
    <i class="return-authorization-form-button-back-icon"></i>
    {{translate 'Back to Account'}}
  </a>
{{/if}}
<section class="return-authorization-form">
  <header>
    <h2 class="return-authorization-form-title">{{pageHeader}}</h2>
  </header>
  <div data-type="alert-placeholder"></div>
  <form class="return-authorization-form-form">
    <fieldset class="return-authorization-form-items-fieldset">
      <p class="return-authorization-form-items-info">
        {{translate '<label class="return-authorization-form-items-fieldset-from-label">From: </label><a href="$(0)">Purchase #$(1)</a>' createdFromURL model.tranid}}
      </p>
      <input type="hidden" name="type" value="{{model.recordtype}}">
      <h5 class="return-authorization-form-products-title">{{translate 'Select products to return'}}</h5>
      <input type="hidden" name="id" value="{{model.internalid}}">
      <div data-view="ListHeader"></div>
      {{#if hasItemsToReturn}}
      <div class="eligible-returns-container">
        <h3 class="product-return-eligibility-header">{{translate 'Eligible Products For Return'}}</h3>
        <div class="return-authorization-form-list">
          <table class="return-authorization-form-returnable-products-table md2sm">
              <tbody data-view="Returnable.Lines.Collection"></tbody>
          </table>
        </div>
      </div>
      {{/if}}
      <p>
        <small class="return-authorization-form-counter-legend">
          {{#if activeLinesLengthGreaterThan1}}
            {{translate '<b>$(0)</b> products selected' activeLinesLength}}
          {{else}}
            {{translate '<b>$(0)</b> product selected' activeLinesLength}}
          {{/if}}
        </small>
      </p>
      <p>
        <small class="return-authorization-form-counter-legend">
          {{#if itemsToReturnLengthGreaterThan1}}
            {{translate '<b>$(0)</b> items in total to return' itemsToReturnLength}}
          {{else}}
            {{translate '<b>$(0)</b> item in total to return' itemsToReturnLength}}
          {{/if}}
        </small>
      </p>
    </fieldset>
    {{#if showInvalidLines}}
    <div class="eligible-returns-container">
      <h3 class="product-return-eligibility-header">{{translate 'Not Eligible Products For Return'}}</h3>
      <div data-content="items-body">
          <table class="return-authorization-form-products-list">
            <thead class="return-authorization-form-table-products-header">
              <th class="return-authorization-form-table-products-header-image"></th>
              <th class="return-authorization-form-table-products-header-product">{{translate 'Product'}}</th>
              <th class="return-authorization-form-table-products-header-qty">{{translate 'Qty'}}</th>
              <th class="return-authorization-form-table-products-header-unit-price">{{translate 'Unit price'}}</th>
              <th class="return-authorization-form-table-products-header-amount">{{translate 'Amount'}}</th>
            </thead>
            <tbody data-view="Invalid.Lines.Collection"></tbody>
          </table>
      </div>
    </div>
    {{/if}}
    <fieldset class="return-authorization-form-comment-fieldset">
      <label class="return-authorization-form-comment-label" for="comment">{{translate 'Add a comment <span class="return-authorization-form-comment-label-optional">(optional)</span>'}}</label>
      <textarea data-action="comments"  class="return-authorization-form-comment" rows="4">{{comments}}</textarea>
    </fieldset>
    <div class="form-actions">
      <button type="submit" class="return-authorization-form-submit-button" {{#unless hasAtLeastOneActiveLine}}disabled{{/unless}}>{{translate 'Submit Request'}}</button>
    </div>
  </form>
</section>
{{!----
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.


----}}


Screenshot:

Leave a comment

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