import { RawEffect } from '~core/modules/order/definitions'; import { Restaurant, Business } from '~backend/business/business.interface'; import { FreeCreditOption, FrontendInfo, Voucher } from '../marketing.interface'; import { User } from '~backend/user/user.interface'; import { Types } from 'mongoose'; import { Ref } from '@typegoose/typegoose'; import { CreditBalance } from '~backend/marketing/credit/credit.interface'; import { StoreOption } from '../store/store.interface'; export declare namespace Benefit { enum Type { basic = "BASIC", schedule = "VOUCHER" } interface Duration { start: string; end: string; } namespace Triggerer { enum Type { cron = "CRON", birthday = "BIRTHDAY" } enum TimeUnit { week = "WEEK", month = "MONTH" } enum BirthdayType { startOf = "START_OF", before = "BEFORE" } interface BaseTriggerer { type: Type; } interface CronTriggerer extends BaseTriggerer { type: Type.cron; cron: string; } interface BaseBirthdayOption { type: BirthdayType; } interface BirthdayStartOfOption extends BaseBirthdayOption { type: BirthdayType.startOf; unit: TimeUnit; } interface BirthdayBeforeOption extends BaseBirthdayOption { type: BirthdayType.before; day: number; } interface BirthdayTriggerer extends BaseTriggerer { type: Type.birthday; option: BirthdayStartOfOption | BirthdayBeforeOption; } type Triggerer = BirthdayTriggerer | CronTriggerer; } interface Scheduler { start: Triggerer.Triggerer; validity: number; timePeriod: Duration[]; } interface BaseOption { type: Type; } interface BasicOption extends BaseOption { type: Type.basic; effect: RawEffect; scheduler: Scheduler | null; } interface ScheduleOption extends BaseOption { type: Type.schedule; vouchers: Ref[]; freeCredit?: FreeCreditOption; /** * weekday, every monday,wednesday: cron 0 0 * * 1,3 * day, every 1st of month: cron 0 0 1 * * * month, everyday of january: cron 0 0 *\/1 * * * specific day, national day: cron 0 0 31 8 * * at birthday: birthday before 0 * at birthday week: birthday startOf week */ triggerer: Triggerer.Triggerer; distributedAt?: Date; } interface Benefit { id: string; name: string; description?: string; image?: string; minLevel: number; maxLevel: number; /** if no minTier, fall back to use level, else level is ignored */ minTier: number; maxTier: number; targetRestaurant?: Ref[]; options: BasicOption | ScheduleOption; requiredTitle?: Ref; frontend?: FrontendInfo; } } export declare namespace Task { enum Type { totalSpent = "TOTAL_SPENT", totalVisit = "TOTAL_VISIT", totalItem = "TOTAL_ITEM" } interface BaseOption { type: Type; } interface TotalSpentOption extends BaseOption { type: Type.totalSpent; require: number; } interface TotalVisitOption extends BaseOption { type: Type.totalVisit; require: number; minSpent: number; } interface TotalItemOption extends BaseOption { type: Type.totalItem; require: number; itemsIds: string[]; } type TaskOption = TotalSpentOption | TotalVisitOption | TotalItemOption; interface Task { id: string; option: TaskOption; } } export declare namespace Level { interface ExperienceRange { minLevel: number; expToLevelUp: number; } interface CycleRule { minLevel: number; minExp: number; levelExpression: string | null; expExpression: string | null; } interface Cycle { resettedAt?: Date; month: number[]; rules: CycleRule[]; } } export declare namespace Reward { interface RandomVoucherReward { voucher: Ref; minLevel: number; weight: number; } interface FixVoucherReward { voucher: Ref; level: number; } interface OnLevelReward { vouchers: RandomVoucherReward[]; noRewardWeight: number; fixVouchers?: FixVoucherReward[]; } interface OnJoinReward { vouchers: Ref[]; } } export declare namespace Member { interface ProductCount { id: string; count: number; } interface Stat { visitCount: number; topupCount: number; lastVisit: Date | null; avgVisitFrequency: number; avgBillSize: number; products: ProductCount[]; } interface TitleInfo { _id: Types.ObjectId; acquiredAt: Date; expiredAt: Date; } interface Member { _id: Types.ObjectId; id: string; joinedAt: Date; business: Ref; membership: Ref; user: string; cardNo?: string; level: number; experience: number; tier: number; stat: Stat; balance: number; creditBalance: CreditBalance; titles: TitleInfo[]; } type MemberInfo = Omit & { user: User; }; } export declare namespace Tier { interface Tier { name: string; minLevel: number; } interface Option { baseTierName: string; tiers: Tier[]; } } export declare namespace Title { interface Title { id: string; image?: string; name: string; internal: boolean; } } export declare namespace MembercardDesign { enum Type { default = "DEFAULT", image = "IMAGE" } interface Base { type: Type; } interface Default extends MembercardDesign.Base { type: Type.default; } interface Image extends MembercardDesign.Base { type: Type.image; image: string; } type MembercardDesign = MembercardDesign.Default | MembercardDesign.Image; } export interface CashbackSettings { percentage: number; validFor: number; } export interface Membership { id: string; name: string; benefits: Benefit.Benefit[]; onLevelReward: Reward.OnLevelReward; baseExpToLevelUp: number; expRange: Level.ExperienceRange[]; levelCycle?: Level.Cycle; tier: Tier.Option; titles: Title.Title[]; store?: StoreOption; onJoinReward: Reward.OnJoinReward; targetRestaurant: Ref[] | null; client?: { canApply: boolean; reason: string; }; design?: MembercardDesign.MembercardDesign; cashback?: CashbackSettings; creditOneToOne?: boolean; } export interface MembershipSummary { newMemberCount: number; topSpentMember: Member.MemberInfo[]; count: number; levelSummary: LevelSummary[]; } export interface LevelSummary { level: number; count: number; } export interface LevelUp { level: number; voucher: Types.ObjectId | null; fixVouchers?: Types.ObjectId[] | null; } export interface MembershipOverview { membership: Membership; summary: MembershipSummary; }