portal-www
Version:
Nova Portal Website. Based on Next starter by Ueno
1,196 lines (1,079 loc) • 38.6 kB
text/typescript
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');
}
}
};
}