@@ -2,9 +2,9 @@ import { z } from 'zod';
2
2
import { Injectable } from '@nestjs/common' ;
3
3
import { Prisma } from '@prisma/client' ;
4
4
import { DefaultArgs } from '@prisma/client/runtime/library' ;
5
-
6
5
import { PrismaService } from '../prisma/prisma.service' ;
7
6
import {
7
+ ComplexSearchSchema ,
8
8
CreateShelterSchema ,
9
9
FullUpdateShelterSchema ,
10
10
UpdateShelterSchema ,
@@ -70,7 +70,6 @@ export class ShelterService {
70
70
prioritySum : true ,
71
71
latitude : true ,
72
72
longitude : true ,
73
- verified : true ,
74
73
shelterSupplies : {
75
74
select : {
76
75
priority : true ,
@@ -143,4 +142,175 @@ export class ShelterService {
143
142
} ,
144
143
) ;
145
144
}
145
+
146
+ async search ( props : z . infer < typeof ComplexSearchSchema > ) {
147
+ const payload = ComplexSearchSchema . parse ( {
148
+ ...props ,
149
+ supplyCategories :
150
+ typeof props [ 'supplyCategories[]' ] === 'string'
151
+ ? [ props [ 'supplyCategories[]' ] ]
152
+ : props [ 'supplyCategories[]' ] ,
153
+ supplies :
154
+ typeof props [ 'supplies[]' ] === 'string'
155
+ ? [ props [ 'supplies[]' ] ]
156
+ : props [ 'supplies[]' ] ,
157
+ } ) ;
158
+
159
+ const shelterStatusFilter = this . addShelterStatusFilter ( payload ) ;
160
+ const where = this . mountWhereFilter ( payload ) ;
161
+ const take = payload . perPage ;
162
+ const skip = payload . perPage * ( payload . page - 1 ) ;
163
+
164
+ if ( shelterStatusFilter . length > 0 ) {
165
+ where [ 'AND' ] . push ( {
166
+ OR : shelterStatusFilter ,
167
+ } ) ;
168
+ }
169
+
170
+ const count = await this . prismaService . shelter . count ( {
171
+ where : where ,
172
+ } ) ;
173
+
174
+ const results = await this . prismaService . shelter . findMany ( {
175
+ where : where ,
176
+ orderBy : {
177
+ prioritySum : 'desc' ,
178
+ } ,
179
+ take,
180
+ skip,
181
+ select : {
182
+ id : true ,
183
+ name : true ,
184
+ pix : true ,
185
+ address : true ,
186
+ capacity : true ,
187
+ contact : true ,
188
+ verified : true ,
189
+ petFriendly : true ,
190
+ shelteredPeople : true ,
191
+ prioritySum : true ,
192
+ latitude : true ,
193
+ longitude : true ,
194
+ createdAt : true ,
195
+ updatedAt : true ,
196
+ shelterSupplies : {
197
+ where : {
198
+ priority : {
199
+ gte : SupplyPriority . Needing ,
200
+ } ,
201
+ } ,
202
+ take : 10 ,
203
+ select : {
204
+ priority : true ,
205
+ supply : {
206
+ select : {
207
+ name : true ,
208
+ } ,
209
+ } ,
210
+ } ,
211
+ orderBy : {
212
+ priority : 'desc' ,
213
+ } ,
214
+ } ,
215
+ } ,
216
+ } ) ;
217
+ return { perPage : payload . perPage , page : payload . page , count, results } ;
218
+ }
219
+
220
+ private mountWhereFilter ( payload : z . infer < typeof ComplexSearchSchema > ) {
221
+ const filter : any = {
222
+ AND : [
223
+ {
224
+ OR : [
225
+ { address : { contains : payload . search } } ,
226
+ { name : { contains : payload . search } } ,
227
+ ] ,
228
+ } ,
229
+ ] ,
230
+ } ;
231
+
232
+ const shelterSuppliesFilter = {
233
+ shelterSupplies : {
234
+ some : { } ,
235
+ } ,
236
+ } ;
237
+
238
+ if ( payload . priority ) {
239
+ shelterSuppliesFilter . shelterSupplies . some [ 'priority' ] = parseInt (
240
+ payload . priority ,
241
+ ) ;
242
+ }
243
+
244
+ if ( payload ?. supplyCategories && payload ?. supplyCategories . length !== 0 ) {
245
+ shelterSuppliesFilter . shelterSupplies . some [ 'supply' ] = {
246
+ supplyCategoryId : {
247
+ in : payload . supplyCategories ,
248
+ } ,
249
+ } ;
250
+ }
251
+
252
+ if ( payload ?. supplies && payload ?. supplies . length !== 0 ) {
253
+ shelterSuppliesFilter . shelterSupplies . some [ 'supplyId' ] = {
254
+ in : payload . supplies ,
255
+ } ;
256
+ }
257
+
258
+ if ( Object . keys ( shelterSuppliesFilter . shelterSupplies . some ) . length !== 0 ) {
259
+ filter [ 'AND' ] . push ( shelterSuppliesFilter ) ;
260
+ }
261
+
262
+ return filter ;
263
+ }
264
+
265
+ private addShelterStatusFilter ( payload : z . infer < typeof ComplexSearchSchema > ) {
266
+ const shelterStatusFilter : any = [ ] ;
267
+
268
+ if ( payload . filterAvailableShelter ) {
269
+ shelterStatusFilter . push ( {
270
+ AND : [
271
+ {
272
+ capacity : {
273
+ gt : this . prismaService . shelter . fields . shelteredPeople ,
274
+ } ,
275
+ } ,
276
+ {
277
+ capacity : { not : null } ,
278
+ } ,
279
+ {
280
+ shelteredPeople : { not : null } ,
281
+ } ,
282
+ ] ,
283
+ } ) ;
284
+ }
285
+
286
+ if ( payload . filterUnavailableShelter ) {
287
+ shelterStatusFilter . push ( {
288
+ AND : [
289
+ {
290
+ capacity : {
291
+ lte : this . prismaService . shelter . fields . shelteredPeople ,
292
+ } ,
293
+ } ,
294
+ {
295
+ capacity : { not : null } ,
296
+ } ,
297
+ {
298
+ shelteredPeople : { not : null } ,
299
+ } ,
300
+ ] ,
301
+ } ) ;
302
+ }
303
+
304
+ if ( payload . waitingShelterAvailability ) {
305
+ shelterStatusFilter . push ( {
306
+ capacity : null ,
307
+ } ) ;
308
+
309
+ shelterStatusFilter . push ( {
310
+ shelteredPeople : null ,
311
+ } ) ;
312
+ }
313
+
314
+ return shelterStatusFilter ;
315
+ }
146
316
}
0 commit comments