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)
|
||||
throw new common_1.NotFoundException('آیتم سبد یافت نشد');
|
||||
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({
|
||||
where: { id: cart.id },
|
||||
data: { updatedAt: new Date() },
|
||||
data: {
|
||||
companyId: remaining[0]?.companyId ?? null,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
return this.getCart(userId);
|
||||
}
|
||||
@@ -151,12 +158,14 @@ let CartsService = class CartsService {
|
||||
return cart;
|
||||
}
|
||||
mapCart(cart) {
|
||||
const companyName = cart.items[0]?.companyName;
|
||||
const companyNames = [
|
||||
...new Set(cart.items.map((item) => item.companyName).filter(Boolean)),
|
||||
];
|
||||
return {
|
||||
id: cart.id,
|
||||
userId: cart.userId,
|
||||
companyId: cart.companyId ?? cart.items[0]?.companyId,
|
||||
companyName: companyName ?? '',
|
||||
companyName: companyNames.join('، '),
|
||||
notes: cart.notes ?? undefined,
|
||||
items: cart.items.map((item) => ({
|
||||
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) {
|
||||
const order = await this.prisma.order.findUnique({
|
||||
where: { id: orderId },
|
||||
include: { cashReceipt: true },
|
||||
include: { cashReceipt: true, items: true },
|
||||
});
|
||||
if (!order)
|
||||
throw new common_1.NotFoundException('سفارش یافت نشد');
|
||||
@@ -49,10 +49,16 @@ let CashPaymentsService = class CashPaymentsService {
|
||||
order.cashInvoiceExpiresAt.getTime() < Date.now()) {
|
||||
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({
|
||||
where: {
|
||||
id: dto.destinationAccountId,
|
||||
companyId: order.companyId,
|
||||
companyId: { in: companyIds },
|
||||
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;
|
||||
cashInvoiceValidityHours: number;
|
||||
}): Date;
|
||||
export declare function earliestCashInvoiceExpiry(companies: Array<{
|
||||
cashInvoiceValidUntilHour: number | null;
|
||||
cashInvoiceValidityHours: number;
|
||||
}>): Date;
|
||||
|
||||
Vendored
+9
@@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.computeCashInvoiceExpiry = computeCashInvoiceExpiry;
|
||||
exports.earliestCashInvoiceExpiry = earliestCashInvoiceExpiry;
|
||||
const tehran_time_1 = require("./tehran-time");
|
||||
function computeCashInvoiceExpiry(company) {
|
||||
const now = new Date();
|
||||
@@ -14,4 +15,12 @@ function computeCashInvoiceExpiry(company) {
|
||||
}
|
||||
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
|
||||
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;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
|
||||
+2
@@ -59,6 +59,8 @@ export declare class DashboardService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
|
||||
Vendored
+1
@@ -34,6 +34,7 @@ export declare class ChooseSettlementDto {
|
||||
checkMode?: CheckRegistrationMode;
|
||||
}
|
||||
export declare class AdminCreateOrderDto {
|
||||
customerId?: string;
|
||||
userId?: string;
|
||||
customerPhone?: string;
|
||||
customerName?: string;
|
||||
|
||||
Vendored
+6
@@ -185,6 +185,7 @@ __decorate([
|
||||
__metadata("design:type", String)
|
||||
], ChooseSettlementDto.prototype, "checkMode", void 0);
|
||||
class AdminCreateOrderDto {
|
||||
customerId;
|
||||
userId;
|
||||
customerPhone;
|
||||
customerName;
|
||||
@@ -196,6 +197,11 @@ class AdminCreateOrderDto {
|
||||
items;
|
||||
}
|
||||
exports.AdminCreateOrderDto = AdminCreateOrderDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], AdminCreateOrderDto.prototype, "customerId", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(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;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -152,6 +154,8 @@ export declare class CustomerOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -255,6 +259,8 @@ export declare class CustomerOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -358,6 +364,8 @@ export declare class CustomerOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -461,6 +469,8 @@ export declare class CustomerOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -568,6 +578,8 @@ export declare class AdminOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -671,6 +683,8 @@ export declare class AdminOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -774,6 +788,8 @@ export declare class AdminOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -877,6 +893,8 @@ export declare class AdminOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -980,6 +998,8 @@ export declare class AdminOrdersController {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
|
||||
Vendored
+23
@@ -71,6 +71,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -174,6 +176,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -280,6 +284,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -383,6 +389,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -486,6 +494,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -589,6 +599,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -692,6 +704,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -795,6 +809,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -898,6 +914,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -1001,6 +1019,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
@@ -1062,6 +1082,7 @@ export declare class OrdersService {
|
||||
private mapCheckCreate;
|
||||
private nextOrderNumber;
|
||||
private createWithUniqueOrderNumber;
|
||||
private companiesForOrder;
|
||||
private getOrder;
|
||||
mapOrder(order: OrderFull, adminView?: boolean): {
|
||||
id: string;
|
||||
@@ -1108,6 +1129,8 @@ export declare class OrdersService {
|
||||
lineTotal: number | null;
|
||||
totalAmount: number | null;
|
||||
notes: string | undefined;
|
||||
companyId: string;
|
||||
companyName: string;
|
||||
}[];
|
||||
checks: {
|
||||
id: string;
|
||||
|
||||
Vendored
+106
-31
@@ -101,26 +101,53 @@ let OrdersService = class OrdersService {
|
||||
return this.mapOrder(order, true);
|
||||
}
|
||||
async submitOrder(userId, dto) {
|
||||
const [company, settings] = await Promise.all([
|
||||
this.prisma.company.findUnique({ where: { id: dto.companyId } }),
|
||||
this.prisma.systemSettings.findUnique({
|
||||
const settings = await this.prisma.systemSettings.findUnique({
|
||||
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) {
|
||||
throw new common_1.BadRequestException('یک یا چند محصول نامعتبر است');
|
||||
const productIds = dto.items.map((i) => i.productId);
|
||||
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]));
|
||||
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;
|
||||
const itemsData = dto.items.map((item) => {
|
||||
const product = productMap.get(item.productId);
|
||||
@@ -140,18 +167,28 @@ let OrdersService = class OrdersService {
|
||||
color: product.color,
|
||||
requestedMeterage: item.meterage,
|
||||
notes: item.notes?.trim() || null,
|
||||
companyId: product.companyId,
|
||||
companyName: product.company.name,
|
||||
};
|
||||
});
|
||||
if (totalMeterage > maxMeterage) {
|
||||
throw new common_1.BadRequestException(`حداکثر متراژ مجاز هر فاکتور ${maxMeterage} متر است`);
|
||||
const companyNames = [
|
||||
...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 created = await tx.order.create({
|
||||
data: {
|
||||
orderNumber,
|
||||
userId,
|
||||
companyId: company.id,
|
||||
companyName: company.name,
|
||||
companyId: primaryCompany.id,
|
||||
companyName: companyNames.join('، '),
|
||||
settlementType: null,
|
||||
checkMode: null,
|
||||
status: client_1.OrderStatus.awaiting_review,
|
||||
@@ -174,7 +211,17 @@ let OrdersService = class OrdersService {
|
||||
const cart = await tx.cart.findFirst({ where: { userId } });
|
||||
if (cart) {
|
||||
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;
|
||||
@@ -200,6 +247,9 @@ let OrdersService = class OrdersService {
|
||||
? client_1.OrderStatus.awaiting_cash_payment
|
||||
: client_1.OrderStatus.check_in_progress;
|
||||
(0, order_transitions_1.assertTransition)(order.status, nextStatus);
|
||||
const cashCompanies = isCash
|
||||
? await this.companiesForOrder(order)
|
||||
: [];
|
||||
await this.prisma.$transaction(async (tx) => {
|
||||
await tx.order.update({
|
||||
where: { id },
|
||||
@@ -209,7 +259,7 @@ let OrdersService = class OrdersService {
|
||||
? null
|
||||
: (dto.checkMode ?? client_1.CheckRegistrationMode.full),
|
||||
cashInvoiceExpiresAt: isCash
|
||||
? (0, cash_expiry_1.computeCashInvoiceExpiry)(order.company)
|
||||
? (0, cash_expiry_1.earliestCashInvoiceExpiry)(cashCompanies)
|
||||
: null,
|
||||
cashReminderSentAt: null,
|
||||
status: nextStatus,
|
||||
@@ -235,8 +285,16 @@ let OrdersService = class OrdersService {
|
||||
});
|
||||
if (!company)
|
||||
throw new common_1.NotFoundException('شرکت یافت نشد');
|
||||
let userId = dto.userId;
|
||||
if (!userId && dto.customerPhone) {
|
||||
let userId = dto.customerId || dto.userId;
|
||||
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));
|
||||
if (!(0, phone_1.isValidPhone)(phone)) {
|
||||
throw new common_1.BadRequestException('شماره موبایل نامعتبر است');
|
||||
@@ -257,7 +315,7 @@ let OrdersService = class OrdersService {
|
||||
userId = customer.id;
|
||||
}
|
||||
if (!userId) {
|
||||
throw new common_1.BadRequestException('شناسه یا شماره مشتری الزامی است');
|
||||
throw new common_1.BadRequestException('انتخاب مشتری الزامی است');
|
||||
}
|
||||
const totalMeterage = dto.meterage ?? 0;
|
||||
const ownerId = userId;
|
||||
@@ -372,6 +430,12 @@ let OrdersService = class OrdersService {
|
||||
(order.finalAmount ?? 0) <= 0) {
|
||||
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 tx.order.update({
|
||||
where: { id },
|
||||
@@ -389,17 +453,12 @@ let OrdersService = class OrdersService {
|
||||
reason: dto.reason || null,
|
||||
},
|
||||
});
|
||||
if (dto.status === client_1.OrderStatus.cash_invoice_issued ||
|
||||
dto.status === client_1.OrderStatus.awaiting_cash_payment) {
|
||||
if (!order.cashInvoiceExpiresAt) {
|
||||
if (cashExpiry) {
|
||||
await tx.order.update({
|
||||
where: { id },
|
||||
data: {
|
||||
cashInvoiceExpiresAt: (0, cash_expiry_1.computeCashInvoiceExpiry)(order.company),
|
||||
},
|
||||
data: { cashInvoiceExpiresAt: cashExpiry },
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
const event = (0, notification_events_1.eventForStatus)(dto.status);
|
||||
if (event) {
|
||||
@@ -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) {
|
||||
const order = await this.prisma.order.findUnique({
|
||||
where: { id },
|
||||
@@ -572,6 +645,8 @@ let OrdersService = class OrdersService {
|
||||
lineTotal: hidePrices ? null : item.lineTotal,
|
||||
totalAmount: hidePrices ? null : item.lineTotal,
|
||||
notes: item.notes ?? undefined,
|
||||
companyId: item.companyId,
|
||||
companyName: item.companyName,
|
||||
})),
|
||||
checks: order.checks.map((c) => ({
|
||||
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