Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
6.3 kB
2
Indexable
Never
import {Injectable} from '@angular/core';
import {WindowRef} from './window.reference';
import {ScriptService} from './scripts.service';
import {HttpClient} from '@angular/common/http';
import {AppSettingsService} from './appSettings/appSettings.service';
import {AppSettings} from '../models/app-settings';
import { UserActionTracker } from './user-action-tracker';
import { Constants } from '../constants';

export interface BoomerangConfig {
  readonly beacon_url: string;
  readonly click_url: string;
  readonly environmentName: string;
  readonly appId: string;
}

export class BoomerangCustomFields {
  public static readonly qte_num = 'qte_num';
  public static readonly qte_vrsn = 'qte_vrsn';
  public static readonly businessUnitID = 'businessUnitID';
  public static readonly quoteNumber = 'quoteNumber';
  public static readonly quoteVersion = 'quoteVersion';
  public static readonly solutionId = 'solutionId';
  public static readonly cartId = 'cartId';
  public static readonly customerCountry = 'customerCountry';
  public static readonly customerSegment = 'customerSegment';
  public static readonly customerSet = 'customerSet';
  public static readonly customerRegion = 'customerRegion';
  public static readonly salesOrderID = 'salesOrderID';
  public static readonly MultiOc = 'multioc';
}

interface PageNameReplacer {
  predicate: (text: string) => boolean;
  run: (text?: string) => string;
}

function replacement(regExp: RegExp, replaceWith: string): PageNameReplacer {
  return {predicate: (text: string) => regExp.test(text), run: () => replaceWith};
}

@Injectable()
export class BoomerangService {
  private static readonly defaultPageName: string = 'home';
  public pageNameMfe = () => { return Constants.BoomerangPageName};

  private static readonly replacements: PageNameReplacer[] = [
    replacement(/\/error-message\/\S*/i, 'error-message'),
    replacement(/\/order-review\/\S*/i, 'order-review'),
    replacement(/\/payment\/\S*/i, 'checkout/payment'),
    replacement(/salesapp\/payments\/\S*/i, 'checkout/payment'),
    replacement(/\/subscription-payment\/\S*/i, 'checkout/subscription-payment'),
    replacement(/\/quotes\/\S*/i, 'quotes'),
    replacement(/\/quote\/\S*/i, 'quote-details'),
    replacement(/salesapp\/quote\/\S\S\/\S\S\/\S*/i, 'quote-details'),
    replacement(/\/salesapp\/\S*\/\S*\/quote\/\S*/i, 'quote-details'),
    replacement(/salesapp\/quote\/\S\S\/\S\S*/i, 'quote-details'),
    replacement(/\/compliance-notification\/\S*/i, 'compliance-notification'),
    replacement(/access-denied\/\S*/i, 'access-denied'),
    replacement(/\/order-confirmation\/\S*/i, 'order-confirmation'),
    replacement(/\/order\/\S*/i, 'order'),
    replacement(/\/software-customer-information\/\S*/i, 'checkout/software-customer-information')
  ];

  private readonly _customFields: Map<string,any>;

  constructor(
    private readonly _window: WindowRef,
    private readonly _scriptsService: ScriptService,
    private readonly _appSettingsService: AppSettingsService,
    private readonly _httpClient: HttpClient,
    private readonly _uat: UserActionTracker,
  ) {
    this._customFields = new Map<string, any>();
  }

  public getPageName(): string {
    try {
      let pageName = this._window.nativeWindow.location.pathname;
      if (pageName) {
        BoomerangService.replacements.some(r => {
          if (r.predicate(pageName)) {
            pageName = r.run(pageName);
            return true;
          }
        });
      }
      return pageName || BoomerangService.defaultPageName;
    } catch (e) {
      console.error('Failed to get page name for Boomerang:', e);
      return BoomerangService.defaultPageName;
    }
  }


  public init(config: BoomerangConfig): Promise<void> {
    const boomerangScriptUrl = (config.environmentName === 'prod') ?
      '//afcs.dellcdn.com/boomerang/latest/boomerang-history.min.js' :
      '//afcs.dellcdn.com/boomerang/sit/boomerang-history.min.js';

    return this._scriptsService.loadScript(boomerangScriptUrl).then(() => {
      if (!this._window.nativeWindow.BOOMR) {
        return;
      }

      this._appSettingsService.get().subscribe((appSettings: AppSettings) => {
        this.readUser(appSettings.partnerServiceAPIUrl).subscribe(user => {
          this.startBoomerang(config, user);
        });
      });
    });
  }

  public setCustomUserField(name: string, value: any | undefined) { // TODO: change to `value: string | undefined`
    if (value) { // TODO: Delete nulls or do not allow to pass them at all?
      this._customFields.set(name, value);
    }
  }

  public getCustomFields() {
    return this._customFields;
  }

  private readUser(partnerServiceAPIUrl: string) {

    const apiUrl = `${partnerServiceAPIUrl}v1/boomerang/user`;
    return this._httpClient.get(apiUrl, {withCredentials: true});
  }

  private startBoomerang(config: BoomerangConfig, user: any) {
    const me = this;
    if (undefined !== user.category && undefined === user.profile_id) {
      user.profile_id = user.category;
      delete user.category;
    }

    // noinspection JSUnusedGlobalSymbols
    this._window.nativeWindow.BOOMR.init({
      autorun: false,
      beacon_type: 'POST',
      instrument_xhr: true,
      Errors: {
        enabled: true,
        sendAfterOnload: true
      },
      Continuity: {
        enabled: true,
        afterOnload: true,
        waitAfterOnload: 1000,
        monitorStats: false,
        monitorInteractions: false
      },
      History: {
        enabled: true,
        auto: true
      },
      beacon_url: config.beacon_url,
      clicks: {
        click_url: config.click_url,
        track_spa_clicks: true,
      },
      log: function () {
      },
      applicationInfo: {
        getAppId: () => config.appId,
        getServerName: () => config.environmentName,
        getUserObj: function getUserObj() {
          // noinspection UnnecessaryLocalVariableJS
          const newUser = {
            ...user,
            ...me._customFields,
            transactionId: me._uat.getTransactionId(),
            pageName: me.getPageName()
          };
          return newUser;
        }
      }
    });
  }
}