1 package net.sumaris.server.http.graphql.data;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Preconditions;
26 import com.google.common.collect.Maps;
27 import io.leangen.graphql.annotations.*;
28 import net.sumaris.core.dao.referential.metier.MetierRepository;
29 import net.sumaris.core.dao.technical.SortDirection;
30 import net.sumaris.core.dao.technical.model.IEntity;
31 import net.sumaris.core.model.data.*;
32 import net.sumaris.core.service.data.*;
33 import net.sumaris.core.service.referential.PmfmService;
34 import net.sumaris.core.vo.administration.user.DepartmentVO;
35 import net.sumaris.core.vo.administration.user.PersonVO;
36 import net.sumaris.core.vo.data.*;
37 import net.sumaris.core.vo.filter.*;
38 import net.sumaris.core.vo.referential.MetierVO;
39 import net.sumaris.core.vo.referential.PmfmVO;
40 import net.sumaris.server.http.security.IsSupervisor;
41 import net.sumaris.server.http.security.IsUser;
42 import net.sumaris.server.service.administration.ImageService;
43 import net.sumaris.server.service.technical.ChangesPublisherService;
44 import org.apache.commons.collections4.CollectionUtils;
45 import org.reactivestreams.Publisher;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Service;
48 import org.springframework.transaction.annotation.Transactional;
49
50 import java.io.File;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Set;
54
55 @Service
56 @Transactional
57 public class DataGraphQLService {
58
59 @Autowired
60 private VesselService vesselService;
61
62 @Autowired
63 private TripService tripService;
64
65 @Autowired
66 private ObservedLocationService observedLocationService;
67
68 @Autowired
69 private OperationService operationService;
70
71 @Autowired
72 private LandingService landingService;
73
74 @Autowired
75 private SaleService saleService;
76
77 @Autowired
78 private VesselPositionService vesselPositionService;
79
80 @Autowired
81 private SampleService sampleService;
82
83 @Autowired
84 private BatchService batchService;
85
86 @Autowired
87 private MeasurementService measurementService;
88
89 @Autowired
90 private PmfmService pmfmService;
91
92 @Autowired
93 protected PhysicalGearService physicalGearService;
94
95 @Autowired
96 private ImageService imageService;
97
98 @Autowired
99 private ChangesPublisherService changesPublisherService;
100
101 @Autowired
102 private MetierRepository metierRepository;
103
104
105
106 @GraphQLQuery(name = "vesselSnapshots", description = "Search in vessel snapshots")
107 @Transactional(readOnly = true)
108 @IsUser
109 public List<VesselSnapshotVO> findVesselSnapshotsByFilter(@GraphQLArgument(name = "filter") VesselFilterVO filter,
110 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
111 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
112 @GraphQLArgument(name = "sortBy", defaultValue = VesselSnapshotVO.Fields.EXTERIOR_MARKING) String sort,
113 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction
114 ) {
115 return vesselService.findSnapshotByFilter(filter, offset, size, sort,
116 direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null);
117 }
118
119 @GraphQLQuery(name = "vessels", description = "Search in vessels")
120 @Transactional(readOnly = true)
121 @IsUser
122 public List<VesselVO> findVesselByFilter(@GraphQLArgument(name = "filter") VesselFilterVO filter,
123 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
124 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
125 @GraphQLArgument(name = "sortBy") String sort,
126 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction
127 ) {
128 return vesselService.findVesselsByFilter(filter, offset, size, sort,
129 direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null);
130 }
131
132 @GraphQLQuery(name = "vesselsCount", description = "Get total vessels count")
133 @Transactional(readOnly = true)
134 @IsUser
135 public long getVesselsCount(@GraphQLArgument(name = "filter") VesselFilterVO filter) {
136 return vesselService.countVesselsByFilter(filter);
137 }
138
139 @GraphQLQuery(name = "vessel", description = "Get a vessel")
140 @Transactional(readOnly = true)
141 @IsUser
142 public VesselVO getVesselById(@GraphQLArgument(name = "vesselId") int vesselId) {
143 return vesselService.getVesselById(vesselId);
144 }
145
146 @GraphQLQuery(name = "vesselFeaturesHistory", description = "Get vessel features history")
147 @Transactional(readOnly = true)
148 @IsUser
149 public List<VesselFeaturesVO> getVesselFeaturesHistory(@GraphQLArgument(name = "vesselId") Integer vesselId,
150 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
151 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
152 @GraphQLArgument(name = "sortBy", defaultValue = VesselFeaturesVO.Fields.START_DATE) String sort,
153 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction) {
154 return vesselService.getFeaturesByVesselId(vesselId, offset, size, sort, direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null);
155 }
156
157 @GraphQLQuery(name = "vesselRegistrationHistory", description = "Get vessel registration history")
158 @Transactional(readOnly = true)
159 @IsUser
160 public List<VesselRegistrationVO> getVesselRegistrationHistory(@GraphQLArgument(name = "vesselId") Integer vesselId,
161 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
162 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
163 @GraphQLArgument(name = "sortBy", defaultValue = VesselRegistrationVO.Fields.START_DATE) String sort,
164 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction) {
165 return vesselService.getRegistrationsByVesselId(vesselId, offset, size, sort, direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null);
166 }
167
168 @GraphQLMutation(name = "saveVessel", description = "Create or update a vessel")
169 @IsUser
170 public VesselVO saveVessel(@GraphQLArgument(name = "vessel") VesselVO vessel) {
171 return vesselService.save(vessel);
172 }
173
174 @GraphQLMutation(name = "saveVessels", description = "Create or update many vessels")
175 @IsUser
176 public List<VesselVO> saveVessels(@GraphQLArgument(name = "vessels") List<VesselVO> vessels) {
177 return vesselService.save(vessels);
178 }
179
180 @GraphQLMutation(name = "deleteVessel", description = "Delete a vessel (by vessel features id)")
181 @IsUser
182 public void deleteVessel(@GraphQLArgument(name = "id") int id) {
183 vesselService.delete(id);
184 }
185
186 @GraphQLMutation(name = "deleteVessels", description = "Delete many vessels (by vessel features ids)")
187 @IsUser
188 public void deleteVessels(@GraphQLArgument(name = "ids") List<Integer> ids) {
189 vesselService.delete(ids);
190 }
191
192
193
194
195 @GraphQLQuery(name = "trips", description = "Search in trips")
196 @Transactional(readOnly = true)
197 @IsUser
198 public List<TripVO> findTripsByFilter(@GraphQLArgument(name = "filter") TripFilterVO filter,
199 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
200 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
201 @GraphQLArgument(name = "sortBy", defaultValue = TripVO.Fields.DEPARTURE_DATE_TIME) String sort,
202 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction,
203 @GraphQLEnvironment() Set<String> fields
204 ) {
205
206 final List<TripVO> result = tripService.findByFilter(filter, offset, size, sort,
207 direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null,
208 getFetchOptions(fields));
209
210
211 fillTrips(result, fields);
212
213 return result;
214 }
215
216 @GraphQLQuery(name = "tripsCount", description = "Get total trips count")
217 @Transactional(readOnly = true)
218 @IsUser
219 public long getTripsCount(@GraphQLArgument(name = "filter") TripFilterVO filter) {
220 return tripService.countByFilter(filter);
221 }
222
223 @GraphQLQuery(name = "trip", description = "Get a trip, by id")
224 @Transactional(readOnly = true)
225 @IsUser
226 public TripVO getTripById(@GraphQLArgument(name = "id") int id,
227 @GraphQLEnvironment() Set<String> fields) {
228 final TripVO result = tripService.get(id);
229
230
231 fillTripFields(result, fields);
232
233 return result;
234 }
235
236 @GraphQLMutation(name = "saveTrip", description = "Create or update a trip")
237 @IsUser
238 public TripVO saveTrip(@GraphQLArgument(name = "trip") TripVO trip, @GraphQLEnvironment() Set<String> fields) {
239 final TripVO result = tripService.save(trip, false);
240
241
242 fillTripFields(result, fields);
243
244 return result;
245 }
246
247 @GraphQLMutation(name = "saveTrips", description = "Create or update many trips")
248 @IsUser
249 public List<TripVO> saveTrips(@GraphQLArgument(name = "trips") List<TripVO> trips, @GraphQLEnvironment() Set<String> fields) {
250 final List<TripVO> result = tripService.save(trips, false);
251
252
253 fillTrips(result, fields);
254
255 return result;
256 }
257
258 @GraphQLMutation(name = "deleteTrip", description = "Delete a trip")
259 @IsUser
260 public void deleteTrip(@GraphQLArgument(name = "id") int id) {
261 tripService.delete(id);
262 }
263
264 @GraphQLMutation(name = "deleteTrips", description = "Delete many trips")
265 @IsUser
266 public void deleteTrips(@GraphQLArgument(name = "ids") List<Integer> ids) {
267 tripService.delete(ids);
268 }
269
270 @GraphQLSubscription(name = "updateTrip", description = "Subscribe to changes on a trip")
271 @IsUser
272 public Publisher<TripVO> updateTrip(@GraphQLArgument(name = "id") final int id,
273 @GraphQLArgument(name = "interval", defaultValue = "30", description = "Minimum interval to get changes, in seconds.") final Integer minIntervalInSecond) {
274
275 Preconditions.checkArgument(id >= 0, "Invalid id");
276 return changesPublisherService.getPublisher(Trip.class, TripVO.class, id, minIntervalInSecond, true);
277 }
278
279 @GraphQLMutation(name = "controlTrip", description = "Control a trip")
280 @IsUser
281 public TripVO controlTrip(@GraphQLArgument(name = "trip") TripVO trip, @GraphQLEnvironment() Set<String> fields) {
282 final TripVO result = tripService.control(trip);
283
284
285 fillTripFields(result, fields);
286
287 return result;
288 }
289
290 @GraphQLMutation(name = "validateTrip", description = "Validate a trip")
291 @IsSupervisor
292 public TripVO validateTrip(@GraphQLArgument(name = "trip") TripVO trip, @GraphQLEnvironment() Set<String> fields) {
293 final TripVO result = tripService.validate(trip);
294
295
296 fillTripFields(result, fields);
297
298 return result;
299 }
300
301 @GraphQLMutation(name = "unvalidateTrip", description = "Unvalidate a trip")
302 @IsSupervisor
303 public TripVO unvalidateTrip(@GraphQLArgument(name = "trip") TripVO trip, @GraphQLEnvironment() Set<String> fields) {
304 final TripVO result = tripService.unvalidate(trip);
305
306
307 fillTripFields(result, fields);
308
309 return result;
310 }
311
312 @GraphQLMutation(name = "qualifyTrip", description = "Qualify a trip")
313 @IsSupervisor
314 public TripVO qualifyTrip(@GraphQLArgument(name = "trip") TripVO trip, @GraphQLEnvironment() Set<String> fields) {
315 final TripVO result = tripService.qualify(trip);
316
317
318 fillTripFields(result, fields);
319
320 return result;
321 }
322
323
324
325 @GraphQLQuery(name = "gears", description = "Get operation's gears")
326 public List<PhysicalGearVO> getGearsByTrip(@GraphQLContext TripVO trip) {
327 return physicalGearService.getPhysicalGearByTripId(trip.getId());
328 }
329
330
331
332 @GraphQLQuery(name = "observedLocations", description = "Search in observed locations")
333 @Transactional(readOnly = true)
334 @IsUser
335 public List<ObservedLocationVO> findObservedLocationsByFilter(@GraphQLArgument(name = "filter") ObservedLocationFilterVO filter,
336 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
337 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
338 @GraphQLArgument(name = "sortBy", defaultValue = ObservedLocationVO.Fields.START_DATE_TIME) String sort,
339 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction,
340 @GraphQLEnvironment() Set<String> fields
341 ) {
342 final List<ObservedLocationVO> result = observedLocationService.findByFilter(filter, offset, size, sort,
343 direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null,
344 getFetchOptions(fields));
345
346
347 fillObservedLocationsFields(result, fields);
348
349 return result;
350 }
351
352 @GraphQLQuery(name = "observedLocationsCount", description = "Get total number of observed locations")
353 @Transactional(readOnly = true)
354 @IsUser
355 public long getObservedLocationsCount(@GraphQLArgument(name = "filter") ObservedLocationFilterVO filter) {
356 return observedLocationService.countByFilter(filter);
357 }
358
359 @GraphQLQuery(name = "observedLocation", description = "Get an observed location, by id")
360 @Transactional(readOnly = true)
361 @IsUser
362 public ObservedLocationVO getObservedLocationById(@GraphQLArgument(name = "id") int id,
363 @GraphQLEnvironment() Set<String> fields) {
364 final ObservedLocationVO result = observedLocationService.get(id);
365
366
367 fillObservedLocationFields(result, fields);
368
369 return result;
370 }
371
372 @GraphQLMutation(name = "saveObservedLocation", description = "Create or update an observed location")
373 @IsUser
374 public ObservedLocationVO saveObservedLocation(@GraphQLArgument(name = "observedLocation") ObservedLocationVO observedLocation, @GraphQLEnvironment() Set<String> fields) {
375 final ObservedLocationVO result = observedLocationService.save(observedLocation, false);
376
377
378 fillObservedLocationFields(result, fields);
379
380 return result;
381 }
382
383 @GraphQLMutation(name = "saveObservedLocations", description = "Create or update many observed locations")
384 @IsUser
385 public List<ObservedLocationVO> saveObservedLocations(@GraphQLArgument(name = "observedLocations") List<ObservedLocationVO> observedLocations, @GraphQLEnvironment() Set<String> fields) {
386 final List<ObservedLocationVO> result = observedLocationService.save(observedLocations, false);
387
388
389 fillObservedLocationsFields(result, fields);
390
391 return result;
392 }
393
394 @GraphQLMutation(name = "deleteObservedLocation", description = "Delete an observed location")
395 @IsUser
396 public void deleteObservedLocation(@GraphQLArgument(name = "id") int id) {
397 observedLocationService.delete(id);
398 }
399
400 @GraphQLMutation(name = "deleteObservedLocations", description = "Delete many observed locations")
401 @IsUser
402 public void deleteObservedLocations(@GraphQLArgument(name = "ids") List<Integer> ids) {
403 observedLocationService.delete(ids);
404 }
405
406 @GraphQLSubscription(name = "updateObservedLocation", description = "Subscribe to changes on an observed location")
407 @IsUser
408 public Publisher<ObservedLocationVO> updateObservedLocation(@GraphQLArgument(name = "id") final int id,
409 @GraphQLArgument(name = "interval", defaultValue = "30", description = "Minimum interval to get changes, in seconds.") final Integer minIntervalInSecond) {
410
411 Preconditions.checkArgument(id >= 0, "Invalid id");
412 return changesPublisherService.getPublisher(ObservedLocation.class, ObservedLocationVO.class, id, minIntervalInSecond, true);
413 }
414
415 @GraphQLMutation(name = "controlObservedLocation", description = "Control an observed location")
416 @IsUser
417 public ObservedLocationVO controlObservedLocation(@GraphQLArgument(name = "observedLocation") ObservedLocationVO observedLocation, @GraphQLEnvironment() Set<String> fields) {
418 final ObservedLocationVO result = observedLocationService.control(observedLocation);
419
420
421 fillObservedLocationFields(result, fields);
422
423 return result;
424 }
425
426 @GraphQLMutation(name = "validateObservedLocation", description = "Validate an observed location")
427 @IsSupervisor
428 public ObservedLocationVO validateObservedLocation(@GraphQLArgument(name = "observedLocation") ObservedLocationVO observedLocation, @GraphQLEnvironment() Set<String> fields) {
429 final ObservedLocationVO result = observedLocationService.validate(observedLocation);
430
431
432 fillObservedLocationFields(result, fields);
433
434 return result;
435 }
436
437 @GraphQLMutation(name = "unvalidateObservedLocation", description = "Unvalidate an observed location")
438 @IsSupervisor
439 public ObservedLocationVO unvalidateObservedLocation(@GraphQLArgument(name = "observedLocation") ObservedLocationVO observedLocation, @GraphQLEnvironment() Set<String> fields) {
440 final ObservedLocationVO result = observedLocationService.unvalidate(observedLocation);
441
442
443 fillObservedLocationFields(result, fields);
444
445 return result;
446 }
447
448
449
450
451 @GraphQLQuery(name = "sales", description = "Get trip's sales")
452 public List<SaleVO> getSalesByTrip(@GraphQLContext TripVO trip) {
453 return saleService.getAllByTripId(trip.getId());
454 }
455
456 @GraphQLQuery(name = "sale", description = "Get trip's unique sale")
457 public SaleVO getUniqueSaleByTrip(@GraphQLContext TripVO trip) {
458 List<SaleVO> sales = saleService.getAllByTripId(trip.getId());
459 return CollectionUtils.isEmpty(sales) ? null : CollectionUtils.extractSingleton(sales);
460 }
461
462
463
464 @GraphQLQuery(name = "operations", description = "Get trip's operations")
465 @Transactional(readOnly = true)
466 @IsUser
467 public List<OperationVO> getOperationsByTripId(@GraphQLArgument(name = "filter") OperationFilterVO filter,
468 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
469 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
470 @GraphQLArgument(name = "sortBy", defaultValue = OperationVO.Fields.START_DATE_TIME) String sort,
471 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction) {
472 Preconditions.checkNotNull(filter, "Missing tripFilter or tripFilter.tripId");
473 Preconditions.checkNotNull(filter.getTripId(), "Missing tripFilter or tripFilter.tripId");
474 return operationService.getAllByTripId(filter.getTripId(), offset, size, sort, direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null);
475 }
476
477 @GraphQLQuery(name = "operations", description = "Get trip's operations")
478 public List<OperationVO> getOperationsByTrip(@GraphQLContext TripVO trip) {
479 return operationService.getAllByTripId(trip.getId(), 0, 100, OperationVO.Fields.START_DATE_TIME, SortDirection.ASC);
480 }
481
482 @GraphQLQuery(name = "operation", description = "Get an operation")
483 @Transactional(readOnly = true)
484 @IsUser
485 public OperationVO getOperation(@GraphQLArgument(name = "id") int id) {
486 return operationService.get(id);
487 }
488
489 @GraphQLMutation(name = "saveOperations", description = "Save operations")
490 @IsUser
491 public List<OperationVO> saveOperations(@GraphQLArgument(name = "operations") List<OperationVO> operations) {
492 return operationService.save(operations);
493 }
494
495 @GraphQLMutation(name = "saveOperation", description = "Create or update an operation")
496 @IsUser
497 public OperationVO saveOperation(@GraphQLArgument(name = "operation") OperationVO operation) {
498 return operationService.save(operation);
499 }
500
501 @GraphQLMutation(name = "deleteOperation", description = "Delete an operation")
502 @IsUser
503 public void deleteOperation(@GraphQLArgument(name = "id") int id) {
504 operationService.delete(id);
505 }
506
507 @GraphQLMutation(name = "deleteOperations", description = "Delete many operations")
508 @IsUser
509 public void deleteOperations(@GraphQLArgument(name = "ids") List<Integer> ids) {
510 operationService.delete(ids);
511 }
512
513 @GraphQLSubscription(name = "updateOperation", description = "Subscribe to changes on an operation")
514 @IsUser
515 public Publisher<OperationVO> updateOperation(@GraphQLArgument(name = "id") final int id,
516 @GraphQLArgument(name = "interval", defaultValue = "30", description = "Minimum interval to get changes, in seconds.") final Integer minIntervalInSecond) {
517
518 Preconditions.checkArgument(id >= 0, "Invalid id");
519 return changesPublisherService.getPublisher(Operation.class, OperationVO.class, id, minIntervalInSecond, true);
520 }
521
522
523
524 @GraphQLQuery(name = "positions", description = "Get operation's position")
525 public List<VesselPositionVO> getPositionsByOperation(@GraphQLContext OperationVO operation) {
526
527 if (CollectionUtils.isNotEmpty(operation.getPositions())) {
528 return operation.getPositions();
529 }
530 return vesselPositionService.getAllByOperationId(operation.getId(), 0, 100, VesselPositionVO.Fields.DATE_TIME, SortDirection.ASC);
531 }
532
533
534
535 @GraphQLQuery(name = "vesselSnapshot", description = "Get trip vessel snapshot")
536 public VesselSnapshotVO getVesselFeaturesByTrip(@GraphQLContext TripVO trip) {
537 return vesselService.getSnapshotByIdAndDate(trip.getVesselSnapshot().getId(), trip.getDepartureDateTime());
538 }
539
540
541
542 @GraphQLQuery(name = "samples", description = "Get operation's samples")
543 public List<SampleVO> getSamplesByOperation(@GraphQLContext OperationVO operation) {
544
545 if (CollectionUtils.isNotEmpty(operation.getSamples())) {
546 return operation.getSamples();
547 }
548
549 return sampleService.getAllByOperationId(operation.getId());
550 }
551
552
553 @GraphQLQuery(name = "samples", description = "Get landing's samples")
554 public List<SampleVO> getSamplesByLanding(@GraphQLContext LandingVO landing) {
555
556 if (CollectionUtils.isNotEmpty(landing.getSamples())) {
557 return landing.getSamples();
558 }
559
560 return sampleService.getAllByLandingId(landing.getId());
561 }
562
563
564
565 @GraphQLQuery(name = "batches", description = "Get operation's batches")
566 public List<BatchVO> getBatchesByOperation(@GraphQLContext OperationVO operation) {
567
568 if (operation.getBatches() != null) {
569 return operation.getBatches();
570 }
571
572
573 return batchService.getAllByOperationId(operation.getId());
574 }
575
576
577
578 @GraphQLQuery(name = "landings", description = "Search in landings")
579 @Transactional(readOnly = true)
580
581 public List<LandingVO> findAllLandings(@GraphQLArgument(name = "filter") LandingFilterVO filter,
582 @GraphQLArgument(name = "offset", defaultValue = "0") Integer offset,
583 @GraphQLArgument(name = "size", defaultValue = "1000") Integer size,
584 @GraphQLArgument(name = "sortBy", defaultValue = LandingVO.Fields.DATE_TIME) String sort,
585 @GraphQLArgument(name = "sortDirection", defaultValue = "asc") String direction,
586 @GraphQLEnvironment() Set<String> fields
587 ) {
588 final List<LandingVO> result = landingService.findAll(filter, offset, size, sort,
589 direction != null ? SortDirection.valueOf(direction.toUpperCase()) : null,
590 getFetchOptions(fields));
591
592
593 fillLandingsFields(result, fields);
594
595 return result;
596 }
597
598 @GraphQLQuery(name = "landingsCount", description = "Get total number of landings")
599 @Transactional(readOnly = true)
600 @IsUser
601 public long countLandings(@GraphQLArgument(name = "filter") LandingFilterVO filter) {
602 return landingService.countByFilter(filter);
603 }
604
605 @GraphQLQuery(name = "landing", description = "Get an observed location, by id")
606 @Transactional(readOnly = true)
607 @IsUser
608 public LandingVO getLanding(@GraphQLArgument(name = "id") int id,
609 @GraphQLEnvironment() Set<String> fields) {
610 final LandingVO result = landingService.get(id);
611
612
613 fillLandingFields(result, fields);
614
615 return result;
616 }
617
618 @GraphQLMutation(name = "saveLanding", description = "Create or update an landing")
619 @IsUser
620 public LandingVO saveLanding(@GraphQLArgument(name = "landing") LandingVO landing,
621 @GraphQLEnvironment() Set<String> fields) {
622 final LandingVO result = landingService.save(landing);
623
624
625 fillLandingFields(result, fields);
626
627 return result;
628 }
629
630 @GraphQLMutation(name = "saveLandings", description = "Create or update many landings")
631 @IsUser
632 public List<LandingVO> saveLandings(@GraphQLArgument(name = "landings") List<LandingVO> landings, @GraphQLEnvironment() Set<String> fields) {
633 final List<LandingVO> result = landingService.save(landings);
634
635
636 fillLandingsFields(result, fields);
637
638 return result;
639 }
640
641 @GraphQLMutation(name = "deleteLanding", description = "Delete an observed location")
642 @IsUser
643 public void deleteLanding(@GraphQLArgument(name = "id") int id) {
644 landingService.delete(id);
645 }
646
647 @GraphQLMutation(name = "deleteLandings", description = "Delete many observed locations")
648 @IsUser
649 public void deleteLandings(@GraphQLArgument(name = "ids") List<Integer> ids) {
650 landingService.delete(ids);
651 }
652
653 @GraphQLSubscription(name = "updateLanding", description = "Subscribe to changes on an landing")
654 @IsUser
655 public Publisher<LandingVO> updateLanding(@GraphQLArgument(name = "id") final int id,
656 @GraphQLArgument(name = "interval", defaultValue = "30", description = "Minimum interval to get changes, in seconds.") final Integer minIntervalInSecond) {
657
658 Preconditions.checkArgument(id >= 0, "Invalid id");
659 return changesPublisherService.getPublisher(Landing.class, LandingVO.class, id, minIntervalInSecond, true);
660 }
661
662
663
664
665 @GraphQLQuery(name = "measurements", description = "Get trip's measurements")
666 public List<MeasurementVO> getTripVesselUseMeasurements(@GraphQLContext TripVO trip) {
667 return measurementService.getTripVesselUseMeasurements(trip.getId());
668 }
669
670 @GraphQLQuery(name = "measurementValues", description = "Get trip's measurements")
671 public Map<Integer, String> getTripVesselUseMeasurementsMap(@GraphQLContext TripVO trip) {
672 if (trip.getMeasurementValues() != null) {
673 return trip.getMeasurementValues();
674 }
675 return measurementService.getTripVesselUseMeasurementsMap(trip.getId());
676 }
677
678
679 @GraphQLQuery(name = "measurements", description = "Get operation's measurements")
680 public List<MeasurementVO> getOperationVesselUseMeasurements(@GraphQLContext OperationVO operation) {
681 return measurementService.getOperationVesselUseMeasurements(operation.getId());
682 }
683
684 @GraphQLQuery(name = "measurementValues", description = "Get operation's measurements")
685 public Map<Integer, String> getOperationVesselUseMeasurementsMap(@GraphQLContext OperationVO operation) {
686 if (operation.getMeasurementValues() != null) {
687 return operation.getMeasurementValues();
688 }
689 return measurementService.getOperationVesselUseMeasurementsMap(operation.getId());
690 }
691
692 @GraphQLQuery(name = "gearMeasurements", description = "Get operation's gear measurements")
693 public List<MeasurementVO> getOperationGearUseMeasurements(@GraphQLContext OperationVO operation) {
694 return measurementService.getOperationGearUseMeasurements(operation.getId());
695 }
696
697 @GraphQLQuery(name = "gearMeasurementValues", description = "Get operation's gear measurements")
698 public Map<Integer, String> getOperationGearUseMeasurementsMap(@GraphQLContext OperationVO operation) {
699 if (operation.getGearMeasurementValues() != null) {
700 return operation.getGearMeasurementValues();
701 }
702 return measurementService.getOperationGearUseMeasurementsMap(operation.getId());
703 }
704
705
706
707 @GraphQLQuery(name = "measurements", description = "Get physical gear measurements")
708 public List<MeasurementVO> getPhysicalGearMeasurements(@GraphQLContext PhysicalGearVO physicalGear) {
709 return measurementService.getPhysicalGearMeasurements(physicalGear.getId());
710 }
711
712 @GraphQLQuery(name = "measurementValues", description = "Get physical gear measurements")
713 public Map<Integer, String> getPhysicalGearMeasurementsMap(@GraphQLContext PhysicalGearVO physicalGear) {
714 if (physicalGear.getMeasurementValues() != null) {
715 return physicalGear.getMeasurementValues();
716 }
717 return measurementService.getPhysicalGearMeasurementsMap(physicalGear.getId());
718 }
719
720
721 @GraphQLQuery(name = "metier", description = "Get operation's metier")
722 public MetierVO getOperationMetier(@GraphQLContext OperationVO operation) {
723
724 if (operation.getMetier() == null || operation.getMetier().getTaxonGroup() != null) {
725 return operation.getMetier();
726 }
727 Integer metierId = operation.getMetier().getId();
728 if (metierId == null) return null;
729
730 return metierRepository.getById(metierId);
731 }
732
733
734 @GraphQLQuery(name = "measurements", description = "Get sample measurements")
735 public List<MeasurementVO> getSampleMeasurements(@GraphQLContext SampleVO sample) {
736 if (sample.getMeasurements() != null) {
737 return sample.getMeasurements();
738 }
739 return measurementService.getSampleMeasurements(sample.getId());
740 }
741
742 @GraphQLQuery(name = "measurementValues", description = "Get measurement values (as a key/value map, using pmfmId as key)")
743 public Map<Integer, String> getSampleMeasurementValues(@GraphQLContext SampleVO sample) {
744 if (sample.getMeasurementValues() != null) {
745 return sample.getMeasurementValues();
746 }
747 return measurementService.getSampleMeasurementsMap(sample.getId());
748 }
749
750
751 @GraphQLQuery(name = "measurementValues", description = "Get measurement values (as a key/value map, using pmfmId as key)")
752 public Map<Integer, String> getBatchMeasurementValues(@GraphQLContext BatchVO batch) {
753 if (batch.getMeasurementValues() != null) {
754 return batch.getMeasurementValues();
755 }
756 Map<Integer, String> map = Maps.newHashMap();
757 map.putAll(measurementService.getBatchSortingMeasurementsMap(batch.getId()));
758 map.putAll(measurementService.getBatchQuantificationMeasurementsMap(batch.getId()));
759 return map;
760 }
761
762
763 @GraphQLQuery(name = "measurements", description = "Get measurement values")
764 public List<MeasurementVO> getObservedLocationMeasurements(@GraphQLContext ObservedLocationVO observedLocation) {
765 if (observedLocation.getMeasurements() != null) {
766 return observedLocation.getMeasurements();
767 }
768 return measurementService.getObservedLocationMeasurements(observedLocation.getId());
769 }
770
771 @GraphQLQuery(name = "measurementValues", description = "Get measurement values (as a key/value map, using pmfmId as key)")
772 public Map<Integer, String> getObservedLocationMeasurementsMap(@GraphQLContext ObservedLocationVO observedLocation) {
773 if (observedLocation.getMeasurementValues() != null) {
774 return observedLocation.getMeasurementValues();
775 }
776 return measurementService.getObservedLocationMeasurementsMap(observedLocation.getId());
777 }
778
779 @GraphQLQuery(name = "measurementValues", description = "Get measurement values (as a key/value map, using pmfmId as key)")
780 public Map<Integer, String> getLandingMeasurementsMap(@GraphQLContext LandingVO landing) {
781 if (landing.getMeasurementValues() != null) {
782 return landing.getMeasurementValues();
783 }
784 return measurementService.getLandingMeasurementsMap(landing.getId());
785 }
786
787
788 @GraphQLQuery(name = "pmfm", description = "Get measurement's pmfm")
789 public PmfmVO getMeasurementPmfm(@GraphQLContext MeasurementVO measurement) {
790 return pmfmService.get(measurement.getPmfmId());
791 }
792
793
794 @GraphQLQuery(name = "measurements", description = "Get vessel's physical measurements")
795 public List<MeasurementVO> getVesselFeaturesMeasurements(@GraphQLContext VesselSnapshotVO vesselSnapshot) {
796 return measurementService.getVesselFeaturesMeasurements(vesselSnapshot.getId());
797 }
798
799 @GraphQLQuery(name = "measurementValues", description = "Get vessel's physical measurements")
800 public Map<Integer, String> getVesselFeaturesMeasurementsMap(@GraphQLContext VesselSnapshotVO vesselSnapshot) {
801 if (vesselSnapshot.getMeasurementValues() == null) {
802 return measurementService.getVesselFeaturesMeasurementsMap(vesselSnapshot.getId());
803 }
804 return vesselSnapshot.getMeasurementValues();
805 }
806
807
808
809
810 protected void fillTripFields(TripVO trip, Set<String> fields) {
811
812 fillImages(trip, fields);
813
814
815 fillVesselSnapshot(trip, fields);
816 }
817
818 protected void fillTrips(List<TripVO> trips, Set<String> fields) {
819
820 fillImages(trips, fields);
821
822
823 fillVesselSnapshot(trips, fields);
824 }
825
826 protected void fillObservedLocationFields(ObservedLocationVO observedLocation, Set<String> fields) {
827
828 fillImages(observedLocation, fields);
829 }
830
831 protected void fillObservedLocationsFields(List<ObservedLocationVO> observedLocations, Set<String> fields) {
832
833 fillImages(observedLocations, fields);
834 }
835
836 protected void fillLandingFields(LandingVO landing, Set<String> fields) {
837
838 fillImages(landing, fields);
839
840
841 fillVesselSnapshot(landing, fields);
842 }
843
844 protected void fillLandingsFields(List<LandingVO> landings, Set<String> fields) {
845
846 fillImages(landings, fields);
847
848
849 fillVesselSnapshot(landings, fields);
850 }
851
852 protected boolean hasImageField(Set<String> fields) {
853 return fields.contains(TripVO.Fields.RECORDER_DEPARTMENT + File.separator + DepartmentVO.Fields.LOGO) ||
854 fields.contains(TripVO.Fields.RECORDER_PERSON + File.separator + PersonVO.Fields.AVATAR);
855 }
856
857 protected boolean hasVesselFeaturesField(Set<String> fields) {
858 return fields.contains(TripVO.Fields.VESSEL_SNAPSHOT + File.separator + VesselSnapshotVO.Fields.EXTERIOR_MARKING)
859 || fields.contains(TripVO.Fields.VESSEL_SNAPSHOT + File.separator + VesselSnapshotVO.Fields.NAME);
860 }
861
862 protected <T extends IRootDataVO<?>> List<T> fillImages(final List<T> results) {
863 results.forEach(this::fillImages);
864 return results;
865 }
866
867 protected <T extends IRootDataVO<?>> T fillImages(T result) {
868 if (result != null) {
869
870
871 imageService.fillLogo(result.getRecorderDepartment());
872
873
874 imageService.fillAvatar(result.getRecorderPerson());
875 }
876
877 return result;
878 }
879
880 protected <T extends IRootDataVO<?>> List<T> fillImages(final List<T> results, Set<String> fields) {
881 if (hasImageField(fields)) results.forEach(this::fillImages);
882 return results;
883 }
884
885 protected <T extends IRootDataVO<?>> T fillImages(T result, Set<String> fields) {
886 if (hasImageField(fields) && result != null) {
887
888
889 imageService.fillLogo(result.getRecorderDepartment());
890
891
892 imageService.fillAvatar(result.getRecorderPerson());
893 }
894
895 return result;
896 }
897
898 protected <T extends IWithVesselSnapshotEntity<?, VesselSnapshotVO>> void fillVesselSnapshot(T bean, Set<String> fields) {
899
900 if (hasVesselFeaturesField(fields)) {
901 if (bean.getVesselSnapshot() != null && bean.getVesselSnapshot().getId() != null) {
902 bean.setVesselSnapshot(vesselService.getSnapshotByIdAndDate(bean.getVesselSnapshot().getId(), bean.getVesselDateTime()));
903 }
904 }
905 }
906
907 protected <T extends IWithVesselSnapshotEntity<?, VesselSnapshotVO>> void fillVesselSnapshot(List<T> beans, Set<String> fields) {
908
909 if (hasVesselFeaturesField(fields)) {
910 beans.forEach(bean -> {
911 if (bean.getVesselSnapshot() != null && bean.getVesselSnapshot().getId() != null) {
912 bean.setVesselSnapshot(vesselService.getSnapshotByIdAndDate(bean.getVesselSnapshot().getId(), bean.getVesselDateTime()));
913 }
914 });
915 }
916 }
917
918 protected DataFetchOptions getFetchOptions(Set<String> fields) {
919 return DataFetchOptions.builder()
920 .withObservers(fields.contains(IWithObserversEntity.Fields.OBSERVERS + "/" + IEntity.Fields.ID))
921 .withRecorderDepartment(fields.contains(IWithRecorderDepartmentEntity.Fields.RECORDER_DEPARTMENT + "/" + IEntity.Fields.ID))
922 .withRecorderPerson(fields.contains(IWithRecorderPersonEntity.Fields.RECORDER_PERSON + "/" + IEntity.Fields.ID))
923 .build();
924 }
925 }