package com.qcadoo.mes.materialFlowResources.batch; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.qcadoo.localization.api.TranslationService; import com.qcadoo.mes.basic.BasicLookupController; import com.qcadoo.mes.basic.GridResponse; import com.qcadoo.mes.basic.LookupUtils; import com.qcadoo.mes.materialFlowResources.DocumentPositionService; import com.qcadoo.mes.materialFlowResources.ResourceDTO; import com.qcadoo.mes.materialFlowResources.WarehouseMethodOfDisposalService; @Controller @RequestMapping(value = "resource") public class ResourceLookupController extends BasicLookupController<ResourceDTO> { @Autowired private DocumentPositionService documentPositionService; @Autowired private WarehouseMethodOfDisposalService warehouseMethodOfDisposalService; @Autowired private LookupUtils lookupUtils; @Autowired private TranslationService translationService; @Override @ResponseBody @RequestMapping(value = "records", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public GridResponse<ResourceDTO> getRecords(@RequestParam String sidx, @RequestParam String sord, @RequestParam(defaultValue = "1", required = false, value = "page") Integer page, @RequestParam(value = "rows") int perPage, @RequestParam(defaultValue = "0", required = false, value = "context") Long context, ResourceDTO record) { return getResponse(sidx, sord, page, perPage, record, context); } private GridResponse<ResourceDTO> getResponse(String sidx, String sord, Integer page, int perPage, ResourceDTO record, Long context) { String additionalCode = record.getAc(); boolean useAdditionalCode = org.apache.commons.lang3.StringUtils.isNotEmpty(additionalCode); Map<String, Object> parameters = geParameters(context, record, useAdditionalCode, additionalCode); boolean properFilter = prepareWasteFilter(record); if ("wasteString".equals(sidx)) { sidx = "waste"; } String query = getQuery(context, useAdditionalCode, documentPositionService.addMethodOfDisposalCondition(context, parameters, false, useAdditionalCode), !properFilter); GridResponse<ResourceDTO> response = lookupUtils.getGridResponse(query, sidx, sord, page, perPage, record, parameters); if (response.getRows().isEmpty() && useAdditionalCode) { parameters = geParameters(context, record, false, additionalCode); query = getQuery(context, false, documentPositionService.addMethodOfDisposalCondition(context, parameters, false, false), !properFilter); response = lookupUtils.getGridResponse(query, sidx, sord, page, perPage, record, parameters); } setTranslatedWasteFlag(response); return response; } protected String getQuery(final Long context, boolean useAdditionalCode, boolean addMethodOfDisposal, boolean wasteFilterIsWrong) { StringBuilder queryBuilder = new StringBuilder(); queryBuilder.append( "select %s from (select r.*, sl.number as storageLocation, pn.number as palletNumber, ac.code as additionalCode, bp.unit as unit "); queryBuilder.append("FROM materialflowresources_resource r "); queryBuilder.append("LEFT JOIN materialflowresources_storagelocation sl on sl.id = storageLocation_id "); queryBuilder.append("LEFT JOIN basic_additionalcode ac on ac.id = additionalcode_id "); queryBuilder.append("LEFT JOIN basic_product bp on bp.number = :product "); queryBuilder.append("LEFT JOIN basic_palletnumber pn on pn.id = palletnumber_id WHERE r.product_id = bp.id "); queryBuilder.append( " AND r.location_id in (SELECT DISTINCT COALESCE(locationfrom_id, locationto_id) as location from materialflowresources_document WHERE id = :context)"); queryBuilder.append(" AND r.conversion = :conversion AND r.availablequantity > 0 "); if (wasteFilterIsWrong) { queryBuilder.append(" AND waste IS NULL "); } if (useAdditionalCode) { // queryBuilder.append(" AND additionalcode_id = (SELECT id FROM basic_additionalcode WHERE code = :add_code) "); } if (addMethodOfDisposal) { // queryBuilder.append(" AND "); // queryBuilder.append(warehouseMethodOfDisposalService.getSqlConditionForResourceLookup(context)); // queryBuilder.append(" WHERE product_id = (SELECT id FROM basic_product WHERE number = :product)"); // queryBuilder // .append(" and location_id in (SELECT DISTINCT COALESCE(locationfrom_id, locationto_id) as location from // materialflowresources_document WHERE id = :context)"); // queryBuilder.append(" AND conversion = :conversion"); // if (useAdditionalCode) { // queryBuilder.append(" AND additionalcode_id = (SELECT id FROM basic_additionalcode WHERE code = :add_code) "); // } // queryBuilder.append(" )"); queryBuilder.append(warehouseMethodOfDisposalService.getSqlOrderByForResource(context)); } queryBuilder.append(") as resources"); return queryBuilder.toString(); } protected Map<String, Object> geParameters(Long context, ResourceDTO resourceDTO, boolean useAdditionalCode, String additionalCode) { Map<String, Object> params = new HashMap<>(); params.put("product", resourceDTO.getProduct()); params.put("conversion", resourceDTO.getConversion()); params.put("context", context); if (useAdditionalCode) { params.put("add_code", additionalCode); } resourceDTO.setProduct(null); resourceDTO.setConversion(null); resourceDTO.setAc(null); return params; } @Override protected List<String> getGridFields() { return Arrays.asList(new String[] { "number", "quantity", "unit", "quantityInAdditionalUnit", "givenUnit", "reservedQuantity", "availableQuantity", "expirationDate", "storageLocation", "batch", "palletNumber", "additionalCode", "wasteString" }); } @Override protected String getRecordName() { return "resource"; } @Override protected String getQueryForRecords(Long context) { return null; } private void setTranslatedWasteFlag(GridResponse<ResourceDTO> responce) { String yes = translationService.translate("documentGrid.gridColumn.wasteString.value.yes", LocaleContextHolder.getLocale()); String no = translationService.translate("documentGrid.gridColumn.wasteString.value.no", LocaleContextHolder.getLocale()); responce.getRows().forEach(resDTO -> resDTO.setWasteString(resDTO.isWaste() ? yes : no)); } private boolean prepareWasteFilter(ResourceDTO record) { String yes = translationService .translate("documentGrid.gridColumn.wasteString.value.yes", LocaleContextHolder.getLocale()).toLowerCase(); String no = translationService.translate("documentGrid.gridColumn.wasteString.value.no", LocaleContextHolder.getLocale()) .toLowerCase(); String filter = record.getWasteString(); record.setWasteString(null); if (filter != null) { filter = filter.toLowerCase(); } if (yes.equals(filter)) { record.setWaste(true); } else if (no.equals(filter)) { record.setWaste(false); } else if (!StringUtils.isEmpty(filter)) { return false; } else { record.setWaste(null); } return true; } }