fix: update status when loyalty program reaches maximum usage

This commit is contained in:
Gadha2311
2026-02-02 17:11:24 +05:30
parent 446585dee7
commit 8e10bf313d
5 changed files with 60 additions and 19 deletions
+18 -10
View File
@@ -7,22 +7,30 @@ export async function checkLoyaltyProgramExpiry() {
try { try {
const currentDate = new Date(); const currentDate = new Date();
const loyaltyPrograms = (await dm.db?.getAll(ModelNameEnum.LoyaltyProgram, { const loyaltyPrograms = await dm.db?.getAll(ModelNameEnum.LoyaltyProgram, {
fields: ['name', 'toDate', 'status', 'isEnabled'], fields: ['name', 'toDate', 'status', 'isEnabled', 'maximumUse', 'used'],
filters: { filters: {
status: ['!=', 'Expired'], status: ['not in', ['Expired', 'Maxed']],
isEnabled: true, isEnabled: true,
}, },
})) as Array<{ });
name: string;
toDate: string;
status: string;
isEnabled: boolean;
}>;
if (loyaltyPrograms) { if (loyaltyPrograms) {
for (const program of loyaltyPrograms) { for (const program of loyaltyPrograms) {
if (program.toDate && new Date(program.toDate) <= currentDate) { const maximumUse = Number(program.maximumUse) || 0;
const used = Number(program.used) || 0;
if (maximumUse > 0 && used >= maximumUse) {
await dm.db?.knex!(ModelNameEnum.LoyaltyProgram)
.where({ name: program.name })
.update({
status: 'Maxed',
isEnabled: false,
});
continue;
}
if (program.toDate && new Date(String(program.toDate)) <= currentDate) {
await dm.db?.knex!(ModelNameEnum.LoyaltyProgram) await dm.db?.knex!(ModelNameEnum.LoyaltyProgram)
.where({ name: program.name }) .where({ name: program.name })
.update({ .update({
+2 -2
View File
@@ -886,7 +886,7 @@ export abstract class Invoice extends Transactional {
} }
async updateUsedCountOfLoyaltyProgram() { async updateUsedCountOfLoyaltyProgram() {
if (!this.loyaltyProgram) { if (!this.loyaltyProgram || !this.redeemLoyaltyPoints) {
return; return;
} }
@@ -901,7 +901,7 @@ export abstract class Invoice extends Transactional {
} }
async reduceUsedCountOfLoyaltyProgram() { async reduceUsedCountOfLoyaltyProgram() {
if (!this.loyaltyProgram) { if (!this.loyaltyProgram || !this.redeemLoyaltyPoints) {
return; return;
} }
@@ -11,6 +11,7 @@ export class LoyaltyProgram extends Doc {
expiryDuration?: number; expiryDuration?: number;
maximumUse?: number; maximumUse?: number;
used?: number; used?: number;
status?: 'Active' | 'Expired' | 'Maxed' | 'Disabled';
validations: ValidationMap = { validations: ValidationMap = {
used: (value: DocValue) => { used: (value: DocValue) => {
@@ -34,6 +35,15 @@ export class LoyaltyProgram extends Doc {
}, },
}; };
async afterSubmit() {
const maximumUse = (this.maximumUse as number) || 0;
const used = (this.used as number) || 0;
if (maximumUse > 0 && used >= maximumUse) {
await this.setAndSync({ status: 'Maxed', isEnabled: false });
}
}
static filters: FiltersMap = { static filters: FiltersMap = {
expenseAccount: () => ({ expenseAccount: () => ({
rootType: AccountRootTypeEnum.Expense, rootType: AccountRootTypeEnum.Expense,
+10 -4
View File
@@ -765,6 +765,13 @@ export function getLoyaltyProgramStatus(doc?: RenderData | Doc): string {
return ''; return '';
} }
const maximumUse = doc.maximumUse as number;
const used = doc.used as number;
if (maximumUse > 0 && used >= maximumUse) {
return 'Maxed';
}
const currentDate = new Date(); const currentDate = new Date();
currentDate.setHours(0, 0, 0, 0); currentDate.setHours(0, 0, 0, 0);
@@ -781,6 +788,7 @@ export const loyaltyProgramStatusColor: Record<string, string | undefined> = {
Active: 'green', Active: 'green',
Disabled: 'gray', Disabled: 'gray',
Expired: 'red', Expired: 'red',
Maxed: 'orange',
}; };
export function getLoyaltyProgramStatusText(status: string): string { export function getLoyaltyProgramStatusText(status: string): string {
@@ -791,6 +799,8 @@ export function getLoyaltyProgramStatusText(status: string): string {
return t`Disabled`; return t`Disabled`;
case 'Expired': case 'Expired':
return t`Expired`; return t`Expired`;
case 'Maxed':
return t`Maxed`;
default: default:
return ''; return '';
} }
@@ -1658,10 +1668,6 @@ export async function isLoyaltyProgramMaxedOut(
fyo: Fyo, fyo: Fyo,
loyaltyProgramName: string loyaltyProgramName: string
): Promise<boolean> { ): Promise<boolean> {
if (!loyaltyProgramName) {
return false;
}
const loyaltyProgram = await fyo.db.getAll(ModelNameEnum.LoyaltyProgram, { const loyaltyProgram = await fyo.db.getAll(ModelNameEnum.LoyaltyProgram, {
fields: ['maximumUse', 'used', 'isEnabled'], fields: ['maximumUse', 'used', 'isEnabled'],
filters: { name: loyaltyProgramName }, filters: { name: loyaltyProgramName },
+20 -3
View File
@@ -79,6 +79,8 @@ export default defineComponent({
Unpaid: this.t`Unpaid`, Unpaid: this.t`Unpaid`,
PartlyPaid: this.t`Partly Paid`, PartlyPaid: this.t`Partly Paid`,
Expired: this.t`Expired`, Expired: this.t`Expired`,
Maxed: this.t`Maxed`,
Active: this.t`Active`,
}[this.status]; }[this.status];
}, },
color(): UIColors { color(): UIColors {
@@ -102,6 +104,8 @@ const statusColorMap: Record<Status, UIColors> = {
Unpaid: 'red', Unpaid: 'red',
PartlyPaid: 'yellow', PartlyPaid: 'yellow',
Expired: 'red', Expired: 'red',
Maxed: 'orange',
Active: 'green',
}; };
function getStatus(doc: Doc) { function getStatus(doc: Doc) {
@@ -115,10 +119,23 @@ function getStatus(doc: Doc) {
if (doc instanceof LoyaltyProgram) { if (doc instanceof LoyaltyProgram) {
const currentDate = new Date(); const currentDate = new Date();
if (doc.toDate && doc.toDate instanceof Date && doc.toDate <= currentDate) { currentDate.setHours(0, 0, 0, 0);
return 'Expired';
const maximumUse = doc.maximumUse as number;
const used = doc.used as number;
if (maximumUse > 0 && used >= maximumUse) {
return 'Maxed';
} }
return 'Saved';
if (doc.toDate && doc.toDate instanceof Date) {
const toDate = new Date(doc.toDate);
toDate.setHours(0, 0, 0, 0);
if (toDate <= currentDate) {
return 'Expired';
}
}
return 'Active';
} }
if (doc instanceof Party && doc.outstandingAmount?.isZero() !== true) { if (doc instanceof Party && doc.outstandingAmount?.isZero() !== true) {