@floristcloud/api-lib 1.2.103 → 1.2.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commands/payment-invoice/create-payment-invoice.command.js +16 -2
- package/build/commands/payment-invoice/index.js +1 -0
- package/build/commands/payment-invoice/pay-payment-invoice.command.js +22 -0
- package/build/constant/error.js +28 -0
- package/build/enum/index.js +1 -0
- package/build/enum/payment-invoice-status.enum.js +11 -0
- package/build/schemas/order/order.schema.js +5 -0
- package/build/schemas/payment-invoice/payment-invoice.schema.js +16 -0
- package/commands/payment-invoice/create-payment-invoice.command.ts +20 -5
- package/commands/payment-invoice/index.ts +1 -0
- package/commands/payment-invoice/pay-payment-invoice.command.ts +24 -0
- package/constant/error.ts +28 -0
- package/enum/index.ts +1 -0
- package/enum/payment-invoice-status.enum.ts +7 -0
- package/package.json +1 -1
- package/schemas/order/order.schema.ts +5 -0
- package/schemas/payment-invoice/payment-invoice.schema.ts +17 -0
|
@@ -3,10 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CreatePaymentInvoiceContractCommand = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const payment_invoice_schema_1 = require("../../schemas/payment-invoice/payment-invoice.schema");
|
|
6
|
-
|
|
6
|
+
// Потолок числа заказов в счёте. Это защита от абсурдного запроса, а не бизнес-правило: счёт за месяц
|
|
7
|
+
// клиенту с ежедневными поставками — это уже 30 строк, поэтому 10-20 отрезали бы живые сценарии.
|
|
8
|
+
// Сто строк — это 3-4 страницы таблицы, документ такого размера собирается и читается нормально.
|
|
9
|
+
const MAX_INVOICE_ORDER_COUNT = 100;
|
|
10
|
+
// Счёт выставляется одним из двух способов:
|
|
11
|
+
// - по заказам: orderUUIDs непустой, итог считается на бэке как сумма totalCost этих заказов,
|
|
12
|
+
// а amount — необязательная правка итога (например скидка по счёту), она уходит отдельной строкой;
|
|
13
|
+
// - вручную: orderUUIDs пуст, тогда amount обязателен и становится единственной строкой счёта.
|
|
14
|
+
const CreatePaymentInvoiceRequestSchema = zod_1.z
|
|
15
|
+
.object({
|
|
7
16
|
clientUUID: zod_1.z.uuid(),
|
|
8
17
|
invoiceDate: zod_1.z.coerce.date(),
|
|
9
|
-
|
|
18
|
+
orderUUIDs: zod_1.z.uuid().array().max(MAX_INVOICE_ORDER_COUNT).optional(),
|
|
19
|
+
amount: zod_1.z.coerce.number().positive().optional(),
|
|
20
|
+
})
|
|
21
|
+
.refine(value => { var _a; return Boolean((_a = value.orderUUIDs) === null || _a === void 0 ? void 0 : _a.length) || value.amount !== undefined; }, {
|
|
22
|
+
message: 'Either orderUUIDs or amount must be provided',
|
|
23
|
+
path: ['amount'],
|
|
10
24
|
});
|
|
11
25
|
const CreatePaymentInvoiceResponseSchema = zod_1.z.object({
|
|
12
26
|
message: zod_1.z.string().optional(),
|
|
@@ -18,3 +18,4 @@ __exportStar(require("./create-payment-invoice.command"), exports);
|
|
|
18
18
|
__exportStar(require("./get-payment-invoice-list.query"), exports);
|
|
19
19
|
__exportStar(require("./get-payment-invoice.query"), exports);
|
|
20
20
|
__exportStar(require("./delete-payment-invoice.command"), exports);
|
|
21
|
+
__exportStar(require("./pay-payment-invoice.command"), exports);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PayPaymentInvoiceContractCommand = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const payment_invoice_schema_1 = require("../../schemas/payment-invoice/payment-invoice.schema");
|
|
6
|
+
// Оплата по счёту. amount не передан — гасим остаток целиком; передан — частичная оплата.
|
|
7
|
+
const PayPaymentInvoiceRequestSchema = zod_1.z.object({
|
|
8
|
+
moneyAccountUUID: zod_1.z.uuid(),
|
|
9
|
+
amount: zod_1.z.coerce.number().positive().optional(),
|
|
10
|
+
comment: zod_1.z.string().optional(),
|
|
11
|
+
cashFlowItemUUID: zod_1.z.uuid().nullable().optional(),
|
|
12
|
+
createdAt: zod_1.z.coerce.date().optional(),
|
|
13
|
+
});
|
|
14
|
+
const PayPaymentInvoiceResponseSchema = zod_1.z.object({
|
|
15
|
+
message: zod_1.z.string().optional(),
|
|
16
|
+
data: payment_invoice_schema_1.PaymentInvoiceSchema,
|
|
17
|
+
});
|
|
18
|
+
var PayPaymentInvoiceContractCommand;
|
|
19
|
+
(function (PayPaymentInvoiceContractCommand) {
|
|
20
|
+
PayPaymentInvoiceContractCommand.RequestSchema = PayPaymentInvoiceRequestSchema;
|
|
21
|
+
PayPaymentInvoiceContractCommand.ResponseSchema = PayPaymentInvoiceResponseSchema;
|
|
22
|
+
})(PayPaymentInvoiceContractCommand || (exports.PayPaymentInvoiceContractCommand = PayPaymentInvoiceContractCommand = {}));
|
package/build/constant/error.js
CHANGED
|
@@ -379,6 +379,11 @@ exports.ERRORS = {
|
|
|
379
379
|
ORDER_MODIFY_NOT_ALLOWED: { code: 'O018', message: 'Modifying the order is not allowed', httpCode: 500 },
|
|
380
380
|
ORDER_SPLIT_ERROR: { code: 'O015', message: 'Error splitting orders', httpCode: 500 },
|
|
381
381
|
ORDER_PAYMENT_NOT_EMPTY: { code: 'O016', message: 'Order not deleted, the order contains payments', httpCode: 400 },
|
|
382
|
+
ORDER_IN_PAYMENT_INVOICE: {
|
|
383
|
+
code: 'O039',
|
|
384
|
+
message: 'Order not deleted, the order is included in a payment invoice',
|
|
385
|
+
httpCode: 409,
|
|
386
|
+
},
|
|
382
387
|
ORDER_SPLIT_NOT_COMPLETELY_ERROR: { code: 'O019', message: 'Error splitting orders, not all orders were split', httpCode: 500 },
|
|
383
388
|
ORDER_TOTAL_COST_NEGATIVE: { code: 'O020', message: 'Order total cost is negative', httpCode: 400 },
|
|
384
389
|
ORDER_SUBTOTAL_NEGATIVE: { code: 'O021', message: 'Order subtotal is negative', httpCode: 400 },
|
|
@@ -1107,6 +1112,29 @@ exports.ERRORS = {
|
|
|
1107
1112
|
PAYMENT_INVOICE_NOT_FOUND: { code: 'PINV003', message: 'Payment invoice not found', httpCode: 404 },
|
|
1108
1113
|
PAYMENT_INVOICE_FETCH_FAILED: { code: 'PINV004', message: 'Failed to fetch payment invoices', httpCode: 500 },
|
|
1109
1114
|
PAYMENT_INVOICE_DELETE_FAILED: { code: 'PINV005', message: 'Failed to delete payment invoice', httpCode: 500 },
|
|
1115
|
+
PAYMENT_INVOICE_ORDERS_NOT_FOUND: {
|
|
1116
|
+
code: 'PINV006',
|
|
1117
|
+
message: 'Some of the requested orders were not found for this client',
|
|
1118
|
+
httpCode: 404,
|
|
1119
|
+
},
|
|
1120
|
+
PAYMENT_INVOICE_ORDER_ALREADY_INVOICED: {
|
|
1121
|
+
code: 'PINV007',
|
|
1122
|
+
message: 'Some of the requested orders are already included in another invoice',
|
|
1123
|
+
httpCode: 409,
|
|
1124
|
+
},
|
|
1125
|
+
PAYMENT_INVOICE_AMOUNT_INVALID: { code: 'PINV008', message: 'Payment invoice amount must be positive', httpCode: 400 },
|
|
1126
|
+
PAYMENT_INVOICE_ALREADY_PAID: { code: 'PINV009', message: 'Payment invoice is already fully paid', httpCode: 409 },
|
|
1127
|
+
PAYMENT_INVOICE_PAYMENT_EXCEEDS_REMAINING: {
|
|
1128
|
+
code: 'PINV010',
|
|
1129
|
+
message: 'Payment amount exceeds the remaining amount of the invoice',
|
|
1130
|
+
httpCode: 400,
|
|
1131
|
+
},
|
|
1132
|
+
PAYMENT_INVOICE_PAYMENT_FAILED: { code: 'PINV011', message: 'Failed to register payment for the invoice', httpCode: 500 },
|
|
1133
|
+
PAYMENT_INVOICE_HAS_PAYMENTS: {
|
|
1134
|
+
code: 'PINV012',
|
|
1135
|
+
message: 'Payment invoice has registered payments and cannot be deleted',
|
|
1136
|
+
httpCode: 409,
|
|
1137
|
+
},
|
|
1110
1138
|
// AUTH GATEWAY
|
|
1111
1139
|
AUTH_GATEWAY_VOICE_FAILED: { code: 'AG001', message: 'Failed to send code via voice call', httpCode: 500 },
|
|
1112
1140
|
AUTH_GATEWAY_TELEGRAM_FAILED: { code: 'AG002', message: 'Failed to send code via Telegram', httpCode: 500 },
|
package/build/enum/index.js
CHANGED
|
@@ -110,3 +110,4 @@ __exportStar(require("./consignment-transfer-direction.enum"), exports);
|
|
|
110
110
|
__exportStar(require("./legal-identifier-field.enum"), exports);
|
|
111
111
|
__exportStar(require("./permission-key.enum"), exports);
|
|
112
112
|
__exportStar(require("./cash-flow-item-status.enum"), exports);
|
|
113
|
+
__exportStar(require("./payment-invoice-status.enum"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PaymentInvoiceStatusEnum = void 0;
|
|
4
|
+
// Статус счёта — производный: считается из суммы живых платежей, привязанных к счёту.
|
|
5
|
+
// В БД не хранится, поэтому не имеет пары в Prisma-энамах и не нуждается в prisma-enum-bridge.
|
|
6
|
+
var PaymentInvoiceStatusEnum;
|
|
7
|
+
(function (PaymentInvoiceStatusEnum) {
|
|
8
|
+
PaymentInvoiceStatusEnum["ISSUED"] = "ISSUED";
|
|
9
|
+
PaymentInvoiceStatusEnum["PARTIALLY_PAID"] = "PARTIALLY_PAID";
|
|
10
|
+
PaymentInvoiceStatusEnum["PAID"] = "PAID";
|
|
11
|
+
})(PaymentInvoiceStatusEnum || (exports.PaymentInvoiceStatusEnum = PaymentInvoiceStatusEnum = {}));
|
|
@@ -32,15 +32,20 @@ exports.OrderSchema = zod_1.z.object({
|
|
|
32
32
|
totalProductNumber: zod_1.z.number(),
|
|
33
33
|
invoiceSendAt: zod_1.z.date().nullable(),
|
|
34
34
|
deliveryRouteUUID: zod_1.z.uuid().nullable(),
|
|
35
|
+
// Счёт на оплату, в который включён заказ. Сам счёт (номер, файл, статус оплаты) читается
|
|
36
|
+
// отдельным запросом GET /payment-invoice/:uuid — здесь только ссылка, чтобы не утяжелять список заказов.
|
|
37
|
+
paymentInvoiceUUID: zod_1.z.uuid().nullable(),
|
|
35
38
|
completedAt: zod_1.z.date().nullable(),
|
|
36
39
|
paymentDueAt: zod_1.z.date().nullable(),
|
|
37
40
|
createdAt: zod_1.z.date(),
|
|
38
41
|
updatedAt: zod_1.z.date(),
|
|
39
42
|
deletedAt: zod_1.z.date().nullable(),
|
|
40
43
|
});
|
|
44
|
+
// Витрина клиента не показывает внутреннюю кухню счетов, поэтому ссылка на счёт сюда не попадает.
|
|
41
45
|
exports.OrderForClientSchema = exports.OrderSchema.omit({
|
|
42
46
|
comment: true,
|
|
43
47
|
tag: true,
|
|
48
|
+
paymentInvoiceUUID: true,
|
|
44
49
|
});
|
|
45
50
|
exports.OrderExtendedSchema = exports.OrderSchema.extend({
|
|
46
51
|
client: client_1.ClientSchema,
|
|
@@ -2,13 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PaymentInvoiceSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
+
const payment_invoice_status_enum_1 = require("../../enum/payment-invoice-status.enum");
|
|
6
|
+
// Строка счёта. Для счёта, собранного из заказов, каждая строка — снимок заказа на момент
|
|
7
|
+
// выставления: заказ потом может измениться, а выставленный счёт обязан остаться прежним.
|
|
8
|
+
const PaymentInvoiceItemSchema = zod_1.z.object({
|
|
9
|
+
orderUUID: zod_1.z.string().nullable(),
|
|
10
|
+
orderId: zod_1.z.number().nullable(),
|
|
11
|
+
orderDate: zod_1.z.coerce.date().nullable(),
|
|
12
|
+
description: zod_1.z.string(),
|
|
13
|
+
amount: zod_1.z.coerce.number(),
|
|
14
|
+
});
|
|
5
15
|
exports.PaymentInvoiceSchema = zod_1.z.object({
|
|
6
16
|
uuid: zod_1.z.string(),
|
|
7
17
|
number: zod_1.z.string(),
|
|
8
18
|
invoiceDate: zod_1.z.coerce.date(),
|
|
9
19
|
amount: zod_1.z.coerce.number(),
|
|
20
|
+
paidAmount: zod_1.z.coerce.number(),
|
|
21
|
+
remainingAmount: zod_1.z.coerce.number(),
|
|
22
|
+
status: zod_1.z.nativeEnum(payment_invoice_status_enum_1.PaymentInvoiceStatusEnum),
|
|
10
23
|
clientUUID: zod_1.z.string(),
|
|
11
24
|
clientName: zod_1.z.string(),
|
|
25
|
+
contractNumber: zod_1.z.string().nullable(),
|
|
26
|
+
contractDate: zod_1.z.coerce.date().nullable(),
|
|
27
|
+
items: PaymentInvoiceItemSchema.array(),
|
|
12
28
|
fileUrl: zod_1.z.string().nullable(),
|
|
13
29
|
createdAt: zod_1.z.coerce.date(),
|
|
14
30
|
});
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { PaymentInvoiceSchema } from '../../schemas/payment-invoice/payment-invoice.schema';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
// Потолок числа заказов в счёте. Это защита от абсурдного запроса, а не бизнес-правило: счёт за месяц
|
|
5
|
+
// клиенту с ежедневными поставками — это уже 30 строк, поэтому 10-20 отрезали бы живые сценарии.
|
|
6
|
+
// Сто строк — это 3-4 страницы таблицы, документ такого размера собирается и читается нормально.
|
|
7
|
+
const MAX_INVOICE_ORDER_COUNT = 100;
|
|
8
|
+
|
|
9
|
+
// Счёт выставляется одним из двух способов:
|
|
10
|
+
// - по заказам: orderUUIDs непустой, итог считается на бэке как сумма totalCost этих заказов,
|
|
11
|
+
// а amount — необязательная правка итога (например скидка по счёту), она уходит отдельной строкой;
|
|
12
|
+
// - вручную: orderUUIDs пуст, тогда amount обязателен и становится единственной строкой счёта.
|
|
13
|
+
const CreatePaymentInvoiceRequestSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
clientUUID: z.uuid(),
|
|
16
|
+
invoiceDate: z.coerce.date(),
|
|
17
|
+
orderUUIDs: z.uuid().array().max(MAX_INVOICE_ORDER_COUNT).optional(),
|
|
18
|
+
amount: z.coerce.number().positive().optional(),
|
|
19
|
+
})
|
|
20
|
+
.refine(value => Boolean(value.orderUUIDs?.length) || value.amount !== undefined, {
|
|
21
|
+
message: 'Either orderUUIDs or amount must be provided',
|
|
22
|
+
path: ['amount'],
|
|
23
|
+
});
|
|
9
24
|
|
|
10
25
|
const CreatePaymentInvoiceResponseSchema = z.object({
|
|
11
26
|
message: z.string().optional(),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { PaymentInvoiceSchema } from '../../schemas/payment-invoice/payment-invoice.schema';
|
|
3
|
+
|
|
4
|
+
// Оплата по счёту. amount не передан — гасим остаток целиком; передан — частичная оплата.
|
|
5
|
+
const PayPaymentInvoiceRequestSchema = z.object({
|
|
6
|
+
moneyAccountUUID: z.uuid(),
|
|
7
|
+
amount: z.coerce.number().positive().optional(),
|
|
8
|
+
comment: z.string().optional(),
|
|
9
|
+
cashFlowItemUUID: z.uuid().nullable().optional(),
|
|
10
|
+
createdAt: z.coerce.date().optional(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const PayPaymentInvoiceResponseSchema = z.object({
|
|
14
|
+
message: z.string().optional(),
|
|
15
|
+
data: PaymentInvoiceSchema,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export namespace PayPaymentInvoiceContractCommand {
|
|
19
|
+
export const RequestSchema = PayPaymentInvoiceRequestSchema;
|
|
20
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
21
|
+
|
|
22
|
+
export const ResponseSchema = PayPaymentInvoiceResponseSchema;
|
|
23
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
24
|
+
}
|
package/constant/error.ts
CHANGED
|
@@ -393,6 +393,11 @@ export const ERRORS = {
|
|
|
393
393
|
ORDER_MODIFY_NOT_ALLOWED: { code: 'O018', message: 'Modifying the order is not allowed', httpCode: 500 },
|
|
394
394
|
ORDER_SPLIT_ERROR: { code: 'O015', message: 'Error splitting orders', httpCode: 500 },
|
|
395
395
|
ORDER_PAYMENT_NOT_EMPTY: { code: 'O016', message: 'Order not deleted, the order contains payments', httpCode: 400 },
|
|
396
|
+
ORDER_IN_PAYMENT_INVOICE: {
|
|
397
|
+
code: 'O039',
|
|
398
|
+
message: 'Order not deleted, the order is included in a payment invoice',
|
|
399
|
+
httpCode: 409,
|
|
400
|
+
},
|
|
396
401
|
ORDER_SPLIT_NOT_COMPLETELY_ERROR: { code: 'O019', message: 'Error splitting orders, not all orders were split', httpCode: 500 },
|
|
397
402
|
ORDER_TOTAL_COST_NEGATIVE: { code: 'O020', message: 'Order total cost is negative', httpCode: 400 },
|
|
398
403
|
ORDER_SUBTOTAL_NEGATIVE: { code: 'O021', message: 'Order subtotal is negative', httpCode: 400 },
|
|
@@ -1155,6 +1160,29 @@ export const ERRORS = {
|
|
|
1155
1160
|
PAYMENT_INVOICE_NOT_FOUND: { code: 'PINV003', message: 'Payment invoice not found', httpCode: 404 },
|
|
1156
1161
|
PAYMENT_INVOICE_FETCH_FAILED: { code: 'PINV004', message: 'Failed to fetch payment invoices', httpCode: 500 },
|
|
1157
1162
|
PAYMENT_INVOICE_DELETE_FAILED: { code: 'PINV005', message: 'Failed to delete payment invoice', httpCode: 500 },
|
|
1163
|
+
PAYMENT_INVOICE_ORDERS_NOT_FOUND: {
|
|
1164
|
+
code: 'PINV006',
|
|
1165
|
+
message: 'Some of the requested orders were not found for this client',
|
|
1166
|
+
httpCode: 404,
|
|
1167
|
+
},
|
|
1168
|
+
PAYMENT_INVOICE_ORDER_ALREADY_INVOICED: {
|
|
1169
|
+
code: 'PINV007',
|
|
1170
|
+
message: 'Some of the requested orders are already included in another invoice',
|
|
1171
|
+
httpCode: 409,
|
|
1172
|
+
},
|
|
1173
|
+
PAYMENT_INVOICE_AMOUNT_INVALID: { code: 'PINV008', message: 'Payment invoice amount must be positive', httpCode: 400 },
|
|
1174
|
+
PAYMENT_INVOICE_ALREADY_PAID: { code: 'PINV009', message: 'Payment invoice is already fully paid', httpCode: 409 },
|
|
1175
|
+
PAYMENT_INVOICE_PAYMENT_EXCEEDS_REMAINING: {
|
|
1176
|
+
code: 'PINV010',
|
|
1177
|
+
message: 'Payment amount exceeds the remaining amount of the invoice',
|
|
1178
|
+
httpCode: 400,
|
|
1179
|
+
},
|
|
1180
|
+
PAYMENT_INVOICE_PAYMENT_FAILED: { code: 'PINV011', message: 'Failed to register payment for the invoice', httpCode: 500 },
|
|
1181
|
+
PAYMENT_INVOICE_HAS_PAYMENTS: {
|
|
1182
|
+
code: 'PINV012',
|
|
1183
|
+
message: 'Payment invoice has registered payments and cannot be deleted',
|
|
1184
|
+
httpCode: 409,
|
|
1185
|
+
},
|
|
1158
1186
|
|
|
1159
1187
|
// AUTH GATEWAY
|
|
1160
1188
|
AUTH_GATEWAY_VOICE_FAILED: { code: 'AG001', message: 'Failed to send code via voice call', httpCode: 500 },
|
package/enum/index.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Статус счёта — производный: считается из суммы живых платежей, привязанных к счёту.
|
|
2
|
+
// В БД не хранится, поэтому не имеет пары в Prisma-энамах и не нуждается в prisma-enum-bridge.
|
|
3
|
+
export enum PaymentInvoiceStatusEnum {
|
|
4
|
+
ISSUED = 'ISSUED',
|
|
5
|
+
PARTIALLY_PAID = 'PARTIALLY_PAID',
|
|
6
|
+
PAID = 'PAID',
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -34,6 +34,9 @@ export const OrderSchema = z.object({
|
|
|
34
34
|
totalProductNumber: z.number(),
|
|
35
35
|
invoiceSendAt: z.date().nullable(),
|
|
36
36
|
deliveryRouteUUID: z.uuid().nullable(),
|
|
37
|
+
// Счёт на оплату, в который включён заказ. Сам счёт (номер, файл, статус оплаты) читается
|
|
38
|
+
// отдельным запросом GET /payment-invoice/:uuid — здесь только ссылка, чтобы не утяжелять список заказов.
|
|
39
|
+
paymentInvoiceUUID: z.uuid().nullable(),
|
|
37
40
|
|
|
38
41
|
completedAt: z.date().nullable(),
|
|
39
42
|
paymentDueAt: z.date().nullable(),
|
|
@@ -43,9 +46,11 @@ export const OrderSchema = z.object({
|
|
|
43
46
|
deletedAt: z.date().nullable(),
|
|
44
47
|
});
|
|
45
48
|
|
|
49
|
+
// Витрина клиента не показывает внутреннюю кухню счетов, поэтому ссылка на счёт сюда не попадает.
|
|
46
50
|
export const OrderForClientSchema = OrderSchema.omit({
|
|
47
51
|
comment: true,
|
|
48
52
|
tag: true,
|
|
53
|
+
paymentInvoiceUUID: true,
|
|
49
54
|
});
|
|
50
55
|
|
|
51
56
|
export const OrderExtendedSchema = OrderSchema.extend({
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { PaymentInvoiceStatusEnum } from '../../enum/payment-invoice-status.enum';
|
|
3
|
+
|
|
4
|
+
// Строка счёта. Для счёта, собранного из заказов, каждая строка — снимок заказа на момент
|
|
5
|
+
// выставления: заказ потом может измениться, а выставленный счёт обязан остаться прежним.
|
|
6
|
+
const PaymentInvoiceItemSchema = z.object({
|
|
7
|
+
orderUUID: z.string().nullable(),
|
|
8
|
+
orderId: z.number().nullable(),
|
|
9
|
+
orderDate: z.coerce.date().nullable(),
|
|
10
|
+
description: z.string(),
|
|
11
|
+
amount: z.coerce.number(),
|
|
12
|
+
});
|
|
2
13
|
|
|
3
14
|
export const PaymentInvoiceSchema = z.object({
|
|
4
15
|
uuid: z.string(),
|
|
5
16
|
number: z.string(),
|
|
6
17
|
invoiceDate: z.coerce.date(),
|
|
7
18
|
amount: z.coerce.number(),
|
|
19
|
+
paidAmount: z.coerce.number(),
|
|
20
|
+
remainingAmount: z.coerce.number(),
|
|
21
|
+
status: z.nativeEnum(PaymentInvoiceStatusEnum),
|
|
8
22
|
clientUUID: z.string(),
|
|
9
23
|
clientName: z.string(),
|
|
24
|
+
contractNumber: z.string().nullable(),
|
|
25
|
+
contractDate: z.coerce.date().nullable(),
|
|
26
|
+
items: PaymentInvoiceItemSchema.array(),
|
|
10
27
|
fileUrl: z.string().nullable(),
|
|
11
28
|
createdAt: z.coerce.date(),
|
|
12
29
|
});
|