Rebuild order flow: settle after pricing, notifications, and invoice expiry.

Hide prices until admin sends the invoice, enforce status transitions, add customer/admin SMS+in-app notifications, schedule cash invoice reminders, and ship updated dist/prisma-client/deploy-bundle for git-pull deploys.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-09 12:00:13 +03:30
co-authored by Cursor
parent 06e5f48d07
commit d4aaa8e997
102 changed files with 2989 additions and 509 deletions
+2
View File
@@ -0,0 +1,2 @@
export declare const FALLBACK_MAX_METERAGE = 5000;
export declare function resolveMaxMeterage(companyValue: number | null | undefined, settingsValue: number | null | undefined): number;
+13
View File
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FALLBACK_MAX_METERAGE = void 0;
exports.resolveMaxMeterage = resolveMaxMeterage;
exports.FALLBACK_MAX_METERAGE = 5000;
function resolveMaxMeterage(companyValue, settingsValue) {
if (companyValue != null && companyValue > 0)
return companyValue;
if (settingsValue != null && settingsValue > 0)
return settingsValue;
return exports.FALLBACK_MAX_METERAGE;
}
//# sourceMappingURL=meterage.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"meterage.js","sourceRoot":"","sources":["../../../src/common/utils/meterage.ts"],"names":[],"mappings":";;;AAMA,gDAOC;AAZY,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAK1C,SAAgB,kBAAkB,CAChC,YAAuC,EACvC,aAAwC;IAExC,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IAClE,IAAI,aAAa,IAAI,IAAI,IAAI,aAAa,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC;IACrE,OAAO,6BAAqB,CAAC;AAC/B,CAAC"}
+10 -8
View File
@@ -7,22 +7,24 @@ const client_1 = require("@prisma/client");
exports.ADMIN_STATUS_MAP = {
pending_review: [
client_1.OrderStatus.cart,
client_1.OrderStatus.awaiting_settlement,
client_1.OrderStatus.cash_in_progress,
client_1.OrderStatus.check_in_progress,
client_1.OrderStatus.submitted,
client_1.OrderStatus.awaiting_review,
client_1.OrderStatus.pricing,
],
awaiting_customer: [
client_1.OrderStatus.awaiting_settlement,
client_1.OrderStatus.awaiting_settlement_fix,
client_1.OrderStatus.check_in_progress,
client_1.OrderStatus.cash_in_progress,
client_1.OrderStatus.cash_invoice_issued,
client_1.OrderStatus.awaiting_cash_payment,
],
pending_check: [client_1.OrderStatus.awaiting_check_review],
pending_payment: [
client_1.OrderStatus.cash_payment_submitted,
client_1.OrderStatus.awaiting_cash_confirmation,
],
pending_check: [client_1.OrderStatus.awaiting_check_review],
needs_correction: [
client_1.OrderStatus.needs_correction,
client_1.OrderStatus.awaiting_settlement_fix,
],
needs_correction: [client_1.OrderStatus.needs_correction],
check_correction: [client_1.OrderStatus.check_needs_fix, client_1.OrderStatus.check_rejected],
final_approval: [
client_1.OrderStatus.final_approved,
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"order-status.js","sourceRoot":"","sources":["../../../src/common/utils/order-status.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"order-status.js","sourceRoot":"","sources":["../../../src/common/utils/order-status.ts"],"names":[],"mappings":";;;AA2CA,4DASC;AAED,sCAMC;AA5DD,2CAA6C;AAGhC,QAAA,gBAAgB,GAAkC;IAC7D,cAAc,EAAE;QACd,oBAAW,CAAC,IAAI;QAChB,oBAAW,CAAC,SAAS;QACrB,oBAAW,CAAC,eAAe;QAC3B,oBAAW,CAAC,OAAO;KACpB;IACD,iBAAiB,EAAE;QACjB,oBAAW,CAAC,mBAAmB;QAC/B,oBAAW,CAAC,uBAAuB;QACnC,oBAAW,CAAC,iBAAiB;QAC7B,oBAAW,CAAC,gBAAgB;QAC5B,oBAAW,CAAC,mBAAmB;QAC/B,oBAAW,CAAC,qBAAqB;KAClC;IACD,aAAa,EAAE,CAAC,oBAAW,CAAC,qBAAqB,CAAC;IAClD,eAAe,EAAE;QACf,oBAAW,CAAC,sBAAsB;QAClC,oBAAW,CAAC,0BAA0B;KACvC;IACD,gBAAgB,EAAE,CAAC,oBAAW,CAAC,gBAAgB,CAAC;IAChD,gBAAgB,EAAE,CAAC,oBAAW,CAAC,eAAe,EAAE,oBAAW,CAAC,cAAc,CAAC;IAC3E,cAAc,EAAE;QACd,oBAAW,CAAC,cAAc;QAC1B,oBAAW,CAAC,eAAe;QAC3B,oBAAW,CAAC,cAAc;QAC1B,oBAAW,CAAC,SAAS;QACrB,oBAAW,CAAC,aAAa;KAC1B;IACD,OAAO,EAAE,CAAC,oBAAW,CAAC,OAAO,CAAC;IAC9B,SAAS,EAAE,CAAC,oBAAW,CAAC,SAAS,CAAC;CACnC,CAAC;AAGF,MAAM,iBAAiB,GAAkB;IACvC,oBAAW,CAAC,SAAS;IACrB,oBAAW,CAAC,QAAQ;IACpB,oBAAW,CAAC,OAAO;CACpB,CAAC;AAEF,SAAgB,wBAAwB,CACtC,MAAe;IAEf,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,IAAI,wBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,wBAAgB,CAAC,MAAM,CAAC,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,CAAC,oBAAW,CAAC,CAAC,QAAQ,CAAC,MAAqB,CAAC,EAAE,CAAC;QAC/D,OAAO,CAAC,MAAqB,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,aAAa,CAAC,MAAmB;IAC/C,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,wBAAgB,CAAC,EAAE,CAAC;QAC7D,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;IAC1C,CAAC;IACD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACtD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAEY,QAAA,mBAAmB,GAAgC;IAC9D,IAAI,EAAE,UAAU;IAChB,mBAAmB,EAAE,iBAAiB;IACtC,gBAAgB,EAAE,iBAAiB;IACnC,iBAAiB,EAAE,eAAe;IAClC,SAAS,EAAE,SAAS;IACpB,eAAe,EAAE,iBAAiB;IAClC,OAAO,EAAE,YAAY;IACrB,gBAAgB,EAAE,eAAe;IACjC,uBAAuB,EAAE,aAAa;IACtC,mBAAmB,EAAE,kBAAkB;IACvC,qBAAqB,EAAE,uBAAuB;IAC9C,sBAAsB,EAAE,qBAAqB;IAC7C,0BAA0B,EAAE,mBAAmB;IAC/C,cAAc,EAAE,sBAAsB;IACtC,qBAAqB,EAAE,UAAU;IACjC,eAAe,EAAE,UAAU;IAC3B,cAAc,EAAE,OAAO;IACvB,eAAe,EAAE,aAAa;IAC9B,cAAc,EAAE,aAAa;IAC7B,SAAS,EAAE,YAAY;IACvB,aAAa,EAAE,aAAa;IAC5B,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,SAAS;IACpB,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,OAAO;CACjB,CAAC"}
+6
View File
@@ -0,0 +1,6 @@
import { OrderStatus } from '@prisma/client';
export declare const ORDER_TRANSITIONS: Record<OrderStatus, OrderStatus[]>;
export declare function isFinalStatus(status: OrderStatus): boolean;
export declare function allowedTransitions(from: OrderStatus): OrderStatus[];
export declare function canTransition(from: OrderStatus, to: OrderStatus): boolean;
export declare function assertTransition(from: OrderStatus, to: OrderStatus): void;
+83
View File
@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ORDER_TRANSITIONS = void 0;
exports.isFinalStatus = isFinalStatus;
exports.allowedTransitions = allowedTransitions;
exports.canTransition = canTransition;
exports.assertTransition = assertTransition;
const common_1 = require("@nestjs/common");
const client_1 = require("@prisma/client");
const order_status_1 = require("./order-status");
exports.ORDER_TRANSITIONS = {
awaiting_review: [client_1.OrderStatus.pricing],
pricing: [client_1.OrderStatus.awaiting_settlement],
awaiting_settlement: [
client_1.OrderStatus.awaiting_cash_payment,
client_1.OrderStatus.check_in_progress,
client_1.OrderStatus.pricing,
],
awaiting_cash_payment: [
client_1.OrderStatus.awaiting_cash_confirmation,
client_1.OrderStatus.expired,
],
awaiting_cash_confirmation: [
client_1.OrderStatus.cash_confirmed,
client_1.OrderStatus.awaiting_cash_payment,
],
cash_confirmed: [client_1.OrderStatus.final_approved],
check_in_progress: [client_1.OrderStatus.awaiting_check_review],
awaiting_check_review: [
client_1.OrderStatus.checks_approved,
client_1.OrderStatus.check_needs_fix,
],
check_needs_fix: [client_1.OrderStatus.awaiting_check_review],
checks_approved: [client_1.OrderStatus.final_approved],
final_approved: [client_1.OrderStatus.preparing],
preparing: [client_1.OrderStatus.ready_to_ship],
ready_to_ship: [client_1.OrderStatus.shipped],
shipped: [client_1.OrderStatus.delivered],
delivered: [],
cancelled: [],
rejected: [],
expired: [],
cart: [client_1.OrderStatus.awaiting_review],
submitted: [client_1.OrderStatus.awaiting_review],
needs_correction: [client_1.OrderStatus.awaiting_review, client_1.OrderStatus.pricing],
awaiting_settlement_fix: [client_1.OrderStatus.awaiting_settlement],
cash_in_progress: [client_1.OrderStatus.awaiting_cash_payment],
cash_invoice_issued: [client_1.OrderStatus.awaiting_cash_payment],
cash_payment_submitted: [client_1.OrderStatus.awaiting_cash_confirmation],
check_rejected: [client_1.OrderStatus.check_needs_fix],
};
const ADMIN_TERMINAL_TRANSITIONS = [
client_1.OrderStatus.cancelled,
client_1.OrderStatus.rejected,
];
const FINAL_STATUSES = [
client_1.OrderStatus.delivered,
client_1.OrderStatus.cancelled,
client_1.OrderStatus.rejected,
client_1.OrderStatus.expired,
];
function isFinalStatus(status) {
return FINAL_STATUSES.includes(status);
}
function allowedTransitions(from) {
const next = [...(exports.ORDER_TRANSITIONS[from] ?? [])];
if (!isFinalStatus(from)) {
for (const terminal of ADMIN_TERMINAL_TRANSITIONS) {
if (!next.includes(terminal))
next.push(terminal);
}
}
return next;
}
function canTransition(from, to) {
return allowedTransitions(from).includes(to);
}
function assertTransition(from, to) {
if (canTransition(from, to))
return;
throw new common_1.BadRequestException(`تغییر وضعیت از «${order_status_1.ORDER_STATUS_LABELS[from]}» به «${order_status_1.ORDER_STATUS_LABELS[to]}» مجاز نیست`);
}
//# sourceMappingURL=order-transitions.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"order-transitions.js","sourceRoot":"","sources":["../../../src/common/utils/order-transitions.ts"],"names":[],"mappings":"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"}