UNPKG

portal-www

Version:

Nova Portal Website. Based on Next starter by Ueno

1,196 lines (1,079 loc) 38.6 kB
import { Cookies } from 'react-cookie'; import { ApolloClient } from '@apollo/client'; import { isProvisionedSubscriptionVariant } from 'beta/utils/typeGuards'; import { AVAILABLE_PHONE_NUMBERS } from 'graphql/queries/mobile-signup/numberPot'; import { PRODUCT_BY_ID, VARIANT_PRODUCT_BY_ID } from 'graphql/queries/mobile-signup/productById'; import { cloneDeep } from 'lodash'; import { extendObservable, makeObservable, observable, runInAction } from 'mobx'; import { alltSamanOfferStep, companyStaffStepsData, companyStepsData, staffSteps, staffStepsData, stepsData, } from 'pages/farsimi/kaupa/StepSetup'; import { AvailablePhoneNumbersQuery, CartItem, CartItemInput, ContactInfoInput, ContractExtraPayerInfoInput, ContractRequestType, MsisdnType, NumberType, OptionVariant, PhoneNumberRightHolderInfoInput, ProductByIdQuery, ProvisionedSubscriptionVariant, PurchaseInfo, PurchaseInfoInput, ServiceRequestInput, ServiceRequestType, SignupContractInput, SimCardType, SubscriptionVariantOptionType, UserInfoInput, Variant, VariantProductByIdQuery, } from 'typings/graphql'; import { hasMobileServiceRequest, hasValidPurchaseInfo } from 'utils/helpers'; import Authentication from './authentication'; import Cart from './cart'; import { SignupStep } from './signupSteps'; export enum MobileSignupProducts { Askrift = 'askrift', Frelsi = 'frelsi', Stakt = 'stakt', Fyrirtaeki = 'fyrirtaeki', Netkort = 'netkort', M2M = 'm2m', } export const UTLANDAPAKKI = 'farsimi-utlandapakki'; export const URLAUSN = 'urlausn'; export const SIM_CARD = 'plast-sim'; export const E_SIM_CARD = 'e-sim'; export const PHONE_NUMBERS = '150395'; export const SINGLE_OFFERING = '140140'; export const COMPANY = '150156'; export const COMPANY_NETKORT = '150129'; export const COMPANY_M2M = '150127'; export type ExtraServices = 'farsimi-utlandapakki' | 'urlausn'; type SimCardPurchaseInfo = Pick< PurchaseInfoInput, 'iccid' | 'numberType' | 'phoneNumber' | 'serviceCartItemId' | 'simCardType' >; type ServicePurchaseInfo = { service: Pick< ServiceRequestInput, | 'portInDate' | 'isUnregisteredPlan' | 'type' | 'phoneNumber' | 'isNewNumber' | 'user' | 'mobileSignupRightHolder' >; contract: Pick<SignupContractInput, 'cartItemId' | 'type'>; departmentId?: string; invoiceExplanation?: string; contractExtraPayerInfo?: ContractExtraPayerInfoInput; }; type CompanyInfoInput = { departmentId?: string; invoiceExplanation?: string; contractExtraPayerInfo?: ContractExtraPayerInfoInput; }; export const throwErrorWithMessage = (error: unknown, customMessage: string) => { if (error instanceof Error) { const errorMesage = `${customMessage}: ${error.message}`; // eslint-disable-next-line no-console console.log(errorMesage); } }; export type MobileSignupProductsType = keyof typeof MobileSignupProducts; const goldNumberVariant = 'simanumer-gull'; const normalNumberVariant = 'simanumer-venjulegt'; const netNumberVariant = 'simanumer-netnumer'; export default class MobileSignup { private client: ApolloClient<object>; private cart: Cart; private authentication: Authentication; constructor( { mobileSignup = {} }, client: ApolloClient<object>, cart: Cart, cookies: string | object | null | undefined, authentication: Authentication, ) { this.cookies = new Cookies(cookies); makeObservable(this, { primaryVariant: observable, extraVariants: observable, secondaryVariant: observable, selectedSubscriptionType: observable, servicePurchaseInfo: observable, variantInfoRecord: observable, simCardPurchaseInfo: observable, updatingCartItem: observable, askriftMonthly: observable, frelsiMobileMonthly: observable, isOskrad: observable, isCompany: observable, selectedQuestionVariant: observable, selectedRequiredOption: observable, selectedProvisionedVariantOption: observable, steps: observable, isEligibleForNetNet: observable, activateOnAnotherDevice: observable, deviceType: observable, randomNetnumer: observable, }); extendObservable(this, mobileSignup); this.client = client; this.cart = cart; this.authentication = authentication; } cookies; isEligibleForNetNet: boolean = false; activateOnAnotherDevice: boolean = false; isOskrad: boolean = false; isCompany: boolean = false; deviceType: string = ''; primaryVariant: string = ''; secondaryVariant: string = ''; extraVariants: Array<string> = []; updatingCartItem: string | undefined = undefined; frelsiMobileInternet: (OptionVariant | undefined)[] = []; frelsiMobileKronur: (OptionVariant | undefined)[] = []; frelsiMobileMonthly: (OptionVariant | undefined)[] = []; askriftMonthly: (OptionVariant | undefined)[] = []; selectedRequiredOption: OptionVariant | undefined = undefined; selectedProvisionedVariantOption: ProvisionedSubscriptionVariant | undefined = undefined; phoneNumberVariants: Variant[] = []; randomNetnumer: string = ''; variantInfoRecord: Record< string, { price: number; name: string; } > = {}; foreignPacks: (OptionVariant | undefined)[] = []; selectedSubscriptionType: MobileSignupProducts | undefined = undefined; selectedQuestionVariant: string | undefined = undefined; steps: Array<SignupStep> = stepsData; servicePurchaseInfo: ServicePurchaseInfo = { departmentId: '', invoiceExplanation: '', contractExtraPayerInfo: { customerId: '', amount: undefined, }, service: { portInDate: undefined, isUnregisteredPlan: false, type: ServiceRequestType.Mobile, phoneNumber: '', mobileSignupRightHolder: { nationalId: '', email: '', }, isNewNumber: undefined, user: { customerId: '', email: '', name: '', nationalId: '', phoneNumber: '', }, }, contract: { cartItemId: '', type: ContractRequestType.New, }, }; simCardPurchaseInfo: SimCardPurchaseInfo = { iccid: '', // For Simcard numberType: undefined, serviceCartItemId: '', phoneNumber: '', // for portable number simCardType: undefined, }; // Getters get hasUtlandapakki() { return !!this.extraVariants.find((item) => item.includes(UTLANDAPAKKI)); } get isUpdatingSubscription() { return !!this.updatingCartItem; } get hasUrlausn() { return !!this.extraVariants.find((item) => item === URLAUSN); } get hasExtraServices() { return this.hasUrlausn || this.hasUtlandapakki; } hasPlasticSimCard = async () => { const cart = await this.cart.fetchCart(); return !!cart?.items.find((item) => item.purchaseInfo?.simCardType === SimCardType.Plastic); }; getVariantName = (variantId: string) => { return this.variantInfoRecord[variantId]?.name; }; getVariantPrice = (variantId: string) => { return this.variantInfoRecord[variantId]?.price; }; getRightHolder = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const items = cart?.items; const purchaseInfo = items?.find((item) => item.id === cartItemId)?.purchaseInfo; if ( purchaseInfo?.service?.__typename === 'MobileServiceRequest' && !purchaseInfo?.service?.isNewNumber ) { return purchaseInfo?.service?.mobileSignupRightHolder?.nationalId; } else { return null; } }; setIsOskrad = (value: boolean) => { this.isOskrad = value; }; setIsCompany = (value: boolean) => { this.isCompany = value; }; setRandomNetnumer = (value: string) => { this.randomNetnumer = value; }; // Variant setters setSelectedQuestionVariant = (variant: string | undefined) => { this.selectedQuestionVariant = variant; }; // Tell the signup which id user is updating in "Update inputs" Mode setUpdatingCartItemId = (cartItemId: string | undefined) => { this.updatingCartItem = cartItemId; }; setPrimaryVariant = (variantId: string) => { this.primaryVariant = variantId; }; setSecondaryVariant = (variantId: string) => { this.secondaryVariant = variantId; }; setExtraVariant = (variant: string) => { this.extraVariants.push(variant); }; removeExtraVariant = (variant: string) => { const filteredExtraVariants = this.extraVariants.filter((item) => item !== variant); this.extraVariants = filteredExtraVariants; }; setIsEligibleForNetNet = (isEligable: boolean) => { this.isEligibleForNetNet = isEligable; }; setIsActivatingOnAnotherDevice = (activateOnAnotherDevice: boolean) => { this.activateOnAnotherDevice = activateOnAnotherDevice; }; setDeviceType = (deviceType: string) => { this.deviceType = deviceType; }; // If user has utlandapakki and changes subscriptionType // We want to switch the pack to the correct one. switchUtlandaPakkiVariant = (variant: OptionVariant) => { const correctUtlandaPakki = this.foreignPacks.find((item) => item?.id !== variant.id); if (correctUtlandaPakki) { this.removeExtraVariant(variant.id); this.setExtraVariant(correctUtlandaPakki.id); } }; validConditions: Record<MobileSignupProducts, MobileSignupProducts> = { [MobileSignupProducts.Askrift]: MobileSignupProducts.Frelsi, [MobileSignupProducts.Frelsi]: MobileSignupProducts.Askrift, [MobileSignupProducts.Stakt]: MobileSignupProducts.Askrift, [MobileSignupProducts.Fyrirtaeki]: MobileSignupProducts.Fyrirtaeki, [MobileSignupProducts.Netkort]: MobileSignupProducts.Netkort, [MobileSignupProducts.M2M]: MobileSignupProducts.M2M, }; setSelectedSubscriptionType = (type: MobileSignupProducts) => { this.selectedSubscriptionType = type; const relatedType = this.validConditions[type]; const currentForeignPack = this.foreignPacks.find( (item) => item && this.extraVariants.includes(item.id), ); if (relatedType && currentForeignPack?.id.includes(relatedType)) { this.switchUtlandaPakkiVariant(currentForeignPack); } if (this.isOskrad) { if (type === MobileSignupProducts.Stakt || type === MobileSignupProducts.Frelsi) { this.setPrimaryVariant('frelsi-oskrad'); return; } } if (type === MobileSignupProducts.Stakt) { this.setPrimaryVariant(MobileSignupProducts.Frelsi); return; } this.setPrimaryVariant(type); }; setSelectedRequiredOption = (option: OptionVariant | undefined) => { this.selectedRequiredOption = option; }; setSelectedProvisionedVariantOption = (variant: ProvisionedSubscriptionVariant | undefined) => { this.selectedProvisionedVariantOption = variant; }; // PurchaseInfo setters setIccid = (iccid: string) => { if (this.servicePurchaseInfo.service) { this.simCardPurchaseInfo.iccid = iccid; } }; setPortingNumber = (number: string) => { this.servicePurchaseInfo.service.isNewNumber = false; this.servicePurchaseInfo.service.phoneNumber = number; this.simCardPurchaseInfo.phoneNumber = number; this.simCardPurchaseInfo.numberType = undefined; }; setSelectedNumer = (number: string, numberType: NumberType, isNetNumber?: boolean) => { const hasNormalNumberInCart = this.extraVariants.find( (item) => item === normalNumberVariant || item === netNumberVariant, ); const hasGoldNumberInCart = this.extraVariants.find((item) => item === goldNumberVariant); if (number === this.simCardPurchaseInfo.phoneNumber) { this.removeExtraVariant( numberType === NumberType.Gold ? (hasGoldNumberInCart as string) : (hasNormalNumberInCart as string), ); this.servicePurchaseInfo.service.isNewNumber = false; this.servicePurchaseInfo.service.phoneNumber = ''; this.simCardPurchaseInfo.numberType = undefined; this.simCardPurchaseInfo.phoneNumber = ''; } this.servicePurchaseInfo.service.isNewNumber = true; this.servicePurchaseInfo.service.phoneNumber = number; this.simCardPurchaseInfo.numberType = numberType; this.simCardPurchaseInfo.phoneNumber = number; if (numberType === NumberType.Gold) { if (!hasGoldNumberInCart) { this.setExtraVariant(goldNumberVariant); } this.removeExtraVariant(normalNumberVariant); } else { if (!hasNormalNumberInCart) { if (isNetNumber) { this.setExtraVariant(netNumberVariant); } else { this.setExtraVariant(normalNumberVariant); } } this.removeExtraVariant(goldNumberVariant); } }; setSimCardType = (type: SimCardType) => { if (type === SimCardType.Plastic) { this.extraVariants.push(SIM_CARD); this.removeExtraVariant(E_SIM_CARD); } if (type === SimCardType.ESim) { this.extraVariants.push(E_SIM_CARD); this.removeExtraVariant(SIM_CARD); } this.simCardPurchaseInfo.simCardType = type; }; setParentContractId = (parentId: string) => { if (this.servicePurchaseInfo.contract) { this.servicePurchaseInfo.contract.cartItemId = parentId; } }; setUserPurchaseInfo = (user: UserInfoInput) => { if (this.servicePurchaseInfo.service?.user) { this.servicePurchaseInfo.service.user = user; } }; setRightHolder = (rightHolder: PhoneNumberRightHolderInfoInput) => { if (this.servicePurchaseInfo.service?.mobileSignupRightHolder) { this.servicePurchaseInfo.service.mobileSignupRightHolder = rightHolder; } }; // Fetches fetchAllProducts = async () => { await this.fetchFrelsiMobileProduct(); await this.fetchAskriftMobileProduct(); await this.fetchPhoneNumberVariants(); await this.fetchAvailablePhoneNumbers(); this.addToVariantInfoRecord(); }; fetchPhoneNumberVariants = async () => { if (this.phoneNumberVariants.length !== 0) return null; try { const { data } = await this.client.query<VariantProductByIdQuery | undefined>({ query: VARIANT_PRODUCT_BY_ID, variables: { productId: PHONE_NUMBERS, }, }); runInAction(() => { const variants = data?.product?.variants; if (!variants?.length) null; else { this.phoneNumberVariants = variants as Variant[]; } }); } catch (e) { throwErrorWithMessage(e, 'Failed to fetch subscription data'); } }; fetchAvailablePhoneNumbers = async () => { if (this.randomNetnumer.length > 0) return null; try { const { data } = await this.client.query<AvailablePhoneNumbersQuery | undefined>({ query: AVAILABLE_PHONE_NUMBERS, variables: { input: { count: 1, type: MsisdnType.Normal }, }, }); runInAction(() => { const firstNumber = data?.availablePhoneNumbers?.length && data.availablePhoneNumbers.length > 0 ? data?.availablePhoneNumbers[0] : null; if (!firstNumber) null; else { this.randomNetnumer = firstNumber.phoneNumber ?? ''; } }); } catch (e) { throwErrorWithMessage(e, 'Failed to fetch available phone numbers'); } }; fetchAskriftMobileProduct = async () => { if (this.askriftMonthly.length !== 0) return null; try { const { data } = await this.client.query<ProductByIdQuery | undefined>({ query: PRODUCT_BY_ID, variables: { productId: '150149', }, }); runInAction(() => { const variants = data?.product?.variants; if (!variants?.length) null; else { const provisionedVariant = variants?.filter( (item) => item.__typename === 'ProvisionedSubscriptionVariant', ) as ProvisionedSubscriptionVariant[]; this.variantInfoRecord[`${provisionedVariant[0].id}`] = { price: 0, name: provisionedVariant[0].shortName ?? '', }; const subscriptionOptionsVariants = provisionedVariant[0].options?.find( (item) => item?.type === SubscriptionVariantOptionType.Required, )?.variants; const subscriptionForeignPack = provisionedVariant[0].options?.find( (item) => item?.type === SubscriptionVariantOptionType.Optional && item.variants[0].id.includes('utlanda'), )?.variants; if (subscriptionForeignPack) { this.foreignPacks.push(subscriptionForeignPack[0]); } this.askriftMonthly = subscriptionOptionsVariants || []; } }); } catch (e) { throwErrorWithMessage(e, 'Failed to fetch subscription data'); } }; fetchFrelsiMobileProduct = async () => { if ( this.frelsiMobileInternet.length !== 0 && this.frelsiMobileKronur.length !== 0 && this.frelsiMobileMonthly.length !== 0 ) return null; try { const { data } = await this.client.query<ProductByIdQuery | undefined>({ query: PRODUCT_BY_ID, variables: { productId: '150151', }, }); runInAction(() => { const variants = data?.product?.variants; if (!variants?.length) null; else { const provisionedVariant = variants?.filter(isProvisionedSubscriptionVariant); this.variantInfoRecord[`${provisionedVariant[0].id}`] = { price: 0, name: provisionedVariant[0].shortName ?? '', }; // Frelsi Monthly const frelsiSubscriptionType = provisionedVariant[0].options?.find( (item) => item?.type === SubscriptionVariantOptionType.Optional, )?.variants; this.frelsiMobileMonthly = frelsiSubscriptionType || []; // Frelsi Útlandapakki const frelsiForeignPack = provisionedVariant[0].options?.find( (item) => item?.type === SubscriptionVariantOptionType.Optional && item.variants[0].id.includes('utlanda'), )?.variants; if (frelsiForeignPack) { this.foreignPacks.push(frelsiForeignPack[0]); } // Frelsi Kronur const frelsiKronur = provisionedVariant[0].options?.filter( (item) => item?.type === SubscriptionVariantOptionType.Optional && item.variants[0].id.includes('afylling'), ); this.frelsiMobileKronur = frelsiKronur?.map((item) => item?.variants[0]) || []; // Frelsi Internet pakki const frelsiInternet = provisionedVariant[0].options?.filter( (item) => item?.type === SubscriptionVariantOptionType.Optional && item.variants[0].id.includes('netid'), ); this.frelsiMobileInternet = frelsiInternet?.map((item) => item?.variants[0]) || []; } }); } catch (e) { throwErrorWithMessage(e, 'Failed to fetch frelsi data'); } }; addToVariantInfoRecord = () => { [ ...this.askriftMonthly, ...this.frelsiMobileInternet, ...this.frelsiMobileKronur, ...this.frelsiMobileMonthly, ...this.phoneNumberVariants, ...this.foreignPacks, ].map((item) => { if (!item) return null; if (item.__typename === 'Variant') { this.variantInfoRecord[`${item.id}`] = { price: item.price, name: item.name, }; } if (item.__typename === 'OptionVariant') { if (item.variantDetails?.monthlyCharge) { this.variantInfoRecord[`${item?.id}`] = { price: item?.variantDetails?.monthlyCharge, name: item.variantDetails.name ?? '', }; } else if (item.variantDetails?.price) { this.variantInfoRecord[`${item?.id}`] = { price: item?.variantDetails?.price, name: item.variantDetails.name ?? '', }; } else { this.variantInfoRecord[`${item?.id}`] = { price: 0, name: item?.variantDetails?.name ?? '', }; } } }); }; addSubscriptionToCart = async (variantId: string) => { const subscriptionInput = { variantId, quantity: 1, purchaseInfo: {}, } as CartItemInput; try { const res = await this.cart.addToCart('mobileSignup', subscriptionInput); if (!this.cart.activeCartId && res?.cart?.addToCart.cart?.id) { this.cart.setActiveCartId(res?.cart?.addToCart.cart?.id); } } catch (e) { throwErrorWithMessage(e, 'Failed to add subscription to cart'); } }; addServiceToCart = async (serviceVariant: string, parentId: string) => { if (parentId && serviceVariant) { try { this.setParentContractId(parentId); const servicenInput = { variantId: serviceVariant, quantity: 1, purchaseInfo: this.servicePurchaseInfo, } as CartItemInput; await this.cart.addToCart('mobileSignup', servicenInput); } catch (e) { throwErrorWithMessage(e, 'Failed to add service to cart'); } } }; addExtraServicesToCart = async (serviceCartItemId: string) => { if (!this.extraVariants.length) return null; try { const promises = this.extraVariants.map(async (variantId) => { let extraServiceInput; if (variantId === URLAUSN) return null; if (variantId === UTLANDAPAKKI) { extraServiceInput = { variantId, quantity: 1, purchaseInfo: { serviceCartItemId, }, } as CartItemInput; } else { extraServiceInput = { variantId, quantity: 1, purchaseInfo: { ...this.simCardPurchaseInfo, serviceCartItemId, }, } as CartItemInput; } // Return the promise from addToCart return this.cart.addToCart('mobileSignup', extraServiceInput); }); // Wait for all promises to resolve await Promise.all(promises); } catch (e) { throwErrorWithMessage(e, 'Failed to add extra service to cart'); } }; addAllToCart = async () => { // Check if user has selected with home fiber variant before adding to cart // Auth step is behind the select subscription so we don't know for sure // if the customer has really has fiber. // Scroll to Subscription step if use doesn't have fiber and remove the fiber mobile variant await this.addSubscriptionToCart(this.primaryVariant); const parentId: string | undefined = await this.findParentSubscription(this.primaryVariant); if (parentId) { await this.addServiceToCart(this.secondaryVariant, parentId); const serviceItem = await this.findServiceItem(parentId); if (serviceItem) { await this.addExtraServicesToCart(serviceItem.id); } } }; addContactToCart = async (user: ContactInfoInput) => { const cart = await this.cart.fetchCart(); const { salesNumber } = this.cart; const contactInfo = { email: user?.email ?? cart?.contact?.email, msisdn: user?.msisdn ?? cart?.contact?.msisdn, ssn: user?.ssn ?? cart?.contact?.ssn, name: user?.name ?? cart?.contact?.name, address: user?.address ?? cart?.contact?.address, zip: user?.zip ?? cart?.contact?.zip, ...(user?.id && { id: user.id }), ...(salesNumber && { salesNumber: salesNumber }), }; if (!(cart?.contact?.id && !user?.id)) { try { await this.cart.updateCartContact(contactInfo); } catch (e) { throwErrorWithMessage(e, 'Failed to update contact on cart'); } } }; updateUserInfo = async (user: UserInfoInput, cartItemId: string) => { try { if (cartItemId) { const mobileServiceItem = await this.findServiceItem(cartItemId); const serviceItem = cloneDeep(mobileServiceItem); if (hasMobileServiceRequest(serviceItem)) { serviceItem.purchaseInfo.service.user.name = user.name; serviceItem.purchaseInfo.service.user.nationalId = user.nationalId; serviceItem.purchaseInfo.service.user.email = user.email; serviceItem.purchaseInfo.service.user.customerId = user.customerId ?? null; serviceItem.purchaseInfo.service.user.phoneNumber = user.phoneNumber ?? null; } if (serviceItem?.id && serviceItem?.variantId && hasValidPurchaseInfo(serviceItem)) { await this.cart.updateCartItem({ id: serviceItem?.id, variantId: serviceItem?.variantId, quantity: serviceItem?.quantity, purchaseInfo: serviceItem?.purchaseInfo, }); } } } catch (error) { throwErrorWithMessage(error, 'Ekki tókst að vista notanda'); } }; updateRightHolder = async (rightHolder: PhoneNumberRightHolderInfoInput, cartItemId: string) => { try { if (cartItemId) { const mobileServiceItem = await this.findServiceItem(cartItemId); const serviceItem = cloneDeep(mobileServiceItem); if (hasMobileServiceRequest(serviceItem)) { serviceItem.purchaseInfo.service.user.nationalId = rightHolder.nationalId; serviceItem.purchaseInfo.service.user.email = rightHolder.email; } if (serviceItem?.id && serviceItem?.variantId && hasValidPurchaseInfo(serviceItem)) { await this.cart.updateCartItem({ id: serviceItem?.id, variantId: serviceItem?.variantId, quantity: serviceItem?.quantity, purchaseInfo: serviceItem?.purchaseInfo, }); } } } catch (error) { throwErrorWithMessage(error, 'Ekki tókst að vista rétthafa'); } }; updateCompanyInfo = async (companyInfo: CompanyInfoInput, cartItemId: string) => { try { if (cartItemId) { const getContractItem = await this.findContractItem(cartItemId); const contractItem = cloneDeep(getContractItem); const signupContract = { invoiceExplanation: companyInfo?.invoiceExplanation, contractExtraPayerInfo: { amount: companyInfo?.contractExtraPayerInfo?.amount, customerId: companyInfo?.contractExtraPayerInfo?.customerId, }, departmentId: companyInfo?.departmentId, type: ContractRequestType.New, }; const purchaseInfo: PurchaseInfo = { ...signupContract, }; if (contractItem?.id && contractItem?.purchaseInfo) { await this.cart.updateCartItem({ id: contractItem?.id, variantId: contractItem?.variantId, quantity: contractItem?.quantity, purchaseInfo: purchaseInfo as PurchaseInfoInput, }); } } } catch (error) { throwErrorWithMessage(error, 'Ekki tókst að vista breytingar'); } }; // Helpers // Fill out purchaseInfo based on subscription fillPurchaseInfo = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const serviceItem = await this.findServiceItem(cartItemId); const serviceCartItemId = serviceItem?.id; const serviceItemPurchaseInfo = serviceItem?.purchaseInfo; if (serviceItemPurchaseInfo?.service) { const service = serviceItemPurchaseInfo.service; const contract = serviceItemPurchaseInfo.contract; if ( service.__typename === 'MobileServiceRequest' && contract?.__typename === 'SignupContract' ) { this.servicePurchaseInfo = { service: { phoneNumber: service.phoneNumber, isNewNumber: service.isNewNumber, portInDate: service.portInDate, type: ServiceRequestType.Mobile, mobileSignupRightHolder: { nationalId: service.mobileSignupRightHolder?.nationalId ?? '', email: service.mobileSignupRightHolder?.email ?? '', }, user: { customerId: service.user.customerId || '', email: service.user.email || '', name: service.user.name || '', nationalId: service.user.nationalId || '', phoneNumber: service.user.phoneNumber || '', }, }, contract: { cartItemId: contract.cartItemId, type: ContractRequestType.New, }, }; } } if (serviceCartItemId) { const simCardPurchaseInfo = cart?.items.filter((item) => { return item.purchaseInfo?.serviceCartItemId === serviceCartItemId; }); simCardPurchaseInfo?.map((item) => { if (item.variantId === SIM_CARD || item.variantId === E_SIM_CARD) { this.simCardPurchaseInfo = { ...this.simCardPurchaseInfo, iccid: item.purchaseInfo?.iccid || '', serviceCartItemId: item.purchaseInfo?.serviceCartItemId || '', simCardType: item.purchaseInfo?.simCardType || undefined, }; } if (item.variantId.includes('simanumer')) { this.simCardPurchaseInfo = { ...this.simCardPurchaseInfo, phoneNumber: item.purchaseInfo?.phoneNumber || '', numberType: item.purchaseInfo?.numberType || undefined, }; } }); } }; // Find Parent Subscription // There can be multiple 'askrift-25gb' for example // This searches for subscription that doesn't have // a service depending on it already. findParentSubscription = async (subscriptionId: string) => { const cart = await this.cart.fetchCart(); const subscription = cart?.items.filter((item) => item.variantId === subscriptionId); if (subscription && cart?.items.length === 1) return subscription[0].id; const idThatDoesntDepend = subscription?.find((subscriptionItem) => { return !cart?.items.some((serviceItem) => { if (!serviceItem.purchaseInfo?.contract) return false; // Return false if its subscription else { const check = serviceItem.purchaseInfo.contract.__typename === 'SignupContract' && serviceItem.purchaseInfo.contract.cartItemId === subscriptionItem.id; return check; } }); }); return idThatDoesntDepend?.id; }; // FindServiceItem based on Subscription cartItemId // We need this to point extra services to the findServiceItem = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const serviceItem = cart?.items.find((item) => { if (item.purchaseInfo?.contract?.__typename === 'SignupContract') { return item.purchaseInfo.contract.cartItemId === cartItemId; } }); if (serviceItem) { return serviceItem as CartItem; } }; findContractItem = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const contractItem = cart?.items.find((item) => { return item?.id === cartItemId; }); if (contractItem) { return contractItem as CartItem; } }; // Function to fetch a phoneNumber when user doesn't have a // a primary number registered in our db. getPortInNumberFromPayer = async (nationalId: string) => { const cart = await this.cart.fetchCart(); const newPrimaryPhoneNumber = cart?.items.find((item) => { if (item.purchaseInfo?.service?.__typename === 'MobileServiceRequest') { return ( item.purchaseInfo.service.mobileSignupRightHolder?.nationalId === nationalId && !item.purchaseInfo.service.isNewNumber ); } }); return ( newPrimaryPhoneNumber?.purchaseInfo?.service?.__typename === 'MobileServiceRequest' && newPrimaryPhoneNumber.purchaseInfo.service.phoneNumber ); }; reset = () => { this.selectedSubscriptionType = undefined; this.setUpdatingCartItemId(undefined); this.primaryVariant = ''; this.secondaryVariant = ''; this.extraVariants = []; this.simCardPurchaseInfo = { iccid: '', // For Simcard numberType: undefined, serviceCartItemId: '', phoneNumber: '', // for portable number simCardType: undefined, }; this.servicePurchaseInfo = { service: { portInDate: undefined, isUnregisteredPlan: false, type: ServiceRequestType.Mobile, phoneNumber: '', mobileSignupRightHolder: { nationalId: '', email: '', }, isNewNumber: undefined, user: { customerId: '', email: '', name: '', nationalId: '', phoneNumber: '', }, }, contract: { cartItemId: '', type: ContractRequestType.New, }, }; }; // When user is in "Update Inputs" Mode. We are using this to // update the cart. updateItems = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const subscription = cart?.items.find((item) => item.id === cartItemId); if (subscription?.variantId !== this.primaryVariant) { await this.updateSubscription(cartItemId); } await this.updateService(cartItemId); await this.updateExtraServices(cartItemId); }; updateSubscription = async (cartItemId: string) => { try { await this.cart.updateCartItem({ id: cartItemId, quantity: 1, variantId: this.primaryVariant, }); } catch (e) { throwErrorWithMessage(e, `failed to update subscription: ${cartItemId}`); } }; updateService = async (cartItemId: string) => { const serviceItem = await this.findServiceItem(cartItemId); try { await this.cart.updateCartItem({ id: serviceItem?.id, variantId: this.secondaryVariant, purchaseInfo: this.servicePurchaseInfo, quantity: 1, }); } catch (e) { throwErrorWithMessage(e, `Failed to update service: ${serviceItem?.variantId}`); } }; updateExtraServices = async (cartItemId: string) => { const cart = await this.cart.fetchCart(); const serviceItem = await this.findServiceItem(cartItemId); const serviceCartItemId = serviceItem?.id; const allRemovedServices = cart?.items.filter((item) => { return ( item.purchaseInfo?.serviceCartItemId === serviceCartItemId && !this.extraVariants.includes(item.variantId) ); }); if (allRemovedServices) { const removeVariantIds = allRemovedServices.map((item) => item.id); await this.removeExtraServices(removeVariantIds); } try { const updateCartItems = cart?.items.filter( (item) => item.purchaseInfo?.serviceCartItemId === serviceCartItemId && this.extraVariants.includes(item.variantId), ); const promises = updateCartItems?.map(async (item) => { let extraServiceInput; if (item.variantId === URLAUSN) return null; if (item.variantId.includes(UTLANDAPAKKI)) { extraServiceInput = { variantId: item.variantId, quantity: 1, purchaseInfo: { serviceCartItemId, }, } as CartItemInput; } else if (item.variantId.includes('simanumer')) { extraServiceInput = { id: item.id, variantId: item.variantId, quantity: 1, purchaseInfo: { phoneNumber: this.simCardPurchaseInfo.phoneNumber, numberType: this.simCardPurchaseInfo.numberType, }, } as CartItemInput; } else if (item.variantId === E_SIM_CARD || item.variantId === SIM_CARD) { extraServiceInput = { id: item.id, variantId: item.variantId, quantity: 1, purchaseInfo: { iccid: this.simCardPurchaseInfo.iccid, simCardType: this.simCardPurchaseInfo.simCardType, serviceCartItemId, }, } as CartItemInput; } // Return the promise from addToCart if (extraServiceInput) { return this.cart.updateCartItem(extraServiceInput); } }); // Wait for all promises to resolve if (promises) { await Promise.all(promises); } } catch (e) { throwErrorWithMessage(e, 'Failed to add extra service to cart'); } }; storeInCookie = () => { this.cookies.set( 'state', { subscriptionType: this.selectedSubscriptionType, secondary: this.secondaryVariant, primary: this.primaryVariant, }, { path: '/' }, ); }; getFromCookie = () => { const state = this.cookies.get('state'); if (!state) { return false; } else { this.selectedSubscriptionType = state.subscriptionType; this.primaryVariant = state.primary; this.secondaryVariant = state.secondary; // Finish the first three steps when user is // coming back froum Auth if (!this.authentication.isStaff) { this.steps[0].isComplete = true; this.steps[1].isComplete = true; this.steps[2].isComplete = true; } return true; } }; clearCookie = () => { this.cookies.remove('state', { path: '/' }); }; initSteps = (isCompany: boolean) => { const { salesNumber, customerId } = this.cart; const hasSalesNumber = !!salesNumber; const hasPayer = !!customerId; const isStaff = this.authentication.isStaff; const baseSteps = isCompany ? companyStepsData : stepsData; const withAlltSamanSteps = [...alltSamanOfferStep, ...baseSteps]; const staffBaseSteps = isCompany ? companyStaffStepsData : staffStepsData; const staffWithAlltSamanSteps = isCompany ? [...staffSteps, ...companyStepsData] : [...staffSteps, ...alltSamanOfferStep, ...stepsData]; if (isStaff && !hasSalesNumber && !hasPayer) { this.steps = hasPayer ? staffBaseSteps : staffWithAlltSamanSteps; } else { this.steps = hasPayer ? baseSteps : withAlltSamanSteps; } }; removeExtraServices = async (cartItems: string[]) => { if (cartItems) { try { const promises = cartItems?.map(async (item) => { // Return the promise from addToCart return this.cart.removeFromCart(item); }); // Wait for all promises to resolve await Promise.all(promises); } catch (e) { throwErrorWithMessage(e, 'Failed to remove extra service'); } } }; }