Ship deploy build for multi-company order items.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
+12
-3
@@ -105,9 +105,16 @@ let CartsService = class CartsService {
|
|||||||
if (!item)
|
if (!item)
|
||||||
throw new common_1.NotFoundException('آیتم سبد یافت نشد');
|
throw new common_1.NotFoundException('آیتم سبد یافت نشد');
|
||||||
await this.prisma.cartItem.delete({ where: { id: itemId } });
|
await this.prisma.cartItem.delete({ where: { id: itemId } });
|
||||||
|
const remaining = await this.prisma.cartItem.findMany({
|
||||||
|
where: { cartId: cart.id },
|
||||||
|
take: 1,
|
||||||
|
});
|
||||||
await this.prisma.cart.update({
|
await this.prisma.cart.update({
|
||||||
where: { id: cart.id },
|
where: { id: cart.id },
|
||||||
data: { updatedAt: new Date() },
|
data: {
|
||||||
|
companyId: remaining[0]?.companyId ?? null,
|
||||||
|
updatedAt: new Date(),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return this.getCart(userId);
|
return this.getCart(userId);
|
||||||
}
|
}
|
||||||
@@ -151,12 +158,14 @@ let CartsService = class CartsService {
|
|||||||
return cart;
|
return cart;
|
||||||
}
|
}
|
||||||
mapCart(cart) {
|
mapCart(cart) {
|
||||||
const companyName = cart.items[0]?.companyName;
|
const companyNames = [
|
||||||
|
...new Set(cart.items.map((item) => item.companyName).filter(Boolean)),
|
||||||
|
];
|
||||||
return {
|
return {
|
||||||
id: cart.id,
|
id: cart.id,
|
||||||
userId: cart.userId,
|
userId: cart.userId,
|
||||||
companyId: cart.companyId ?? cart.items[0]?.companyId,
|
companyId: cart.companyId ?? cart.items[0]?.companyId,
|
||||||
companyName: companyName ?? '',
|
companyName: companyNames.join('، '),
|
||||||
notes: cart.notes ?? undefined,
|
notes: cart.notes ?? undefined,
|
||||||
items: cart.items.map((item) => ({
|
items: cart.items.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+8
-2
@@ -32,7 +32,7 @@ let CashPaymentsService = class CashPaymentsService {
|
|||||||
async submitReceipt(userId, orderId, dto) {
|
async submitReceipt(userId, orderId, dto) {
|
||||||
const order = await this.prisma.order.findUnique({
|
const order = await this.prisma.order.findUnique({
|
||||||
where: { id: orderId },
|
where: { id: orderId },
|
||||||
include: { cashReceipt: true },
|
include: { cashReceipt: true, items: true },
|
||||||
});
|
});
|
||||||
if (!order)
|
if (!order)
|
||||||
throw new common_1.NotFoundException('سفارش یافت نشد');
|
throw new common_1.NotFoundException('سفارش یافت نشد');
|
||||||
@@ -49,10 +49,16 @@ let CashPaymentsService = class CashPaymentsService {
|
|||||||
order.cashInvoiceExpiresAt.getTime() < Date.now()) {
|
order.cashInvoiceExpiresAt.getTime() < Date.now()) {
|
||||||
throw new common_1.BadRequestException('مهلت پرداخت فاکتور نقدی به پایان رسیده است');
|
throw new common_1.BadRequestException('مهلت پرداخت فاکتور نقدی به پایان رسیده است');
|
||||||
}
|
}
|
||||||
|
const companyIds = [
|
||||||
|
...new Set([
|
||||||
|
order.companyId,
|
||||||
|
...order.items.map((item) => item.companyId).filter(Boolean),
|
||||||
|
].filter(Boolean)),
|
||||||
|
];
|
||||||
const account = await this.prisma.bankAccount.findFirst({
|
const account = await this.prisma.bankAccount.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: dto.destinationAccountId,
|
id: dto.destinationAccountId,
|
||||||
companyId: order.companyId,
|
companyId: { in: companyIds },
|
||||||
isActive: true,
|
isActive: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
@@ -2,3 +2,7 @@ export declare function computeCashInvoiceExpiry(company: {
|
|||||||
cashInvoiceValidUntilHour: number | null;
|
cashInvoiceValidUntilHour: number | null;
|
||||||
cashInvoiceValidityHours: number;
|
cashInvoiceValidityHours: number;
|
||||||
}): Date;
|
}): Date;
|
||||||
|
export declare function earliestCashInvoiceExpiry(companies: Array<{
|
||||||
|
cashInvoiceValidUntilHour: number | null;
|
||||||
|
cashInvoiceValidityHours: number;
|
||||||
|
}>): Date;
|
||||||
|
|||||||
Vendored
+9
@@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.computeCashInvoiceExpiry = computeCashInvoiceExpiry;
|
exports.computeCashInvoiceExpiry = computeCashInvoiceExpiry;
|
||||||
|
exports.earliestCashInvoiceExpiry = earliestCashInvoiceExpiry;
|
||||||
const tehran_time_1 = require("./tehran-time");
|
const tehran_time_1 = require("./tehran-time");
|
||||||
function computeCashInvoiceExpiry(company) {
|
function computeCashInvoiceExpiry(company) {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -14,4 +15,12 @@ function computeCashInvoiceExpiry(company) {
|
|||||||
}
|
}
|
||||||
return new Date(now.getTime() + company.cashInvoiceValidityHours * 60 * 60 * 1000);
|
return new Date(now.getTime() + company.cashInvoiceValidityHours * 60 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
function earliestCashInvoiceExpiry(companies) {
|
||||||
|
if (!companies.length) {
|
||||||
|
return new Date(Date.now() + 8 * 60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
return companies
|
||||||
|
.map((company) => computeCashInvoiceExpiry(company))
|
||||||
|
.reduce((earliest, current) => current.getTime() < earliest.getTime() ? current : earliest);
|
||||||
|
}
|
||||||
//# sourceMappingURL=cash-expiry.js.map
|
//# sourceMappingURL=cash-expiry.js.map
|
||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"cash-expiry.js","sourceRoot":"","sources":["../../../src/common/utils/cash-expiry.ts"],"names":[],"mappings":";;AAEA,4DAmBC;AArBD,+CAAsD;AAEtD,SAAgB,wBAAwB,CAAC,OAGxC;IACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,IACE,OAAO,CAAC,yBAAyB,IAAI,IAAI;QACzC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAClD,CAAC;QACD,MAAM,OAAO,GAAG,IAAA,0BAAY,EAAC,GAAG,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YACvC,OAAO,IAAA,0BAAY,EAAC,IAAA,qBAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,IAAI,CACb,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,wBAAwB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAClE,CAAC;AACJ,CAAC"}
|
{"version":3,"file":"cash-expiry.js","sourceRoot":"","sources":["../../../src/common/utils/cash-expiry.ts"],"names":[],"mappings":";;AAEA,4DAmBC;AAGD,8DAcC;AAtCD,+CAAsD;AAEtD,SAAgB,wBAAwB,CAAC,OAGxC;IACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,IACE,OAAO,CAAC,yBAAyB,IAAI,IAAI;QACzC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAClD,CAAC;QACD,MAAM,OAAO,GAAG,IAAA,0BAAY,EAAC,GAAG,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YACvC,OAAO,IAAA,0BAAY,EAAC,IAAA,qBAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,IAAI,CACb,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,wBAAwB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAClE,CAAC;AACJ,CAAC;AAGD,SAAgB,yBAAyB,CACvC,SAGE;IAEF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,SAAS;SACb,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;SACnD,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAC5B,OAAO,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAC5D,CAAC;AACN,CAAC"}
|
||||||
+2
@@ -57,6 +57,8 @@ export declare class DashboardController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
+2
@@ -59,6 +59,8 @@ export declare class DashboardService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
Vendored
+1
@@ -34,6 +34,7 @@ export declare class ChooseSettlementDto {
|
|||||||
checkMode?: CheckRegistrationMode;
|
checkMode?: CheckRegistrationMode;
|
||||||
}
|
}
|
||||||
export declare class AdminCreateOrderDto {
|
export declare class AdminCreateOrderDto {
|
||||||
|
customerId?: string;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
customerPhone?: string;
|
customerPhone?: string;
|
||||||
customerName?: string;
|
customerName?: string;
|
||||||
|
|||||||
Vendored
+6
@@ -185,6 +185,7 @@ __decorate([
|
|||||||
__metadata("design:type", String)
|
__metadata("design:type", String)
|
||||||
], ChooseSettlementDto.prototype, "checkMode", void 0);
|
], ChooseSettlementDto.prototype, "checkMode", void 0);
|
||||||
class AdminCreateOrderDto {
|
class AdminCreateOrderDto {
|
||||||
|
customerId;
|
||||||
userId;
|
userId;
|
||||||
customerPhone;
|
customerPhone;
|
||||||
customerName;
|
customerName;
|
||||||
@@ -196,6 +197,11 @@ class AdminCreateOrderDto {
|
|||||||
items;
|
items;
|
||||||
}
|
}
|
||||||
exports.AdminCreateOrderDto = AdminCreateOrderDto;
|
exports.AdminCreateOrderDto = AdminCreateOrderDto;
|
||||||
|
__decorate([
|
||||||
|
(0, class_validator_1.IsOptional)(),
|
||||||
|
(0, class_validator_1.IsString)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], AdminCreateOrderDto.prototype, "customerId", void 0);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, class_validator_1.IsOptional)(),
|
(0, class_validator_1.IsOptional)(),
|
||||||
(0, class_validator_1.IsString)(),
|
(0, class_validator_1.IsString)(),
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+20
@@ -49,6 +49,8 @@ export declare class CustomerOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -152,6 +154,8 @@ export declare class CustomerOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -255,6 +259,8 @@ export declare class CustomerOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -358,6 +364,8 @@ export declare class CustomerOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -461,6 +469,8 @@ export declare class CustomerOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -568,6 +578,8 @@ export declare class AdminOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -671,6 +683,8 @@ export declare class AdminOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -774,6 +788,8 @@ export declare class AdminOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -877,6 +893,8 @@ export declare class AdminOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -980,6 +998,8 @@ export declare class AdminOrdersController {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
Vendored
+23
@@ -71,6 +71,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -174,6 +176,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -280,6 +284,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -383,6 +389,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -486,6 +494,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -589,6 +599,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -692,6 +704,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -795,6 +809,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -898,6 +914,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -1001,6 +1019,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -1062,6 +1082,7 @@ export declare class OrdersService {
|
|||||||
private mapCheckCreate;
|
private mapCheckCreate;
|
||||||
private nextOrderNumber;
|
private nextOrderNumber;
|
||||||
private createWithUniqueOrderNumber;
|
private createWithUniqueOrderNumber;
|
||||||
|
private companiesForOrder;
|
||||||
private getOrder;
|
private getOrder;
|
||||||
mapOrder(order: OrderFull, adminView?: boolean): {
|
mapOrder(order: OrderFull, adminView?: boolean): {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -1108,6 +1129,8 @@ export declare class OrdersService {
|
|||||||
lineTotal: number | null;
|
lineTotal: number | null;
|
||||||
totalAmount: number | null;
|
totalAmount: number | null;
|
||||||
notes: string | undefined;
|
notes: string | undefined;
|
||||||
|
companyId: string;
|
||||||
|
companyName: string;
|
||||||
}[];
|
}[];
|
||||||
checks: {
|
checks: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
Vendored
+111
-36
@@ -101,26 +101,53 @@ let OrdersService = class OrdersService {
|
|||||||
return this.mapOrder(order, true);
|
return this.mapOrder(order, true);
|
||||||
}
|
}
|
||||||
async submitOrder(userId, dto) {
|
async submitOrder(userId, dto) {
|
||||||
const [company, settings] = await Promise.all([
|
const settings = await this.prisma.systemSettings.findUnique({
|
||||||
this.prisma.company.findUnique({ where: { id: dto.companyId } }),
|
where: { id: 'default' },
|
||||||
this.prisma.systemSettings.findUnique({
|
select: { maxMeteragePerInvoice: true },
|
||||||
where: { id: 'default' },
|
|
||||||
select: { maxMeteragePerInvoice: true },
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
if (!company || !company.isActive) {
|
|
||||||
throw new common_1.NotFoundException('شرکت یافت نشد یا غیرفعال است');
|
|
||||||
}
|
|
||||||
const maxMeterage = (0, meterage_1.resolveMaxMeterage)(company.maxMeteragePerInvoice, settings?.maxMeteragePerInvoice);
|
|
||||||
const productIds = dto.items.map((i) => i.productId);
|
|
||||||
const products = await this.prisma.product.findMany({
|
|
||||||
where: { id: { in: productIds }, companyId: company.id, isActive: true },
|
|
||||||
include: { catalog: true },
|
|
||||||
});
|
});
|
||||||
if (products.length !== productIds.length) {
|
const productIds = dto.items.map((i) => i.productId);
|
||||||
throw new common_1.BadRequestException('یک یا چند محصول نامعتبر است');
|
const uniqueProductIds = [...new Set(productIds)];
|
||||||
|
if (uniqueProductIds.length !== productIds.length) {
|
||||||
|
throw new common_1.BadRequestException('محصول تکراری در سفارش مجاز نیست');
|
||||||
}
|
}
|
||||||
|
const products = await this.prisma.product.findMany({
|
||||||
|
where: { id: { in: uniqueProductIds } },
|
||||||
|
include: { catalog: true, company: true },
|
||||||
|
});
|
||||||
const productMap = new Map(products.map((p) => [p.id, p]));
|
const productMap = new Map(products.map((p) => [p.id, p]));
|
||||||
|
for (const item of dto.items) {
|
||||||
|
const product = productMap.get(item.productId);
|
||||||
|
if (!product) {
|
||||||
|
throw new common_1.BadRequestException('یک یا چند محصول نامعتبر است یا دیگر در سیستم وجود ندارد. سبد را خالی کنید و دوباره اضافه کنید.');
|
||||||
|
}
|
||||||
|
if (!product.isActive) {
|
||||||
|
throw new common_1.BadRequestException(`محصول «${product.name}» غیرفعال است و قابل سفارش نیست`);
|
||||||
|
}
|
||||||
|
if (!product.company?.isActive) {
|
||||||
|
throw new common_1.BadRequestException(`شرکت محصول «${product.name}» غیرفعال است`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const meterageByCompany = new Map();
|
||||||
|
for (const item of dto.items) {
|
||||||
|
const product = productMap.get(item.productId);
|
||||||
|
const current = meterageByCompany.get(product.companyId);
|
||||||
|
if (current) {
|
||||||
|
current.meterage += item.meterage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
meterageByCompany.set(product.companyId, {
|
||||||
|
name: product.company.name,
|
||||||
|
meterage: item.meterage,
|
||||||
|
max: product.company.maxMeteragePerInvoice,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const row of meterageByCompany.values()) {
|
||||||
|
const maxMeterageResolved = (0, meterage_1.resolveMaxMeterage)(row.max, settings?.maxMeteragePerInvoice);
|
||||||
|
if (row.meterage > maxMeterageResolved) {
|
||||||
|
throw new common_1.BadRequestException(`حداکثر متراژ مجاز فاکتور برای «${row.name}» برابر ${maxMeterageResolved} متر است`);
|
||||||
|
}
|
||||||
|
}
|
||||||
let totalMeterage = 0;
|
let totalMeterage = 0;
|
||||||
const itemsData = dto.items.map((item) => {
|
const itemsData = dto.items.map((item) => {
|
||||||
const product = productMap.get(item.productId);
|
const product = productMap.get(item.productId);
|
||||||
@@ -140,18 +167,28 @@ let OrdersService = class OrdersService {
|
|||||||
color: product.color,
|
color: product.color,
|
||||||
requestedMeterage: item.meterage,
|
requestedMeterage: item.meterage,
|
||||||
notes: item.notes?.trim() || null,
|
notes: item.notes?.trim() || null,
|
||||||
|
companyId: product.companyId,
|
||||||
|
companyName: product.company.name,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (totalMeterage > maxMeterage) {
|
const companyNames = [
|
||||||
throw new common_1.BadRequestException(`حداکثر متراژ مجاز هر فاکتور ${maxMeterage} متر است`);
|
...new Set(itemsData.map((item) => item.companyName).filter(Boolean)),
|
||||||
|
];
|
||||||
|
const preferredCompanyId = itemsData.some((item) => item.companyId === dto.companyId)
|
||||||
|
? dto.companyId
|
||||||
|
: itemsData[0].companyId;
|
||||||
|
const primaryCompany = products.find((p) => p.companyId === preferredCompanyId)
|
||||||
|
?.company;
|
||||||
|
if (!primaryCompany) {
|
||||||
|
throw new common_1.NotFoundException('شرکت محصولات یافت نشد یا غیرفعال است');
|
||||||
}
|
}
|
||||||
const order = await this.createWithUniqueOrderNumber((orderNumber) => this.prisma.$transaction(async (tx) => {
|
const order = await this.createWithUniqueOrderNumber((orderNumber) => this.prisma.$transaction(async (tx) => {
|
||||||
const created = await tx.order.create({
|
const created = await tx.order.create({
|
||||||
data: {
|
data: {
|
||||||
orderNumber,
|
orderNumber,
|
||||||
userId,
|
userId,
|
||||||
companyId: company.id,
|
companyId: primaryCompany.id,
|
||||||
companyName: company.name,
|
companyName: companyNames.join('، '),
|
||||||
settlementType: null,
|
settlementType: null,
|
||||||
checkMode: null,
|
checkMode: null,
|
||||||
status: client_1.OrderStatus.awaiting_review,
|
status: client_1.OrderStatus.awaiting_review,
|
||||||
@@ -174,7 +211,17 @@ let OrdersService = class OrdersService {
|
|||||||
const cart = await tx.cart.findFirst({ where: { userId } });
|
const cart = await tx.cart.findFirst({ where: { userId } });
|
||||||
if (cart) {
|
if (cart) {
|
||||||
await tx.cartItem.deleteMany({
|
await tx.cartItem.deleteMany({
|
||||||
where: { cartId: cart.id, companyId: company.id },
|
where: {
|
||||||
|
cartId: cart.id,
|
||||||
|
productId: { in: uniqueProductIds },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const remaining = await tx.cartItem.findFirst({
|
||||||
|
where: { cartId: cart.id },
|
||||||
|
});
|
||||||
|
await tx.cart.update({
|
||||||
|
where: { id: cart.id },
|
||||||
|
data: { companyId: remaining?.companyId ?? null },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return created;
|
return created;
|
||||||
@@ -200,6 +247,9 @@ let OrdersService = class OrdersService {
|
|||||||
? client_1.OrderStatus.awaiting_cash_payment
|
? client_1.OrderStatus.awaiting_cash_payment
|
||||||
: client_1.OrderStatus.check_in_progress;
|
: client_1.OrderStatus.check_in_progress;
|
||||||
(0, order_transitions_1.assertTransition)(order.status, nextStatus);
|
(0, order_transitions_1.assertTransition)(order.status, nextStatus);
|
||||||
|
const cashCompanies = isCash
|
||||||
|
? await this.companiesForOrder(order)
|
||||||
|
: [];
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.$transaction(async (tx) => {
|
||||||
await tx.order.update({
|
await tx.order.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@@ -209,7 +259,7 @@ let OrdersService = class OrdersService {
|
|||||||
? null
|
? null
|
||||||
: (dto.checkMode ?? client_1.CheckRegistrationMode.full),
|
: (dto.checkMode ?? client_1.CheckRegistrationMode.full),
|
||||||
cashInvoiceExpiresAt: isCash
|
cashInvoiceExpiresAt: isCash
|
||||||
? (0, cash_expiry_1.computeCashInvoiceExpiry)(order.company)
|
? (0, cash_expiry_1.earliestCashInvoiceExpiry)(cashCompanies)
|
||||||
: null,
|
: null,
|
||||||
cashReminderSentAt: null,
|
cashReminderSentAt: null,
|
||||||
status: nextStatus,
|
status: nextStatus,
|
||||||
@@ -235,8 +285,16 @@ let OrdersService = class OrdersService {
|
|||||||
});
|
});
|
||||||
if (!company)
|
if (!company)
|
||||||
throw new common_1.NotFoundException('شرکت یافت نشد');
|
throw new common_1.NotFoundException('شرکت یافت نشد');
|
||||||
let userId = dto.userId;
|
let userId = dto.customerId || dto.userId;
|
||||||
if (!userId && dto.customerPhone) {
|
if (userId) {
|
||||||
|
const existing = await this.prisma.customer.findUnique({
|
||||||
|
where: { id: userId },
|
||||||
|
});
|
||||||
|
if (!existing) {
|
||||||
|
throw new common_1.BadRequestException('مشتری انتخابشده یافت نشد');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dto.customerPhone) {
|
||||||
const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.customerPhone));
|
const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.customerPhone));
|
||||||
if (!(0, phone_1.isValidPhone)(phone)) {
|
if (!(0, phone_1.isValidPhone)(phone)) {
|
||||||
throw new common_1.BadRequestException('شماره موبایل نامعتبر است');
|
throw new common_1.BadRequestException('شماره موبایل نامعتبر است');
|
||||||
@@ -257,7 +315,7 @@ let OrdersService = class OrdersService {
|
|||||||
userId = customer.id;
|
userId = customer.id;
|
||||||
}
|
}
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new common_1.BadRequestException('شناسه یا شماره مشتری الزامی است');
|
throw new common_1.BadRequestException('انتخاب مشتری الزامی است');
|
||||||
}
|
}
|
||||||
const totalMeterage = dto.meterage ?? 0;
|
const totalMeterage = dto.meterage ?? 0;
|
||||||
const ownerId = userId;
|
const ownerId = userId;
|
||||||
@@ -372,6 +430,12 @@ let OrdersService = class OrdersService {
|
|||||||
(order.finalAmount ?? 0) <= 0) {
|
(order.finalAmount ?? 0) <= 0) {
|
||||||
throw new common_1.BadRequestException('ابتدا سفارش را قیمتگذاری کنید تا فاکتور قابل ارسال باشد');
|
throw new common_1.BadRequestException('ابتدا سفارش را قیمتگذاری کنید تا فاکتور قابل ارسال باشد');
|
||||||
}
|
}
|
||||||
|
const needsCashExpiry = (dto.status === client_1.OrderStatus.cash_invoice_issued ||
|
||||||
|
dto.status === client_1.OrderStatus.awaiting_cash_payment) &&
|
||||||
|
!order.cashInvoiceExpiresAt;
|
||||||
|
const cashExpiry = needsCashExpiry
|
||||||
|
? (0, cash_expiry_1.earliestCashInvoiceExpiry)(await this.companiesForOrder(order))
|
||||||
|
: null;
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.$transaction(async (tx) => {
|
||||||
await tx.order.update({
|
await tx.order.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@@ -389,16 +453,11 @@ let OrdersService = class OrdersService {
|
|||||||
reason: dto.reason || null,
|
reason: dto.reason || null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (dto.status === client_1.OrderStatus.cash_invoice_issued ||
|
if (cashExpiry) {
|
||||||
dto.status === client_1.OrderStatus.awaiting_cash_payment) {
|
await tx.order.update({
|
||||||
if (!order.cashInvoiceExpiresAt) {
|
where: { id },
|
||||||
await tx.order.update({
|
data: { cashInvoiceExpiresAt: cashExpiry },
|
||||||
where: { id },
|
});
|
||||||
data: {
|
|
||||||
cashInvoiceExpiresAt: (0, cash_expiry_1.computeCashInvoiceExpiry)(order.company),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const event = (0, notification_events_1.eventForStatus)(dto.status);
|
const event = (0, notification_events_1.eventForStatus)(dto.status);
|
||||||
@@ -515,6 +574,20 @@ let OrdersService = class OrdersService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async companiesForOrder(order) {
|
||||||
|
const companyIds = [
|
||||||
|
...new Set([
|
||||||
|
order.companyId,
|
||||||
|
...order.items.map((item) => item.companyId).filter(Boolean),
|
||||||
|
].filter(Boolean)),
|
||||||
|
];
|
||||||
|
if (!companyIds.length)
|
||||||
|
return order.company ? [order.company] : [];
|
||||||
|
const companies = await this.prisma.company.findMany({
|
||||||
|
where: { id: { in: companyIds } },
|
||||||
|
});
|
||||||
|
return companies.length ? companies : order.company ? [order.company] : [];
|
||||||
|
}
|
||||||
async getOrder(id) {
|
async getOrder(id) {
|
||||||
const order = await this.prisma.order.findUnique({
|
const order = await this.prisma.order.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
@@ -572,6 +645,8 @@ let OrdersService = class OrdersService {
|
|||||||
lineTotal: hidePrices ? null : item.lineTotal,
|
lineTotal: hidePrices ? null : item.lineTotal,
|
||||||
totalAmount: hidePrices ? null : item.lineTotal,
|
totalAmount: hidePrices ? null : item.lineTotal,
|
||||||
notes: item.notes ?? undefined,
|
notes: item.notes ?? undefined,
|
||||||
|
companyId: item.companyId,
|
||||||
|
companyName: item.companyName,
|
||||||
})),
|
})),
|
||||||
checks: order.checks.map((c) => ({
|
checks: order.checks.map((c) => ({
|
||||||
id: c.id,
|
id: c.id,
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
Reference in New Issue
Block a user