@escapenavigator/types 2.1.21 → 2.1.23
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/dist/admin/admin.ro.d.ts +1 -0
- package/dist/admin/aggregator-order/aggregator-order.ro.d.ts +14 -0
- package/dist/admin/aggregator-order/aggregator-order.ro.js +17 -0
- package/dist/admin/aggregator-order/enum/aggregator-order-agreed-by.enum.d.ts +4 -0
- package/dist/admin/aggregator-order/enum/aggregator-order-agreed-by.enum.js +8 -0
- package/dist/admin/aggregator-order/query-aggregator-order.dto.d.ts +10 -0
- package/dist/admin/aggregator-order/query-aggregator-order.dto.js +14 -0
- package/dist/admin/aggregator-order/update-aggregator-order.dto.d.ts +6 -0
- package/dist/admin/aggregator-order/update-aggregator-order.dto.js +6 -0
- package/dist/admin/create-admin.dto.d.ts +1 -0
- package/dist/admin/create-admin.dto.js +11 -0
- package/dist/admin/sms/admin-sms.ro.d.ts +11 -0
- package/dist/admin/sms/admin-sms.ro.js +2 -0
- package/dist/admin/sms/send-admin-sms.dto.d.ts +13 -0
- package/dist/admin/sms/send-admin-sms.dto.js +87 -0
- package/dist/admin/telephony/admin-call.ro.d.ts +38 -0
- package/dist/admin/telephony/admin-call.ro.js +2 -0
- package/dist/admin/telephony/start-admin-call.dto.d.ts +16 -0
- package/dist/admin/telephony/start-admin-call.dto.js +104 -0
- package/dist/balance/balance-invoice-status.enum.d.ts +5 -0
- package/dist/balance/balance-invoice-status.enum.js +9 -0
- package/dist/balance/balance-invoice.ro.d.ts +25 -0
- package/dist/balance/balance-invoice.ro.js +89 -0
- package/dist/balance/balance-item.ro.d.ts +11 -0
- package/dist/balance/balance-item.ro.js +32 -0
- package/dist/balance/balance-payer.d.ts +6 -0
- package/dist/balance/balance-payer.js +2 -0
- package/dist/balance/balance-payment.ro.d.ts +7 -0
- package/dist/balance/balance-payment.ro.js +25 -1
- package/dist/balance/create-balance-invoice.dto.d.ts +8 -0
- package/dist/balance/create-balance-invoice.dto.js +47 -0
- package/dist/certificate-v2/update-certificate-settings.dto.js +21 -8
- package/dist/integrations/connect-integration.dto.d.ts +1 -1
- package/dist/integrations/provider-code.enum.d.ts +1 -1
- package/dist/integrations/provider-code.enum.js +1 -1
- package/dist/lead/lead-board.ro.d.ts +2 -0
- package/dist/lead/lead-time.constants.d.ts +6 -0
- package/dist/lead/lead-time.constants.js +9 -0
- package/dist/lead/public/public-lead-form.ro.d.ts +2 -0
- package/dist/lead/public/submit-lead.dto.d.ts +2 -0
- package/dist/lead/public/submit-lead.dto.js +6 -0
- package/dist/openapi/certificates-v2/openapi-create-certificate-shop-sale.dto.d.ts +2 -0
- package/dist/openapi/certificates-v2/openapi-create-certificate-shop-sale.dto.js +6 -0
- package/dist/openapi/profiles/openapi-profile-booking-list-item.ro.js +6 -2
- package/dist/openapi/widget/openapi-widget-info.ro.d.ts +2 -0
- package/dist/openapi/widget/openapi-widget-info.ro.js +8 -0
- package/dist/order/order.ro.d.ts +23 -0
- package/dist/order/order.ro.js +64 -0
- package/dist/player/player.ro.d.ts +3 -0
- package/dist/player/player.ro.js +12 -0
- package/dist/profile/action/create-profile-action.dto.d.ts +6 -0
- package/dist/profile/action/create-profile-action.dto.js +14 -0
- package/dist/profile/agb/profile-document-type.enum.d.ts +19 -0
- package/dist/profile/agb/profile-document-type.enum.js +27 -0
- package/dist/profile/agb/profile-document.ro.d.ts +35 -0
- package/dist/profile/agb/profile-document.ro.js +2 -0
- package/dist/profile/agb/update-profile-document.dto.d.ts +8 -0
- package/dist/profile/agb/update-profile-document.dto.js +35 -0
- package/dist/profile/company-ai-context.d.ts +1 -0
- package/dist/profile/enum/profile-partner-board-status.enum.d.ts +12 -0
- package/dist/profile/enum/profile-partner-board-status.enum.js +16 -0
- package/dist/profile/enum/profile-verification-board-status.enum.d.ts +13 -0
- package/dist/profile/enum/profile-verification-board-status.enum.js +17 -0
- package/dist/profile/partner-board.ro.d.ts +36 -0
- package/dist/profile/partner-board.ro.js +116 -0
- package/dist/profile/profile.ro.d.ts +2 -0
- package/dist/profile/profile.ro.js +8 -0
- package/dist/profile/update-current-ym.dto.d.ts +8 -0
- package/dist/profile/update-current-ym.dto.js +33 -0
- package/dist/profile/verification-board.ro.d.ts +37 -0
- package/dist/profile/verification-board.ro.js +116 -0
- package/dist/questroom/create-questroom-admin-note.dto.d.ts +3 -0
- package/dist/questroom/create-questroom-admin-note.dto.js +24 -0
- package/dist/questroom/enum/questroom-admin-note-type.enum.d.ts +4 -0
- package/dist/questroom/enum/questroom-admin-note-type.enum.js +8 -0
- package/dist/questroom/questroom-admin-card.ro.d.ts +85 -0
- package/dist/questroom/questroom-admin-card.ro.js +276 -0
- package/dist/questroom/questroom-admin-note.ro.d.ts +10 -0
- package/dist/questroom/{update-questroom-integration.dto.js → questroom-admin-note.ro.js} +17 -16
- package/dist/questroom/questroom-admin.ro.d.ts +2 -0
- package/dist/questroom/questroom-admin.ro.js +4 -0
- package/dist/questroom/questrooms-list-admin.ro.d.ts +2 -14
- package/dist/questroom/questrooms-list-admin.ro.js +8 -35
- package/dist/referral/referral.dto.d.ts +15 -0
- package/dist/referral/referral.dto.js +69 -0
- package/dist/referral/referral.enums.d.ts +36 -0
- package/dist/referral/referral.enums.js +45 -0
- package/dist/referral/referral.ro.d.ts +58 -0
- package/dist/referral/referral.ro.js +2 -0
- package/dist/registration-request/create-registration-request.dto.d.ts +1 -0
- package/dist/registration-request/create-registration-request.dto.js +17 -0
- package/dist/registration-request/registration-request.ro.d.ts +1 -0
- package/dist/registration-request/update-registration-request.dto.d.ts +5 -0
- package/dist/registration-request/update-registration-request.dto.js +28 -0
- package/dist/role/create-role.dto.d.ts +1 -0
- package/dist/role/create-role.dto.js +6 -0
- package/dist/role/role.ro.d.ts +5 -0
- package/dist/role/role.ro.js +4 -0
- package/dist/search/search.ro.d.ts +12 -0
- package/dist/slot-rule/create-rule.dto.d.ts +1 -0
- package/dist/slot-rule/create-rule.dto.js +7 -0
- package/dist/slot-rule/defailt-rule.d.ts +1 -0
- package/dist/slot-rule/defailt-rule.js +1 -0
- package/dist/slot-rule/rule.ro.d.ts +1 -0
- package/dist/slot-rule/rule.ro.js +4 -0
- package/dist/statistics/leads.d.ts +70 -0
- package/dist/statistics/leads.js +2 -0
- package/dist/statistics/pnl.d.ts +6 -0
- package/dist/statistics/pnl.js +9 -0
- package/dist/statistics/questroom-ids.d.ts +16 -0
- package/dist/statistics/questroom-ids.js +38 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/user/fine/create-user-fine.dto.d.ts +2 -0
- package/dist/user/fine/create-user-fine.dto.js +8 -0
- package/dist/user/fine/user-fine-kind.d.ts +29 -0
- package/dist/user/fine/user-fine-kind.js +66 -0
- package/dist/user/fine/user-fine.ro.d.ts +2 -0
- package/dist/user/fine/user-fine.ro.js +5 -0
- package/dist/user/reports/user-monthly-report.ro.d.ts +11 -0
- package/dist/widget/create-widget.dto.d.ts +6 -0
- package/dist/widget/create-widget.dto.js +15 -0
- package/dist/widget/widget.ro.d.ts +1 -0
- package/package.json +2 -2
- package/dist/questroom/update-questroom-integration.dto.d.ts +0 -6
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ProfileCurrencyEnum } from '../profile/enum/profile-currency';
|
|
2
|
+
import { ReferralEarningSourceEnum, ReferralEarningStatusEnum, ReferralRelationStatusEnum, ReferralWithdrawalStatusEnum } from './referral.enums';
|
|
3
|
+
export type ReferralRelationRO = {
|
|
4
|
+
id: number;
|
|
5
|
+
companyTitle: string;
|
|
6
|
+
status: ReferralRelationStatusEnum;
|
|
7
|
+
attributedAt: Date;
|
|
8
|
+
firstPaidAt: Date | null;
|
|
9
|
+
earnThrough: Date | null;
|
|
10
|
+
earnedAmount: number;
|
|
11
|
+
currency: ProfileCurrencyEnum;
|
|
12
|
+
};
|
|
13
|
+
export type ReferralEarningRO = {
|
|
14
|
+
id: number;
|
|
15
|
+
relationId: number;
|
|
16
|
+
source: ReferralEarningSourceEnum;
|
|
17
|
+
sourceId: string;
|
|
18
|
+
eligibleAmount: number;
|
|
19
|
+
amount: number;
|
|
20
|
+
currency: ProfileCurrencyEnum;
|
|
21
|
+
status: ReferralEarningStatusEnum;
|
|
22
|
+
availableAt: Date;
|
|
23
|
+
createdAt: Date;
|
|
24
|
+
};
|
|
25
|
+
export type ReferralWithdrawalRO = {
|
|
26
|
+
id: number;
|
|
27
|
+
profileId: number;
|
|
28
|
+
profileTitle?: string;
|
|
29
|
+
publisherUserId?: number;
|
|
30
|
+
publisherName?: string;
|
|
31
|
+
amount: number;
|
|
32
|
+
currency: ProfileCurrencyEnum;
|
|
33
|
+
status: ReferralWithdrawalStatusEnum;
|
|
34
|
+
userComment: string;
|
|
35
|
+
adminComment: string;
|
|
36
|
+
externalReference: string | null;
|
|
37
|
+
reviewerAdminId: number | null;
|
|
38
|
+
reviewedAt: Date | null;
|
|
39
|
+
paidAt: Date | null;
|
|
40
|
+
createdAt: Date;
|
|
41
|
+
updatedAt: Date;
|
|
42
|
+
};
|
|
43
|
+
export type ReferralOverviewRO = {
|
|
44
|
+
code: string;
|
|
45
|
+
shareUrl: string;
|
|
46
|
+
promoSeen: boolean;
|
|
47
|
+
beneficiaryProfileId: number;
|
|
48
|
+
balances: Array<{
|
|
49
|
+
currency: ProfileCurrencyEnum;
|
|
50
|
+
pending: number;
|
|
51
|
+
available: number;
|
|
52
|
+
reserved: number;
|
|
53
|
+
paid: number;
|
|
54
|
+
}>;
|
|
55
|
+
relations: ReferralRelationRO[];
|
|
56
|
+
earnings: ReferralEarningRO[];
|
|
57
|
+
withdrawals: ReferralWithdrawalRO[];
|
|
58
|
+
};
|
|
@@ -13,9 +13,26 @@ exports.CreateRegistrationRequestDto = void 0;
|
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const is_not_blank_1 = require("../shared/is-not-blank");
|
|
16
|
+
/** Пустая строка — то же, что поле не заполнили. */
|
|
17
|
+
const blankToNull = ({ value }) => {
|
|
18
|
+
if (value === null || value === undefined)
|
|
19
|
+
return null;
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return value;
|
|
22
|
+
const trimmed = value.trim();
|
|
23
|
+
return trimmed || null;
|
|
24
|
+
};
|
|
16
25
|
class CreateRegistrationRequestDto {
|
|
17
26
|
}
|
|
18
27
|
exports.CreateRegistrationRequestDto = CreateRegistrationRequestDto;
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_validator_1.IsOptional)(),
|
|
30
|
+
(0, class_transformer_1.Transform)(blankToNull),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.MaxLength)(120),
|
|
33
|
+
(0, class_transformer_1.Expose)(),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], CreateRegistrationRequestDto.prototype, "fullName", void 0);
|
|
19
36
|
__decorate([
|
|
20
37
|
(0, class_validator_1.IsEmail)(),
|
|
21
38
|
(0, class_transformer_1.Transform)(({ value }) => value === null || value === void 0 ? void 0 : value.trim().toLowerCase()),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CountriesEnum } from '../shared/enum/countries.enum';
|
|
2
2
|
import { RegistrationRequestStatusEnum } from './enum/registration-request-status';
|
|
3
3
|
export type RegistrationRequestResponseObject = {
|
|
4
|
+
fullName?: string | null;
|
|
4
5
|
email: string;
|
|
5
6
|
phone: string;
|
|
6
7
|
site: string;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { RegistrationRequestStatusEnum } from './enum/registration-request-status';
|
|
2
2
|
export declare class UpdateRegistrationRequestDto {
|
|
3
|
+
fullName?: string | null;
|
|
3
4
|
email: string;
|
|
4
5
|
phone: string;
|
|
6
|
+
/**
|
|
7
|
+
* Admin Input шлёт строку; `(1105)` раньше доезжало до Postgres integer
|
|
8
|
+
* и валило 500 (ESCAPE-NAVIGATOR-API-RW). Пустое/null не превращаем в 0.
|
|
9
|
+
*/
|
|
5
10
|
profileId: number;
|
|
6
11
|
site: string;
|
|
7
12
|
status?: RegistrationRequestStatusEnum;
|
|
@@ -17,6 +17,21 @@ const registration_request_status_1 = require("./enum/registration-request-statu
|
|
|
17
17
|
class UpdateRegistrationRequestDto {
|
|
18
18
|
}
|
|
19
19
|
exports.UpdateRegistrationRequestDto = UpdateRegistrationRequestDto;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
|
+
(0, class_transformer_1.Transform)(({ value }) => {
|
|
23
|
+
if (value === null || value === undefined)
|
|
24
|
+
return null;
|
|
25
|
+
if (typeof value !== 'string')
|
|
26
|
+
return value;
|
|
27
|
+
const trimmed = value.trim();
|
|
28
|
+
return trimmed || null;
|
|
29
|
+
}),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.MaxLength)(120),
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], UpdateRegistrationRequestDto.prototype, "fullName", void 0);
|
|
20
35
|
__decorate([
|
|
21
36
|
(0, class_validator_1.IsEmail)(),
|
|
22
37
|
(0, class_transformer_1.Transform)(({ value }) => value === null || value === void 0 ? void 0 : value.trim().toLowerCase()),
|
|
@@ -30,6 +45,19 @@ __decorate([
|
|
|
30
45
|
], UpdateRegistrationRequestDto.prototype, "phone", void 0);
|
|
31
46
|
__decorate([
|
|
32
47
|
(0, class_validator_1.IsOptional)(),
|
|
48
|
+
(0, class_transformer_1.Transform)(({ value }) => {
|
|
49
|
+
if (value === null || value === undefined || value === '')
|
|
50
|
+
return undefined;
|
|
51
|
+
if (typeof value === 'number')
|
|
52
|
+
return value;
|
|
53
|
+
if (typeof value === 'string') {
|
|
54
|
+
const parsed = Number(value.trim());
|
|
55
|
+
return Number.isFinite(parsed) ? parsed : value;
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}),
|
|
59
|
+
(0, class_validator_1.IsInt)(),
|
|
60
|
+
(0, class_validator_1.IsPositive)(),
|
|
33
61
|
(0, class_transformer_1.Expose)(),
|
|
34
62
|
__metadata("design:type", Number)
|
|
35
63
|
], UpdateRegistrationRequestDto.prototype, "profileId", void 0);
|
|
@@ -15,6 +15,7 @@ export declare class CreateRoleDto {
|
|
|
15
15
|
canSeeIncomingLeadCards: boolean;
|
|
16
16
|
accessToMarketingSection: boolean;
|
|
17
17
|
accessToFinanceSection: boolean;
|
|
18
|
+
financePaymentsOnly: boolean;
|
|
18
19
|
accessToStatisticSection: boolean;
|
|
19
20
|
accessToSettingsSection: boolean;
|
|
20
21
|
accessToOrdersSection: boolean;
|
|
@@ -87,6 +87,12 @@ __decorate([
|
|
|
87
87
|
(0, class_transformer_1.Expose)(),
|
|
88
88
|
__metadata("design:type", Boolean)
|
|
89
89
|
], CreateRoleDto.prototype, "accessToFinanceSection", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
(0, class_validator_1.IsBoolean)(),
|
|
92
|
+
(0, class_transformer_1.Transform)(({ value }) => (value !== undefined ? value : false)),
|
|
93
|
+
(0, class_transformer_1.Expose)(),
|
|
94
|
+
__metadata("design:type", Boolean)
|
|
95
|
+
], CreateRoleDto.prototype, "financePaymentsOnly", void 0);
|
|
90
96
|
__decorate([
|
|
91
97
|
(0, class_validator_1.IsBoolean)(),
|
|
92
98
|
(0, class_transformer_1.Transform)(({ value }) => (value !== undefined ? value : false)),
|
package/dist/role/role.ro.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export declare class RoleRO extends RoleLightRO {
|
|
|
14
14
|
canSeeIncomingLeadCards: boolean;
|
|
15
15
|
accessToMarketingSection: boolean;
|
|
16
16
|
accessToFinanceSection: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* При доступе к бухгалтерии оставляет только вкладку платежей.
|
|
19
|
+
* Не действует на владельца (`totalAccess`).
|
|
20
|
+
*/
|
|
21
|
+
financePaymentsOnly: boolean;
|
|
17
22
|
accessToStatisticSection: boolean;
|
|
18
23
|
accessToSettingsSection: boolean;
|
|
19
24
|
accessToOrdersSection: boolean;
|
package/dist/role/role.ro.js
CHANGED
|
@@ -55,6 +55,10 @@ __decorate([
|
|
|
55
55
|
(0, class_transformer_1.Expose)(),
|
|
56
56
|
__metadata("design:type", Boolean)
|
|
57
57
|
], RoleRO.prototype, "accessToFinanceSection", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, class_transformer_1.Expose)(),
|
|
60
|
+
__metadata("design:type", Boolean)
|
|
61
|
+
], RoleRO.prototype, "financePaymentsOnly", void 0);
|
|
58
62
|
__decorate([
|
|
59
63
|
(0, class_transformer_1.Expose)(),
|
|
60
64
|
__metadata("design:type", Boolean)
|
|
@@ -3,9 +3,21 @@ import { CertificateUploadedRO } from '../certificate-uploaded/certificate-uploa
|
|
|
3
3
|
import { ClientRO } from '../client/client.ro';
|
|
4
4
|
import { OrderRO } from '../order/order.ro';
|
|
5
5
|
import { PromocodeRO } from '../promocode/promocode.ro';
|
|
6
|
+
/** Строка сделки в глобальном поиске: номер и клиент, без графа заказов. */
|
|
7
|
+
export type OrderGroupSearchRO = {
|
|
8
|
+
id: number;
|
|
9
|
+
code: string | null;
|
|
10
|
+
client?: {
|
|
11
|
+
id: number;
|
|
12
|
+
name?: string | null;
|
|
13
|
+
surname?: string | null;
|
|
14
|
+
phone?: string | null;
|
|
15
|
+
} | null;
|
|
16
|
+
};
|
|
6
17
|
export type SearchRO = {
|
|
7
18
|
clients: ClientRO[];
|
|
8
19
|
orders: OrderRO[];
|
|
20
|
+
groups: OrderGroupSearchRO[];
|
|
9
21
|
certificates: CertificateSaleRO[];
|
|
10
22
|
promocodes: PromocodeRO[];
|
|
11
23
|
uploadedCertificates: CertificateUploadedRO[];
|
|
@@ -143,6 +143,13 @@ __decorate([
|
|
|
143
143
|
(0, class_transformer_1.Expose)(),
|
|
144
144
|
__metadata("design:type", Boolean)
|
|
145
145
|
], CreateRuleDto.prototype, "prepayForTourists", void 0);
|
|
146
|
+
__decorate([
|
|
147
|
+
(0, class_validator_1.ValidateIf)((o) => !o.ruleId),
|
|
148
|
+
(0, class_transformer_1.Transform)(({ value }) => value !== null && value !== void 0 ? value : false),
|
|
149
|
+
(0, class_validator_1.IsBoolean)(),
|
|
150
|
+
(0, class_transformer_1.Expose)(),
|
|
151
|
+
__metadata("design:type", Boolean)
|
|
152
|
+
], CreateRuleDto.prototype, "partialPrepaymentOnly", void 0);
|
|
146
153
|
__decorate([
|
|
147
154
|
(0, class_validator_1.IsOptional)(),
|
|
148
155
|
(0, class_transformer_1.Expose)(),
|
|
@@ -89,6 +89,10 @@ __decorate([
|
|
|
89
89
|
(0, class_transformer_1.Expose)(),
|
|
90
90
|
__metadata("design:type", Boolean)
|
|
91
91
|
], RuleRO.prototype, "prepayForTourists", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, class_transformer_1.Expose)(),
|
|
94
|
+
__metadata("design:type", Boolean)
|
|
95
|
+
], RuleRO.prototype, "partialPrepaymentOnly", void 0);
|
|
92
96
|
__decorate([
|
|
93
97
|
(0, class_transformer_1.Expose)(),
|
|
94
98
|
__metadata("design:type", Number)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { LeadLostReasonEnum } from '../lead/enums/lead-lost-reason.enum';
|
|
2
|
+
import { LeadSourceEnum } from '../lead/enums/lead-source.enum';
|
|
3
|
+
import { LeadStageKindEnum } from '../lead/enums/lead-stage-kind.enum';
|
|
4
|
+
/**
|
|
5
|
+
* Когорта отчёта — заявки, **созданные** в `dateFrom..dateTo`.
|
|
6
|
+
* «Выиграно» / «проиграно» — их текущий этап, а не сделки, закрытые в эти даты.
|
|
7
|
+
* Спам и дубли входят в `created`, но вычтены из win rate и conversion.
|
|
8
|
+
*/
|
|
9
|
+
export type LeadsKpi = {
|
|
10
|
+
created: number;
|
|
11
|
+
open: number;
|
|
12
|
+
won: number;
|
|
13
|
+
lost: number;
|
|
14
|
+
/** Спам (`lostReason=spam`) и дубли (`duplicateOfLeadId` или `lostReason=duplicate`). */
|
|
15
|
+
unqualified: number;
|
|
16
|
+
/** qualified won / (qualified won + qualified lost). 0, если закрытых нет. 0..1 */
|
|
17
|
+
winRate: number;
|
|
18
|
+
/** qualified won / (created − unqualified). Открытые остаются в знаменателе. 0..1 */
|
|
19
|
+
conversionRate: number;
|
|
20
|
+
/** Медиана часов от создания до первого открытия. null — никто не открывал. */
|
|
21
|
+
medianFirstResponseHours: number | null;
|
|
22
|
+
/** Медиана часов от создания до текущего этапа won. null — побед нет. */
|
|
23
|
+
medianTimeToWinHours: number | null;
|
|
24
|
+
};
|
|
25
|
+
export type LeadsTrendGranularity = 'day' | 'week' | 'month';
|
|
26
|
+
export type LeadsTrendPoint = {
|
|
27
|
+
/** `YYYY-MM-DD` | `YYYY-Www` | `YYYY-MM` — см. `trendGranularity`. */
|
|
28
|
+
period: string;
|
|
29
|
+
created: number;
|
|
30
|
+
won: number;
|
|
31
|
+
};
|
|
32
|
+
export type LeadsBySourceRow = {
|
|
33
|
+
source: LeadSourceEnum;
|
|
34
|
+
count: number;
|
|
35
|
+
won: number;
|
|
36
|
+
lost: number;
|
|
37
|
+
};
|
|
38
|
+
export type LeadsByStageRow = {
|
|
39
|
+
kind: LeadStageKindEnum;
|
|
40
|
+
count: number;
|
|
41
|
+
};
|
|
42
|
+
export type LeadsLostReasonRow = {
|
|
43
|
+
reason: LeadLostReasonEnum;
|
|
44
|
+
count: number;
|
|
45
|
+
};
|
|
46
|
+
export type LeadsByAssigneeRow = {
|
|
47
|
+
assigneeId: number | null;
|
|
48
|
+
/** Пустая строка — заявка ни на кого не назначена. */
|
|
49
|
+
name: string;
|
|
50
|
+
count: number;
|
|
51
|
+
won: number;
|
|
52
|
+
lost: number;
|
|
53
|
+
};
|
|
54
|
+
export type LeadsByQuestroomRow = {
|
|
55
|
+
questroomId: number | null;
|
|
56
|
+
title: string;
|
|
57
|
+
count: number;
|
|
58
|
+
won: number;
|
|
59
|
+
lost: number;
|
|
60
|
+
};
|
|
61
|
+
export type LeadsReportRO = {
|
|
62
|
+
kpi: LeadsKpi;
|
|
63
|
+
trendGranularity: LeadsTrendGranularity;
|
|
64
|
+
trend: LeadsTrendPoint[];
|
|
65
|
+
bySource: LeadsBySourceRow[];
|
|
66
|
+
byStage: LeadsByStageRow[];
|
|
67
|
+
lostReasons: LeadsLostReasonRow[];
|
|
68
|
+
byAssignee: LeadsByAssigneeRow[];
|
|
69
|
+
byQuestroom: LeadsByQuestroomRow[];
|
|
70
|
+
};
|
package/dist/statistics/pnl.d.ts
CHANGED
|
@@ -30,6 +30,12 @@ export declare class DashboardQueryDto {
|
|
|
30
30
|
dateTo: string;
|
|
31
31
|
locationId?: number;
|
|
32
32
|
questroomId?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Несколько квестов одним фильтром. Пусто — все квесты локации или профиля.
|
|
35
|
+
* Отчёт не размножается: в SQL это один `IN`, тот же запрос, что и для
|
|
36
|
+
* одного квеста. `questroomId` остаётся для одиночного выбора.
|
|
37
|
+
*/
|
|
38
|
+
questroomIds?: number[];
|
|
33
39
|
utmSource?: string;
|
|
34
40
|
utmMedium?: string;
|
|
35
41
|
utmCampaign?: string;
|
package/dist/statistics/pnl.js
CHANGED
|
@@ -10,7 +10,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DashboardQueryDto = exports.PeriodType = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
13
14
|
const class_validator_1 = require("class-validator");
|
|
15
|
+
const questroom_ids_1 = require("./questroom-ids");
|
|
14
16
|
var PeriodType;
|
|
15
17
|
(function (PeriodType) {
|
|
16
18
|
PeriodType["MONTH"] = "month";
|
|
@@ -52,6 +54,13 @@ __decorate([
|
|
|
52
54
|
(0, class_validator_1.IsOptional)(),
|
|
53
55
|
__metadata("design:type", Number)
|
|
54
56
|
], DashboardQueryDto.prototype, "questroomId", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, class_validator_1.IsOptional)(),
|
|
59
|
+
(0, class_transformer_1.Transform)(({ value }) => (0, questroom_ids_1.parseQuestroomIdList)(value)),
|
|
60
|
+
(0, class_validator_1.IsArray)(),
|
|
61
|
+
(0, class_validator_1.IsInt)({ each: true }),
|
|
62
|
+
__metadata("design:type", Array)
|
|
63
|
+
], DashboardQueryDto.prototype, "questroomIds", void 0);
|
|
55
64
|
__decorate([
|
|
56
65
|
(0, class_validator_1.IsOptional)(),
|
|
57
66
|
(0, class_validator_1.IsString)(),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Список id квестов из query-string.
|
|
3
|
+
* Axios 0.21 шлёт массив как `questroomIds[]=1&questroomIds[]=2`,
|
|
4
|
+
* Express собирает это в `string[]`. Допускаем и запятую (`1,2`).
|
|
5
|
+
* Мусор, нули и дубли отбрасываем. Порядок стабильный — от него зависит ключ кеша.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseQuestroomIdList(value: unknown): number[] | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Id квестов, которыми надо сузить отчёт.
|
|
10
|
+
* Непустой `questroomIds` важнее одиночного `questroomId`.
|
|
11
|
+
* Пустой результат — фильтр по квесту не применять (все квесты локации/профиля).
|
|
12
|
+
*/
|
|
13
|
+
export declare function effectiveQuestroomIds(query: {
|
|
14
|
+
questroomId?: number;
|
|
15
|
+
questroomIds?: number[];
|
|
16
|
+
}): number[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseQuestroomIdList = parseQuestroomIdList;
|
|
4
|
+
exports.effectiveQuestroomIds = effectiveQuestroomIds;
|
|
5
|
+
const MAX_QUESTROOM_IDS = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Список id квестов из query-string.
|
|
8
|
+
* Axios 0.21 шлёт массив как `questroomIds[]=1&questroomIds[]=2`,
|
|
9
|
+
* Express собирает это в `string[]`. Допускаем и запятую (`1,2`).
|
|
10
|
+
* Мусор, нули и дубли отбрасываем. Порядок стабильный — от него зависит ключ кеша.
|
|
11
|
+
*/
|
|
12
|
+
function parseQuestroomIdList(value) {
|
|
13
|
+
if (value == null || value === '')
|
|
14
|
+
return undefined;
|
|
15
|
+
const parts = Array.isArray(value) ? value : String(value).split(',');
|
|
16
|
+
const ids = [
|
|
17
|
+
...new Set(parts
|
|
18
|
+
.map((part) => Number(typeof part === 'string' ? part.trim() : part))
|
|
19
|
+
.filter((id) => Number.isInteger(id) && id > 0)),
|
|
20
|
+
].sort((a, b) => a - b);
|
|
21
|
+
if (!ids.length)
|
|
22
|
+
return undefined;
|
|
23
|
+
return ids.slice(0, MAX_QUESTROOM_IDS);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Id квестов, которыми надо сузить отчёт.
|
|
27
|
+
* Непустой `questroomIds` важнее одиночного `questroomId`.
|
|
28
|
+
* Пустой результат — фильтр по квесту не применять (все квесты локации/профиля).
|
|
29
|
+
*/
|
|
30
|
+
function effectiveQuestroomIds(query) {
|
|
31
|
+
const fromList = parseQuestroomIdList(query.questroomIds);
|
|
32
|
+
if (fromList === null || fromList === void 0 ? void 0 : fromList.length)
|
|
33
|
+
return fromList;
|
|
34
|
+
const single = Number(query.questroomId);
|
|
35
|
+
if (Number.isInteger(single) && single > 0)
|
|
36
|
+
return [single];
|
|
37
|
+
return [];
|
|
38
|
+
}
|