mirror of
https://github.com/frappe/books.git
synced 2026-08-24 10:04:45 -05:00
fix: update status when loyalty program reaches maximum usage
This commit is contained in:
@@ -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({
|
||||||
|
|||||||
@@ -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
@@ -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 },
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user