@floristcloud/api-lib 1.2.167 → 1.2.169
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/client/index.js +2 -0
- package/build/commands/client/profile/create-client-legal-profile.command.js +4 -15
- package/build/commands/client/profile/delete-client-legal-profile.command.js +4 -11
- package/build/commands/client/profile/get-client-legal-profile-list.query.js +10 -0
- package/build/commands/client/profile/index.js +1 -0
- package/build/commands/client/profile/update-client-legal-profile.command.js +4 -15
- package/build/commands/client/webshop/create-client-legal-profile-for-client.command.js +10 -0
- package/build/commands/client/webshop/update-client-legal-profile-for-client.command.js +10 -0
- package/build/commands/payment-invoice/create-payment-invoice.command.js +4 -29
- package/build/constant/discount-rules-pricing-type-list.constant.js +14 -0
- package/build/constant/error.js +17 -0
- package/build/constant/index.js +1 -0
- package/build/enum/discount-rules-mode-type.enum.js +2 -4
- package/build/enum/discount-rules-type.enum.js +1 -0
- package/build/schemas/client/client-extended-for-client.schema.js +2 -2
- package/build/schemas/client/client-extended.schema.js +2 -0
- package/build/schemas/client/client-legal-profile-for-client-response.schema.js +9 -0
- package/build/schemas/client/client-legal-profile-for-client.schema.js +27 -0
- package/build/schemas/client/client-legal-profile-requisites.schema.js +15 -0
- package/build/schemas/client/client-legal-profile.schema.js +3 -0
- package/build/schemas/client/create-client-legal-profile-request.schema.js +10 -0
- package/build/schemas/client/create-client-legal-profile-response.schema.js +9 -0
- package/build/schemas/client/delete-client-legal-profile-request.schema.js +5 -0
- package/build/schemas/client/delete-client-legal-profile-response.schema.js +9 -0
- package/build/schemas/client/delete-client-legal-profile-result.schema.js +9 -0
- package/build/schemas/client/get-client-legal-profile-list-request.schema.js +5 -0
- package/build/schemas/client/get-client-legal-profile-list-response.schema.js +9 -0
- package/build/schemas/client/index.js +12 -0
- package/build/schemas/client/update-client-legal-profile-request.schema.js +13 -0
- package/build/schemas/client/update-client-legal-profile-response.schema.js +9 -0
- package/build/schemas/discount-rules/discount-rules.schema.js +25 -11
- package/build/schemas/discount-rules/product-discount-price-data.schema.js +9 -0
- package/build/schemas/discount-rules/product-discount-price-multiplicity-option.schema.js +2 -0
- package/build/schemas/index.js +2 -0
- package/build/schemas/order-product/price-correction-analyze-item.schema.js +6 -0
- package/build/schemas/payment-invoice/create-payment-invoice-request.schema.js +27 -0
- package/build/schemas/payment-invoice/create-payment-invoice-response.schema.js +9 -0
- package/build/schemas/payment-invoice/payment-invoice.schema.js +2 -0
- package/commands/client/index.ts +2 -0
- package/commands/client/profile/create-client-legal-profile.command.ts +3 -15
- package/commands/client/profile/delete-client-legal-profile.command.ts +3 -12
- package/commands/client/profile/get-client-legal-profile-list.query.ts +11 -0
- package/commands/client/profile/index.ts +1 -0
- package/commands/client/profile/update-client-legal-profile.command.ts +3 -15
- package/commands/client/webshop/create-client-legal-profile-for-client.command.ts +11 -0
- package/commands/client/webshop/update-client-legal-profile-for-client.command.ts +11 -0
- package/commands/payment-invoice/create-payment-invoice.command.ts +3 -31
- package/constant/discount-rules-pricing-type-list.constant.ts +12 -0
- package/constant/error.ts +17 -0
- package/constant/index.ts +1 -0
- package/enum/discount-rules-mode-type.enum.ts +2 -4
- package/enum/discount-rules-type.enum.ts +1 -0
- package/package.json +1 -1
- package/schemas/client/client-extended-for-client.schema.ts +2 -2
- package/schemas/client/client-extended.schema.ts +2 -0
- package/schemas/client/client-legal-profile-for-client-response.schema.ts +7 -0
- package/schemas/client/client-legal-profile-for-client.schema.ts +25 -0
- package/schemas/client/client-legal-profile-requisites.schema.ts +13 -0
- package/schemas/client/client-legal-profile.schema.ts +3 -0
- package/schemas/client/create-client-legal-profile-request.schema.ts +8 -0
- package/schemas/client/create-client-legal-profile-response.schema.ts +7 -0
- package/schemas/client/delete-client-legal-profile-request.schema.ts +3 -0
- package/schemas/client/delete-client-legal-profile-response.schema.ts +7 -0
- package/schemas/client/delete-client-legal-profile-result.schema.ts +7 -0
- package/schemas/client/get-client-legal-profile-list-request.schema.ts +3 -0
- package/schemas/client/get-client-legal-profile-list-response.schema.ts +7 -0
- package/schemas/client/index.ts +12 -0
- package/schemas/client/update-client-legal-profile-request.schema.ts +11 -0
- package/schemas/client/update-client-legal-profile-response.schema.ts +7 -0
- package/schemas/discount-rules/discount-rules.schema.ts +28 -11
- package/schemas/discount-rules/product-discount-price-data.schema.ts +9 -0
- package/schemas/discount-rules/product-discount-price-multiplicity-option.schema.ts +2 -0
- package/schemas/index.ts +2 -0
- package/schemas/order-product/price-correction-analyze-item.schema.ts +7 -0
- package/schemas/payment-invoice/create-payment-invoice-request.schema.ts +26 -0
- package/schemas/payment-invoice/create-payment-invoice-response.schema.ts +7 -0
- package/schemas/payment-invoice/payment-invoice.schema.ts +2 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreatePaymentInvoiceRequestSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const positive_money_schema_1 = require("../positive-money.schema");
|
|
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
|
+
exports.CreatePaymentInvoiceRequestSchema = zod_1.z
|
|
15
|
+
.object({
|
|
16
|
+
clientUUID: zod_1.z.uuid(),
|
|
17
|
+
// Карточка реквизитов покупателя. Не передана — счёт выписывается на основную карточку клиента.
|
|
18
|
+
clientLegalProfileUUID: zod_1.z.uuid().optional(),
|
|
19
|
+
invoiceDate: zod_1.z.coerce.date(),
|
|
20
|
+
orderUUIDs: zod_1.z.uuid().array().max(MAX_INVOICE_ORDER_COUNT).optional(),
|
|
21
|
+
// Строго положительная сумма: отсекаем минус по знаку строки и нулевые записи вида "0" / "0.00".
|
|
22
|
+
amount: positive_money_schema_1.PositiveMoneySchema.optional(),
|
|
23
|
+
})
|
|
24
|
+
.refine(value => { var _a; return Boolean((_a = value.orderUUIDs) === null || _a === void 0 ? void 0 : _a.length) || value.amount !== undefined; }, {
|
|
25
|
+
message: 'Either orderUUIDs or amount must be provided',
|
|
26
|
+
path: ['amount'],
|
|
27
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreatePaymentInvoiceResponseSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const payment_invoice_schema_1 = require("./payment-invoice.schema");
|
|
6
|
+
exports.CreatePaymentInvoiceResponseSchema = zod_1.z.object({
|
|
7
|
+
message: zod_1.z.string().optional(),
|
|
8
|
+
data: payment_invoice_schema_1.PaymentInvoiceSchema,
|
|
9
|
+
});
|
|
@@ -22,6 +22,8 @@ exports.PaymentInvoiceSchema = zod_1.z.object({
|
|
|
22
22
|
remainingAmount: money_schema_1.MoneySchema,
|
|
23
23
|
status: zod_1.z.nativeEnum(payment_invoice_status_enum_1.PaymentInvoiceStatusEnum),
|
|
24
24
|
clientUUID: zod_1.z.string(),
|
|
25
|
+
// Карточка реквизитов, на которую выписан счёт; null — у старых счетов и у клиентов без карточек.
|
|
26
|
+
clientLegalProfileUUID: zod_1.z.string().nullable(),
|
|
25
27
|
clientName: zod_1.z.string(),
|
|
26
28
|
contractNumber: zod_1.z.string().nullable(),
|
|
27
29
|
contractDate: zod_1.z.coerce.date().nullable(),
|
package/commands/client/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ export * from './detach-user-from-client.command';
|
|
|
15
15
|
export * from './webshop/register-client-webshop.command';
|
|
16
16
|
export * from './webshop/update-client-for-client.command';
|
|
17
17
|
export * from './webshop/get-client-me-webshop.query';
|
|
18
|
+
export * from './webshop/create-client-legal-profile-for-client.command';
|
|
19
|
+
export * from './webshop/update-client-legal-profile-for-client.command';
|
|
18
20
|
//marking
|
|
19
21
|
export * from './marking/create-client-marking.command';
|
|
20
22
|
export * from './marking/update-client-marking.command';
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const CreateClientLegalProfileRequestSchema = ClientLegalProfileSchema.omit({
|
|
5
|
-
uuid: true,
|
|
6
|
-
createdAt: true,
|
|
7
|
-
updatedAt: true,
|
|
8
|
-
}).extend({
|
|
9
|
-
correspondentAccount: ClientLegalProfileSchema.shape.correspondentAccount.optional(),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const CreateClientLegalProfileResponseSchema = z.object({
|
|
13
|
-
message: z.string().optional(),
|
|
14
|
-
data: ClientLegalProfileSchema.nullable(),
|
|
15
|
-
});
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { CreateClientLegalProfileRequestSchema } from '../../../schemas/client/create-client-legal-profile-request.schema';
|
|
3
|
+
import { CreateClientLegalProfileResponseSchema } from '../../../schemas/client/create-client-legal-profile-response.schema';
|
|
16
4
|
|
|
17
5
|
export namespace CreateClientLegalProfileContractCommand {
|
|
18
6
|
export const RequestSchema = CreateClientLegalProfileRequestSchema;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const DeleteDataResponseSchema = z.object({
|
|
6
|
-
success: z.boolean(),
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
const DeleteClientLegalProfileResponseSchema = z.object({
|
|
10
|
-
message: z.string().optional(),
|
|
11
|
-
data: DeleteDataResponseSchema,
|
|
12
|
-
});
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { DeleteClientLegalProfileRequestSchema } from '../../../schemas/client/delete-client-legal-profile-request.schema';
|
|
3
|
+
import { DeleteClientLegalProfileResponseSchema } from '../../../schemas/client/delete-client-legal-profile-response.schema';
|
|
13
4
|
|
|
14
5
|
export namespace DeleteClientLegalProfileContractCommand {
|
|
15
6
|
export const RequestSchema = DeleteClientLegalProfileRequestSchema;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { GetClientLegalProfileListRequestSchema } from '../../../schemas/client/get-client-legal-profile-list-request.schema';
|
|
3
|
+
import { GetClientLegalProfileListResponseSchema } from '../../../schemas/client/get-client-legal-profile-list-response.schema';
|
|
4
|
+
|
|
5
|
+
export namespace GetClientLegalProfileListContractQuery {
|
|
6
|
+
export const RequestSchema = GetClientLegalProfileListRequestSchema;
|
|
7
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
8
|
+
|
|
9
|
+
export const ResponseSchema = GetClientLegalProfileListResponseSchema;
|
|
10
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
11
|
+
}
|
|
@@ -5,3 +5,4 @@ export * from './delete-client-individual-profile.command';
|
|
|
5
5
|
export * from './create-client-legal-profile.command';
|
|
6
6
|
export * from './update-client-legal-profile.command';
|
|
7
7
|
export * from './delete-client-legal-profile.command';
|
|
8
|
+
export * from './get-client-legal-profile-list.query';
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const UpdateClientLegalProfileRequestSchema = ClientLegalProfileSchema.omit({
|
|
5
|
-
uuid: true,
|
|
6
|
-
createdAt: true,
|
|
7
|
-
updatedAt: true,
|
|
8
|
-
}).extend({
|
|
9
|
-
correspondentAccount: ClientLegalProfileSchema.shape.correspondentAccount.optional(),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const UpdateClientLegalProfileResponseSchema = z.object({
|
|
13
|
-
message: z.string().optional(),
|
|
14
|
-
data: ClientLegalProfileSchema.nullable(),
|
|
15
|
-
});
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { UpdateClientLegalProfileRequestSchema } from '../../../schemas/client/update-client-legal-profile-request.schema';
|
|
3
|
+
import { UpdateClientLegalProfileResponseSchema } from '../../../schemas/client/update-client-legal-profile-response.schema';
|
|
16
4
|
|
|
17
5
|
export namespace UpdateClientLegalProfileContractCommand {
|
|
18
6
|
export const RequestSchema = UpdateClientLegalProfileRequestSchema;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { ClientLegalProfileRequisitesSchema } from '../../../schemas/client/client-legal-profile-requisites.schema';
|
|
3
|
+
import { ClientLegalProfileForClientResponseSchema } from '../../../schemas/client/client-legal-profile-for-client-response.schema';
|
|
4
|
+
|
|
5
|
+
export namespace CreateClientLegalProfileForClientContractCommand {
|
|
6
|
+
export const RequestSchema = ClientLegalProfileRequisitesSchema;
|
|
7
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
8
|
+
|
|
9
|
+
export const ResponseSchema = ClientLegalProfileForClientResponseSchema;
|
|
10
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { ClientLegalProfileRequisitesSchema } from '../../../schemas/client/client-legal-profile-requisites.schema';
|
|
3
|
+
import { ClientLegalProfileForClientResponseSchema } from '../../../schemas/client/client-legal-profile-for-client-response.schema';
|
|
4
|
+
|
|
5
|
+
export namespace UpdateClientLegalProfileForClientContractCommand {
|
|
6
|
+
export const RequestSchema = ClientLegalProfileRequisitesSchema;
|
|
7
|
+
export type Request = z.infer<typeof RequestSchema>;
|
|
8
|
+
|
|
9
|
+
export const ResponseSchema = ClientLegalProfileForClientResponseSchema;
|
|
10
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
11
|
+
}
|
|
@@ -1,34 +1,6 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PositiveMoneySchema } from '../../schemas/positive-money.schema';
|
|
5
|
-
|
|
6
|
-
// Потолок числа заказов в счёте. Это защита от абсурдного запроса, а не бизнес-правило: счёт за месяц
|
|
7
|
-
// клиенту с ежедневными поставками — это уже 30 строк, поэтому 10-20 отрезали бы живые сценарии.
|
|
8
|
-
// Сто строк — это 3-4 страницы таблицы, документ такого размера собирается и читается нормально.
|
|
9
|
-
const MAX_INVOICE_ORDER_COUNT = 100;
|
|
10
|
-
|
|
11
|
-
// Счёт выставляется одним из двух способов:
|
|
12
|
-
// - по заказам: orderUUIDs непустой, итог считается на бэке как сумма totalCost этих заказов,
|
|
13
|
-
// а amount — необязательная правка итога (например скидка по счёту), она уходит отдельной строкой;
|
|
14
|
-
// - вручную: orderUUIDs пуст, тогда amount обязателен и становится единственной строкой счёта.
|
|
15
|
-
const CreatePaymentInvoiceRequestSchema = z
|
|
16
|
-
.object({
|
|
17
|
-
clientUUID: z.uuid(),
|
|
18
|
-
invoiceDate: z.coerce.date(),
|
|
19
|
-
orderUUIDs: z.uuid().array().max(MAX_INVOICE_ORDER_COUNT).optional(),
|
|
20
|
-
// Строго положительная сумма: отсекаем минус по знаку строки и нулевые записи вида "0" / "0.00".
|
|
21
|
-
amount: PositiveMoneySchema.optional(),
|
|
22
|
-
})
|
|
23
|
-
.refine(value => Boolean(value.orderUUIDs?.length) || value.amount !== undefined, {
|
|
24
|
-
message: 'Either orderUUIDs or amount must be provided',
|
|
25
|
-
path: ['amount'],
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const CreatePaymentInvoiceResponseSchema = z.object({
|
|
29
|
-
message: z.string().optional(),
|
|
30
|
-
data: PaymentInvoiceSchema,
|
|
31
|
-
});
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { CreatePaymentInvoiceRequestSchema } from '../../schemas/payment-invoice/create-payment-invoice-request.schema';
|
|
3
|
+
import { CreatePaymentInvoiceResponseSchema } from '../../schemas/payment-invoice/create-payment-invoice-response.schema';
|
|
32
4
|
|
|
33
5
|
export namespace CreatePaymentInvoiceContractCommand {
|
|
34
6
|
export const RequestSchema = CreatePaymentInvoiceRequestSchema;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DiscountRulesTypeEnum } from '../enum/discount-rules-type.enum';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Правила ценообразования: задают цену клиента целиком, а не уменьшают её.
|
|
5
|
+
*
|
|
6
|
+
* Цена от себестоимости или от прайса плюс наценка. Если у клиента есть такое правило, скидки к нему не
|
|
7
|
+
* применяются, и больше одного действующего правила ценообразования на клиента быть не может.
|
|
8
|
+
*/
|
|
9
|
+
export const DISCOUNT_RULES_PRICING_TYPE_LIST: DiscountRulesTypeEnum[] = [
|
|
10
|
+
DiscountRulesTypeEnum.COST_PLUS_MARKUP,
|
|
11
|
+
DiscountRulesTypeEnum.PRICE_PLUS_MARKUP,
|
|
12
|
+
];
|
package/constant/error.ts
CHANGED
|
@@ -206,6 +206,12 @@ export const ERRORS = {
|
|
|
206
206
|
CLIENT_LEGAL_PROFILE_NOT_FOUND: { code: 'CL020', message: 'Legal profile not founded', httpCode: 404 },
|
|
207
207
|
CLIENT_LEGAL_PROFILE_NOT_DELETED: { code: 'CL021', message: 'Legal profile not deleted', httpCode: 500 },
|
|
208
208
|
CLIENT_LEGAL_PROFILE_NOT_UPDATED: { code: 'CL022', message: 'Legal profile not updated', httpCode: 500 },
|
|
209
|
+
CLIENT_LEGAL_PROFILE_ARCHIVED: { code: 'CL046', message: 'Legal profile is archived', httpCode: 409 },
|
|
210
|
+
CLIENT_LEGAL_PROFILE_DEFAULT_REQUIRED: {
|
|
211
|
+
code: 'CL047',
|
|
212
|
+
message: 'Client must keep a default legal profile: assign another one instead',
|
|
213
|
+
httpCode: 409,
|
|
214
|
+
},
|
|
209
215
|
CLIENT_CALCULATE_FAILED: { code: 'CL023', message: 'Failed calculate by client', httpCode: 500 },
|
|
210
216
|
//BRANCH
|
|
211
217
|
BRANCH_NOT_CREATED: { code: 'B001', message: 'Failed to create branch', httpCode: 500 },
|
|
@@ -1406,6 +1412,17 @@ export const ERRORS = {
|
|
|
1406
1412
|
message: 'Too many products for a single consignment discount operation',
|
|
1407
1413
|
httpCode: 400,
|
|
1408
1414
|
},
|
|
1415
|
+
DISCOUNT_RULES_PRICING_RULE_CONFLICT: {
|
|
1416
|
+
code: 'DR007',
|
|
1417
|
+
message: 'A client can have only one active pricing rule',
|
|
1418
|
+
httpCode: 409,
|
|
1419
|
+
},
|
|
1420
|
+
// Не дождались транзакционной блокировки правил ценообразования компании (lock_timeout).
|
|
1421
|
+
DISCOUNT_RULES_PRICING_RULE_LOCK_BUSY: {
|
|
1422
|
+
code: 'DR008',
|
|
1423
|
+
message: 'Pricing rules of this company are being changed right now, try again',
|
|
1424
|
+
httpCode: 409,
|
|
1425
|
+
},
|
|
1409
1426
|
DISCOUNT_RULES_NOT_FOUND: { code: 'DR010', message: 'Discount-rules not found', httpCode: 404 },
|
|
1410
1427
|
|
|
1411
1428
|
// ACTION LOG
|
package/constant/index.ts
CHANGED
|
@@ -15,3 +15,4 @@ export * from './product-image-merge.constant';
|
|
|
15
15
|
export * from './client-group-actions.constant';
|
|
16
16
|
export * from './standing-order-positions.constant';
|
|
17
17
|
export * from './order-external-number.constant';
|
|
18
|
+
export * from './discount-rules-pricing-type-list.constant';
|
|
@@ -4,10 +4,8 @@ export enum DiscountRulesModeTypeEnum {
|
|
|
4
4
|
/**
|
|
5
5
|
* Готовая цена, а не величина скидки.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* (`discountRulesModeSchema`) знает только FIXED и PERCENT, а схема выдачи
|
|
10
|
-
* (`discountPriceOutcomeSchema`) — все три.
|
|
7
|
+
* Больше не отдаётся: правило `COST_PLUS_MARKUP` стало правилом ценообразования и задаёт цену
|
|
8
|
+
* клиента, а не вариант скидки. Значение оставлено, чтобы не ломать клиентов, которые его разбирают.
|
|
11
9
|
*/
|
|
12
10
|
TARGET_PRICE = 'TARGET_PRICE',
|
|
13
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ClientForClientSchema } from './client-for-client.schema';
|
|
2
2
|
import { ClientIndividualProfileSchema } from './client-individual-profile.schema';
|
|
3
|
-
import {
|
|
3
|
+
import { ClientLegalProfileForClientSchema } from './client-legal-profile-for-client.schema';
|
|
4
4
|
import { UserContactForClientSchema } from '../user/user-contact-for-client.schema';
|
|
5
5
|
import { UserNameSchema } from '../user/user-name.schema';
|
|
6
6
|
import { DiscountRulesForClientSchema } from '../discount-rules/discount-rules-for-client.schema';
|
|
@@ -10,6 +10,6 @@ export const ClientExtendedForClientSchema = ClientForClientSchema.extend({
|
|
|
10
10
|
user: UserContactForClientSchema.nullable(),
|
|
11
11
|
responsibleUser: UserNameSchema.nullable(),
|
|
12
12
|
clientIndividualProfile: ClientIndividualProfileSchema.nullable(),
|
|
13
|
-
clientLegalProfile:
|
|
13
|
+
clientLegalProfile: ClientLegalProfileForClientSchema.nullable(),
|
|
14
14
|
discountRulesList: DiscountRulesForClientSchema.array(),
|
|
15
15
|
});
|
|
@@ -10,7 +10,9 @@ import { ClientSchema } from './client-base.schema';
|
|
|
10
10
|
export const ClientExtendedSchema = ClientSchema.extend({
|
|
11
11
|
user: UserSchema.nullable(),
|
|
12
12
|
clientIndividualProfile: ClientIndividualProfileSchema.nullable(),
|
|
13
|
+
// Основная карточка реквизитов; все карточки клиента, включая архивные, — в clientLegalProfileList.
|
|
13
14
|
clientLegalProfile: ClientLegalProfileSchema.nullable(),
|
|
15
|
+
clientLegalProfileList: ClientLegalProfileSchema.array(),
|
|
14
16
|
discountRulesList: DiscountRulesSchema.array().optional(),
|
|
15
17
|
orderCount: z.number(),
|
|
16
18
|
responsibleUser: UserSchema.nullable(),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ClientLegalProfileForClientSchema } from './client-legal-profile-for-client.schema';
|
|
3
|
+
|
|
4
|
+
export const ClientLegalProfileForClientResponseSchema = z.object({
|
|
5
|
+
message: z.string().optional(),
|
|
6
|
+
data: ClientLegalProfileForClientSchema.nullable(),
|
|
7
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ClientLegalTypeEnum } from '../../enum/client-legal-type.enum';
|
|
3
|
+
|
|
4
|
+
// Реквизиты покупателя на витрине. Подпись и флаги карточки — внутренние поля панели, наружу не отдаются.
|
|
5
|
+
export const ClientLegalProfileForClientSchema = z.object({
|
|
6
|
+
uuid: z.uuid(),
|
|
7
|
+
fullCompanyName: z.string().nullable(),
|
|
8
|
+
taxId: z.string().nullable(),
|
|
9
|
+
ogrn: z.string().nullable(),
|
|
10
|
+
ogrnip: z.string().nullable(),
|
|
11
|
+
kpp: z.string().nullable(),
|
|
12
|
+
bankName: z.string().nullable(),
|
|
13
|
+
bankAccountNumber: z.string().nullable(),
|
|
14
|
+
correspondentAccount: z.string().nullable(),
|
|
15
|
+
bankBic: z.string().nullable(),
|
|
16
|
+
directorName: z.string().nullable(),
|
|
17
|
+
directorPosition: z.string().nullable(),
|
|
18
|
+
directorAuthority: z.string().nullable(),
|
|
19
|
+
edoUsage: z.boolean(),
|
|
20
|
+
edoId: z.string().nullable(),
|
|
21
|
+
address: z.string().nullable(),
|
|
22
|
+
legalType: z.nativeEnum(ClientLegalTypeEnum),
|
|
23
|
+
createdAt: z.date(),
|
|
24
|
+
updatedAt: z.date(),
|
|
25
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ClientLegalProfileSchema } from './client-legal-profile.schema';
|
|
2
|
+
|
|
3
|
+
// Реквизиты карточки, которые пользователь заполняет сам: без служебных полей и флагов карточки.
|
|
4
|
+
export const ClientLegalProfileRequisitesSchema = ClientLegalProfileSchema.omit({
|
|
5
|
+
uuid: true,
|
|
6
|
+
label: true,
|
|
7
|
+
isDefault: true,
|
|
8
|
+
isArchived: true,
|
|
9
|
+
createdAt: true,
|
|
10
|
+
updatedAt: true,
|
|
11
|
+
}).extend({
|
|
12
|
+
correspondentAccount: ClientLegalProfileSchema.shape.correspondentAccount.optional(),
|
|
13
|
+
});
|
|
@@ -3,6 +3,9 @@ import { ClientLegalTypeEnum } from '../../enum';
|
|
|
3
3
|
|
|
4
4
|
export const ClientLegalProfileSchema = z.object({
|
|
5
5
|
uuid: z.uuid(),
|
|
6
|
+
label: z.string().nullable(),
|
|
7
|
+
isDefault: z.boolean(),
|
|
8
|
+
isArchived: z.boolean(),
|
|
6
9
|
fullCompanyName: z.string().nullable(),
|
|
7
10
|
taxId: z.string().nullable(),
|
|
8
11
|
ogrn: z.string().nullable(),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ClientLegalProfileSchema } from './client-legal-profile.schema';
|
|
3
|
+
import { ClientLegalProfileRequisitesSchema } from './client-legal-profile-requisites.schema';
|
|
4
|
+
|
|
5
|
+
export const CreateClientLegalProfileRequestSchema = ClientLegalProfileRequisitesSchema.extend({
|
|
6
|
+
label: ClientLegalProfileSchema.shape.label.optional(),
|
|
7
|
+
isDefault: z.boolean().optional(),
|
|
8
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { DeleteClientLegalProfileResultSchema } from './delete-client-legal-profile-result.schema';
|
|
3
|
+
|
|
4
|
+
export const DeleteClientLegalProfileResponseSchema = z.object({
|
|
5
|
+
message: z.string().optional(),
|
|
6
|
+
data: DeleteClientLegalProfileResultSchema,
|
|
7
|
+
});
|
package/schemas/client/index.ts
CHANGED
|
@@ -2,12 +2,24 @@ export * from './client.schema';
|
|
|
2
2
|
export * from './client-name.schema';
|
|
3
3
|
export * from './client-individual-profile.schema';
|
|
4
4
|
export * from './client-legal-profile.schema';
|
|
5
|
+
export * from './client-legal-profile-requisites.schema';
|
|
6
|
+
export * from './create-client-legal-profile-request.schema';
|
|
7
|
+
export * from './create-client-legal-profile-response.schema';
|
|
8
|
+
export * from './update-client-legal-profile-request.schema';
|
|
9
|
+
export * from './update-client-legal-profile-response.schema';
|
|
10
|
+
export * from './delete-client-legal-profile-request.schema';
|
|
11
|
+
export * from './delete-client-legal-profile-result.schema';
|
|
12
|
+
export * from './delete-client-legal-profile-response.schema';
|
|
13
|
+
export * from './get-client-legal-profile-list-request.schema';
|
|
14
|
+
export * from './get-client-legal-profile-list-response.schema';
|
|
5
15
|
export * from './client-marking.schema';
|
|
6
16
|
export * from './client-debt.schema';
|
|
7
17
|
export * from './client-responsible-assignment.schema';
|
|
8
18
|
export * from './client-responsible-assignment-result.schema';
|
|
9
19
|
export * from './client-for-client.schema';
|
|
10
20
|
export * from './client-extended-for-client.schema';
|
|
21
|
+
export * from './client-legal-profile-for-client.schema';
|
|
22
|
+
export * from './client-legal-profile-for-client-response.schema';
|
|
11
23
|
export * from './get-client-me-webshop-response.schema';
|
|
12
24
|
export * from './register-client-webshop-request.schema';
|
|
13
25
|
export * from './register-client-webshop-response.schema';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ClientLegalProfileSchema } from './client-legal-profile.schema';
|
|
3
|
+
import { ClientLegalProfileRequisitesSchema } from './client-legal-profile-requisites.schema';
|
|
4
|
+
|
|
5
|
+
// Правка частичная: поле, которого нет в запросе, не меняется, null — очищает. Так карточку можно сделать
|
|
6
|
+
// основной или убрать в архив, не пересылая реквизиты.
|
|
7
|
+
export const UpdateClientLegalProfileRequestSchema = ClientLegalProfileRequisitesSchema.partial().extend({
|
|
8
|
+
label: ClientLegalProfileSchema.shape.label.optional(),
|
|
9
|
+
isDefault: z.boolean().optional(),
|
|
10
|
+
isArchived: z.boolean().optional(),
|
|
11
|
+
});
|
|
@@ -23,10 +23,9 @@ export const discountRulesModeSchema = z.discriminatedUnion('typeDiscount', [dis
|
|
|
23
23
|
/**
|
|
24
24
|
* Итог применения правила к товару — то, что уезжает клиенту в `discountDataList`.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* создании правила нельзя, `discountRulesModeSchema` его не принимает.
|
|
26
|
+
* Ветка TARGET_PRICE больше не отдаётся: правило от себестоимости стало правилом ценообразования и
|
|
27
|
+
* задаёт цену клиента (`price`, `clientPrice`), а не вариант скидки. Ветка оставлена, чтобы не ломать
|
|
28
|
+
* клиентов, которые её разбирают.
|
|
30
29
|
*/
|
|
31
30
|
export const discountPriceOutcomeSchema = z.discriminatedUnion('typeDiscount', [
|
|
32
31
|
discountPercentModeSchema,
|
|
@@ -68,19 +67,33 @@ const DiscountRulesItemDiscountDataSchema = discountRulesModeSchema;
|
|
|
68
67
|
const DiscountRulesDiscountProhibitedDataSchema = z.object({}).default({});
|
|
69
68
|
|
|
70
69
|
/**
|
|
71
|
-
* Наценка
|
|
70
|
+
* Наценка правила ценообразования: процент или сумма на единицу.
|
|
72
71
|
*
|
|
73
|
-
*
|
|
74
|
-
* — только вверх, знака у величины
|
|
75
|
-
* — ноль допустим (
|
|
76
|
-
* `NonNegativeMoneySchema`, а не `PositiveMoneySchema`;
|
|
72
|
+
* Отличия от режима скидки намеренные:
|
|
73
|
+
* — только вверх, знака у величины нет;
|
|
74
|
+
* — ноль допустим (цена ровно равна источнику), поэтому FIXED берёт `NonNegativeMoneySchema`;
|
|
77
75
|
* — у процента нет верхней границы: наценка в 150 % законна, в отличие от скидки в 150 %.
|
|
78
76
|
*/
|
|
77
|
+
const pricingMarkupPercentSchema = z.object({ typeMarkup: z.literal(DiscountRulesModeTypeEnum.PERCENT), markupValue: z.number().min(0) });
|
|
78
|
+
const pricingMarkupFixedSchema = z.object({ typeMarkup: z.literal(DiscountRulesModeTypeEnum.FIXED), markupValue: NonNegativeMoneySchema });
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Потолок «не выше прайса» есть только у цены от себестоимости: цена от прайса с наценкой выше
|
|
82
|
+
* прайса по определению. Поле необязательное, и отсутствие значит разное: при создании — потолка
|
|
83
|
+
* нет, при правке — оставить как было. Так старая панель, которая флага не знает, не снимает потолок
|
|
84
|
+
* у правил, которым его проставила миграция.
|
|
85
|
+
*/
|
|
86
|
+
const costPlusCapShape = { isCappedByPrice: z.boolean().optional() };
|
|
87
|
+
|
|
88
|
+
/** Цена клиента = себестоимость + наценка. */
|
|
79
89
|
const DiscountRulesCostPlusMarkupDataSchema = z.discriminatedUnion('typeMarkup', [
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
pricingMarkupPercentSchema.extend(costPlusCapShape),
|
|
91
|
+
pricingMarkupFixedSchema.extend(costPlusCapShape),
|
|
82
92
|
]);
|
|
83
93
|
|
|
94
|
+
/** Цена клиента = цена позиции (фасовки, если она выбрана) + наценка. */
|
|
95
|
+
const DiscountRulesPricePlusMarkupDataSchema = z.discriminatedUnion('typeMarkup', [pricingMarkupPercentSchema, pricingMarkupFixedSchema]);
|
|
96
|
+
|
|
84
97
|
export const DiscountRulesTypeSchema = z.discriminatedUnion('type', [
|
|
85
98
|
z.object({
|
|
86
99
|
type: z.literal(DiscountRulesTypeEnum.PERSONAL_DISCOUNT),
|
|
@@ -106,6 +119,10 @@ export const DiscountRulesTypeSchema = z.discriminatedUnion('type', [
|
|
|
106
119
|
type: z.literal(DiscountRulesTypeEnum.COST_PLUS_MARKUP),
|
|
107
120
|
data: DiscountRulesCostPlusMarkupDataSchema,
|
|
108
121
|
}),
|
|
122
|
+
z.object({
|
|
123
|
+
type: z.literal(DiscountRulesTypeEnum.PRICE_PLUS_MARKUP),
|
|
124
|
+
data: DiscountRulesPricePlusMarkupDataSchema,
|
|
125
|
+
}),
|
|
109
126
|
]);
|
|
110
127
|
|
|
111
128
|
export const DiscountRulesBaseSchema = z.object({
|
|
@@ -3,9 +3,18 @@ import { MoneySchema } from '../money.schema';
|
|
|
3
3
|
import { ProductDiscountPriceItemSchema } from './product-discount-price-item.schema';
|
|
4
4
|
import { ProductDiscountPriceMultiplicityOptionSchema } from './product-discount-price-multiplicity-option.schema';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Две базы рядом, и это намеренно. `price` / `optionPrice` — прайс, одинаковый для всех.
|
|
8
|
+
* `clientPrice` / `clientOptionPrice` — цена этого клиента до скидок: у клиента с правилом
|
|
9
|
+
* ценообразования (от себестоимости или от прайса с наценкой) это цена по правилу, у остальных — тот
|
|
10
|
+
* же прайс. Скидки считаются от прайса и только у клиентов без правила ценообразования: у клиента с
|
|
11
|
+
* таким правилом скидок нет, списки вариантов пусты. Цену позиции без скидки берите из `clientPrice`,
|
|
12
|
+
* а не из `price`: иначе цена по правилу потеряется.
|
|
13
|
+
*/
|
|
6
14
|
export const ProductDiscountPriceDataSchema = z.object({
|
|
7
15
|
productUUID: z.string(),
|
|
8
16
|
price: MoneySchema,
|
|
17
|
+
clientPrice: MoneySchema,
|
|
9
18
|
priceWithBestDiscount: MoneySchema.nullable(),
|
|
10
19
|
multiplicityOptions: ProductDiscountPriceMultiplicityOptionSchema.array(),
|
|
11
20
|
/**
|
|
@@ -5,6 +5,8 @@ import { ProductDiscountPriceItemSchema } from './product-discount-price-item.sc
|
|
|
5
5
|
export const ProductDiscountPriceMultiplicityOptionSchema = z.object({
|
|
6
6
|
uuid: z.string(),
|
|
7
7
|
optionPrice: MoneySchema.nullable(),
|
|
8
|
+
/** `null` ровно тогда, когда `null` у `optionPrice`: своей цены у фасовки нет, база — `clientPrice`. */
|
|
9
|
+
clientOptionPrice: MoneySchema.nullable(),
|
|
8
10
|
optionPriceWithDiscount: MoneySchema.nullable(),
|
|
9
11
|
isDiscountApplicable: z.boolean(),
|
|
10
12
|
/**
|
package/schemas/index.ts
CHANGED
|
@@ -71,6 +71,8 @@ export * from './package/validate-package.schema';
|
|
|
71
71
|
export * from './pagination-request.schema';
|
|
72
72
|
export * from './parser';
|
|
73
73
|
export * from './payment-invoice/payment-invoice.schema';
|
|
74
|
+
export * from './payment-invoice/create-payment-invoice-request.schema';
|
|
75
|
+
export * from './payment-invoice/create-payment-invoice-response.schema';
|
|
74
76
|
export * from './positive-decimal4.schema';
|
|
75
77
|
export * from './positive-money.schema';
|
|
76
78
|
export * from './pre-order';
|
|
@@ -37,6 +37,13 @@ export const PriceCorrectionAnalyzeItemSchema = z.object({
|
|
|
37
37
|
priceDifferenceWithoutDiscount: MoneySchema,
|
|
38
38
|
priceDifferenceWithDiscount: MoneySchema,
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* У клиента действует правило ценообразования (от себестоимости или от прайса с наценкой).
|
|
42
|
+
* Его цена — `newPriceWithDiscount`; «без скидок» для него означает прайс, то есть снятие наценки.
|
|
43
|
+
* Сотруднику стоит показать это до применения.
|
|
44
|
+
*/
|
|
45
|
+
hasPricingRule: z.boolean(),
|
|
46
|
+
|
|
40
47
|
isSkipped: z.boolean(),
|
|
41
48
|
skipReason: ErrorMessageSchema.optional(),
|
|
42
49
|
});
|