import type { IPerxUserProxy } from './manager' import type { IPerxService, PerxCustomer, PerxRewardScope, PerxLoyalty, PerxLoyaltyTransactionsHistoryResponse, PerxRewardSearchResultResponse, PerxVoucher, PerxVoucherScope, PerxVouchersResponse, PerxRewardsResponse, PerxCategory, PerxRewardReservation, IPerxToken, PerxCategoriesResultResponse, PerxRewardResponse, PerxVoucherResponse, PerxMerchant, PerxMerchantsResponse, } from '..' import { chunk } from 'lodash' import { PerxCampaign, PerxCampaignsResponse } from '../models' export class PerxUserProxy implements IPerxUserProxy { public constructor(public readonly getToken: () => Promise, private readonly perxService: IPerxService) { } public async getReward(rewardId: number): Promise { const token = await this.getToken() return this.perxService.getReward(token.accessToken, rewardId) } public async queryRewards(scope: Partial): Promise { const token = await this.getToken() return this.perxService.getRewards(token.accessToken, scope) } public async searchRewards(keyword: string, page: number = 1, size: number = 25): Promise { const token = await this.getToken() return this.perxService.searchRewards(token.accessToken, keyword, page, size) } public async issueReward(rewardId: string): Promise { const token = await this.getToken() return this.perxService.issueVoucher(token.accessToken, rewardId) } public async queryVouchers(scope: Partial): Promise { const token = await this.getToken() return this.perxService.getVouchers(token.accessToken, scope) } public async listCategories(page: number, pageSize: number): Promise { return this.listCategoriesByParentId(null, page, pageSize) } public async listCategoriesByParentId(parentId: number | null, page: number, pageSize: number): Promise { const token = await this.getToken() return this.perxService.getCategories(token.accessToken, parentId, page, pageSize) } public async listAllCategories(parentId: number | null = null): Promise { const token = await this.getToken() let hasNextPage = false let page = 1 const pageSize = 50 const output: PerxCategory[] = [] do { const resp = await this.perxService.getCategories(token.accessToken, parentId, page, pageSize) output.push(...resp.data) const totalPages = resp.meta.totalPages hasNextPage = totalPages > page page = resp.meta.nextPage || (page + 1) } while (hasNextPage) return output } public async reserveReward(rewardId: string, timeoutInMs: number = 900 * 1000): Promise { const token = await this.getToken() return this.perxService.reserveReward(token.accessToken, rewardId, timeoutInMs) } public async releaseReservedReward(reservationId: string): Promise { const token = await this.getToken() return this.perxService.releaseRewardReservation(token.accessToken, reservationId) } public async confirmReservedReward(reservationId: string): Promise { const token = await this.getToken() return this.perxService.confirmRewardReservation(token.accessToken, reservationId) } public async reserveVouchers(voucherIds: string[]): Promise { return this._forEachVoucher(voucherIds, (token, voucherId) => { return this.perxService.redeemVoucher(token.accessToken, voucherId, false) }) } public async confirmVouchers(voucherIds: string[]): Promise { return this._forEachVoucher(voucherIds, (token, voucherId) => { return this.perxService.redeemVoucher(token.accessToken, voucherId, true) }) } public async getVoucher(voucherId: number): Promise { const userToken = await this.getToken() return this.perxService.getVoucher(userToken.accessToken, voucherId) } public async redeemVouchers(voucherIds: string[]): Promise { return this._forEachVoucher(voucherIds, (token, voucherId) => { return this.perxService.redeemVoucher(token.accessToken, voucherId) }) } public async getMe(): Promise { const token = await this.getToken() return this.perxService.getMe(token.accessToken) } public async getLoyaltyProgram(loyaltyProgramId: number | string): Promise { const token = await this.getToken() return this.perxService.getLoyaltyProgram(token.accessToken, loyaltyProgramId) } public async queryLoyaltyPrograms(): Promise { const token = await this.getToken() return this.perxService.getLoyaltyPrograms(token.accessToken) } public async queryTransactionsHistory(page: number = 1, perPage: number = 25, transactionReference?: string): Promise { const token = await this.getToken() return this.perxService.queryLoyaltyTransactionsHistory(token.accessToken, page, perPage, transactionReference) } public async listAllMerchants(page: number = 1, perPage: number = 25, favorite: boolean | undefined = undefined): Promise { const token = await this.getToken() return this.perxService.listAllMerchants(token.accessToken, page, perPage, favorite) } public async getMerchant(merchantId: number): Promise { const token = await this.getToken() return this.perxService.getMerchant(token.accessToken, merchantId) } public async performCustomTrigger(perxCustomTriggerId: string): Promise { const token = await this.getToken() return this.perxService.performCustomTrigger(token.accessToken, perxCustomTriggerId) } private async _forEachVoucher(voucherIds: string[], callback: (token: IPerxToken, voucherId: string) => Promise): Promise { const token = await this.getToken() let results: R[] = [] for(const chunkedVoucherIds of chunk(voucherIds, 5)) { const r = await Promise.all(chunkedVoucherIds.map((voucherId) => { return callback(token, voucherId) })) results = results.concat(r) } return results } public async listAllCampaign(page: number = 1, perPage: number = 25, campaignType: string | undefined = undefined): Promise { const token = await this.getToken() return this.perxService.listAllCampaign(token.accessToken, page, perPage, campaignType) } public async getCampaign(campaignId: number): Promise { const token = await this.getToken() const result = await this.perxService.getCampaign(token.accessToken, campaignId) return result } }