@floristcloud/api-lib 1.2.107 → 1.2.108
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/create-client.command.js +2 -0
- package/build/commands/client/get-client-list.query.js +8 -0
- package/build/commands/client/index.js +1 -0
- package/build/commands/client/update-client-contract-data.command.js +22 -0
- package/build/commands/client/update-client.command.js +2 -0
- package/build/commands/money-account/get-money-account-by-criteria.query.js +7 -2
- package/build/commands/money-account/get-money-account-list.query.js +5 -1
- package/build/commands/report/export-inventory-stock.query.js +4 -17
- package/build/commands/report/export-inventory-turnover.query.js +4 -27
- package/build/commands/report/get-inventory-stock.query.js +34 -0
- package/build/commands/report/get-inventory-turnover.query.js +43 -0
- package/build/commands/report/get-report-by-client-weeks.query.js +19 -0
- package/build/commands/report/get-report-group-by-client.query.js +21 -2
- package/build/commands/report/get-report-group-by-position.query.js +21 -2
- package/build/commands/report/get-sales-by-client.query.js +45 -0
- package/build/commands/report/index.js +3 -0
- package/build/commands/settings/get-company-profile.query.js +24 -0
- package/build/commands/settings/index.js +1 -0
- package/build/enum/client-contract-status.enum.js +13 -0
- package/build/enum/index.js +3 -0
- package/build/enum/report-sort-by.enum.js +13 -0
- package/build/helpers/index.js +2 -0
- package/build/helpers/pagination.helper.js +12 -0
- package/build/helpers/query-boolean.helper.js +16 -0
- package/build/schemas/client/client.schema.js +2 -0
- package/build/schemas/index.js +7 -0
- package/build/schemas/money-account/money-account-with-balance.schema.js +13 -0
- package/build/schemas/report/inventory-stock-category-item.schema.js +10 -0
- package/build/schemas/report/inventory-stock-detailed-item.schema.js +14 -0
- package/build/schemas/report/inventory-turnover-category-item.schema.js +15 -0
- package/build/schemas/report/inventory-turnover-detailed-item.schema.js +19 -0
- package/build/schemas/report/sales-by-client-row.schema.js +45 -0
- package/build/schemas/report/sales-by-client-top-item.schema.js +9 -0
- package/commands/client/create-client.command.ts +2 -0
- package/commands/client/get-client-list.query.ts +8 -0
- package/commands/client/index.ts +1 -0
- package/commands/client/update-client-contract-data.command.ts +24 -0
- package/commands/client/update-client.command.ts +2 -0
- package/commands/money-account/get-money-account-by-criteria.query.ts +10 -3
- package/commands/money-account/get-money-account-list.query.ts +8 -2
- package/commands/report/export-inventory-stock.query.ts +4 -19
- package/commands/report/export-inventory-turnover.query.ts +4 -29
- package/commands/report/get-inventory-stock.query.ts +36 -0
- package/commands/report/get-inventory-turnover.query.ts +45 -0
- package/commands/report/get-report-by-client-weeks.query.ts +20 -1
- package/commands/report/get-report-group-by-client.query.ts +22 -3
- package/commands/report/get-report-group-by-position.query.ts +23 -4
- package/commands/report/get-sales-by-client.query.ts +47 -0
- package/commands/report/index.ts +3 -0
- package/commands/settings/get-company-profile.query.ts +24 -0
- package/commands/settings/index.ts +1 -0
- package/enum/client-contract-status.enum.ts +9 -0
- package/enum/index.ts +3 -0
- package/enum/report-sort-by.enum.ts +9 -0
- package/helpers/index.ts +2 -0
- package/helpers/pagination.helper.ts +9 -0
- package/helpers/query-boolean.helper.ts +14 -0
- package/package.json +1 -1
- package/schemas/client/client.schema.ts +2 -0
- package/schemas/index.ts +7 -0
- package/schemas/money-account/money-account-with-balance.schema.ts +11 -0
- package/schemas/report/inventory-stock-category-item.schema.ts +8 -0
- package/schemas/report/inventory-stock-detailed-item.schema.ts +12 -0
- package/schemas/report/inventory-turnover-category-item.schema.ts +13 -0
- package/schemas/report/inventory-turnover-detailed-item.schema.ts +17 -0
- package/schemas/report/sales-by-client-row.schema.ts +43 -0
- package/schemas/report/sales-by-client-top-item.schema.ts +7 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Company-level facts every panel role may read: who the company is, how it is named, which time
|
|
5
|
+
* zone its calendar days are counted in and which currency its figures are in. `companyUUID` is
|
|
6
|
+
* echoed so a caller can prove the profile belongs to its own tenant — the ADMIN-only
|
|
7
|
+
* `settings/for-admin` answer carries no such marker and cannot be cross-checked.
|
|
8
|
+
*/
|
|
9
|
+
const CompanyProfileSchema = z.object({
|
|
10
|
+
companyUUID: z.string(),
|
|
11
|
+
companyName: z.string().nullable(),
|
|
12
|
+
timeZone: z.string().nullable(),
|
|
13
|
+
currency: z.string().nullable(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const GetCompanyProfileResponseSchema = z.object({
|
|
17
|
+
message: z.string().optional(),
|
|
18
|
+
data: CompanyProfileSchema,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export namespace GetCompanyProfileContractQuery {
|
|
22
|
+
export const ResponseSchema = GetCompanyProfileResponseSchema;
|
|
23
|
+
export type Response = z.infer<typeof ResponseSchema>;
|
|
24
|
+
}
|
package/enum/index.ts
CHANGED
|
@@ -36,6 +36,7 @@ export * from './order-distribute-status-list';
|
|
|
36
36
|
export * from './order-active-status-list';
|
|
37
37
|
export * from './order-price-correction-skipped-status-list';
|
|
38
38
|
export * from './client-status.enum';
|
|
39
|
+
export * from './client-contract-status.enum';
|
|
39
40
|
export * from './client-type.enum';
|
|
40
41
|
export * from './consignment-distribution-validation-status.enum';
|
|
41
42
|
export * from './consignment-distribution-validation-type.enum';
|
|
@@ -95,3 +96,5 @@ export * from './legal-identifier-field.enum';
|
|
|
95
96
|
export * from './permission-key.enum';
|
|
96
97
|
export * from './cash-flow-item-status.enum';
|
|
97
98
|
export * from './payment-invoice-status.enum';
|
|
99
|
+
export * from './order-by.enum';
|
|
100
|
+
export * from './report-sort-by.enum';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Метрика сортировки для отчётов-группировок (по позициям и по клиентам).
|
|
3
|
+
* Значения совпадают с именами полей ответа, чтобы клиент мог сортировать «по тому, что видит».
|
|
4
|
+
*/
|
|
5
|
+
export enum ReportSortByEnum {
|
|
6
|
+
GROSS_PROFIT = 'grossProfit',
|
|
7
|
+
TOTAL_SALES = 'totalSales',
|
|
8
|
+
SOLD_UNITS = 'soldUnits',
|
|
9
|
+
}
|
package/helpers/index.ts
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `page` имеет смысл только вместе с `count`.
|
|
3
|
+
*
|
|
4
|
+
* Раньше `page` без `count` молча игнорировался и отчёт отдавался целиком: агент, листающий
|
|
5
|
+
* страницы, бесконечно получал одну и ту же выдачу и не мог отличить это от «страниц больше нет».
|
|
6
|
+
* Поэтому неполная пара отклоняется валидацией — единообразно во всех постраничных отчётах.
|
|
7
|
+
*/
|
|
8
|
+
export const isPageAccompaniedByCount = (value: { page?: number; count?: number }): boolean =>
|
|
9
|
+
value.page === undefined || value.count !== undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Boolean-флаг, приходящий в query-строке.
|
|
5
|
+
*
|
|
6
|
+
* Не `z.coerce.boolean()`: в query всегда приходит текст, а `Boolean('false') === true` —
|
|
7
|
+
* такой флаг невозможно выключить явным значением. Принимаем `true` / `1` как включение,
|
|
8
|
+
* всё остальное — выключение. По умолчанию флаг выключен, чтобы поведение без параметра не менялось.
|
|
9
|
+
*/
|
|
10
|
+
export const queryBooleanSchema = z
|
|
11
|
+
.union([z.boolean(), z.string()])
|
|
12
|
+
.optional()
|
|
13
|
+
.default(false)
|
|
14
|
+
.transform(value => (typeof value === 'boolean' ? value : value === 'true' || value === '1'));
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ClientStatusEnum } from '../../enum/client-status.enum';
|
|
3
|
+
import { ClientContractStatusEnum } from '../../enum/client-contract-status.enum';
|
|
3
4
|
import { ClientTypeEnum } from '../../enum/client-type.enum';
|
|
4
5
|
import { UserSchema } from '../user/user.schema';
|
|
5
6
|
import { ClientIndividualProfileSchema } from './client-individual-profile.schema';
|
|
@@ -17,6 +18,7 @@ export const ClientSchema = z.object({
|
|
|
17
18
|
isCommon: z.boolean(),
|
|
18
19
|
contractNumber: z.string().nullable(),
|
|
19
20
|
contractDate: z.date().nullable(),
|
|
21
|
+
contractStatus: z.nativeEnum(ClientContractStatusEnum),
|
|
20
22
|
address: z.string().nullable(),
|
|
21
23
|
city: z.string().nullable(),
|
|
22
24
|
code: z.string().nullable(),
|
package/schemas/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from './product-image/product-image.schema';
|
|
|
22
22
|
export * from './settings/settings.schema';
|
|
23
23
|
export * from './payment-invoice/payment-invoice.schema';
|
|
24
24
|
export * from './money-account/money-account.schema';
|
|
25
|
+
export * from './money-account/money-account-with-balance.schema';
|
|
25
26
|
export * from './domain/domain.schema';
|
|
26
27
|
export * from './category/category.schema';
|
|
27
28
|
export * from './branch/branch.schema';
|
|
@@ -52,6 +53,12 @@ export * from './consignment/consignment-distribution-validation.schema';
|
|
|
52
53
|
export * from './product-image-template/product-image-template.schema';
|
|
53
54
|
export * from './report/client-statement.schema';
|
|
54
55
|
export * from './report/client-by-weeks.schema';
|
|
56
|
+
export * from './report/inventory-stock-category-item.schema';
|
|
57
|
+
export * from './report/inventory-stock-detailed-item.schema';
|
|
58
|
+
export * from './report/inventory-turnover-category-item.schema';
|
|
59
|
+
export * from './report/inventory-turnover-detailed-item.schema';
|
|
60
|
+
export * from './report/sales-by-client-top-item.schema';
|
|
61
|
+
export * from './report/sales-by-client-row.schema';
|
|
55
62
|
export * from './action-log/index';
|
|
56
63
|
export * from './delivery-route/delivery-route.schema';
|
|
57
64
|
export * from './product/product-multiplicity-option.schema';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { MoneyAccountSchema } from './money-account.schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Денежный счёт в ответах списков. `balance` — текущий остаток счёта (приход минус расход),
|
|
6
|
+
* приходит только при `?withBalance=true`: поле аддитивное, клиенты без этого параметра
|
|
7
|
+
* получают ровно прежнюю форму ответа.
|
|
8
|
+
*/
|
|
9
|
+
export const MoneyAccountWithBalanceSchema = MoneyAccountSchema.extend({
|
|
10
|
+
balance: z.number().optional(),
|
|
11
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Строка отчёта об остатках с детализацией по name/size/grower (`detailed=true`). */
|
|
4
|
+
export const InventoryStockDetailedItemSchema = z.object({
|
|
5
|
+
categoryUUID: z.string(),
|
|
6
|
+
categoryName: z.string(),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
color: z.string().nullable(),
|
|
9
|
+
size: z.string().nullable(),
|
|
10
|
+
grower: z.string().nullable(),
|
|
11
|
+
balance: z.number(),
|
|
12
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Строка отчёта об оборачиваемости в разрезе категорий (`detailed=false`). */
|
|
4
|
+
export const InventoryTurnoverCategoryItemSchema = z.object({
|
|
5
|
+
categoryUUID: z.string(),
|
|
6
|
+
categoryName: z.string(),
|
|
7
|
+
initialBalance: z.number(), // начальный остаток
|
|
8
|
+
receipts: z.number(), // приходы
|
|
9
|
+
sales: z.number(), // продажи
|
|
10
|
+
currentBalance: z.number(), // текущий остаток
|
|
11
|
+
daysInStock: z.number(), // дни в наличии на складе
|
|
12
|
+
turnoverRate: z.number(), // коэффициент оборачиваемости
|
|
13
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Строка отчёта об оборачиваемости с детализацией по name/size/grower (`detailed=true`). */
|
|
4
|
+
export const InventoryTurnoverDetailedItemSchema = z.object({
|
|
5
|
+
categoryUUID: z.string(),
|
|
6
|
+
categoryName: z.string(),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
color: z.string().nullable(),
|
|
9
|
+
size: z.string().nullable(),
|
|
10
|
+
grower: z.string().nullable(), // производитель
|
|
11
|
+
initialBalance: z.number(), // начальный остаток
|
|
12
|
+
receipts: z.number(), // приходы
|
|
13
|
+
sales: z.number(), // продажи
|
|
14
|
+
currentBalance: z.number(), // текущий остаток
|
|
15
|
+
daysInStock: z.number(), // дни в наличии на складе
|
|
16
|
+
turnoverRate: z.number(), // коэффициент оборачиваемости
|
|
17
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { SalesByClientTopItemSchema } from './sales-by-client-top-item.schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Строка отчёта «продажи по клиентам» — те же данные, что уходят в Excel из `export/sales/clients`.
|
|
6
|
+
* Опциональные поля отсутствуют в ответе, когда у клиента нет соответствующего значения.
|
|
7
|
+
*/
|
|
8
|
+
export const SalesByClientRowSchema = z.object({
|
|
9
|
+
uuid: z.string(),
|
|
10
|
+
clientName: z.string(),
|
|
11
|
+
responsibleUserName: z.string().optional(),
|
|
12
|
+
totalOrders: z.number(),
|
|
13
|
+
soldUnits: z.number(),
|
|
14
|
+
soldUnitsByUnit: z.object({
|
|
15
|
+
PIECE: z.number(),
|
|
16
|
+
PACK: z.number(),
|
|
17
|
+
BOX: z.number(),
|
|
18
|
+
}),
|
|
19
|
+
totalSales: z.number(),
|
|
20
|
+
avgCheck: z.number(),
|
|
21
|
+
totalWriteOff: z.number(),
|
|
22
|
+
grossProfit: z.number(),
|
|
23
|
+
marginality: z.number(),
|
|
24
|
+
// Оплаты (INCOME) и предоплаты (PREPAYMENT) клиента за период
|
|
25
|
+
totalPayments: z.number(),
|
|
26
|
+
totalPrepayments: z.number(),
|
|
27
|
+
// Сумма услуг (order_service_line) за период — отдельно, вне товарных sales/margin
|
|
28
|
+
totalServiceAmount: z.number(),
|
|
29
|
+
// Текущий баланс клиента (на момент формирования отчёта)
|
|
30
|
+
balance: z.number(),
|
|
31
|
+
lastOrderDate: z.coerce.date().optional(),
|
|
32
|
+
// Топ-5 по сумме выручки за период
|
|
33
|
+
topCategories: z.array(SalesByClientTopItemSchema),
|
|
34
|
+
topProducts: z.array(SalesByClientTopItemSchema),
|
|
35
|
+
// Статическая информация о клиенте
|
|
36
|
+
code: z.string().optional(),
|
|
37
|
+
city: z.string().optional(),
|
|
38
|
+
contactName: z.string().optional(),
|
|
39
|
+
phone: z.string().optional(),
|
|
40
|
+
clientType: z.string().optional(),
|
|
41
|
+
status: z.string().optional(),
|
|
42
|
+
group: z.string().optional(),
|
|
43
|
+
});
|