@hed-hog/contact 0.0.36 → 0.0.41

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 (47) hide show
  1. package/dist/contact-type/contact-type.service.d.ts.map +1 -1
  2. package/dist/contact-type/contact-type.service.js +1 -1
  3. package/dist/contact-type/contact-type.service.js.map +1 -1
  4. package/dist/contact.service.d.ts.map +1 -1
  5. package/dist/contact.service.js +1 -0
  6. package/dist/contact.service.js.map +1 -1
  7. package/dist/document-type/document-type.service.d.ts.map +1 -1
  8. package/dist/document-type/document-type.service.js +1 -1
  9. package/dist/document-type/document-type.service.js.map +1 -1
  10. package/dist/person/address/address.service.d.ts.map +1 -1
  11. package/dist/person/address/address.service.js +17 -1
  12. package/dist/person/address/address.service.js.map +1 -1
  13. package/dist/person/dto/create.dto.d.ts +2 -1
  14. package/dist/person/dto/create.dto.d.ts.map +1 -1
  15. package/dist/person/dto/create.dto.js +4 -1
  16. package/dist/person/dto/create.dto.js.map +1 -1
  17. package/dist/person/dto/update.dto.d.ts +26 -4
  18. package/dist/person/dto/update.dto.d.ts.map +1 -1
  19. package/dist/person/dto/update.dto.js +108 -5
  20. package/dist/person/dto/update.dto.js.map +1 -1
  21. package/dist/person/person-individual/person-individual.controller.d.ts +1 -5
  22. package/dist/person/person-individual/person-individual.controller.d.ts.map +1 -1
  23. package/dist/person/person-individual/person-individual.service.d.ts +1 -5
  24. package/dist/person/person-individual/person-individual.service.d.ts.map +1 -1
  25. package/dist/person/person-individual/person-individual.service.js +8 -4
  26. package/dist/person/person-individual/person-individual.service.js.map +1 -1
  27. package/dist/person/person.controller.d.ts +5 -10
  28. package/dist/person/person.controller.d.ts.map +1 -1
  29. package/dist/person/person.controller.js +6 -8
  30. package/dist/person/person.controller.js.map +1 -1
  31. package/dist/person/person.service.d.ts +7 -13
  32. package/dist/person/person.service.d.ts.map +1 -1
  33. package/dist/person/person.service.js +121 -13
  34. package/dist/person/person.service.js.map +1 -1
  35. package/hedhog/query/add-unique-address-type-locale.sql +3 -0
  36. package/hedhog/query/add-unique-contact-type-locale.sql +3 -0
  37. package/hedhog/query/add-unique-document-type-locale.sql +3 -0
  38. package/package.json +4 -5
  39. package/src/contact-type/contact-type.service.ts +1 -1
  40. package/src/contact.service.ts +1 -0
  41. package/src/document-type/document-type.service.ts +1 -1
  42. package/src/person/address/address.service.ts +9 -2
  43. package/src/person/dto/create.dto.ts +5 -3
  44. package/src/person/dto/update.dto.ts +75 -3
  45. package/src/person/person-individual/person-individual.service.ts +8 -7
  46. package/src/person/person.controller.ts +19 -18
  47. package/src/person/person.service.ts +132 -19
@@ -38,12 +38,27 @@ let PersonService = class PersonService {
38
38
  };
39
39
  }
40
40
  async list(paginationParams) {
41
+ var _a;
41
42
  const OR = [];
42
- if (paginationParams.search && !isNaN(+paginationParams.search)) {
43
- OR.push({ id: { equals: +paginationParams.search } });
43
+ const search = (_a = paginationParams.search) === null || _a === void 0 ? void 0 : _a.trim();
44
+ if (search) {
45
+ if (!isNaN(+search)) {
46
+ OR.push({ id: { equals: +search } });
47
+ }
48
+ OR.push({ name: { contains: search, mode: 'insensitive' } });
49
+ }
50
+ const where = {};
51
+ if (OR.length > 0) {
52
+ where.OR = OR;
53
+ }
54
+ if (paginationParams.type && paginationParams.type !== 'all') {
55
+ where.type = paginationParams.type;
56
+ }
57
+ if (paginationParams.status && paginationParams.status !== 'all') {
58
+ where.status = paginationParams.status;
44
59
  }
45
60
  return this.paginationService.paginate(this.prismaService.person, paginationParams, {
46
- where: OR.length > 0 ? { OR } : {},
61
+ where,
47
62
  include: {
48
63
  address: true,
49
64
  contact: true,
@@ -61,23 +76,116 @@ let PersonService = class PersonService {
61
76
  data,
62
77
  });
63
78
  }
64
- async update({ id, data }) {
65
- return this.prismaService.person.update({
66
- where: { id: id },
67
- data,
79
+ async update(id, data) {
80
+ const incomingContacts = data.contacts || [];
81
+ const incomingAddresses = data.addresses || [];
82
+ const incomingDocuments = data.documents || [];
83
+ const contactPrimaryMap = new Map();
84
+ for (const c of incomingContacts) {
85
+ if (c.is_primary) {
86
+ const key = String(c.contact_type_id);
87
+ contactPrimaryMap.set(key, (contactPrimaryMap.get(key) || 0) + 1);
88
+ }
89
+ }
90
+ for (const [_, count] of contactPrimaryMap.entries()) {
91
+ if (count > 1) {
92
+ throw new common_1.BadRequestException(`Não é permitido mais de um contato do tipo marcado como principal.`);
93
+ }
94
+ }
95
+ const addressPrimaryMap = new Map();
96
+ for (const a of incomingAddresses) {
97
+ if (a.is_primary) {
98
+ const key = String(a.address_type_id);
99
+ addressPrimaryMap.set(key, (addressPrimaryMap.get(key) || 0) + 1);
100
+ }
101
+ }
102
+ for (const [_, count] of addressPrimaryMap.entries()) {
103
+ if (count > 1) {
104
+ throw new common_1.BadRequestException(`Não é permitido mais de um endereço do mesmo tipo marcado como principal.`);
105
+ }
106
+ }
107
+ const documentPrimaryMap = new Map();
108
+ for (const d of incomingDocuments) {
109
+ if (d.is_primary) {
110
+ const key = String(d.document_type_id);
111
+ documentPrimaryMap.set(key, (documentPrimaryMap.get(key) || 0) + 1);
112
+ }
113
+ }
114
+ for (const [_, count] of documentPrimaryMap.entries()) {
115
+ if (count > 1) {
116
+ throw new common_1.BadRequestException(`Não é permitido mais de um documento do mesmo tipo marcado como principal.`);
117
+ }
118
+ }
119
+ return this.prismaService.$transaction(async (tx) => {
120
+ await tx.person.update({
121
+ where: { id },
122
+ data: {
123
+ name: data.name,
124
+ type: data.type,
125
+ status: data.status,
126
+ },
127
+ });
128
+ const existingContacts = await tx.contact.findMany({ where: { person_id: id } });
129
+ for (const c of incomingContacts) {
130
+ if (c.id) {
131
+ await tx.contact.update({ where: { id: c.id }, data: c });
132
+ }
133
+ else {
134
+ await tx.contact.create({ data: Object.assign(Object.assign({}, c), { person_id: id }) });
135
+ }
136
+ }
137
+ for (const old of existingContacts) {
138
+ if (!incomingContacts.find((c) => c.id === old.id)) {
139
+ await tx.contact.delete({ where: { id: old.id } });
140
+ }
141
+ }
142
+ const existingAddresses = await tx.address.findMany({ where: { person_id: id } });
143
+ for (const a of incomingAddresses) {
144
+ if (a.id) {
145
+ await tx.address.update({ where: { id: a.id }, data: a });
146
+ }
147
+ else {
148
+ await tx.address.create({ data: Object.assign(Object.assign({}, a), { person_id: id }) });
149
+ }
150
+ }
151
+ for (const old of existingAddresses) {
152
+ if (!incomingAddresses.find((a) => a.id === old.id)) {
153
+ await tx.address.delete({ where: { id: old.id } });
154
+ }
155
+ }
156
+ const existingDocuments = await tx.document.findMany({ where: { person_id: id } });
157
+ for (const d of incomingDocuments) {
158
+ if (d.id) {
159
+ await tx.document.update({ where: { id: d.id }, data: d });
160
+ }
161
+ else {
162
+ await tx.document.create({ data: Object.assign(Object.assign({}, d), { person_id: id }) });
163
+ }
164
+ }
165
+ for (const old of existingDocuments) {
166
+ if (!incomingDocuments.find((d) => d.id === old.id)) {
167
+ await tx.document.delete({ where: { id: old.id } });
168
+ }
169
+ }
170
+ return { success: true };
68
171
  });
69
172
  }
70
173
  async delete({ ids }) {
71
174
  if (ids == undefined || ids == null) {
72
175
  throw new common_1.BadRequestException('You must select at least one item to delete.');
73
176
  }
74
- return this.prismaService.person.deleteMany({
75
- where: {
76
- id: {
77
- in: ids,
177
+ return this.prismaService.$transaction([
178
+ this.prismaService.contact.deleteMany({ where: { person_id: { in: ids } } }),
179
+ this.prismaService.address.deleteMany({ where: { person_id: { in: ids } } }),
180
+ this.prismaService.document.deleteMany({ where: { person_id: { in: ids } } }),
181
+ this.prismaService.person.deleteMany({
182
+ where: {
183
+ id: {
184
+ in: ids,
185
+ },
78
186
  },
79
- },
80
- });
187
+ }),
188
+ ]);
81
189
  }
82
190
  };
83
191
  exports.PersonService = PersonService;
@@ -1 +1 @@
1
- {"version":3,"file":"person.service.js","sourceRoot":"","sources":["../../src/person/person.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,4DAA2E;AAC3E,oDAAoD;AACpD,2CAKwB;AAKjB,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,YAEmB,aAA4B,EAE5B,iBAAoC;QAFpC,kBAAa,GAAb,aAAa,CAAe;QAE5B,sBAAiB,GAAjB,iBAAiB,CAAmB;IACpD,CAAC;IAEJ,KAAK,CAAC,QAAQ;QACZ,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE;YACjC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC;YAClE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;YAC/D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;YAChE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC;SACnE,CAAC,CAAC;QAEH,OAAO;YACL,KAAK;YACL,UAAU;YACV,OAAO;YACP,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,gBAA+B;QACxC,MAAM,EAAE,GAAU,EAAE,CAAC;QAErB,IAAI,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAChE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CACpC,IAAI,CAAC,aAAa,CAAC,MAAM,EACzB,gBAAgB,EAChB;YACE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;YAClC,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf;SACF,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;SAClB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAe;QAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;YACtC,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAmC;QACxD,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;YACtC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;YACjB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAa;QAC7B,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,4BAAmB,CAC3B,8CAA8C,CAC/C,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE;gBACL,EAAE,EAAE;oBACF,EAAE,EAAE,GAAG;iBACR;aACF;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAjFY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,0BAAa,CAAC,CAAC,CAAA;IAEvC,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,kCAAiB,CAAC,CAAC,CAAA;qCADZ,0BAAa;QAET,kCAAiB;GAL5C,aAAa,CAiFzB"}
1
+ {"version":3,"file":"person.service.js","sourceRoot":"","sources":["../../src/person/person.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ -- Adiciona constraint UNIQUE composta para address_type_id e locale_id
2
+ ALTER TABLE address_type_locale
3
+ ADD CONSTRAINT address_type_locale_unique UNIQUE (address_type_id, locale_id);
@@ -0,0 +1,3 @@
1
+ -- Adiciona constraint UNIQUE composta para contact_type_id e locale_id
2
+ ALTER TABLE contact_type_locale
3
+ ADD CONSTRAINT contact_type_locale_unique UNIQUE (contact_type_id, locale_id);
@@ -0,0 +1,3 @@
1
+ -- Adiciona constraint UNIQUE composta para document_type_id e locale_id
2
+ ALTER TABLE document_type_locale
3
+ ADD CONSTRAINT document_type_locale_unique UNIQUE (document_type_id, locale_id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hed-hog/contact",
3
- "version": "0.0.36",
3
+ "version": "0.0.41",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "dependencies": {
@@ -9,13 +9,12 @@
9
9
  "@nestjs/core": "^11",
10
10
  "@nestjs/jwt": "^11",
11
11
  "@nestjs/mapped-types": "*",
12
- "@hed-hog/api": "0.0.3",
13
12
  "@hed-hog/api-pagination": "0.0.3",
14
- "@hed-hog/country": "0.0.9",
13
+ "@hed-hog/api-prisma": "0.0.4",
14
+ "@hed-hog/api": "0.0.3",
15
15
  "@hed-hog/api-locale": "0.0.10",
16
16
  "@hed-hog/api-mail": "0.0.7",
17
- "@hed-hog/admin": "0.0.129",
18
- "@hed-hog/api-prisma": "0.0.4"
17
+ "@hed-hog/admin": "0.0.130"
19
18
  },
20
19
  "exports": {
21
20
  ".": {
@@ -14,7 +14,7 @@ import { UpdateDTO } from './dto/update.dto';
14
14
  @Injectable()
15
15
  export class PersonContactTypeService {
16
16
  private readonly modelName = 'contact_type';
17
- private readonly foreignKey = 'type_id';
17
+ private readonly foreignKey = 'contact_type_id';
18
18
 
19
19
  constructor(
20
20
  @Inject(forwardRef(() => PrismaService))
@@ -67,6 +67,7 @@ export class ContactService {
67
67
 
68
68
  const person = await this.prismaService.person.create({
69
69
  data: {
70
+ name,
70
71
  type: type_id === 1 ? 'individual' : 'company',
71
72
  status: 'active',
72
73
  },
@@ -14,7 +14,7 @@ import { UpdateDTO } from './dto/update.dto';
14
14
  @Injectable()
15
15
  export class PersonDocumentTypeService {
16
16
  private readonly modelName = 'document_type';
17
- private readonly foreignKey = 'type_id';
17
+ private readonly foreignKey = 'document_type_id';
18
18
 
19
19
  constructor(
20
20
  @Inject(forwardRef(() => PrismaService))
@@ -16,10 +16,17 @@ export class PersonAddressService {
16
16
  ) {}
17
17
 
18
18
  async create(personId: number, data: CreateDTO) {
19
+ const { address_type_id, ...addressData } = data;
19
20
  return this.prismaService.address.create({
20
21
  data: {
21
- person_id: personId,
22
- ...data
22
+ ...addressData,
23
+ line2: addressData.line2 || '',
24
+ person: {
25
+ connect: { id: personId }
26
+ },
27
+ address_type: {
28
+ connect: { id: address_type_id }
29
+ }
23
30
  }
24
31
  });
25
32
  }
@@ -1,4 +1,4 @@
1
- import { IsEnum, IsOptional } from 'class-validator';
1
+ import { IsEnum, IsString } from 'class-validator';
2
2
 
3
3
  export enum PersonType {
4
4
  INDIVIDUAL = 'individual',
@@ -11,10 +11,12 @@ export enum PersonStatus {
11
11
  }
12
12
 
13
13
  export class CreateDTO {
14
+ @IsString()
15
+ name: string;
16
+
14
17
  @IsEnum(PersonType)
15
18
  type: PersonType;
16
19
 
17
- @IsOptional()
18
20
  @IsEnum(PersonStatus)
19
- status?: PersonStatus = PersonStatus.ACTIVE;
21
+ status: PersonStatus = PersonStatus.ACTIVE;
20
22
  }
@@ -1,4 +1,76 @@
1
- import { PartialType } from '@nestjs/mapped-types';
2
- import { CreateDTO } from './create.dto';
1
+ import { Type } from 'class-transformer';
2
+ import { IsArray, IsBoolean, IsInt, IsOptional, IsString, ValidateNested } from 'class-validator';
3
3
 
4
- export class UpdateDTO extends PartialType(CreateDTO) {}
4
+ export class UpdateAllContactDTO {
5
+ @IsOptional()
6
+ @IsInt()
7
+ id?: number;
8
+
9
+ @IsString()
10
+ value: string;
11
+
12
+ @IsBoolean()
13
+ is_primary: boolean;
14
+
15
+ @IsInt()
16
+ contact_type_id: number;
17
+ }
18
+
19
+ export class UpdateAllAddressDTO {
20
+ @IsOptional()
21
+ @IsInt()
22
+ id?: number;
23
+
24
+ @IsString()
25
+ line1: string;
26
+
27
+ @IsString()
28
+ city: string;
29
+
30
+ @IsString()
31
+ state: string;
32
+
33
+ @IsBoolean()
34
+ is_primary: boolean;
35
+
36
+ @IsInt()
37
+ address_type_id: number;
38
+ }
39
+
40
+ export class UpdateAllDocumentDTO {
41
+ @IsOptional()
42
+ @IsInt()
43
+ id?: number;
44
+
45
+ @IsString()
46
+ value: string;
47
+
48
+ @IsInt()
49
+ document_type_id: number;
50
+ }
51
+
52
+ export class UpdateAllPersonDTO {
53
+ @IsString()
54
+ name: string;
55
+
56
+ @IsString()
57
+ type: string;
58
+
59
+ @IsString()
60
+ status: string;
61
+
62
+ @IsArray()
63
+ @ValidateNested({ each: true })
64
+ @Type(() => UpdateAllContactDTO)
65
+ contacts: UpdateAllContactDTO[];
66
+
67
+ @IsArray()
68
+ @ValidateNested({ each: true })
69
+ @Type(() => UpdateAllAddressDTO)
70
+ addresses: UpdateAllAddressDTO[];
71
+
72
+ @IsArray()
73
+ @ValidateNested({ each: true })
74
+ @Type(() => UpdateAllDocumentDTO)
75
+ documents: UpdateAllDocumentDTO[];
76
+ }
@@ -7,13 +7,14 @@ import { UpdateDTO } from './dto/update.dto';
7
7
  export class PersonIndividualService {
8
8
  constructor(private readonly prismaService: PrismaService) {}
9
9
 
10
- async create(personId: number, data: CreateDTO) {
11
- return this.prismaService.person_individual.create({
12
- data: {
13
- id: personId,
14
- ...data
15
- }
16
- });
10
+ async create(personId: number, {birth_date, gender}: CreateDTO) {
11
+ // TODO: Once person_individual.id has a FK constraint to person.id,
12
+ // update this to use proper Prisma relations
13
+ return this.prismaService.$queryRaw`
14
+ INSERT INTO person_individual (id, birth_date, gender)
15
+ VALUES (${personId}, ${birth_date}, ${gender}::person_individual_gender_enum)
16
+ RETURNING *
17
+ ` as Promise<any>;
17
18
  }
18
19
 
19
20
  async get(personId: number) {
@@ -1,19 +1,20 @@
1
1
  import { DeleteDTO, Role } from '@hed-hog/api';
2
2
  import { Pagination } from '@hed-hog/api-pagination';
3
3
  import {
4
- Body,
5
- Controller,
6
- Delete,
7
- Get,
8
- Inject,
9
- Param,
10
- ParseIntPipe,
11
- Patch,
12
- Post,
13
- forwardRef
4
+ Body,
5
+ Controller,
6
+ Delete,
7
+ Get,
8
+ Inject,
9
+ Param,
10
+ ParseIntPipe,
11
+ Patch,
12
+ Post,
13
+ Query,
14
+ forwardRef
14
15
  } from '@nestjs/common';
15
16
  import { CreateDTO } from './dto/create.dto';
16
- import { UpdateDTO } from './dto/update.dto';
17
+ import { UpdateAllPersonDTO } from './dto/update.dto';
17
18
  import { PersonService } from './person.service';
18
19
 
19
20
  @Role()
@@ -30,8 +31,8 @@ export class PersonController {
30
31
  }
31
32
 
32
33
  @Get()
33
- async list(@Pagination() paginationParams) {
34
- return this.personService.list(paginationParams);
34
+ async list(@Pagination() paginationParams, @Query() filters) {
35
+ return this.personService.list({ ...paginationParams, ...filters });
35
36
  }
36
37
 
37
38
  @Get(':id')
@@ -45,11 +46,11 @@ export class PersonController {
45
46
  }
46
47
 
47
48
  @Patch(':id')
48
- async update(@Param('id', ParseIntPipe) id: number, @Body() data: UpdateDTO) {
49
- return this.personService.update({
50
- id,
51
- data
52
- });
49
+ async update(
50
+ @Param('id', ParseIntPipe) id: number,
51
+ @Body() data: UpdateAllPersonDTO
52
+ ) {
53
+ return this.personService.update(id, data);
53
54
  }
54
55
 
55
56
  @Delete()
@@ -2,13 +2,12 @@ import { DeleteDTO } from '@hed-hog/api';
2
2
  import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
3
3
  import { PrismaService } from '@hed-hog/api-prisma';
4
4
  import {
5
- BadRequestException,
6
- Inject,
7
- Injectable,
8
- forwardRef,
5
+ BadRequestException,
6
+ Inject,
7
+ Injectable,
8
+ forwardRef,
9
9
  } from '@nestjs/common';
10
10
  import { CreateDTO } from './dto/create.dto';
11
- import { UpdateDTO } from './dto/update.dto';
12
11
 
13
12
  @Injectable()
14
13
  export class PersonService {
@@ -37,18 +36,34 @@ export class PersonService {
37
36
  };
38
37
  }
39
38
 
40
- async list(paginationParams: PaginationDTO) {
39
+ async list(paginationParams: PaginationDTO & { type: string; status: string }) {
41
40
  const OR: any[] = [];
41
+ const search = paginationParams.search?.trim();
42
42
 
43
- if (paginationParams.search && !isNaN(+paginationParams.search)) {
44
- OR.push({ id: { equals: +paginationParams.search } });
43
+ if (search) {
44
+ if (!isNaN(+search)) {
45
+ OR.push({ id: { equals: +search } });
46
+ }
47
+ OR.push({ name: { contains: search, mode: 'insensitive' } });
48
+ }
49
+
50
+ const where: any = {};
51
+ if (OR.length > 0) {
52
+ where.OR = OR;
53
+ }
54
+
55
+ if (paginationParams.type && paginationParams.type !== 'all') {
56
+ where.type = paginationParams.type;
57
+ }
58
+ if (paginationParams.status && paginationParams.status !== 'all') {
59
+ where.status = paginationParams.status;
45
60
  }
46
61
 
47
62
  return this.paginationService.paginate(
48
63
  this.prismaService.person,
49
64
  paginationParams,
50
65
  {
51
- where: OR.length > 0 ? { OR } : {},
66
+ where,
52
67
  include: {
53
68
  address: true,
54
69
  contact: true,
@@ -70,10 +85,103 @@ export class PersonService {
70
85
  });
71
86
  }
72
87
 
73
- async update({ id, data }: { id: number; data: UpdateDTO }) {
74
- return this.prismaService.person.update({
75
- where: { id: id },
76
- data,
88
+ async update(id: number, data: any) {
89
+ const incomingContacts = data.contacts || [];
90
+ const incomingAddresses = data.addresses || [];
91
+ const incomingDocuments = data.documents || [];
92
+ const contactPrimaryMap = new Map();
93
+ for (const c of incomingContacts) {
94
+ if (c.is_primary) {
95
+ const key = String(c.contact_type_id);
96
+ contactPrimaryMap.set(key, (contactPrimaryMap.get(key) || 0) + 1);
97
+ }
98
+ }
99
+ for (const [_, count] of contactPrimaryMap.entries()) {
100
+ if (count > 1) {
101
+ throw new BadRequestException(`Não é permitido mais de um contato do tipo marcado como principal.`);
102
+ }
103
+ }
104
+
105
+ const addressPrimaryMap = new Map();
106
+ for (const a of incomingAddresses) {
107
+ if (a.is_primary) {
108
+ const key = String(a.address_type_id);
109
+ addressPrimaryMap.set(key, (addressPrimaryMap.get(key) || 0) + 1);
110
+ }
111
+ }
112
+ for (const [_, count] of addressPrimaryMap.entries()) {
113
+ if (count > 1) {
114
+ throw new BadRequestException(`Não é permitido mais de um endereço do mesmo tipo marcado como principal.`);
115
+ }
116
+ }
117
+
118
+ const documentPrimaryMap = new Map();
119
+ for (const d of incomingDocuments) {
120
+ if (d.is_primary) {
121
+ const key = String(d.document_type_id);
122
+ documentPrimaryMap.set(key, (documentPrimaryMap.get(key) || 0) + 1);
123
+ }
124
+ }
125
+ for (const [_, count] of documentPrimaryMap.entries()) {
126
+ if (count > 1) {
127
+ throw new BadRequestException(`Não é permitido mais de um documento do mesmo tipo marcado como principal.`);
128
+ }
129
+ }
130
+
131
+ return this.prismaService.$transaction(async (tx) => {
132
+ await tx.person.update({
133
+ where: { id },
134
+ data: {
135
+ name: data.name,
136
+ type: data.type,
137
+ status: data.status,
138
+ },
139
+ });
140
+
141
+ const existingContacts = await tx.contact.findMany({ where: { person_id: id } });
142
+ for (const c of incomingContacts) {
143
+ if (c.id) {
144
+ await tx.contact.update({ where: { id: c.id }, data: c });
145
+ } else {
146
+ await tx.contact.create({ data: { ...c, person_id: id } });
147
+ }
148
+ }
149
+
150
+ for (const old of existingContacts) {
151
+ if (!incomingContacts.find((c: any) => c.id === old.id)) {
152
+ await tx.contact.delete({ where: { id: old.id } });
153
+ }
154
+ }
155
+
156
+ const existingAddresses = await tx.address.findMany({ where: { person_id: id } });
157
+ for (const a of incomingAddresses) {
158
+ if (a.id) {
159
+ await tx.address.update({ where: { id: a.id }, data: a });
160
+ } else {
161
+ await tx.address.create({ data: { ...a, person_id: id } });
162
+ }
163
+ }
164
+ for (const old of existingAddresses) {
165
+ if (!incomingAddresses.find((a: any) => a.id === old.id)) {
166
+ await tx.address.delete({ where: { id: old.id } });
167
+ }
168
+ }
169
+
170
+ const existingDocuments = await tx.document.findMany({ where: { person_id: id } });
171
+ for (const d of incomingDocuments) {
172
+ if (d.id) {
173
+ await tx.document.update({ where: { id: d.id }, data: d });
174
+ } else {
175
+ await tx.document.create({ data: { ...d, person_id: id } });
176
+ }
177
+ }
178
+ for (const old of existingDocuments) {
179
+ if (!incomingDocuments.find((d: any) => d.id === old.id)) {
180
+ await tx.document.delete({ where: { id: old.id } });
181
+ }
182
+ }
183
+
184
+ return { success: true };
77
185
  });
78
186
  }
79
187
 
@@ -84,12 +192,17 @@ export class PersonService {
84
192
  );
85
193
  }
86
194
 
87
- return this.prismaService.person.deleteMany({
88
- where: {
89
- id: {
90
- in: ids,
195
+ return this.prismaService.$transaction([
196
+ this.prismaService.contact.deleteMany({ where: { person_id: { in: ids } } }),
197
+ this.prismaService.address.deleteMany({ where: { person_id: { in: ids } } }),
198
+ this.prismaService.document.deleteMany({ where: { person_id: { in: ids } } }),
199
+ this.prismaService.person.deleteMany({
200
+ where: {
201
+ id: {
202
+ in: ids,
203
+ },
91
204
  },
92
- },
93
- });
205
+ }),
206
+ ]);
94
207
  }
95
208
  }