feat: auto-set billFwdStatus to pending when all bills have attachments

Enables automatic email notification trigger when the last bill receives an
attachment under "when-attached" forwarding strategy. This eliminates manual
intervention for marking locations ready for tenant notification.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Knee Cola
2025-12-30 12:58:16 +01:00
parent 2b6999d728
commit e26a478577

View File

@@ -72,10 +72,49 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
}),
});
/**
* Checks if billFwdStatus should be updated to "pending" based on attachment conditions
* @param location - The billing location containing the bill
* @param currentBillId - The ID of the bill being updated (to exclude from check)
* @param hasNewAttachment - Whether a new attachment is being added
* @returns true if billFwdStatus should be set to "pending"
*/
const shouldUpdateBillFwdStatus = (
location: BillingLocation,
currentBillId: string | undefined,
hasNewAttachment: boolean
): boolean => {
// Only proceed if a new attachment is being added
if (!hasNewAttachment) {
return false;
}
// Check billFwdEnabled is true
if (location.billFwdEnabled !== true) {
return false;
}
// Check billFwdStrategy is "when-attached"
if (location.billFwdStrategy !== "when-attached") {
return false;
}
// Check billFwdStatus is null or "failed"
if (location.billFwdStatus !== null && location.billFwdStatus !== "failed") {
return false;
}
// Check if ALL other bills have attachments
const otherBills = location.bills.filter(bill => bill._id !== currentBillId);
const allOtherBillsHaveAttachments = otherBills.every(bill => bill.attachment !== null);
return allOtherBillsHaveAttachments;
};
/**
* converts the file to a format stored in the database
* @param billAttachment
* @returns
* @param billAttachment
* @returns
*/
const serializeAttachment = async (billAttachment: File | null): Promise<FileAttachment | null> => {
@@ -177,6 +216,19 @@ export const updateOrAddBill = withUser(async (user: AuthenticatedUser, location
const billAttachment = await serializeAttachment(attachmentFile);
// Fetch the location to check billFwdStatus conditions
const location = await dbClient.collection<BillingLocation>("lokacije").findOne({
_id: locationId,
userId
});
if (!location) {
return { success: false, error: 'Location not found' };
}
// Check if we should update billFwdStatus to "pending"
const shouldSetFwdPending = shouldUpdateBillFwdStatus(location, billId, billAttachment !== null);
if (billId) {
// if there is an attachment, update the attachment field
@@ -199,6 +251,11 @@ export const updateOrAddBill = withUser(async (user: AuthenticatedUser, location
"bills.$[elem].hub3aText": hub3aText,
};
// Add billFwdStatus if needed
if (shouldSetFwdPending) {
(mongoDbSet as any).billFwdStatus = "pending";
}
// update bill in given location with the given locationID
await dbClient.collection<BillingLocation>("lokacije").updateOne(
{
@@ -225,17 +282,27 @@ export const updateOrAddBill = withUser(async (user: AuthenticatedUser, location
hub3aText,
};
// Build update operation
const updateOp: any = {
$push: {
bills: newBill
}
};
// Add billFwdStatus update if needed
if (shouldSetFwdPending) {
updateOp.$set = {
billFwdStatus: "pending"
};
}
// Add to current location
await dbClient.collection<BillingLocation>("lokacije").updateOne(
{
_id: locationId, // find a location with the given locationID
userId // make sure that the location belongs to the user
},
{
$push: {
bills: newBill
}
});
updateOp);
// If addToSubsequentMonths is enabled, add to subsequent months
if (addToSubsequentMonths && billYear && billMonth) {