View Javadoc
1   package net.sumaris.core.service.data;
2   
3   /*-
4    * #%L
5    * SUMARiS:: Core
6    * %%
7    * Copyright (C) 2018 SUMARiS Consortium
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  
26  import com.google.common.base.Preconditions;
27  import com.google.common.collect.Lists;
28  import net.sumaris.core.config.SumarisConfiguration;
29  import net.sumaris.core.dao.data.LandingRepository;
30  import net.sumaris.core.dao.data.MeasurementDao;
31  import net.sumaris.core.dao.technical.SortDirection;
32  import net.sumaris.core.model.data.LandingMeasurement;
33  import net.sumaris.core.util.Beans;
34  import net.sumaris.core.util.DataBeans;
35  import net.sumaris.core.vo.data.*;
36  import net.sumaris.core.vo.filter.LandingFilterVO;
37  import net.sumaris.core.vo.referential.ReferentialVO;
38  import org.apache.commons.collections4.CollectionUtils;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  import org.springframework.beans.factory.annotation.Autowired;
42  import org.springframework.stereotype.Service;
43  
44  import java.util.Date;
45  import java.util.List;
46  import java.util.Objects;
47  import java.util.stream.Collectors;
48  
49  @Service("landingService")
50  public class LandingServiceImpl implements LandingService {
51  
52  	private static final Logger log = LoggerFactory.getLogger(LandingServiceImpl.class);
53  
54      @Autowired
55      protected SumarisConfiguration config;
56  
57  	@Autowired
58  	protected LandingRepository landingRepository;
59  
60  	@Autowired
61  	protected MeasurementDao measurementDao;
62  
63  	@Autowired
64  	protected SampleService sampleService;
65  
66  	@Override
67  	public List<LandingVO> getAll(int offset, int size) {
68  		return findAll(null, offset, size, null, null, null);
69  	}
70  
71  	@Override
72  	public List<LandingVO> findAll(LandingFilterVO filter, int offset, int size) {
73  		return findAll(filter, offset, size, null, null, null);
74  	}
75  
76  	@Override
77  	public List<LandingVO> findAll(LandingFilterVO filter, int offset, int size, String sortAttribute,
78                                     SortDirection sortDirection, DataFetchOptions fetchOptions) {
79  
80  		return landingRepository.findAll(filter, offset, size, sortAttribute, sortDirection, fetchOptions)
81  				.stream().collect(Collectors.toList());
82  	}
83  
84  	@Override
85  	public Long countByFilter(LandingFilterVO filter) {
86  		return landingRepository.count(filter);
87  	}
88  
89  	@Override
90  	public LandingVO get(int landingId) {
91  		return landingRepository.get(landingId);
92  	}
93  
94  	@Override
95  	public LandingVOandingVO.html#LandingVO">LandingVO save(final LandingVO source) {
96  		Preconditions.checkNotNull(source);
97  		Preconditions.checkNotNull(source.getProgram(), "Missing program");
98  		Preconditions.checkArgument(source.getProgram().getId() != null || source.getProgram().getLabel() != null, "Missing program.id or program.label");
99  		Preconditions.checkNotNull(source.getDateTime(), "Missing dateTime");
100 		Preconditions.checkNotNull(source.getLocation(), "Missing location");
101 		Preconditions.checkNotNull(source.getLocation().getId(), "Missing location.id");
102 		Preconditions.checkNotNull(source.getRecorderDepartment(), "Missing recorderDepartment");
103 		Preconditions.checkNotNull(source.getRecorderDepartment().getId(), "Missing recorderDepartment.id");
104 
105 		// Reset control date
106 		source.setControlDate(null);
107 
108 		// Save
109 		LandingVO savedLanding = landingRepository.save(source);
110 
111 		// Save measurements
112 		if (savedLanding.getMeasurementValues() != null) {
113 			measurementDao.saveLandingMeasurementsMap(savedLanding.getId(), savedLanding.getMeasurementValues());
114 		}
115 		else {
116 			List<MeasurementVO> measurements = Beans.getList(savedLanding.getMeasurements());
117 			measurements.forEach(m -> fillDefaultProperties(savedLanding, m));
118 			measurements = measurementDao.saveLandingMeasurements(savedLanding.getId(), measurements);
119 			savedLanding.setMeasurements(measurements);
120 		}
121 
122 		// Save samples
123 		{
124 			List<SampleVO> samples = getSamplesAsList(savedLanding);
125 			samples.forEach(s -> fillDefaultProperties(savedLanding, s));
126 			samples = sampleService.saveByLandingId(savedLanding.getId(), samples);
127 
128 			// Prepare saved samples (e.g. to be used as graphQL query response)
129 			samples.forEach(sample -> {
130 				// Set parentId (instead of parent object)
131 				if (sample.getParent() != null) {
132 					sample.setParentId(sample.getParent().getId());
133 					sample.setParent(null);
134 				}
135 				// Remove link to children
136 				sample.setChildren(null);
137 			});
138 
139 			savedLanding.setSamples(samples);
140 		}
141 
142 		return savedLanding;
143 	}
144 
145 	@Override
146 	public List<LandingVO> save(List<LandingVO> landings) {
147 		Preconditions.checkNotNull(landings);
148 
149 		return landings.stream()
150 				.map(this::save)
151 				.collect(Collectors.toList());
152 	}
153 
154 	@Override
155 	public void delete(int id) {
156 		landingRepository.deleteById(id);
157 	}
158 
159 	@Override
160 	public void delete(List<Integer> ids) {
161 		Preconditions.checkNotNull(ids);
162 		ids.stream()
163 				.filter(Objects::nonNull)
164 				.forEach(this::delete);
165 	}
166 
167 	@Override
168 	public LandingVO./../../../../net/sumaris/core/vo/data/LandingVO.html#LandingVO">LandingVO control(LandingVO landing) {
169 		Preconditions.checkNotNull(landing);
170 		Preconditions.checkNotNull(landing.getId());
171 		Preconditions.checkArgument(landing.getControlDate() == null);
172 
173 		return landingRepository.control(landing);
174 	}
175 
176 	@Override
177 	public LandingVO/../../../../net/sumaris/core/vo/data/LandingVO.html#LandingVO">LandingVO validate(LandingVO landing) {
178 		Preconditions.checkNotNull(landing);
179 		Preconditions.checkNotNull(landing.getId());
180 		Preconditions.checkNotNull(landing.getControlDate());
181 		Preconditions.checkArgument(landing.getValidationDate() == null);
182 
183 		return landingRepository.validate(landing);
184 	}
185 
186 	@Override
187 	public LandingVO./../../../net/sumaris/core/vo/data/LandingVO.html#LandingVO">LandingVO unvalidate(LandingVO landing) {
188 		Preconditions.checkNotNull(landing);
189 		Preconditions.checkNotNull(landing.getId());
190 		Preconditions.checkNotNull(landing.getControlDate());
191 		Preconditions.checkNotNull(landing.getValidationDate());
192 
193 		return landingRepository.unvalidate(landing);
194 	}
195 
196 	/* protected methods */
197 
198 	void fillDefaultProperties(LandingVO parent, MeasurementVO measurement) {
199 		if (measurement == null) return;
200 
201 		// Set default value for recorder department and person
202 		DataBeans.setDefaultRecorderDepartment(measurement, parent.getRecorderDepartment());
203 		DataBeans.setDefaultRecorderPerson(measurement, parent.getRecorderPerson());
204 
205 		measurement.setEntityName(LandingMeasurement.class.getSimpleName());
206 	}
207 
208 	protected void fillDefaultProperties(LandingVO parent, SampleVO sample) {
209 		if (sample == null) return;
210 
211 		// Copy recorder department from the parent
212 		if (sample.getRecorderDepartment() == null || sample.getRecorderDepartment().getId() == null) {
213 			sample.setRecorderDepartment(parent.getRecorderDepartment());
214 		}
215 
216 		// Fill matrix
217 		if (sample.getMatrix() == null || sample.getMatrix().getId() == null) {
218 			ReferentialVO matrix = new ReferentialVO();
219 			matrix.setId(config.getMatrixIdIndividual());
220 			sample.setMatrix(matrix);
221 		}
222 
223 		// Fill sample (use operation end date time)
224 		if (sample.getSampleDate() == null) {
225 			sample.setSampleDate(parent.getDateTime());
226 		}
227 
228 		sample.setLandingId(parent.getId());
229 	}
230 
231 	/**
232 	 * Get all samples, in the sample tree parent/children
233 	 * @param parent
234 	 * @return
235 	 */
236 	protected List<SampleVO> getSamplesAsList(final LandingVO parent) {
237 		final List<SampleVO> result = Lists.newArrayList();
238 		if (CollectionUtils.isNotEmpty(parent.getSamples())) {
239 			parent.getSamples().forEach(sample -> {
240 				fillDefaultProperties(parent, sample);
241 				sampleService.treeToList(sample, result);
242 			});
243 		}
244 		return result;
245 	}
246 }