@hed-hog/contact 0.0.299 → 0.0.301

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.
Files changed (81) hide show
  1. package/dist/contact.module.d.ts.map +1 -1
  2. package/dist/contact.module.js +2 -0
  3. package/dist/contact.module.js.map +1 -1
  4. package/dist/index.d.ts +3 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/person/person.service.js +350 -350
  9. package/dist/proposal/dto/proposal.dto.d.ts +152 -0
  10. package/dist/proposal/dto/proposal.dto.d.ts.map +1 -0
  11. package/dist/proposal/dto/proposal.dto.js +396 -0
  12. package/dist/proposal/dto/proposal.dto.js.map +1 -0
  13. package/dist/proposal/proposal-contract.subscriber.d.ts +11 -0
  14. package/dist/proposal/proposal-contract.subscriber.d.ts.map +1 -0
  15. package/dist/proposal/proposal-contract.subscriber.js +51 -0
  16. package/dist/proposal/proposal-contract.subscriber.js.map +1 -0
  17. package/dist/proposal/proposal-event.types.d.ts +122 -0
  18. package/dist/proposal/proposal-event.types.d.ts.map +1 -0
  19. package/dist/proposal/proposal-event.types.js +13 -0
  20. package/dist/proposal/proposal-event.types.js.map +1 -0
  21. package/dist/proposal/proposal.controller.d.ts +56 -0
  22. package/dist/proposal/proposal.controller.d.ts.map +1 -0
  23. package/dist/proposal/proposal.controller.js +191 -0
  24. package/dist/proposal/proposal.controller.js.map +1 -0
  25. package/dist/proposal/proposal.module.d.ts +3 -0
  26. package/dist/proposal/proposal.module.d.ts.map +1 -0
  27. package/dist/proposal/proposal.module.js +32 -0
  28. package/dist/proposal/proposal.module.js.map +1 -0
  29. package/dist/proposal/proposal.service.d.ts +95 -0
  30. package/dist/proposal/proposal.service.d.ts.map +1 -0
  31. package/dist/proposal/proposal.service.js +1914 -0
  32. package/dist/proposal/proposal.service.js.map +1 -0
  33. package/dist/proposal/proposal.service.spec.d.ts +2 -0
  34. package/dist/proposal/proposal.service.spec.d.ts.map +1 -0
  35. package/dist/proposal/proposal.service.spec.js +187 -0
  36. package/dist/proposal/proposal.service.spec.js.map +1 -0
  37. package/hedhog/data/dashboard.yaml +6 -0
  38. package/hedhog/data/dashboard_component.yaml +87 -0
  39. package/hedhog/data/dashboard_component_role.yaml +55 -0
  40. package/hedhog/data/dashboard_item.yaml +95 -0
  41. package/hedhog/data/dashboard_role.yaml +6 -0
  42. package/hedhog/data/route.yaml +112 -68
  43. package/hedhog/frontend/app/dashboard/_components/dashboard-widgets.tsx.ejs +508 -0
  44. package/hedhog/frontend/app/dashboard/_components/use-crm-dashboard-data.ts.ejs +104 -0
  45. package/hedhog/frontend/app/dashboard/page.tsx.ejs +37 -431
  46. package/hedhog/frontend/app/pipeline/_components/lead-detail-sheet.tsx.ejs +252 -209
  47. package/hedhog/frontend/app/pipeline/_components/lead-proposals-tab.tsx.ejs +1584 -0
  48. package/hedhog/frontend/messages/en.json +136 -42
  49. package/hedhog/frontend/messages/pt.json +135 -41
  50. package/hedhog/frontend/widgets/next-actions.tsx.ejs +40 -0
  51. package/hedhog/frontend/widgets/overview-kpis.tsx.ejs +47 -0
  52. package/hedhog/frontend/widgets/owner-performance.tsx.ejs +42 -0
  53. package/hedhog/frontend/widgets/quick-access.tsx.ejs +29 -0
  54. package/hedhog/frontend/widgets/source-breakdown.tsx.ejs +40 -0
  55. package/hedhog/frontend/widgets/stage-distribution.tsx.ejs +40 -0
  56. package/hedhog/frontend/widgets/top-owners.tsx.ejs +42 -0
  57. package/hedhog/frontend/widgets/unattended.tsx.ejs +40 -0
  58. package/hedhog/table/crm_activity.yaml +68 -68
  59. package/hedhog/table/crm_stage_history.yaml +34 -34
  60. package/hedhog/table/person_company.yaml +27 -27
  61. package/hedhog/table/proposal.yaml +112 -0
  62. package/hedhog/table/proposal_approval.yaml +63 -0
  63. package/hedhog/table/proposal_document.yaml +77 -0
  64. package/hedhog/table/proposal_item.yaml +64 -0
  65. package/hedhog/table/proposal_revision.yaml +78 -0
  66. package/package.json +6 -5
  67. package/src/contact.module.ts +2 -0
  68. package/src/index.ts +3 -0
  69. package/src/person/dto/account.dto.ts +100 -100
  70. package/src/person/dto/activity.dto.ts +54 -54
  71. package/src/person/dto/dashboard-query.dto.ts +25 -25
  72. package/src/person/dto/followup-query.dto.ts +25 -25
  73. package/src/person/dto/reports-query.dto.ts +25 -25
  74. package/src/person/person.controller.ts +176 -176
  75. package/src/person/person.service.ts +4825 -4825
  76. package/src/proposal/dto/proposal.dto.ts +341 -0
  77. package/src/proposal/proposal-contract.subscriber.ts +43 -0
  78. package/src/proposal/proposal-event.types.ts +130 -0
  79. package/src/proposal/proposal.controller.ts +168 -0
  80. package/src/proposal/proposal.module.ts +19 -0
  81. package/src/proposal/proposal.service.ts +2525 -0
@@ -0,0 +1,341 @@
1
+ import { getLocaleText } from '@hed-hog/api-locale';
2
+ import { PartialType } from '@nestjs/mapped-types';
3
+ import { Type } from 'class-transformer';
4
+ import {
5
+ IsArray,
6
+ IsBoolean,
7
+ IsDateString,
8
+ IsEnum,
9
+ IsInt,
10
+ IsNotEmpty,
11
+ IsNumber,
12
+ IsObject,
13
+ IsOptional,
14
+ IsString,
15
+ MaxLength,
16
+ Min,
17
+ ValidateNested,
18
+ } from 'class-validator';
19
+
20
+ export enum ProposalStatus {
21
+ DRAFT = 'draft',
22
+ PENDING_APPROVAL = 'pending_approval',
23
+ APPROVED = 'approved',
24
+ REJECTED = 'rejected',
25
+ CANCELLED = 'cancelled',
26
+ EXPIRED = 'expired',
27
+ CONTRACT_GENERATED = 'contract_generated',
28
+ }
29
+
30
+ export enum ProposalContractCategory {
31
+ EMPLOYEE = 'employee',
32
+ CONTRACTOR = 'contractor',
33
+ CLIENT = 'client',
34
+ SUPPLIER = 'supplier',
35
+ VENDOR = 'vendor',
36
+ PARTNER = 'partner',
37
+ INTERNAL = 'internal',
38
+ OTHER = 'other',
39
+ }
40
+
41
+ export enum ProposalContractType {
42
+ CLT = 'clt',
43
+ PJ = 'pj',
44
+ FREELANCER_AGREEMENT = 'freelancer_agreement',
45
+ SERVICE_AGREEMENT = 'service_agreement',
46
+ FIXED_TERM = 'fixed_term',
47
+ RECURRING_SERVICE = 'recurring_service',
48
+ NDA = 'nda',
49
+ AMENDMENT = 'amendment',
50
+ ADDENDUM = 'addendum',
51
+ OTHER = 'other',
52
+ }
53
+
54
+ export enum ProposalBillingModel {
55
+ TIME_AND_MATERIAL = 'time_and_material',
56
+ MONTHLY_RETAINER = 'monthly_retainer',
57
+ FIXED_PRICE = 'fixed_price',
58
+ }
59
+
60
+ export enum ProposalGenerationMode {
61
+ MANUAL = 'manual',
62
+ AI_ASSISTED = 'ai_assisted',
63
+ DUPLICATED = 'duplicated',
64
+ IMPORTED = 'imported',
65
+ }
66
+
67
+ export enum ProposalItemType {
68
+ SERVICE = 'service',
69
+ PRODUCT = 'product',
70
+ FEE = 'fee',
71
+ DISCOUNT = 'discount',
72
+ NOTE = 'note',
73
+ OTHER = 'other',
74
+ }
75
+
76
+ export enum ProposalTermType {
77
+ VALUE = 'value',
78
+ PAYMENT = 'payment',
79
+ REVENUE = 'revenue',
80
+ FINE = 'fine',
81
+ OTHER = 'other',
82
+ }
83
+
84
+ export enum ProposalRecurrence {
85
+ ONE_TIME = 'one_time',
86
+ MONTHLY = 'monthly',
87
+ QUARTERLY = 'quarterly',
88
+ YEARLY = 'yearly',
89
+ OTHER = 'other',
90
+ }
91
+
92
+ export enum ProposalDocumentType {
93
+ SOURCE_UPLOAD = 'source_upload',
94
+ GENERATED_PDF = 'generated_pdf',
95
+ APPROVAL_ATTACHMENT = 'approval_attachment',
96
+ SIGNED_COPY = 'signed_copy',
97
+ ATTACHMENT = 'attachment',
98
+ OTHER = 'other',
99
+ }
100
+
101
+ export enum ProposalDocumentSourceKind {
102
+ MANUAL = 'manual',
103
+ GENERATED = 'generated',
104
+ IMPORTED = 'imported',
105
+ AI_ASSISTED = 'ai_assisted',
106
+ }
107
+
108
+ export enum ProposalDocumentExtractionStatus {
109
+ PENDING = 'pending',
110
+ PROCESSING = 'processing',
111
+ COMPLETED = 'completed',
112
+ FAILED = 'failed',
113
+ SKIPPED = 'skipped',
114
+ }
115
+
116
+ export class ProposalItemDto {
117
+ @IsOptional()
118
+ @IsEnum(ProposalItemType)
119
+ item_type?: ProposalItemType;
120
+
121
+ @IsOptional()
122
+ @IsEnum(ProposalTermType)
123
+ term_type?: ProposalTermType;
124
+
125
+ @IsString()
126
+ @IsNotEmpty()
127
+ @MaxLength(180)
128
+ name: string;
129
+
130
+ @IsOptional()
131
+ @IsString()
132
+ description?: string | null;
133
+
134
+ @IsOptional()
135
+ @IsNumber()
136
+ quantity?: number;
137
+
138
+ @IsOptional()
139
+ @IsInt()
140
+ unit_amount_cents?: number;
141
+
142
+ @IsOptional()
143
+ @IsInt()
144
+ total_amount_cents?: number;
145
+
146
+ @IsOptional()
147
+ @IsEnum(ProposalRecurrence)
148
+ recurrence?: ProposalRecurrence;
149
+
150
+ @IsOptional()
151
+ @IsInt()
152
+ @Min(1)
153
+ due_day?: number | null;
154
+
155
+ @IsOptional()
156
+ @IsDateString()
157
+ start_date?: string | null;
158
+
159
+ @IsOptional()
160
+ @IsDateString()
161
+ end_date?: string | null;
162
+
163
+ @IsOptional()
164
+ @IsObject()
165
+ metadata_json?: Record<string, any> | null;
166
+ }
167
+
168
+ export class ProposalDocumentDto {
169
+ @IsOptional()
170
+ @IsEnum(ProposalDocumentType)
171
+ document_type?: ProposalDocumentType;
172
+
173
+ @IsOptional()
174
+ @IsInt()
175
+ file_id?: number | null;
176
+
177
+ @IsString()
178
+ @IsNotEmpty()
179
+ @MaxLength(200)
180
+ file_name: string;
181
+
182
+ @IsString()
183
+ @IsNotEmpty()
184
+ @MaxLength(120)
185
+ mime_type: string;
186
+
187
+ @IsOptional()
188
+ @IsString()
189
+ file_content_base64?: string | null;
190
+
191
+ @IsOptional()
192
+ @IsEnum(ProposalDocumentSourceKind)
193
+ source_kind?: ProposalDocumentSourceKind;
194
+
195
+ @IsOptional()
196
+ @IsEnum(ProposalDocumentExtractionStatus)
197
+ extraction_status?: ProposalDocumentExtractionStatus;
198
+
199
+ @IsOptional()
200
+ @IsString()
201
+ extraction_summary?: string | null;
202
+
203
+ @IsOptional()
204
+ @IsString()
205
+ notes?: string | null;
206
+ }
207
+
208
+ export class CreateProposalDto {
209
+ @IsInt({
210
+ message: (args) =>
211
+ getLocaleText('validation.personIdMustBeNumber', args.value),
212
+ })
213
+ person_id: number;
214
+
215
+ @IsOptional()
216
+ @IsString()
217
+ @MaxLength(40)
218
+ code?: string;
219
+
220
+ @IsString()
221
+ @IsNotEmpty()
222
+ @MaxLength(180)
223
+ title: string;
224
+
225
+ @IsOptional()
226
+ @IsEnum(ProposalStatus)
227
+ status?: ProposalStatus;
228
+
229
+ @IsOptional()
230
+ @IsEnum(ProposalContractCategory)
231
+ contract_category?: ProposalContractCategory;
232
+
233
+ @IsOptional()
234
+ @IsEnum(ProposalContractType)
235
+ contract_type?: ProposalContractType;
236
+
237
+ @IsOptional()
238
+ @IsEnum(ProposalBillingModel)
239
+ billing_model?: ProposalBillingModel;
240
+
241
+ @IsOptional()
242
+ @IsString()
243
+ currency_code?: string;
244
+
245
+ @IsOptional()
246
+ @IsDateString()
247
+ valid_from?: string | null;
248
+
249
+ @IsOptional()
250
+ @IsDateString()
251
+ valid_until?: string | null;
252
+
253
+ @IsOptional()
254
+ @IsInt()
255
+ subtotal_amount_cents?: number;
256
+
257
+ @IsOptional()
258
+ @IsInt()
259
+ discount_amount_cents?: number;
260
+
261
+ @IsOptional()
262
+ @IsInt()
263
+ tax_amount_cents?: number;
264
+
265
+ @IsOptional()
266
+ @IsInt()
267
+ total_amount_cents?: number;
268
+
269
+ @IsOptional()
270
+ @IsString()
271
+ notes?: string | null;
272
+
273
+ @IsOptional()
274
+ @IsInt()
275
+ owner_user_id?: number | null;
276
+
277
+ @IsOptional()
278
+ @IsEnum(ProposalGenerationMode)
279
+ generation_mode?: ProposalGenerationMode;
280
+
281
+ @IsOptional()
282
+ @IsString()
283
+ summary?: string | null;
284
+
285
+ @IsOptional()
286
+ @IsString()
287
+ content_html?: string | null;
288
+
289
+ @IsOptional()
290
+ @IsObject()
291
+ snapshot_json?: Record<string, any> | null;
292
+
293
+ @IsOptional()
294
+ @IsArray()
295
+ @ValidateNested({ each: true })
296
+ @Type(() => ProposalItemDto)
297
+ items?: ProposalItemDto[];
298
+
299
+ @IsOptional()
300
+ @IsArray()
301
+ @ValidateNested({ each: true })
302
+ @Type(() => ProposalDocumentDto)
303
+ documents?: ProposalDocumentDto[];
304
+ }
305
+
306
+ export class UpdateProposalDto extends PartialType(CreateProposalDto) {
307
+ @IsOptional()
308
+ @IsBoolean()
309
+ create_new_revision?: boolean;
310
+ }
311
+
312
+ export class SubmitProposalDto {
313
+ @IsOptional()
314
+ @IsInt()
315
+ approver_user_id?: number | null;
316
+
317
+ @IsOptional()
318
+ @IsString()
319
+ note?: string | null;
320
+ }
321
+
322
+ export class ProposalDecisionDto {
323
+ @IsOptional()
324
+ @IsString()
325
+ note?: string | null;
326
+ }
327
+
328
+ export class ProposalListQueryDto {
329
+ @IsOptional()
330
+ @IsString()
331
+ search?: string;
332
+
333
+ @IsOptional()
334
+ @IsEnum(ProposalStatus)
335
+ status?: ProposalStatus;
336
+
337
+ @IsOptional()
338
+ @Type(() => Number)
339
+ @IsInt()
340
+ person_id?: number;
341
+ }
@@ -0,0 +1,43 @@
1
+ import { IntegrationDeveloperApiService } from '@hed-hog/core';
2
+ import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
3
+ import { ProposalService } from './proposal.service';
4
+
5
+ @Injectable()
6
+ export class ProposalContractSubscriber implements OnModuleInit {
7
+ private readonly logger = new Logger(ProposalContractSubscriber.name);
8
+
9
+ constructor(
10
+ private readonly integrationApi: IntegrationDeveloperApiService,
11
+ private readonly proposalService: ProposalService,
12
+ ) {}
13
+
14
+ onModuleInit(): void {
15
+ this.integrationApi.subscribe({
16
+ eventName: 'operations.contract.created',
17
+ consumerName: 'contact.proposal-conversion-tracker',
18
+ priority: 10,
19
+ handler: async (event) => {
20
+ const payload = (event.payload || {}) as any;
21
+ const proposalId = Number(
22
+ payload.proposalId || payload.contract?.originId || 0,
23
+ );
24
+
25
+ if (!Number.isInteger(proposalId) || proposalId <= 0) {
26
+ this.logger.warn(
27
+ `Ignoring ${event.eventName} because no proposalId was provided.`,
28
+ );
29
+ return;
30
+ }
31
+
32
+ if (String(payload.contract?.originType || '') !== 'crm_proposal') {
33
+ this.logger.debug(
34
+ `Ignoring ${event.eventName} for proposal ${proposalId} because originType is ${payload.contract?.originType || 'unknown'}.`,
35
+ );
36
+ return;
37
+ }
38
+
39
+ await this.proposalService.markConvertedFromIntegration(payload);
40
+ },
41
+ });
42
+ }
43
+ }
@@ -0,0 +1,130 @@
1
+ export const PROPOSAL_EVENT_NAMES = {
2
+ CREATED: 'contact.proposal.created',
3
+ SENT: 'contact.proposal.sent',
4
+ APPROVED: 'contact.proposal.approved',
5
+ REJECTED: 'contact.proposal.rejected',
6
+ CANCELLED: 'contact.proposal.cancelled',
7
+ CONVERT_REQUESTED: 'contact.proposal.convert_requested',
8
+ CONVERTED: 'contact.proposal.converted',
9
+ } as const;
10
+
11
+ export type ProposalLifecycleEventName =
12
+ (typeof PROPOSAL_EVENT_NAMES)[keyof typeof PROPOSAL_EVENT_NAMES];
13
+
14
+ export interface ProposalSourceReference {
15
+ sourceModule: 'contact';
16
+ sourceEntity: 'proposal';
17
+ sourceId: string;
18
+ source_module: 'contact';
19
+ source_entity: 'proposal';
20
+ source_id: string;
21
+ }
22
+
23
+ export interface ProposalCommercialTermsSnapshot {
24
+ contractCategory: string | null;
25
+ contractType: string | null;
26
+ billingModel: string | null;
27
+ validFrom: string | null;
28
+ validUntil: string | null;
29
+ summary: string | null;
30
+ notes: string | null;
31
+ }
32
+
33
+ export interface ProposalItemSummary {
34
+ id: number | null;
35
+ name: string;
36
+ description: string | null;
37
+ itemType: string | null;
38
+ termType: string | null;
39
+ quantity: number;
40
+ unitAmountCents: number;
41
+ totalAmountCents: number;
42
+ amount: number;
43
+ recurrence: string | null;
44
+ dueDay: number | null;
45
+ }
46
+
47
+ export interface ProposalPartySnapshot {
48
+ id: number | null;
49
+ name: string | null;
50
+ tradeName: string | null;
51
+ email: string | null;
52
+ phone: string | null;
53
+ document: string | null;
54
+ type: string | null;
55
+ }
56
+
57
+ export interface ProposalRevisionSnapshot {
58
+ id: number | null;
59
+ revisionNumber: number;
60
+ title: string | null;
61
+ summary: string | null;
62
+ contentHtml: string | null;
63
+ submittedAt: string | null;
64
+ approvedAt: string | null;
65
+ }
66
+
67
+ export interface ProposalContractSnapshot {
68
+ contractId: number | null;
69
+ code: string | null;
70
+ name: string | null;
71
+ status: string | null;
72
+ url: string | null;
73
+ }
74
+
75
+ export interface ProposalLifecycleEventPayload extends ProposalSourceReference {
76
+ eventName: ProposalLifecycleEventName;
77
+ eventKey: string;
78
+ correlationId: string;
79
+ proposalId: number;
80
+ proposalRevisionId: number | null;
81
+ approvedByUserId: number | null;
82
+ dealId: number | null;
83
+ personId: number | null;
84
+ companyId: number | null;
85
+ customerIds: {
86
+ personId: number | null;
87
+ companyId: number | null;
88
+ };
89
+ code: string | null;
90
+ title: string | null;
91
+ version: number;
92
+ status: string | null;
93
+ approvedAt: string | null;
94
+ validUntil: string | null;
95
+ currency: string;
96
+ proposal: {
97
+ code: string | null;
98
+ title: string | null;
99
+ status: string | null;
100
+ contractCategory: string | null;
101
+ contractType: string | null;
102
+ billingModel: string | null;
103
+ currencyCode: string | null;
104
+ validFrom: string | null;
105
+ validUntil: string | null;
106
+ subtotalAmountCents: number;
107
+ discountAmountCents: number;
108
+ taxAmountCents: number;
109
+ totalAmountCents: number;
110
+ totalAmount: number;
111
+ notes: string | null;
112
+ };
113
+ subtotal: number;
114
+ subtotalCents: number;
115
+ discount: number;
116
+ discountCents: number;
117
+ tax: number;
118
+ taxCents: number;
119
+ total: number;
120
+ totalCents: number;
121
+ commercialTerms: ProposalCommercialTermsSnapshot;
122
+ itemsSummary: ProposalItemSummary[];
123
+ items: ProposalItemSummary[];
124
+ person: ProposalPartySnapshot | null;
125
+ revision: ProposalRevisionSnapshot | null;
126
+ contract: ProposalContractSnapshot | null;
127
+ triggeredByUserId: number | null;
128
+ emittedAt: string;
129
+ locale: string | null;
130
+ }
@@ -0,0 +1,168 @@
1
+ import { DeleteDTO, Role, User } from '@hed-hog/api';
2
+ import { Locale } from '@hed-hog/api-locale';
3
+ import { Pagination } from '@hed-hog/api-pagination';
4
+ import {
5
+ Body,
6
+ Controller,
7
+ Delete,
8
+ Get,
9
+ Param,
10
+ ParseIntPipe,
11
+ Patch,
12
+ Post,
13
+ Query,
14
+ } from '@nestjs/common';
15
+ import {
16
+ CreateProposalDto,
17
+ ProposalDecisionDto,
18
+ ProposalListQueryDto,
19
+ SubmitProposalDto,
20
+ UpdateProposalDto,
21
+ } from './dto/proposal.dto';
22
+ import { ProposalService } from './proposal.service';
23
+
24
+ @Role()
25
+ @Controller('proposal')
26
+ export class ProposalController {
27
+ constructor(private readonly proposalService: ProposalService) {}
28
+
29
+ @Get()
30
+ async list(
31
+ @Pagination() paginationParams,
32
+ @Query() query: ProposalListQueryDto,
33
+ ) {
34
+ return this.proposalService.list({
35
+ ...paginationParams,
36
+ ...query,
37
+ });
38
+ }
39
+
40
+ @Get('stats')
41
+ async getStats() {
42
+ return this.proposalService.getStats();
43
+ }
44
+
45
+ @Get(':id')
46
+ async getById(
47
+ @Param('id', ParseIntPipe) id: number,
48
+ @Locale() locale: string,
49
+ ) {
50
+ return this.proposalService.getById(id, locale);
51
+ }
52
+
53
+ @Post(':id/generate-pdf')
54
+ async generateDocument(
55
+ @Param('id', ParseIntPipe) id: number,
56
+ @Locale() locale: string,
57
+ @User() user,
58
+ ) {
59
+ return this.proposalService.generateDocument(
60
+ id,
61
+ locale,
62
+ Number(user?.id || 0),
63
+ );
64
+ }
65
+
66
+ @Post()
67
+ async create(
68
+ @Body() body: CreateProposalDto,
69
+ @Locale() locale: string,
70
+ @User() user,
71
+ ) {
72
+ return this.proposalService.create(body, locale, Number(user?.id || 0));
73
+ }
74
+
75
+ @Patch(':id')
76
+ async update(
77
+ @Param('id', ParseIntPipe) id: number,
78
+ @Body() body: UpdateProposalDto,
79
+ @Locale() locale: string,
80
+ @User() user,
81
+ ) {
82
+ return this.proposalService.update(id, body, locale, Number(user?.id || 0));
83
+ }
84
+
85
+ @Post(':id/submit')
86
+ async submitForApproval(
87
+ @Param('id', ParseIntPipe) id: number,
88
+ @Body() body: SubmitProposalDto,
89
+ @Locale() locale: string,
90
+ @User() user,
91
+ ) {
92
+ return this.proposalService.submitForApproval(
93
+ id,
94
+ body,
95
+ locale,
96
+ Number(user?.id || 0),
97
+ );
98
+ }
99
+
100
+ @Post(':id/send')
101
+ async send(
102
+ @Param('id', ParseIntPipe) id: number,
103
+ @Body() body: SubmitProposalDto,
104
+ @Locale() locale: string,
105
+ @User() user,
106
+ ) {
107
+ return this.proposalService.submitForApproval(
108
+ id,
109
+ body,
110
+ locale,
111
+ Number(user?.id || 0),
112
+ );
113
+ }
114
+
115
+ @Post(':id/approve')
116
+ async approve(
117
+ @Param('id', ParseIntPipe) id: number,
118
+ @Body() body: ProposalDecisionDto,
119
+ @Locale() locale: string,
120
+ @User() user,
121
+ ) {
122
+ return this.proposalService.approve(id, body, locale, Number(user?.id || 0));
123
+ }
124
+
125
+ @Post(':id/reject')
126
+ async reject(
127
+ @Param('id', ParseIntPipe) id: number,
128
+ @Body() body: ProposalDecisionDto,
129
+ @Locale() locale: string,
130
+ @User() user,
131
+ ) {
132
+ return this.proposalService.reject(id, body, locale, Number(user?.id || 0));
133
+ }
134
+
135
+ @Post(':id/cancel')
136
+ async cancel(
137
+ @Param('id', ParseIntPipe) id: number,
138
+ @Body() body: ProposalDecisionDto,
139
+ @Locale() locale: string,
140
+ @User() user,
141
+ ) {
142
+ return this.proposalService.cancel(id, body, locale, Number(user?.id || 0));
143
+ }
144
+
145
+ @Post(':id/convert')
146
+ async requestConversion(
147
+ @Param('id', ParseIntPipe) id: number,
148
+ @Body() body: ProposalDecisionDto,
149
+ @Locale() locale: string,
150
+ @User() user,
151
+ ) {
152
+ return this.proposalService.requestConversion(
153
+ id,
154
+ body,
155
+ locale,
156
+ Number(user?.id || 0),
157
+ );
158
+ }
159
+
160
+ @Delete()
161
+ async remove(
162
+ @Body() body: DeleteDTO,
163
+ @Locale() locale: string,
164
+ @User() user,
165
+ ) {
166
+ return this.proposalService.remove(body, locale, Number(user?.id || 0));
167
+ }
168
+ }
@@ -0,0 +1,19 @@
1
+ import { PaginationModule } from '@hed-hog/api-pagination';
2
+ import { PrismaModule } from '@hed-hog/api-prisma';
3
+ import { CoreModule } from '@hed-hog/core';
4
+ import { forwardRef, Module } from '@nestjs/common';
5
+ import { ProposalContractSubscriber } from './proposal-contract.subscriber';
6
+ import { ProposalController } from './proposal.controller';
7
+ import { ProposalService } from './proposal.service';
8
+
9
+ @Module({
10
+ imports: [
11
+ forwardRef(() => CoreModule),
12
+ forwardRef(() => PrismaModule),
13
+ forwardRef(() => PaginationModule),
14
+ ],
15
+ controllers: [ProposalController],
16
+ providers: [ProposalService, ProposalContractSubscriber],
17
+ exports: [ProposalService],
18
+ })
19
+ export class ProposalModule {}