From af7bad03f541496080df42c555746291f4128ab8 Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Thu, 6 Nov 2025 17:30:18 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20style:=20reformat=20crm-customer?= =?UTF-8?q?.service=20for=20improved=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply consistent code formatting with multi-line function parameters and object properties throughout the CRM customer service. No functional changes. --- .../src/domain/crm/crm-customer.service.ts | 1280 +++++++++-------- 1 file changed, 709 insertions(+), 571 deletions(-) diff --git a/apps/isa-app/src/domain/crm/crm-customer.service.ts b/apps/isa-app/src/domain/crm/crm-customer.service.ts index 680437ee5..5142c0188 100644 --- a/apps/isa-app/src/domain/crm/crm-customer.service.ts +++ b/apps/isa-app/src/domain/crm/crm-customer.service.ts @@ -1,571 +1,709 @@ -import { Injectable } from '@angular/core'; -import { - AddressDTO, - AddressService, - AssignedPayerDTO, - AutocompleteDTO, - CommunicationDetailsDTO, - CountryDTO, - CountryService, - CustomerDTO, - CustomerInfoDTO, - CustomerService, - HistoryDTO, - InputDTO, - KeyValueDTOOfStringAndString, - ListResponseArgsOfCustomerInfoDTO, - LoyaltyCardService, - NotificationChannel, - PayerDTO, - PayerService, - QueryTokenDTO, - ResponseArgsOfIEnumerableOfBonusCardInfoDTO, - ShippingAddressDTO, - ShippingAddressService, -} from '@generated/swagger/crm-api'; -import { isArray, memorize } from '@utils/common'; -import { PagedResult, Result } from '@domain/defs'; -import { Observable, of, ReplaySubject } from 'rxjs'; -import { catchError, map, mergeMap, retry, shareReplay } from 'rxjs/operators'; - -@Injectable({ providedIn: 'root' }) -export class CrmCustomerService { - constructor( - private customerService: CustomerService, - private payerService: PayerService, - private addressService: AddressService, - private countryService: CountryService, - private shippingAddressService: ShippingAddressService, - private loyaltyCardService: LoyaltyCardService, - ) {} - - @memorize() - filterSettings() { - return this.customerService.CustomerCustomerQuerySettings().pipe( - map((res) => res.result), - shareReplay(1), - ); - } - - complete(queryString: string, filter?: { [key: string]: string }): Observable> { - return this.customerService.CustomerCustomerAutocomplete({ - input: queryString, - filter: filter || {}, - take: 5, - }); - } - - canUpgrade(customerId: number): Observable { - return this.customerService - .CustomerCanExtendCustomer({ - customerId, - }) - .pipe(map((res) => res.result)); - } - - getCustomers( - queryString: string, - options: { take?: number; skip?: number; filter?: { [key: string]: string } } = { take: 20, skip: 0 }, - ): Observable { - return this.customerService.CustomerListCustomers({ - input: queryString ? { qs: queryString } : undefined, - take: options.take, - skip: options.skip, - filter: options.filter || {}, - }); - } - - getCustomersWithQueryToken(queryToken: QueryTokenDTO) { - if (queryToken.skip === undefined) queryToken.skip = 0; - if (queryToken.take === undefined) queryToken.take = 20; - if (queryToken.input === undefined) queryToken.input = { qs: '' }; - if (queryToken.filter === undefined) queryToken.filter = {}; - - return this.customerService.CustomerListCustomers(queryToken); - } - - getCustomersByCustomerCardNumber(queryString: string): Observable> { - return this.customerService.CustomerGetCustomerByBonuscard(queryString ? queryString : undefined); - } - - getCustomer(customerId: number, eagerLoading?: number): Observable> { - return this.customerService.CustomerGetCustomer({ customerId, eagerLoading }); - } - - getAssignedPayers(params: CustomerService.CustomerGetAssignedPayersByCustomerIdParams) { - return this.customerService.CustomerGetAssignedPayersByCustomerId(params); - } - - /* @internal */ - getNotificationChannelForCommunicationDetails({ - communicationDetails, - }: { - communicationDetails: CommunicationDetailsDTO; - }): NotificationChannel { - let notificationChannels: number = 0; - - if (communicationDetails?.email) { - notificationChannels += 1; - } - if (communicationDetails?.mobile) { - notificationChannels += 2; - } - - return notificationChannels as NotificationChannel; - } - - patchCustomer(customerId: number, customer: CustomerDTO): Observable> { - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: customer?.communicationDetails, - }); - - return this.customerService.CustomerPatchCustomer({ customerId, customer: { ...customer, notificationChannels } }); - } - - createB2BCustomer(customer: CustomerDTO): Promise> { - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: customer?.communicationDetails, - }); - - const payload: CustomerDTO = { ...customer, customerType: 16, notificationChannels }; - - payload.shippingAddresses = payload.shippingAddresses ?? []; - - payload.payers = payload.payers ?? []; - - return this.customerService - .CustomerCreateCustomer({ - customer: payload, - modifiers: [{ key: 'b2b', group: 'customertype' }], - }) - .toPromise(); - } - - createOnlineCustomer(customer: CustomerDTO): Observable> { - const payload: CustomerDTO = { ...customer, customerType: 8, hasOnlineAccount: true }; - - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: customer?.communicationDetails, - }); - - if (!(isArray(payload.shippingAddresses) && payload.shippingAddresses.length > 0)) { - payload.shippingAddresses = [ - { - data: { - address: payload.address, - communicationDetails: payload.communicationDetails, - firstName: payload.firstName, - gender: payload.gender, - lastName: payload.lastName, - organisation: payload.organisation, - title: payload.title, - type: 1, - isDefault: new Date().toISOString(), - }, - }, - ]; - } - - if (!(isArray(payload.payers) && payload.payers.length > 0)) { - payload.payers = [ - { - payer: { - data: { - address: payload.address, - communicationDetails: payload.communicationDetails, - firstName: payload.firstName, - gender: payload.gender, - lastName: payload.lastName, - organisation: payload.organisation, - title: payload.title, - payerType: payload.customerType, - }, - }, - }, - ]; - } - - const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; - - const modifiers: KeyValueDTOOfStringAndString[] = [{ key: 'webshop', group: 'customertype' }]; - - if (p4mUser) { - modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); - } - - return this.customerService.CustomerCreateCustomer({ - customer: { ...payload, notificationChannels }, - modifiers, - }); - } - - mapCustomerToPayer(customer: CustomerDTO): PayerDTO { - return { - address: customer.address, - communicationDetails: customer.communicationDetails, - firstName: customer.firstName, - lastName: customer.lastName, - organisation: customer.organisation, - title: customer.title, - payerType: 1, - gender: customer.gender, - }; - } - - mapCustomerToShippingAddress(customer: CustomerDTO): ShippingAddressDTO { - return { - address: customer.address, - communicationDetails: customer.communicationDetails, - firstName: customer.firstName, - gender: customer.gender, - lastName: customer.lastName, - organisation: customer.organisation, - title: customer.title, - type: 1, - }; - } - - async updateToOnlineCustomer(customer: CustomerDTO): Promise> { - const payload: CustomerDTO = { - shippingAddresses: [], - payers: [], - ...customer, - customerType: 8, - hasOnlineAccount: true, - }; - - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: payload?.communicationDetails, - }); - - const shippingAddressesToAdd = payload.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? []; - payload.shippingAddresses = payload.shippingAddresses?.filter((sa) => !!sa.id) ?? []; - - if (payload.shippingAddresses.length === 0) { - shippingAddressesToAdd.unshift(this.mapCustomerToShippingAddress(payload)); - } - - const payersToAdd = payload.payers?.filter((p) => !p.assignedToCustomer)?.map((p) => p.payer?.data) ?? []; - payload.payers = payload.payers?.filter((p) => !!p.assignedToCustomer) ?? []; - - if (payload.payers.length === 0) { - payersToAdd.unshift({ - ...this.mapCustomerToPayer(payload), - payerType: payload.customerType, - }); - } - - const modifiers: KeyValueDTOOfStringAndString[] = [{ key: 'webshop', group: 'customertype' }]; - - const res = await this.customerService - .CustomerUpdateCustomer({ - customerId: customer.id, - payload: { - modifiers, - customer: { ...payload, notificationChannels }, - }, - }) - .toPromise(); - - for (let shippingAddress of shippingAddressesToAdd) { - await this.createShippingAddress(res.result.id, shippingAddress, true); - } - - for (let payer of payersToAdd) { - await this.createPayer(res.result.id, payer, true); - } - - return res; - } - - async updateToP4MOnlineCustomer(customer: CustomerDTO): Promise> { - const shippingAddressesToAdd = customer.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? []; - customer.shippingAddresses = customer.shippingAddresses?.filter((sa) => !!sa.id) ?? []; - - if (customer.shippingAddresses.length === 0) { - shippingAddressesToAdd.unshift(this.mapCustomerToShippingAddress(customer)); - } - - const payersToAdd = customer.payers?.filter((p) => !p.assignedToCustomer)?.map((p) => p.payer?.data) ?? []; - customer.payers = customer.payers?.filter((p) => !!p.assignedToCustomer) ?? []; - - if (customer.payers.length === 0) { - payersToAdd.unshift({ - ...this.mapCustomerToPayer(customer), - payerType: customer.customerType, - }); - } - - const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; - - const modifiers: KeyValueDTOOfStringAndString[] = [{ key: 'webshop', group: 'customertype' }]; - - if (p4mUser) { - modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); - } - - const res = await this.customerService - .CustomerUpdateCustomer({ - customerId: customer.id, - payload: { - customer, - modifiers, - }, - }) - .toPromise(); - - for (let shippingAddress of shippingAddressesToAdd) { - await this.createShippingAddress(res.result.id, shippingAddress, true); - } - - for (let payer of payersToAdd) { - await this.createPayer(res.result.id, payer, true); - } - - return res; - } - - async updateStoreP4MToWebshopP4M(customer: CustomerDTO): Promise> { - const shippingAddressesToAdd = customer.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? []; - customer.shippingAddresses = customer.shippingAddresses?.filter((sa) => !!sa.id) ?? []; - - if (customer.shippingAddresses.length === 0) { - shippingAddressesToAdd.unshift(this.mapCustomerToShippingAddress(customer)); - } - - const payersToAdd = customer.payers?.filter((p) => !p.assignedToCustomer)?.map((p) => p.payer?.data) ?? []; - customer.payers = customer.payers?.filter((p) => !!p.assignedToCustomer) ?? []; - - if (customer.payers.length === 0) { - payersToAdd.unshift({ - ...this.mapCustomerToPayer(customer), - payerType: customer.customerType, - }); - } - - const modifiers: KeyValueDTOOfStringAndString[] = [{ key: 'webshop', group: 'customertype' }]; - - const res = await this.customerService - .CustomerUpdateCustomer({ - customerId: customer.id, - payload: { - customer, - modifiers, - }, - }) - .toPromise(); - - for (let shippingAddress of shippingAddressesToAdd) { - await this.createShippingAddress(res.result.id, shippingAddress, true); - } - - for (let payer of payersToAdd) { - await this.createPayer(res.result.id, payer, true); - } - - return res; - } - - async createGuestCustomer(customer: CustomerDTO): Promise> { - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: customer?.communicationDetails, - }); - const payload: CustomerDTO = { ...customer, customerType: 8, isGuestAccount: true, notificationChannels }; - - payload.shippingAddresses = customer.shippingAddresses ?? []; - - payload.shippingAddresses.push({ - data: this.mapCustomerToShippingAddress(customer), - }); - - payload.payers = customer.payers ?? []; - - payload.payers.push({ - payer: { - data: { - ...this.mapCustomerToPayer(customer), - payerType: payload.customerType, - }, - }, - }); - - const res = await this.customerService - .CustomerCreateCustomer({ - customer: payload, - modifiers: [{ key: 'webshop', group: 'customertype' }], - }) - .toPromise(); - - return res; - } - - createStoreCustomer(customer: CustomerDTO): Observable> { - const notificationChannels = this.getNotificationChannelForCommunicationDetails({ - communicationDetails: customer?.communicationDetails, - }); - - const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; - - const modifiers: KeyValueDTOOfStringAndString[] = [{ key: 'store', group: 'customertype' }]; - - if (p4mUser) { - modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); - } - - return this.customerService.CustomerCreateCustomer({ - customer: { ...customer, customerType: 8, notificationChannels }, - modifiers, - }); - } - - validateAddress(address: AddressDTO): Observable> { - return this.addressService.AddressValidateAddress(address); - } - - getOnlineCustomerByEmail(email: string): Observable { - return this.getCustomers(email, { - take: 1, - filter: { - customertype: 'webshop', - }, - }).pipe( - map((r) => { - if (r.hits === 1) { - return r.result[0]; - } else { - return null; - } - }), - catchError((err) => [null]), - ); - } - - private cachedCountriesFailed = false; - private cachedCountries: ReplaySubject>; - getCountries(): Observable> { - if (!this.cachedCountries || this.cachedCountriesFailed) { - this.cachedCountriesFailed = false; - this.cachedCountries = new ReplaySubject(); - this.countryService - .CountryGetCountries({}) - .pipe( - retry(3), - catchError((err) => { - this.cachedCountriesFailed = true; - return of>({ - error: true, - message: err?.message, - }); - }), - ) - .subscribe(this.cachedCountries); - } - - return this.cachedCountries.asObservable(); - } - - emailExists(email: string): Observable> { - return this.customerService.CustomerEmailExists(email); - } - - checkLoyaltyCard({ loyaltyCardNumber, customerId }: { loyaltyCardNumber: string; customerId?: number }) { - return this.loyaltyCardService.LoyaltyCardCheckLoyaltyCard({ loyaltyCardNumber, customerId }); - } - - createPayer( - customerId: number, - payer: PayerDTO, - isDefault?: boolean, - ): Promise<[Result, Result]> { - return this.getCustomer(customerId) - .pipe( - mergeMap((customerResponse) => - this.payerService.PayerCreatePayer({ ...payer, payerType: customerResponse.result.customerType }).pipe( - mergeMap((payerResponse) => - this.customerService - .CustomerAddPayerReference({ - customerId: customerId, - payerId: payerResponse.result.id, - isDefault: isDefault, - }) - .pipe( - map( - (assigendPayerResponse) => - [payerResponse, assigendPayerResponse] as [Result, Result], - ), - ), - ), - ), - ), - ) - .toPromise(); - } - - updatePayer(customerId: number, payerId: number, payer: PayerDTO, isDefault?: boolean): Observable> { - return this.payerService - .PayerUpdatePayer({ payerId, payer }) - .pipe(mergeMap((response) => this.setDefaultPayer(payerId, customerId, isDefault).pipe(map(() => response)))); - } - - setDefaultPayer(payerId: number, customerId: number, isDefault = true): Observable> { - return this.customerService.CustomerModifyPayerReference({ payerId, customerId, isDefault }); - } - - createShippingAddress( - customerId: number, - shippingAddress: ShippingAddressDTO, - isDefault?: boolean, - ): Promise> { - const data: ShippingAddressDTO = { ...shippingAddress }; - if (isDefault) { - data.isDefault = new Date().toJSON(); - } else { - delete data.isDefault; - } - - return this.shippingAddressService - .ShippingAddressCreateShippingAddress({ customerId, shippingAddress: data }) - .toPromise(); - } - - updateShippingAddress( - customerId: number, - shippingAddressId: number, - shippingAddress: ShippingAddressDTO, - isDefault?: boolean, - ): Promise> { - const data: ShippingAddressDTO = { ...shippingAddress }; - - if (isDefault) { - data.isDefault = new Date().toJSON(); - } else { - delete data.isDefault; - } - - return this.shippingAddressService - .ShippingAddressUpdateShippingAddress({ shippingAddressId, shippingAddress: data, customerId }) - .toPromise(); - } - - getShippingAddress(shippingAddressId: number): Observable> { - return this.shippingAddressService.ShippingAddressGetShippingaddress(shippingAddressId); - } - - getShippingAddresses( - params: ShippingAddressService.ShippingAddressGetShippingAddressesParams, - ): Observable> { - return this.shippingAddressService.ShippingAddressGetShippingAddresses(params); - } - - getPayer(payerId: number): Observable> { - return this.payerService.PayerGetPayer(payerId); - } - - getCustomerCard(customerId: number): Observable { - return this.customerService.CustomerGetBonuscards(customerId); - } - - getCustomerHistory(customerId: number): Observable { - return this.customerService.CustomerGetCustomerHistory({ customerId }).pipe(map((response) => response?.result)); - } -} +import { Injectable } from '@angular/core'; +import { + AddressDTO, + AddressService, + AssignedPayerDTO, + AutocompleteDTO, + CommunicationDetailsDTO, + CountryDTO, + CountryService, + CustomerDTO, + CustomerInfoDTO, + CustomerService, + HistoryDTO, + InputDTO, + KeyValueDTOOfStringAndString, + ListResponseArgsOfCustomerInfoDTO, + LoyaltyCardService, + NotificationChannel, + PayerDTO, + PayerService, + QueryTokenDTO, + ResponseArgsOfIEnumerableOfBonusCardInfoDTO, + ShippingAddressDTO, + ShippingAddressService, +} from '@generated/swagger/crm-api'; +import { isArray, memorize } from '@utils/common'; +import { PagedResult, Result } from '@domain/defs'; +import { Observable, of, ReplaySubject } from 'rxjs'; +import { catchError, map, mergeMap, retry, shareReplay } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class CrmCustomerService { + constructor( + private customerService: CustomerService, + private payerService: PayerService, + private addressService: AddressService, + private countryService: CountryService, + private shippingAddressService: ShippingAddressService, + private loyaltyCardService: LoyaltyCardService, + ) {} + + @memorize() + filterSettings() { + return this.customerService.CustomerCustomerQuerySettings().pipe( + map((res) => res.result), + shareReplay(1), + ); + } + + complete( + queryString: string, + filter?: { [key: string]: string }, + ): Observable> { + return this.customerService.CustomerCustomerAutocomplete({ + input: queryString, + filter: filter || {}, + take: 5, + }); + } + + canUpgrade(customerId: number): Observable { + return this.customerService + .CustomerCanExtendCustomer({ + customerId, + }) + .pipe(map((res) => res.result)); + } + + getCustomers( + queryString: string, + options: { + take?: number; + skip?: number; + filter?: { [key: string]: string }; + } = { take: 20, skip: 0 }, + ): Observable { + return this.customerService.CustomerListCustomers({ + input: queryString ? { qs: queryString } : undefined, + take: options.take, + skip: options.skip, + filter: options.filter || {}, + }); + } + + getCustomersWithQueryToken(queryToken: QueryTokenDTO) { + if (queryToken.skip === undefined) queryToken.skip = 0; + if (queryToken.take === undefined) queryToken.take = 20; + if (queryToken.input === undefined) queryToken.input = { qs: '' }; + if (queryToken.filter === undefined) queryToken.filter = {}; + + return this.customerService.CustomerListCustomers(queryToken); + } + + getCustomersByCustomerCardNumber( + queryString: string, + ): Observable> { + return this.customerService.CustomerGetCustomerByBonuscard( + queryString ? queryString : undefined, + ); + } + + getCustomer( + customerId: number, + eagerLoading?: number, + ): Observable> { + return this.customerService.CustomerGetCustomer({ + customerId, + eagerLoading, + }); + } + + getAssignedPayers( + params: CustomerService.CustomerGetAssignedPayersByCustomerIdParams, + ) { + return this.customerService.CustomerGetAssignedPayersByCustomerId(params); + } + + /* @internal */ + getNotificationChannelForCommunicationDetails({ + communicationDetails, + }: { + communicationDetails: CommunicationDetailsDTO; + }): NotificationChannel { + let notificationChannels = 0; + + if (communicationDetails?.email) { + notificationChannels += 1; + } + if (communicationDetails?.mobile) { + notificationChannels += 2; + } + + return notificationChannels as NotificationChannel; + } + + patchCustomer( + customerId: number, + customer: CustomerDTO, + ): Observable> { + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: customer?.communicationDetails, + }); + + return this.customerService.CustomerPatchCustomer({ + customerId, + customer: { ...customer, notificationChannels }, + }); + } + + createB2BCustomer(customer: CustomerDTO): Promise> { + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: customer?.communicationDetails, + }); + + const payload: CustomerDTO = { + ...customer, + customerType: 16, + notificationChannels, + }; + + payload.shippingAddresses = payload.shippingAddresses ?? []; + + payload.payers = payload.payers ?? []; + + return this.customerService + .CustomerCreateCustomer({ + customer: payload, + modifiers: [{ key: 'b2b', group: 'customertype' }], + }) + .toPromise(); + } + + createOnlineCustomer(customer: CustomerDTO): Observable> { + const payload: CustomerDTO = { + ...customer, + customerType: 8, + hasOnlineAccount: true, + }; + + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: customer?.communicationDetails, + }); + + if ( + !( + isArray(payload.shippingAddresses) && + payload.shippingAddresses.length > 0 + ) + ) { + payload.shippingAddresses = [ + { + data: { + address: payload.address, + communicationDetails: payload.communicationDetails, + firstName: payload.firstName, + gender: payload.gender, + lastName: payload.lastName, + organisation: payload.organisation, + title: payload.title, + type: 1, + isDefault: new Date().toISOString(), + }, + }, + ]; + } + + if (!(isArray(payload.payers) && payload.payers.length > 0)) { + payload.payers = [ + { + payer: { + data: { + address: payload.address, + communicationDetails: payload.communicationDetails, + firstName: payload.firstName, + gender: payload.gender, + lastName: payload.lastName, + organisation: payload.organisation, + title: payload.title, + payerType: payload.customerType, + }, + }, + }, + ]; + } + + const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; + + const modifiers: KeyValueDTOOfStringAndString[] = [ + { key: 'webshop', group: 'customertype' }, + ]; + + if (p4mUser) { + modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); + } + + return this.customerService.CustomerCreateCustomer({ + customer: { ...payload, notificationChannels }, + modifiers, + }); + } + + mapCustomerToPayer(customer: CustomerDTO): PayerDTO { + return { + address: customer.address, + communicationDetails: customer.communicationDetails, + firstName: customer.firstName, + lastName: customer.lastName, + organisation: customer.organisation, + title: customer.title, + payerType: 1, + gender: customer.gender, + }; + } + + mapCustomerToShippingAddress(customer: CustomerDTO): ShippingAddressDTO { + return { + address: customer.address, + communicationDetails: customer.communicationDetails, + firstName: customer.firstName, + gender: customer.gender, + lastName: customer.lastName, + organisation: customer.organisation, + title: customer.title, + type: 1, + }; + } + + async updateToOnlineCustomer( + customer: CustomerDTO, + ): Promise> { + const payload: CustomerDTO = { + shippingAddresses: [], + payers: [], + ...customer, + customerType: 8, + hasOnlineAccount: true, + }; + + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: payload?.communicationDetails, + }); + + const shippingAddressesToAdd = + payload.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? + []; + payload.shippingAddresses = + payload.shippingAddresses?.filter((sa) => !!sa.id) ?? []; + + if (payload.shippingAddresses.length === 0) { + shippingAddressesToAdd.unshift( + this.mapCustomerToShippingAddress(payload), + ); + } + + const payersToAdd = + payload.payers + ?.filter((p) => !p.assignedToCustomer) + ?.map((p) => p.payer?.data) ?? []; + payload.payers = + payload.payers?.filter((p) => !!p.assignedToCustomer) ?? []; + + if (payload.payers.length === 0) { + payersToAdd.unshift({ + ...this.mapCustomerToPayer(payload), + payerType: payload.customerType, + }); + } + + const modifiers: KeyValueDTOOfStringAndString[] = [ + { key: 'webshop', group: 'customertype' }, + ]; + + const res = await this.customerService + .CustomerUpdateCustomer({ + customerId: customer.id, + payload: { + modifiers, + customer: { ...payload, notificationChannels }, + }, + }) + .toPromise(); + + for (const shippingAddress of shippingAddressesToAdd) { + await this.createShippingAddress(res.result.id, shippingAddress, true); + } + + for (const payer of payersToAdd) { + await this.createPayer(res.result.id, payer, true); + } + + return res; + } + + async updateToP4MOnlineCustomer( + customer: CustomerDTO, + ): Promise> { + const shippingAddressesToAdd = + customer.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? + []; + customer.shippingAddresses = + customer.shippingAddresses?.filter((sa) => !!sa.id) ?? []; + + if (customer.shippingAddresses.length === 0) { + shippingAddressesToAdd.unshift( + this.mapCustomerToShippingAddress(customer), + ); + } + + const payersToAdd = + customer.payers + ?.filter((p) => !p.assignedToCustomer) + ?.map((p) => p.payer?.data) ?? []; + customer.payers = + customer.payers?.filter((p) => !!p.assignedToCustomer) ?? []; + + if (customer.payers.length === 0) { + payersToAdd.unshift({ + ...this.mapCustomerToPayer(customer), + payerType: customer.customerType, + }); + } + + const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; + + const modifiers: KeyValueDTOOfStringAndString[] = [ + { key: 'webshop', group: 'customertype' }, + ]; + + if (p4mUser) { + modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); + } + + const res = await this.customerService + .CustomerUpdateCustomer({ + customerId: customer.id, + payload: { + customer, + modifiers, + }, + }) + .toPromise(); + + for (const shippingAddress of shippingAddressesToAdd) { + await this.createShippingAddress(res.result.id, shippingAddress, true); + } + + for (const payer of payersToAdd) { + await this.createPayer(res.result.id, payer, true); + } + + return res; + } + + async updateStoreP4MToWebshopP4M( + customer: CustomerDTO, + ): Promise> { + const shippingAddressesToAdd = + customer.shippingAddresses?.filter((sa) => !sa.id)?.map((m) => m.data) ?? + []; + customer.shippingAddresses = + customer.shippingAddresses?.filter((sa) => !!sa.id) ?? []; + + if (customer.shippingAddresses.length === 0) { + shippingAddressesToAdd.unshift( + this.mapCustomerToShippingAddress(customer), + ); + } + + const payersToAdd = + customer.payers + ?.filter((p) => !p.assignedToCustomer) + ?.map((p) => p.payer?.data) ?? []; + customer.payers = + customer.payers?.filter((p) => !!p.assignedToCustomer) ?? []; + + if (customer.payers.length === 0) { + payersToAdd.unshift({ + ...this.mapCustomerToPayer(customer), + payerType: customer.customerType, + }); + } + + const modifiers: KeyValueDTOOfStringAndString[] = [ + { key: 'webshop', group: 'customertype' }, + ]; + + const res = await this.customerService + .CustomerUpdateCustomer({ + customerId: customer.id, + payload: { + customer, + modifiers, + }, + }) + .toPromise(); + + for (const shippingAddress of shippingAddressesToAdd) { + await this.createShippingAddress(res.result.id, shippingAddress, true); + } + + for (const payer of payersToAdd) { + await this.createPayer(res.result.id, payer, true); + } + + return res; + } + + async createGuestCustomer( + customer: CustomerDTO, + ): Promise> { + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: customer?.communicationDetails, + }); + const payload: CustomerDTO = { + ...customer, + customerType: 8, + isGuestAccount: true, + notificationChannels, + }; + + payload.shippingAddresses = customer.shippingAddresses ?? []; + + payload.shippingAddresses.push({ + data: this.mapCustomerToShippingAddress(customer), + }); + + payload.payers = customer.payers ?? []; + + payload.payers.push({ + payer: { + data: { + ...this.mapCustomerToPayer(customer), + payerType: payload.customerType, + }, + }, + }); + + const res = await this.customerService + .CustomerCreateCustomer({ + customer: payload, + modifiers: [{ key: 'webshop', group: 'customertype' }], + }) + .toPromise(); + + return res; + } + + createStoreCustomer(customer: CustomerDTO): Observable> { + const notificationChannels = + this.getNotificationChannelForCommunicationDetails({ + communicationDetails: customer?.communicationDetails, + }); + + const p4mUser = customer.features.find((f) => f.key === 'p4mUser')?.value; + + const modifiers: KeyValueDTOOfStringAndString[] = [ + { key: 'store', group: 'customertype' }, + ]; + + if (p4mUser) { + modifiers.push({ key: 'add-loyalty-card', value: p4mUser }); + } + + return this.customerService.CustomerCreateCustomer({ + customer: { ...customer, customerType: 8, notificationChannels }, + modifiers, + }); + } + + validateAddress(address: AddressDTO): Observable> { + return this.addressService.AddressValidateAddress(address); + } + + getOnlineCustomerByEmail(email: string): Observable { + return this.getCustomers(email, { + take: 1, + filter: { + customertype: 'webshop', + }, + }).pipe( + map((r) => { + if (r.hits === 1) { + return r.result[0]; + } else { + return null; + } + }), + catchError((err) => [null]), + ); + } + + private cachedCountriesFailed = false; + private cachedCountries: ReplaySubject>; + getCountries(): Observable> { + if (!this.cachedCountries || this.cachedCountriesFailed) { + this.cachedCountriesFailed = false; + this.cachedCountries = new ReplaySubject(); + this.countryService + .CountryGetCountries({}) + .pipe( + retry(3), + catchError((err) => { + this.cachedCountriesFailed = true; + return of>({ + error: true, + message: err?.message, + }); + }), + ) + .subscribe(this.cachedCountries); + } + + return this.cachedCountries.asObservable(); + } + + emailExists(email: string): Observable> { + return this.customerService.CustomerEmailExists(email); + } + + // checkLoyaltyCard({ loyaltyCardNumber, customerId }: { loyaltyCardNumber: string; customerId?: number }) { + // return this.loyaltyCardService.LoyaltyCardCheckLoyaltyCard({ loyaltyCardNumber, customerId }); + // } + + createPayer( + customerId: number, + payer: PayerDTO, + isDefault?: boolean, + ): Promise<[Result, Result]> { + return this.getCustomer(customerId) + .pipe( + mergeMap((customerResponse) => + this.payerService + .PayerCreatePayer({ + ...payer, + payerType: customerResponse.result.customerType, + }) + .pipe( + mergeMap((payerResponse) => + this.customerService + .CustomerAddPayerReference({ + customerId: customerId, + payerId: payerResponse.result.id, + isDefault: isDefault, + }) + .pipe( + map( + (assigendPayerResponse) => + [payerResponse, assigendPayerResponse] as [ + Result, + Result, + ], + ), + ), + ), + ), + ), + ) + .toPromise(); + } + + updatePayer( + customerId: number, + payerId: number, + payer: PayerDTO, + isDefault?: boolean, + ): Observable> { + return this.payerService + .PayerUpdatePayer({ payerId, payer }) + .pipe( + mergeMap((response) => + this.setDefaultPayer(payerId, customerId, isDefault).pipe( + map(() => response), + ), + ), + ); + } + + setDefaultPayer( + payerId: number, + customerId: number, + isDefault = true, + ): Observable> { + return this.customerService.CustomerModifyPayerReference({ + payerId, + customerId, + isDefault, + }); + } + + createShippingAddress( + customerId: number, + shippingAddress: ShippingAddressDTO, + isDefault?: boolean, + ): Promise> { + const data: ShippingAddressDTO = { ...shippingAddress }; + if (isDefault) { + data.isDefault = new Date().toJSON(); + } else { + delete data.isDefault; + } + + return this.shippingAddressService + .ShippingAddressCreateShippingAddress({ + customerId, + shippingAddress: data, + }) + .toPromise(); + } + + updateShippingAddress( + customerId: number, + shippingAddressId: number, + shippingAddress: ShippingAddressDTO, + isDefault?: boolean, + ): Promise> { + const data: ShippingAddressDTO = { ...shippingAddress }; + + if (isDefault) { + data.isDefault = new Date().toJSON(); + } else { + delete data.isDefault; + } + + return this.shippingAddressService + .ShippingAddressUpdateShippingAddress({ + shippingAddressId, + shippingAddress: data, + customerId, + }) + .toPromise(); + } + + getShippingAddress( + shippingAddressId: number, + ): Observable> { + return this.shippingAddressService.ShippingAddressGetShippingaddress( + shippingAddressId, + ); + } + + getShippingAddresses( + params: ShippingAddressService.ShippingAddressGetShippingAddressesParams, + ): Observable> { + return this.shippingAddressService.ShippingAddressGetShippingAddresses( + params, + ); + } + + getPayer(payerId: number): Observable> { + return this.payerService.PayerGetPayer(payerId); + } + + getCustomerCard( + customerId: number, + ): Observable { + return this.customerService.CustomerGetBonuscards(customerId); + } + + getCustomerHistory(customerId: number): Observable { + return this.customerService + .CustomerGetCustomerHistory({ customerId }) + .pipe(map((response) => response?.result)); + } +}