1
1
import { z } from 'zod' ;
2
2
import { Injectable } from '@nestjs/common' ;
3
- import * as qs from 'qs' ;
4
3
import { Prisma } from '@prisma/client' ;
5
4
import { DefaultArgs } from '@prisma/client/runtime/library' ;
6
-
7
5
import { PrismaService } from '../prisma/prisma.service' ;
8
6
import {
7
+ ComplexSearchSchema ,
9
8
CreateShelterSchema ,
10
9
FullUpdateShelterSchema ,
11
10
UpdateShelterSchema ,
12
- } from './types/types' ;
13
- import { SearchSchema } from '../types' ;
14
- import { ShelterSearch , parseTagResponse } from './ShelterSearch' ;
15
- import { SupplyPriority } from '../supply/types' ;
16
- import { IFilterFormProps } from './types/search.types' ;
11
+ } from './types' ;
12
+ import { SeachQueryProps } from '@/decorators/search-query/types' ;
13
+ import { SupplyPriority } from 'src/supply/types' ;
17
14
18
15
@Injectable ( )
19
16
export class ShelterService {
20
- private voluntaryIds : string [ ] = [ ] ;
21
-
22
- constructor ( private readonly prismaService : PrismaService ) {
23
- this . loadVoluntaryIds ( ) ;
24
- }
17
+ constructor ( private readonly prismaService : PrismaService ) { }
25
18
26
19
async store ( body : z . infer < typeof CreateShelterSchema > ) {
27
20
const payload = CreateShelterSchema . parse ( body ) ;
@@ -84,7 +77,6 @@ export class ShelterService {
84
77
} ,
85
78
select : {
86
79
priority : true ,
87
- quantity : true ,
88
80
supply : {
89
81
select : {
90
82
id : true ,
@@ -110,82 +102,229 @@ export class ShelterService {
110
102
return data ;
111
103
}
112
104
113
- async index ( query : any ) {
114
- const {
115
- order,
116
- orderBy,
117
- page,
118
- perPage,
119
- search : searchQuery ,
120
- } = SearchSchema . parse ( query ) ;
121
- const queryData = qs . parse ( searchQuery ) as unknown as IFilterFormProps ;
122
- const { query : where } = new ShelterSearch ( this . prismaService , queryData ) ;
123
- const count = await this . prismaService . shelter . count ( { where } ) ;
124
-
125
- const take = perPage ;
126
- const skip = perPage * ( page - 1 ) ;
127
-
128
- const whereData : Prisma . ShelterFindManyArgs < DefaultArgs > = {
129
- take,
130
- skip,
131
- orderBy : { [ orderBy ] : order } ,
132
- where,
133
- } ;
105
+ async index ( props : SeachQueryProps ) {
106
+ const { handleSearch } = props ;
107
+
108
+ return await handleSearch < Prisma . ShelterSelect < DefaultArgs > > (
109
+ this . prismaService . shelter ,
110
+ {
111
+ select : {
112
+ id : true ,
113
+ name : true ,
114
+ pix : true ,
115
+ address : true ,
116
+ capacity : true ,
117
+ contact : true ,
118
+ petFriendly : true ,
119
+ shelteredPeople : true ,
120
+ prioritySum : true ,
121
+ verified : true ,
122
+ latitude : true ,
123
+ longitude : true ,
124
+ createdAt : true ,
125
+ updatedAt : true ,
126
+ shelterSupplies : {
127
+ where : {
128
+ priority : {
129
+ gt : SupplyPriority . UnderControl ,
130
+ } ,
131
+ } ,
132
+ select : {
133
+ priority : true ,
134
+ supply : {
135
+ select : {
136
+ id : true ,
137
+ name : true ,
138
+ supplyCategory : {
139
+ select : {
140
+ id : true ,
141
+ name : true ,
142
+ } ,
143
+ } ,
144
+ createdAt : true ,
145
+ updatedAt : true ,
146
+ } ,
147
+ } ,
148
+ } ,
149
+ } ,
150
+ } ,
151
+ } ,
152
+ ) ;
153
+ }
154
+
155
+ async search ( props : z . infer < typeof ComplexSearchSchema > ) {
156
+ const payload = ComplexSearchSchema . parse ( {
157
+ ...props ,
158
+ supplyCategories :
159
+ typeof props [ 'supplyCategories[]' ] === 'string'
160
+ ? [ props [ 'supplyCategories[]' ] ]
161
+ : props [ 'supplyCategories[]' ] ,
162
+ supplies :
163
+ typeof props [ 'supplies[]' ] === 'string'
164
+ ? [ props [ 'supplies[]' ] ]
165
+ : props [ 'supplies[]' ] ,
166
+ } ) ;
167
+
168
+ const shelterStatusFilter = this . addShelterStatusFilter ( payload ) ;
169
+ const where = this . mountWhereFilter ( payload ) ;
170
+ const take = payload . perPage ;
171
+ const skip = payload . perPage * ( payload . page - 1 ) ;
172
+
173
+ if ( shelterStatusFilter . length > 0 ) {
174
+ where [ 'AND' ] . push ( {
175
+ OR : shelterStatusFilter ,
176
+ } ) ;
177
+ }
178
+
179
+ const count = await this . prismaService . shelter . count ( {
180
+ where : where ,
181
+ } ) ;
134
182
135
183
const results = await this . prismaService . shelter . findMany ( {
136
- ...whereData ,
184
+ where : where ,
185
+ orderBy : {
186
+ prioritySum : 'desc' ,
187
+ } ,
188
+ take,
189
+ skip,
137
190
select : {
138
191
id : true ,
139
192
name : true ,
140
193
pix : true ,
141
194
address : true ,
142
195
capacity : true ,
143
196
contact : true ,
197
+ verified : true ,
144
198
petFriendly : true ,
145
199
shelteredPeople : true ,
146
200
prioritySum : true ,
147
- verified : true ,
148
201
latitude : true ,
149
202
longitude : true ,
150
203
createdAt : true ,
151
204
updatedAt : true ,
152
205
shelterSupplies : {
153
206
where : {
154
207
priority : {
155
- notIn : [ SupplyPriority . UnderControl ] ,
208
+ gt : SupplyPriority . UnderControl ,
156
209
} ,
157
210
} ,
158
- orderBy : {
159
- updatedAt : 'desc' ,
160
- } ,
161
- include : {
162
- supply : true ,
211
+ select : {
212
+ priority : true ,
213
+ supply : {
214
+ select : {
215
+ id : true ,
216
+ name : true ,
217
+ supplyCategory : {
218
+ select : {
219
+ id : true ,
220
+ name : true ,
221
+ } ,
222
+ } ,
223
+ createdAt : true ,
224
+ updatedAt : true ,
225
+ } ,
226
+ } ,
163
227
} ,
164
228
} ,
165
229
} ,
166
230
} ) ;
231
+ return { perPage : payload . perPage , page : payload . page , count, results } ;
232
+ }
167
233
168
- const parsed = parseTagResponse ( queryData , results , this . voluntaryIds ) ;
234
+ private mountWhereFilter ( payload : z . infer < typeof ComplexSearchSchema > ) {
235
+ const filter : any = {
236
+ AND : [
237
+ {
238
+ OR : [
239
+ { address : { contains : payload . search , mode : 'insensitive' } } ,
240
+ { name : { contains : payload . search , mode : 'insensitive' } } ,
241
+ ] ,
242
+ } ,
243
+ ] ,
244
+ } ;
169
245
170
- return {
171
- page,
172
- perPage,
173
- count,
174
- results : parsed ,
246
+ const shelterSuppliesFilter = {
247
+ shelterSupplies : {
248
+ some : { } ,
249
+ } ,
175
250
} ;
251
+
252
+ if ( payload . priority ) {
253
+ shelterSuppliesFilter . shelterSupplies . some [ 'priority' ] = parseInt (
254
+ payload . priority ,
255
+ ) ;
256
+ }
257
+
258
+ if ( payload ?. supplyCategories && payload ?. supplyCategories . length !== 0 ) {
259
+ shelterSuppliesFilter . shelterSupplies . some [ 'supply' ] = {
260
+ supplyCategoryId : {
261
+ in : payload . supplyCategories ,
262
+ } ,
263
+ } ;
264
+ }
265
+
266
+ if ( payload ?. supplies && payload ?. supplies . length !== 0 ) {
267
+ shelterSuppliesFilter . shelterSupplies . some [ 'supplyId' ] = {
268
+ in : payload . supplies ,
269
+ } ;
270
+ }
271
+
272
+ if ( Object . keys ( shelterSuppliesFilter . shelterSupplies . some ) . length !== 0 ) {
273
+ filter [ 'AND' ] . push ( shelterSuppliesFilter ) ;
274
+ }
275
+
276
+ return filter ;
176
277
}
177
278
178
- loadVoluntaryIds ( ) {
179
- this . prismaService . supplyCategory
180
- . findMany ( {
181
- where : {
182
- name : {
183
- in : [ 'Especialistas e Profissionais' , 'Voluntariado' ] ,
279
+ private addShelterStatusFilter ( payload : z . infer < typeof ComplexSearchSchema > ) {
280
+ const shelterStatusFilter : any = [ ] ;
281
+
282
+ if ( payload . filterAvailableShelter ) {
283
+ shelterStatusFilter . push ( {
284
+ AND : [
285
+ {
286
+ capacity : {
287
+ gt : this . prismaService . shelter . fields . shelteredPeople ,
288
+ } ,
184
289
} ,
185
- } ,
186
- } )
187
- . then ( ( resp ) => {
188
- this . voluntaryIds . push ( ...resp . map ( ( s ) => s . id ) ) ;
290
+ {
291
+ capacity : { not : null } ,
292
+ } ,
293
+ {
294
+ shelteredPeople : { not : null } ,
295
+ } ,
296
+ ] ,
297
+ } ) ;
298
+ }
299
+
300
+ if ( payload . filterUnavailableShelter ) {
301
+ shelterStatusFilter . push ( {
302
+ AND : [
303
+ {
304
+ capacity : {
305
+ lte : this . prismaService . shelter . fields . shelteredPeople ,
306
+ } ,
307
+ } ,
308
+ {
309
+ capacity : { not : null } ,
310
+ } ,
311
+ {
312
+ shelteredPeople : { not : null } ,
313
+ } ,
314
+ ] ,
189
315
} ) ;
316
+ }
317
+
318
+ if ( payload . waitingShelterAvailability ) {
319
+ shelterStatusFilter . push ( {
320
+ capacity : null ,
321
+ } ) ;
322
+
323
+ shelterStatusFilter . push ( {
324
+ shelteredPeople : null ,
325
+ } ) ;
326
+ }
327
+
328
+ return shelterStatusFilter ;
190
329
}
191
330
}
0 commit comments