Commit 4639fe22 authored by PECQUOT's avatar PECQUOT
Browse files

[fix] refactor FishingAreaRepository add ExpectedSaleRepository

[enh] add missing methods in ProductService
parent c5e82ada
......@@ -37,7 +37,6 @@ import org.ehcache.core.statistics.DefaultStatisticsService;
import org.ehcache.core.statistics.TierStatistics;
import org.ehcache.jsr107.Eh107Configuration;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.data.util.CastUtils;
import javax.cache.Cache;
......@@ -219,7 +218,7 @@ public class Caches {
TierStatistics onHeapStatistics = tierStatistics.get("OnHeap");
if (onHeapStatistics != null) {
result.put("size", onHeapStatistics.getHits());
result.put("heapSize", onHeapStatistics.getAllocatedByteSize());
result.put("heapSize", Math.max(0, onHeapStatistics.getAllocatedByteSize()));
}
TierStatistics offHeapStatistics = tierStatistics.get("OffHeap");
if (offHeapStatistics != null) {
......
......@@ -31,7 +31,6 @@ import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.ParameterExpression;
import java.util.List;
import java.util.Set;
public interface FishingAreaRepository
extends SumarisJpaRepository<FishingArea, Integer, FishingAreaVO>, FishingAreaSpecifications
......@@ -55,7 +54,5 @@ public interface FishingAreaRepository
List<FishingArea> getFishingAreaByOperationId(int operationId);
Set<Integer> getAllIdsByOperationId(int operationId);
void deleteAllByOperationId(int operationId);
}
......@@ -35,6 +35,7 @@ import net.sumaris.core.model.referential.DistanceToCoastGradient;
import net.sumaris.core.model.referential.NearbySpecificArea;
import net.sumaris.core.model.referential.QualityFlag;
import net.sumaris.core.model.referential.location.Location;
import net.sumaris.core.util.Beans;
import net.sumaris.core.vo.data.FishingAreaVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
......@@ -44,7 +45,6 @@ import javax.annotation.Nonnull;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
......@@ -169,7 +169,8 @@ public class FishingAreaRepositoryImpl
sources.forEach(fa -> fa.setOperationId(operationId));
// Get existing fishing areas
Set<Integer> existingIds = self.getAllIdsByOperationId(operationId);
Operation operation = getById(Operation.class, operationId);
List<Integer> existingIds = Beans.collectIds(operation.getFishingAreas());
// Save
sources.forEach(fishingArea -> {
......
......@@ -29,12 +29,13 @@ import net.sumaris.core.vo.data.LandingVO;
import net.sumaris.core.vo.filter.LandingFilterVO;
import java.util.Collection;
import java.util.Optional;
public interface LandingRepository extends
RootDataRepository<Landing, LandingVO, LandingFilterVO, DataFetchOptions>,
LandingSpecifications {
Landing getByTripId(Integer tripId);
Optional<Landing> findByTripId(Integer tripId);
void deleteByIdIn(Collection<Integer> landingIds);
......
......@@ -44,10 +44,8 @@ import net.sumaris.core.util.StringUtils;
import net.sumaris.core.vo.administration.user.PersonVO;
import net.sumaris.core.vo.data.DataFetchOptions;
import net.sumaris.core.vo.data.ProductVO;
import net.sumaris.core.vo.filter.LandingFilterVO;
import net.sumaris.core.vo.filter.ProductFilterVO;
import net.sumaris.core.vo.referential.PmfmVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
......@@ -97,7 +95,8 @@ public class ProductRepositoryImpl
return super.toSpecification(filter, fetchOptions)
.and(hasLandingId(filter.getLandingId()))
.and(hasOperationId(filter.getOperationId()))
.and(hasSaleId(filter.getSaleId()));
.and(hasSaleId(filter.getSaleId()))
.and(hasExpectedSaleId(filter.getExpectedSaleId()));
}
@Override
......@@ -136,6 +135,9 @@ public class ProductRepositoryImpl
if (source.getSale() != null) {
target.setSaleId(source.getSale().getId());
}
if (source.getExpectedSale() != null) {
target.setExpectedSaleId(source.getExpectedSale().getId());
}
if (source.getBatch() != null) {
target.setBatchId(source.getBatch().getId());
}
......@@ -213,12 +215,18 @@ public class ProductRepositoryImpl
target.setOperation(operationId == null ? null : getReference(Operation.class, operationId));
}
// Sale (in SIH, Sale is ExpectedSale and is linked also with Landing)
// Sale
Integer saleId = source.getSaleId() != null ? source.getSaleId() : (source.getSale() != null ? source.getSale().getId() : null);
if (copyIfNull || (saleId != null)) {
target.setSale(saleId == null ? null : getReference(Sale.class, saleId));
}
// ExpectedSale
Integer expectedSaleId = source.getExpectedSaleId() != null ? source.getExpectedSaleId() : (source.getExpectedSale() != null ? source.getExpectedSale().getId() : null);
if (copyIfNull || (expectedSaleId != null)) {
target.setExpectedSale(expectedSaleId == null ? null : getReference(ExpectedSale.class, expectedSaleId));
}
// Batch (link for sale on batch)
Integer batchId = source.getBatchId() != null ? source.getBatchId() : (source.getBatch() != null ? source.getBatch().getId() : null);
if (copyIfNull || (batchId != null)) {
......@@ -239,6 +247,8 @@ public class ProductRepositoryImpl
source.setLanding(null);
source.setSaleId(null);
source.setSale(null);
source.setExpectedSaleId(null);
source.setExpectedSale(null);
// set default weight method
source.setWeightCalculated(false);
});
......@@ -259,6 +269,8 @@ public class ProductRepositoryImpl
source.setOperation(null);
source.setSaleId(null);
source.setSale(null);
source.setExpectedSaleId(null);
source.setExpectedSale(null);
});
// Save all by parent
......@@ -273,14 +285,39 @@ public class ProductRepositoryImpl
// Get landing Id (to optimize linked data for SIH)
Integer landingId = Optional.ofNullable(parent.getTrip())
.map(trip -> landingRepository.findAll(LandingFilterVO.builder().tripId(trip.getId()).build()))
.filter(landings -> CollectionUtils.size(landings) == 1)
.map(landings -> landings.get(0).getId())
.flatMap(trip -> landingRepository.findByTripId(trip.getId()))
.map(Landing::getId)
.orElse(null);
products.forEach(source -> {
source.setSaleId(saleId);
source.setLandingId(landingId);
source.setExpectedSaleId(null);
source.setExpectedSale(null);
source.setOperationId(null);
source.setOperation(null);
});
// Save all by parent
return saveByParent(parent, products);
}
@Override
public List<ProductVO> saveByExpectedSaleId(int expectedSaleId, @Nonnull List<ProductVO> products) {
// Load parent entity
ExpectedSale parent = getById(ExpectedSale.class, expectedSaleId);
// Get landing Id (to optimize linked data for SIH)
Integer landingId = Optional.ofNullable(parent.getTrip())
.flatMap(trip -> landingRepository.findByTripId(trip.getId()))
.map(Landing::getId)
.orElse(null);
products.forEach(source -> {
source.setExpectedSaleId(expectedSaleId);
source.setLandingId(landingId);
source.setSaleId(null);
source.setSale(null);
source.setOperationId(null);
source.setOperation(null);
});
......@@ -312,7 +349,7 @@ public class ProductRepositoryImpl
product.getMeasurementValues().putAll(measurementDao.getProductQuantificationMeasurementsMap(product.getId()));
// Sale specific :
if (product.getSaleId() != null) {
if (product.getSaleId() != null || product.getExpectedSaleId() != null) {
// Get average price per packaging and set it to generic average price pmfm
String packagingId = product.getMeasurementValues().get(PmfmEnum.PACKAGING.getId());
if (StringUtils.isNotBlank(packagingId)) {
......@@ -358,7 +395,7 @@ public class ProductRepositoryImpl
if (product.getMeasurementValues() != null) {
// Sale specific :
if (product.getSaleId() != null) {
if (product.getSaleId() != null || product.getExpectedSaleId() != null) {
// Replace average price per packaging by packaging depending average price
String packagingId = product.getMeasurementValues().get(PmfmEnum.PACKAGING.getId());
......
......@@ -41,6 +41,7 @@ public interface ProductSpecifications extends DataSpecifications<Product> {
String LANDING_ID_PARAM = "landingId";
String OPERATION_ID_PARAM = "operationId";
String SALE_ID_PARAM = "saleId";
String EXPECTED_SALE_ID_PARAM = "expectedSaleId";
default Specification<Product> hasLandingId(Integer landingId) {
BindableSpecification<Product> specification = BindableSpecification.where((root, query, criteriaBuilder) -> {
......@@ -78,11 +79,25 @@ public interface ProductSpecifications extends DataSpecifications<Product> {
return specification;
}
default Specification<Product> hasExpectedSaleId(Integer expectedSaleId) {
BindableSpecification<Product> specification = BindableSpecification.where((root, query, criteriaBuilder) -> {
ParameterExpression<Integer> param = criteriaBuilder.parameter(Integer.class, EXPECTED_SALE_ID_PARAM);
return criteriaBuilder.or(
criteriaBuilder.isNull(param),
criteriaBuilder.equal(root.get(Product.Fields.EXPECTED_SALE).get(IEntity.Fields.ID), param)
);
});
specification.addBind(EXPECTED_SALE_ID_PARAM, expectedSaleId);
return specification;
}
List<ProductVO> saveByOperationId(int operationId, @Nonnull List<ProductVO> products);
List<ProductVO> saveByLandingId(int landingId, @Nonnull List<ProductVO> products);
List<ProductVO> saveBySaleId(int saleId, @Nonnull List<ProductVO> products);
List<ProductVO> saveByExpectedSaleId(int expectedSaleId, @Nonnull List<ProductVO> products);
void fillMeasurementsMap(ProductVO product);
}
......@@ -27,7 +27,6 @@ import net.sumaris.core.model.data.ExpectedSale;
import net.sumaris.core.vo.data.ExpectedSaleVO;
import java.util.List;
import java.util.Set;
/**
* @author peck7 on 01/09/2020.
......@@ -37,6 +36,4 @@ public interface ExpectedSaleRepository
List<ExpectedSale> getExpectedSaleByTripId(int tripId);
Set<Integer> getAllIdsByTripId(int tripId);
}
......@@ -8,6 +8,7 @@ import net.sumaris.core.model.data.Landing;
import net.sumaris.core.model.data.Trip;
import net.sumaris.core.model.referential.SaleType;
import net.sumaris.core.model.referential.location.Location;
import net.sumaris.core.util.Beans;
import net.sumaris.core.vo.data.ExpectedSaleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
......@@ -15,7 +16,6 @@ import org.springframework.context.annotation.Lazy;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public class ExpectedSaleRepositoryImpl
......@@ -110,7 +110,8 @@ public class ExpectedSaleRepositoryImpl
sales = sales.stream().filter(Objects::nonNull).collect(Collectors.toList());
// Get existing fishing areas
Set<Integer> existingIds = self.getAllIdsByTripId(tripId);
Trip parent = getById(Trip.class, tripId);
final List<Integer> existingIds = Beans.collectIds(parent.getExpectedSales());
// Save
sales.forEach(sale -> {
......
......@@ -64,7 +64,7 @@ public class ExpectedSaleServiceImpl implements ExpectedSaleService {
@Override
public List<ExpectedSaleVO> saveAllByTripId(int tripId, List<ExpectedSaleVO> sources) {
Preconditions.checkNotNull(sources);
sources.forEach(this::checkSale);
sources.forEach(this::checkExpectedSale);
List<ExpectedSaleVO> saved = expectedSaleRepository.saveAllByTripId(tripId, sources);
......@@ -108,7 +108,7 @@ public class ExpectedSaleServiceImpl implements ExpectedSaleService {
/* -- protected methods -- */
protected void checkSale(final ExpectedSaleVO source) {
protected void checkExpectedSale(final ExpectedSaleVO source) {
Preconditions.checkNotNull(source);
Preconditions.checkNotNull(source.getSaleLocation(), "Missing saleLocation");
Preconditions.checkNotNull(source.getSaleLocation().getId(), "Missing saleLocation.id");
......@@ -120,18 +120,20 @@ public class ExpectedSaleServiceImpl implements ExpectedSaleService {
// Save measurements
if (source.getMeasurementValues() != null) {
measurementDao.saveSaleMeasurementsMap(source.getId(), source.getMeasurementValues());
measurementDao.saveExpectedSaleMeasurementsMap(source.getId(), source.getMeasurementValues());
}
else {
List<MeasurementVO> measurements = Beans.getList(source.getMeasurements());
measurements.forEach(m -> fillDefaultProperties(source, m, SaleMeasurement.class));
measurements = measurementDao.saveSaleMeasurements(source.getId(), measurements);
measurements = measurementDao.saveExpectedSaleMeasurements(source.getId(), measurements);
source.setMeasurements(measurements);
}
// Save produces
if (source.getProducts() != null) source.getProducts().forEach(product -> fillDefaultProperties(source, product));
productService.saveBySaleId(source.getId(), source.getProducts());
source.setProducts(
productService.saveByExpectedSaleId(source.getId(), source.getProducts())
);
}
protected void fillDefaultProperties(ExpectedSaleVO parent, MeasurementVO measurement, Class<? extends IMeasurementEntity> entityClass) {
......@@ -143,6 +145,6 @@ public class ExpectedSaleServiceImpl implements ExpectedSaleService {
protected void fillDefaultProperties(ExpectedSaleVO parent, ProductVO product) {
if (product == null) return;
product.setSaleId(parent.getId());
product.setExpectedSaleId(parent.getId());
}
}
......@@ -10,19 +10,18 @@ package net.sumaris.core.service.data;
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import net.sumaris.core.dao.data.MeasurementDao;
......@@ -48,6 +47,7 @@ import net.sumaris.core.vo.data.QuantificationMeasurementVO;
import net.sumaris.core.vo.data.batch.BatchFetchOptions;
import net.sumaris.core.vo.data.batch.BatchVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
......@@ -404,9 +404,27 @@ public class PacketServiceImpl implements PacketService {
if (ratioMeasurement == null) {
ratioMeasurement = createQuantificationMeasurement(BatchQuantificationMeasurement.class, estimatedRatioPmfmId);
}
ratioMeasurement.setAlphanumericalValue(
source.getRatios().stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(RATIO_SEPARATOR))
);
// add zeros on null values before first non null value
List<Integer> ratios = source.getRatios();
String ratioValue = "";
if (ratios.stream().anyMatch(Objects::nonNull)) {
// if a non-zero value exists
MutableBoolean firstNonNull = new MutableBoolean();
ratioValue = ratios.stream()
.map(ratio -> {
if (firstNonNull.isFalse() && (ratio == null || ratio == 0)) {
// set 0 on this null (or 0) value
return 0;
}
// a non null value found, return it
firstNonNull.setTrue();
return ratio;
})
.filter(Objects::nonNull) // filter other null values
.map(Object::toString)
.collect(Collectors.joining(RATIO_SEPARATOR));
}
ratioMeasurement.setAlphanumericalValue(ratioValue);
ratioMeasurement.setIsReferenceQuantification(false);
quantificationMeasurements.add(ratioMeasurement);
}
......
......@@ -48,6 +48,9 @@ public interface ProductService {
@Transactional(readOnly = true)
List<ProductVO> getBySaleId(int saleId);
@Transactional(readOnly = true)
List<ProductVO> getByExpectedSaleId(int expectedSaleId);
ProductVO save(ProductVO product);
List<ProductVO> save(List<ProductVO> products);
......@@ -58,6 +61,8 @@ public interface ProductService {
List<ProductVO> saveBySaleId(int saleId, List<ProductVO> products);
List<ProductVO> saveByExpectedSaleId(int id, List<ProductVO> products);
void delete(int id);
void delete(List<Integer> ids);
......@@ -69,4 +74,5 @@ public interface ProductService {
ProductVO unvalidate(ProductVO product);
void fillMeasurementsMap(ProductVO product);
}
......@@ -67,6 +67,11 @@ public class ProductServiceImpl implements ProductService {
return productRepository.findAll(ProductFilterVO.builder().saleId(saleId).build());
}
@Override
public List<ProductVO> getByExpectedSaleId(int expectedSaleId) {
return productRepository.findAll(ProductFilterVO.builder().expectedSaleId(expectedSaleId).build());
}
@Override
public ProductVO save(ProductVO product) {
checkProduct(product);
......@@ -101,6 +106,12 @@ public class ProductServiceImpl implements ProductService {
return productRepository.saveBySaleId(saleId, products);
}
@Override
public List<ProductVO> saveByExpectedSaleId(int expectedSaleId, List<ProductVO> products) {
checkProducts(products);
return productRepository.saveByExpectedSaleId(expectedSaleId, products);
}
@Override
public void delete(int id) {
productRepository.deleteById(id);
......
......@@ -148,7 +148,9 @@ public class SaleServiceImpl implements SaleService {
// Save produces
if (source.getProducts() != null) source.getProducts().forEach(product -> fillDefaultProperties(source, product));
productService.saveBySaleId(source.getId(), source.getProducts());
source.setProducts(
productService.saveBySaleId(source.getId(), source.getProducts())
);
}
protected void fillDefaultProperties(SaleVO parent, MeasurementVO measurement, Class<? extends IMeasurementEntity> entityClass) {
......
......@@ -38,7 +38,6 @@ import net.sumaris.core.event.entity.EntityDeleteEvent;
import net.sumaris.core.event.entity.EntityInsertEvent;
import net.sumaris.core.event.entity.EntityUpdateEvent;
import net.sumaris.core.exception.SumarisTechnicalException;
import net.sumaris.core.model.data.Landing;
import net.sumaris.core.model.data.Trip;
import net.sumaris.core.model.data.VesselUseMeasurement;
import net.sumaris.core.model.referential.SaleType;
......@@ -175,13 +174,13 @@ public class TripServiceImpl implements TripService {
public void fillTripLandingLinks(TripVO target) {
Preconditions.checkNotNull(target);
Preconditions.checkNotNull(target.getId());
Landing landing = landingRepository.getByTripId(target.getId());
if (landing != null) {
landingRepository.findByTripId(target.getId()).ifPresent(landing -> {
target.setLanding(landingRepository.toVO(landing, DataFetchOptions.builder().withRecorderDepartment(false).withObservers(false).build()));
if (landing.getObservedLocation() != null) {
target.setObservedLocationId(landing.getObservedLocation().getId());
}
}
});
}
@Override
......@@ -336,11 +335,10 @@ public class TripServiceImpl implements TripService {
null;
// Remove link LANDING->TRIP
Landing landing = landingRepository.getByTripId(id);
if (landing != null) {
landingRepository.findByTripId(id).ifPresent(landing -> {
landing.setTrip(null);
landingRepository.save(landing);
}
});
// Apply deletion
tripRepository.deleteById(id);
......@@ -621,6 +619,13 @@ public class TripServiceImpl implements TripService {
}
expectedSale.setTripId(parent.getId());
// Also set trip recorder department to expected sale's products, because expected sale don't have it
if (CollectionUtils.isNotEmpty(expectedSale.getProducts())) {
expectedSale.getProducts().stream()
.filter(productVO -> productVO.getRecorderDepartment() == null)
.forEach(productVO -> productVO.setRecorderDepartment(parent.getRecorderDepartment()));
}
}
protected void fillDefaultProperties(TripVO parent, PhysicalGearVO gear) {
......
......@@ -51,5 +51,6 @@ public class ProductFilterVO implements IRootDataFilter {
private Integer landingId;
private Integer operationId;
private Integer saleId;
private Integer expectedSaleId;
}
......@@ -821,6 +821,16 @@ public class DataGraphQLService {
return productService.getBySaleId(sale.getId());
}
@GraphQLQuery(name = "products", description = "Get expected sale's products")
public List<ProductVO> getProductsByExpectedSale(@GraphQLContext ExpectedSaleVO expectedSale) {
if (CollectionUtils.isNotEmpty(expectedSale.getProducts())) {
return expectedSale.getProducts();
}
return productService.getByExpectedSaleId(expectedSale.getId());
}
@GraphQLQuery(name = "products", description = "Get landing's products")
public List<ProductVO> getProductsByLanding(@GraphQLContext LandingVO landing) {
return productService.getByLandingId(landing.getId());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment