1 Commits

Author SHA1 Message Date
5181f5c258 feat(inventory): consolidate inventory lines
Group inventory lines by location, product, unit and tracking Number
Optionally include internal tracking number
Create consolidated line and archive originals
Preserve counting data (value, user, date)
2026-01-07 11:44:14 +01:00
8 changed files with 438 additions and 204 deletions

View File

@ -149,10 +149,6 @@
<boolean name="isDangerousProduct" title="Is dangerous" />
<boolean name="needDt1Validation" title="DT1 validation required" massUpdate="true"/>
<boolean name="needDt2Validation" title="DT2 validation required" massUpdate="true"/>
<boolean name="needQaQc1Validation" title="QAQC1 validation required" massUpdate="true"/>
<boolean name="needQaQc2Validation" title="QAQC2 validation required" massUpdate="true"/>
<many-to-one name="coaSpec" ref="com.axelor.meta.db.MetaFile" />
@ -213,10 +209,6 @@
<field name="shp" />
<field name="stklim" />
<field name="ug" />
<field name="needDt1Validation" />
<field name="needDt2Validation" />
<field name="needQaQc1Validation" />
<field name="needQaQc2Validation" />
<message if="true" on="UPDATE">Product updated</message>
</track>
</entity>

View File

@ -1,81 +0,0 @@
/*
* Axelor Business Solutions
*
* Copyright (C) 2019 Axelor (<http://axelor.com>).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.axelor.apps.message.job;
import com.axelor.apps.message.db.Message;
import com.axelor.apps.message.db.repo.MessageRepository;
import com.axelor.apps.message.service.MessageService;
import com.axelor.exception.service.TraceBackService;
import com.google.inject.Inject;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.util.List;
import javax.mail.MessagingException;
import com.axelor.exception.AxelorException;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** An example {@link Job} class that prints a some messages to the stderr. */
public class SendEmailJob implements Job {
private final Logger log = LoggerFactory.getLogger(SendEmailJob.class);
@Inject private MessageService messageService;
@Inject private MessageRepository messageRepository;
@Override
public void execute(JobExecutionContext context) {
LocalDate today = LocalDate.now();
LocalDateTime startOfDay = today.atStartOfDay();
List<Message> draftMessages = messageRepository
.all()
.filter("self.statusSelect = 1 AND self.createdOn >= :startOfDay")
.bind("startOfDay", startOfDay)
.fetch();
log.debug("Total of draft messages : {}", draftMessages.size());
for (Message message : draftMessages) {
try {
Message m = messageService.sendMessage(message);
} catch (AxelorException e) {
TraceBackService.trace(e);
}
}
List<Message> inProgressMessages = messageRepository
.all()
.filter("self.statusSelect = 2 AND self.createdOn >= :startOfDay")
.bind("startOfDay", startOfDay)
.fetch();
log.debug("Total of in progress messages : {}", inProgressMessages.size());
for (Message message : inProgressMessages) {
try {
Message m = messageService.sendMessage(message);
} catch (AxelorException e) {
TraceBackService.trace(e);
}
}
}
}

View File

@ -27,6 +27,7 @@ import com.axelor.apps.stock.db.TrackingNumber;
import com.axelor.apps.stock.db.repo.InventoryLineRepository;
import com.axelor.apps.stock.db.repo.TrackingNumberRepository;
import com.axelor.auth.AuthUtils;
import com.axelor.auth.db.User;
import com.axelor.db.Query;
import com.axelor.inject.Beans;
import com.google.inject.Inject;
@ -34,12 +35,17 @@ import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class InventoryLineService {
@Inject private ProductRepository productRepository;
private TrackingNumberRepository trackingNumberRepository;
private InventoryLineRepository inventoryLineRepository;
@Inject private InventoryLineRepository inventoryLineRepository;
public InventoryLine createInventoryLine(
Inventory inventory,
@ -171,4 +177,370 @@ public class InventoryLineService {
Beans.get(InventoryLineRepository.class).save(line);
}
@Transactional
public void consolidateInventoryLines(StockLocation stockLocation, Boolean addInternalTrackingNumber) {
List<InventoryLine> inventoryLines =
inventoryLineRepository
.all()
.filter(
"self.stockLocation = ?1 " +
//"AND (self.isConsolidate = false OR self.isConsolidate is null) " +
"AND (self.archived = false OR self.archived is null)",
stockLocation
)
.fetch();
System.out.println("************* lines" + inventoryLines);
Map<String, List<InventoryLine>> groupedLines =
inventoryLines.stream()
.filter(line -> line.getProductName() != null)
.filter(line ->
!addInternalTrackingNumber ||
line.getInternalTrackingNumberStr() == null
)
.collect(Collectors.groupingBy(line -> {
String key =
line.getStockLocation().getId() + "|" +
(line.getProduct() != null
? line.getProduct().getId()
: line.getProductName().trim().toUpperCase()) + "|" +
(line.getUnit() != null ? line.getUnit().getId() : "NULL") + "|" +
(line.getTrackingNumber() != null
? line.getTrackingNumber().getId()
: "NULL") + "|" +
(line.getTrackingNumberStr() != null
? line.getTrackingNumberStr().trim().toUpperCase()
: "NULL");
if (addInternalTrackingNumber) {
key += "|" +
(line.getInternalTrackingNumberStr() != null
? line.getInternalTrackingNumberStr().trim().toUpperCase()
: "NULL");
}
return key;
}));
List<InventoryLine> consolidatedInventoryLines = new ArrayList<>();
System.out.println("************* lines" + groupedLines);
for (List<InventoryLine> lines : groupedLines.values()) {
if (lines.size() <= 1) {
continue;
}
InventoryLine consolidated1 = lines.stream()
.filter(InventoryLine::getIsConsolidate)
.findFirst()
.orElse(null);
boolean hasConsolidatedLine = consolidated1 != null;
if(!hasConsolidatedLine){
InventoryLine first = lines.get(0);
BigDecimal firstCounting = BigDecimal.ZERO;
User firstCountingByUser = null;
LocalDateTime firstCountingDate = null;
BigDecimal secondCounting = BigDecimal.ZERO;
User secondCountingByUser = null;
LocalDateTime secondCountingDate = null;
BigDecimal thirdCounting = BigDecimal.ZERO;
User thirdCountingByUser = null;
LocalDateTime thirdCountingDate = null;
BigDecimal forthCounting = BigDecimal.ZERO;
User forthCountingByUser = null;
LocalDateTime forthCountingDate = null;
BigDecimal controlCounting = BigDecimal.ZERO;
User controlCountingByUser = null;
LocalDateTime controlCountingDate = null;
BigDecimal fifthCounting = BigDecimal.ZERO;
User fifthCountingByUser = null;
LocalDateTime fifthCountingDate = null;
BigDecimal sixthCounting = BigDecimal.ZERO;
User sixthCountingByUser = null;
LocalDateTime sixthCountingDate = null;
for (InventoryLine line : lines) {
if (line.getFirstCounting() != null) {
firstCounting = firstCounting.add(line.getFirstCounting());
if (firstCountingByUser == null) {
firstCountingByUser = line.getFirstCountingByUser();
firstCountingDate = line.getFirstCountingDate();
}
}
if (line.getSecondCounting() != null) {
secondCounting = secondCounting.add(line.getSecondCounting());
if (secondCountingByUser == null) {
secondCountingByUser = line.getSecondCountingByUser();
secondCountingDate = line.getSecondCountingDate();
}
}
if (line.getThirdCounting() != null) {
thirdCounting = thirdCounting.add(line.getThirdCounting());
if (thirdCountingByUser == null) {
thirdCountingByUser = line.getThirdCountingByUser();
thirdCountingDate = line.getThirdCountingDate();
}
}
if (line.getForthCounting() != null) {
forthCounting = forthCounting.add(line.getForthCounting());
if (forthCountingByUser == null) {
forthCountingByUser = line.getForthCountingByUser();
forthCountingDate = line.getForthCountingDate();
}
}
if (line.getControlCounting() != null) {
controlCounting = controlCounting.add(line.getControlCounting());
if (controlCountingByUser == null) {
controlCountingByUser = line.getControlCountingByUser();
controlCountingDate = line.getControlCountingDate();
}
}
if (line.getFifthCounting() != null) {
fifthCounting = fifthCounting.add(line.getFifthCounting());
if (fifthCountingByUser == null) {
fifthCountingByUser = line.getFifthCountingByUser();
fifthCountingDate = line.getFifthCountingDate();
}
}
if (line.getSixthCounting() != null) {
sixthCounting = sixthCounting.add(line.getSixthCounting());
if (sixthCountingByUser == null) {
sixthCountingByUser = line.getSixthCountingByUser();
sixthCountingDate = line.getSixthCountingDate();
}
}
}
InventoryLine consolidated = new InventoryLine();
consolidated.setStockLocation(first.getStockLocation());
if(first.getProduct() != null)
consolidated.setProduct(first.getProduct());
consolidated.setProductName(first.getProductName().trim().toUpperCase());
if(first.getUnit() != null)
consolidated.setUnit(first.getUnit());
if (first.getTrackingNumber() != null) {
consolidated.setTrackingNumber(first.getTrackingNumber());
}
if (first.getTrackingNumberStr() != null) {
consolidated.setTrackingNumberStr(first.getTrackingNumberStr().trim().toUpperCase());
}
if (addInternalTrackingNumber && first.getInternalTrackingNumberStr() != null)
consolidated.setInternalTrackingNumberStr(first.getInternalTrackingNumberStr().trim().toUpperCase());
consolidated.setFirstCounting(firstCounting);
consolidated.setFirstCountingByUser(firstCountingByUser);
consolidated.setFirstCountingDate(firstCountingDate);
consolidated.setSecondCounting(secondCounting);
consolidated.setSecondCountingByUser(secondCountingByUser);
consolidated.setSecondCountingDate(secondCountingDate);
consolidated.setThirdCounting(thirdCounting);
consolidated.setThirdCountingByUser(thirdCountingByUser);
consolidated.setThirdCountingDate(thirdCountingDate);
consolidated.setForthCounting(forthCounting);
consolidated.setForthCountingByUser(forthCountingByUser);
consolidated.setForthCountingDate(forthCountingDate);
consolidated.setControlCounting(controlCounting);
consolidated.setControlCountingByUser(controlCountingByUser);
consolidated.setControlCountingDate(controlCountingDate);
consolidated.setFifthCounting(fifthCounting);
consolidated.setFifthCountingByUser(fifthCountingByUser);
consolidated.setFifthCountingDate(fifthCountingDate);
consolidated.setSixthCounting(sixthCounting);
consolidated.setSixthCountingByUser(sixthCountingByUser);
consolidated.setSixthCountingDate(sixthCountingDate);
consolidated.setIsConsolidate(true);
inventoryLineRepository.save(consolidated);
// Archive old lines
for (InventoryLine line : lines) {
line.setArchived(true);
inventoryLineRepository.save(line);
}
} else {
InventoryLine consolidated = consolidated1;
BigDecimal firstCounting =
consolidated.getFirstCounting() != null
? consolidated.getFirstCounting()
: BigDecimal.ZERO;
BigDecimal secondCounting =
consolidated.getSecondCounting() != null
? consolidated.getSecondCounting()
: BigDecimal.ZERO;
BigDecimal thirdCounting =
consolidated.getThirdCounting() != null
? consolidated.getThirdCounting()
: BigDecimal.ZERO;
BigDecimal forthCounting =
consolidated.getForthCounting() != null
? consolidated.getForthCounting()
: BigDecimal.ZERO;
BigDecimal controlCounting =
consolidated.getControlCounting() != null
? consolidated.getControlCounting()
: BigDecimal.ZERO;
BigDecimal fifthCounting =
consolidated.getFifthCounting() != null
? consolidated.getFifthCounting()
: BigDecimal.ZERO;
BigDecimal sixthCounting =
consolidated.getSixthCounting() != null
? consolidated.getSixthCounting()
: BigDecimal.ZERO;
User firstCountingByUser = consolidated.getFirstCountingByUser();
LocalDateTime firstCountingDate = consolidated.getFirstCountingDate();
User secondCountingByUser = consolidated.getSecondCountingByUser();
LocalDateTime secondCountingDate = consolidated.getSecondCountingDate();
User thirdCountingByUser = consolidated.getThirdCountingByUser();
LocalDateTime thirdCountingDate = consolidated.getThirdCountingDate();
User forthCountingByUser = consolidated.getForthCountingByUser();
LocalDateTime forthCountingDate = consolidated.getForthCountingDate();
User controlCountingByUser = consolidated.getControlCountingByUser();
LocalDateTime controlCountingDate = consolidated.getControlCountingDate();
User fifthCountingByUser = consolidated.getFifthCountingByUser();
LocalDateTime fifthCountingDate = consolidated.getFifthCountingDate();
User sixthCountingByUser = consolidated.getSixthCountingByUser();
LocalDateTime sixthCountingDate = consolidated.getSixthCountingDate();
for (InventoryLine line : lines) {
if (line.getIsConsolidate()) {
continue; // skip the consolidated line itself
}
if (line.getFirstCounting() != null) {
firstCounting = firstCounting.add(line.getFirstCounting());
if (firstCountingByUser == null) {
firstCountingByUser = line.getFirstCountingByUser();
firstCountingDate = line.getFirstCountingDate();
}
}
if (line.getSecondCounting() != null) {
secondCounting = secondCounting.add(line.getSecondCounting());
if (secondCountingByUser == null) {
secondCountingByUser = line.getSecondCountingByUser();
secondCountingDate = line.getSecondCountingDate();
}
}
if (line.getThirdCounting() != null) {
thirdCounting = thirdCounting.add(line.getThirdCounting());
if (thirdCountingByUser == null) {
thirdCountingByUser = line.getThirdCountingByUser();
thirdCountingDate = line.getThirdCountingDate();
}
}
if (line.getForthCounting() != null) {
forthCounting = forthCounting.add(line.getForthCounting());
if (forthCountingByUser == null) {
forthCountingByUser = line.getForthCountingByUser();
forthCountingDate = line.getForthCountingDate();
}
}
if (line.getControlCounting() != null) {
controlCounting = controlCounting.add(line.getControlCounting());
if (controlCountingByUser == null) {
controlCountingByUser = line.getControlCountingByUser();
controlCountingDate = line.getControlCountingDate();
}
}
if (line.getFifthCounting() != null) {
fifthCounting = fifthCounting.add(line.getFifthCounting());
if (fifthCountingByUser == null) {
fifthCountingByUser = line.getFifthCountingByUser();
fifthCountingDate = line.getFifthCountingDate();
}
}
if (line.getSixthCounting() != null) {
sixthCounting = sixthCounting.add(line.getSixthCounting());
if (sixthCountingByUser == null) {
sixthCountingByUser = line.getSixthCountingByUser();
sixthCountingDate = line.getSixthCountingDate();
}
}
line.setArchived(true);
inventoryLineRepository.save(line);
}
consolidated.setFirstCounting(firstCounting);
consolidated.setFirstCountingByUser(firstCountingByUser);
consolidated.setFirstCountingDate(firstCountingDate);
consolidated.setSecondCounting(secondCounting);
consolidated.setSecondCountingByUser(secondCountingByUser);
consolidated.setSecondCountingDate(secondCountingDate);
consolidated.setThirdCounting(thirdCounting);
consolidated.setThirdCountingByUser(thirdCountingByUser);
consolidated.setThirdCountingDate(thirdCountingDate);
consolidated.setForthCounting(forthCounting);
consolidated.setForthCountingByUser(forthCountingByUser);
consolidated.setForthCountingDate(forthCountingDate);
consolidated.setControlCounting(controlCounting);
consolidated.setControlCountingByUser(controlCountingByUser);
consolidated.setControlCountingDate(controlCountingDate);
consolidated.setFifthCounting(fifthCounting);
consolidated.setFifthCountingByUser(fifthCountingByUser);
consolidated.setFifthCountingDate(fifthCountingDate);
consolidated.setSixthCounting(sixthCounting);
consolidated.setSixthCountingByUser(sixthCountingByUser);
consolidated.setSixthCountingDate(sixthCountingDate);
inventoryLineRepository.save(consolidated);
}
}
}
}

View File

@ -418,59 +418,22 @@ public class StockMoveServiceImpl implements StockMoveService {
String newStockSeq = null;
stockMoveLineService.checkTrackingNumber(stockMove);
stockMoveLineService.checkConformitySelection(stockMove);
System.out.println("Checking oooo...................");
System.out.println("----------------------------------------------------");
System.out.println("stockMove.getTypeSelect() : " + stockMove.getTypeSelect());
System.out.println("----------------------------------------------------");
// checking .....
if (stockMove.getFromStockLocation().getTypeSelect() != StockLocationRepository.TYPE_VIRTUAL)
{
List<Long> listOfIds = Arrays.asList(10L, 11L, 13L, 14L, 15L, 16L, 13L, 12L, 54L, 55L, 58L,50L);
System.out.println("Checking...................");
System.out.println(listOfIds.contains(stockMove.getToStockLocation().getId()));
System.out.println("Checking...................");
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INTERNAL){
System.out.println("INTERNAL MOVE");
StockConfig stockConfig = stockMove.getCompany().getStockConfig();
StockLocation parentwasteStockLocation = stockConfig.getWasteStockLocationParent();
if(Boolean.TRUE.equals(stockMove.getToStockLocation().getNeedCheckInVerification())){
System.out.println("Check-in required for this stock location...");
checkIfConforme(stockMove);
checkIfNonConformityTag(stockMove);
} else if (parentwasteStockLocation.equals(stockMove.getToStockLocation().getParentStockLocation())){
System.out.println("**************************** Child of Waste Parent ******************************");
CheckIfNotNotconforme(stockMove);
checkIfNonConformityTag(stockMove);
}
if(listOfIds.contains(stockMove.getToStockLocation().getId())){
checkIfQuarantine(stockMove);
checkIfNonConformityTag(stockMove);
}
}
else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING
&& stockMove.getPartner().getId() != 853
&& stockMove.getIsReversion() == false){
System.out.println("Livraison Client.");
checkIfConforme(stockMove);
checkIfNonConformityTag(stockMove);
}
else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING
&& stockMove.getPartner().getId() == 853
&& stockMove.getIsReversion() == false){
System.out.println("Sortie.");
StockConfig stockConfig = stockMove.getCompany().getStockConfig();
StockLocation nonCoreStockLocationParent = stockConfig.getNonCoreStockLocation();
StockLocation parentwasteStockLocation = stockConfig.getWasteStockLocationParent();
if (parentwasteStockLocation.equals(stockMove.getToStockLocation().getParentStockLocation())){
System.out.println("**************************** Child of Waste Parent ******************************");
CheckIfNotNotconforme(stockMove);
checkIfNonConformityTag(stockMove);
} else if (!nonCoreStockLocationParent.equals(stockMove.getToStockLocation().getParentStockLocation())) {
checkIfConforme(stockMove);
checkIfNonConformityTag(stockMove);
}
}
checkExpirationDates(stockMove);
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING) {
@ -1629,81 +1592,53 @@ public class StockMoveServiceImpl implements StockMoveService {
}
public void checkIfConforme(StockMove stockMove)
public void checkIfQuarantine(StockMove stockMove)
throws AxelorException {
Query sql =
JPA.em()
.createNativeQuery(
"SELECT LINE.ID"+
" FROM STOCK_STOCK_MOVE_LINE LINE LEFT JOIN STOCK_STOCK_LOCATION_LINE LOCATION_LINE ON LINE.TRACKING_NUMBER = LOCATION_LINE.TRACKING_NUMBER and LINE.product = LOCATION_LINE.product"+
" where LOCATION_LINE.DETAILS_STOCK_LOCATION = ?1 AND LOCATION_LINE.CONFORMITY_SELECT != 2 AND LINE.STOCK_MOVE = ?2");
" FROM STOCK_STOCK_MOVE_LINE LINE LEFT JOIN STOCK_STOCK_LOCATION_LINE LOCATION_LINE ON LINE.TRACKING_NUMBER = LOCATION_LINE.TRACKING_NUMBER and LINE.INTERNAL_TRACKING_NUMBER = LOCATION_LINE.INTERNAL_TRACKING_NUMBER and LINE.product = LOCATION_LINE.product"+
" where LOCATION_LINE.DETAILS_STOCK_LOCATION = ?1 AND LOCATION_LINE.CONFORMITY_SELECT != 2 AND LOCATION_LINE.CONFORMITY_SELECT != 5 AND LINE.STOCK_MOVE = ?2");
sql.setParameter(1, stockMove.getFromStockLocation().getId());
sql.setParameter(2, stockMove.getId());
System.out.println("*****************checkIfConforme******************");
System.out.println("*****************checkIfQuarantine******************");
System.out.println(sql.getResultList().size() > 0);
System.out.println("******************checkIfConforme*****************");
System.out.println("******************checkIfQuarantine*****************");
if (sql.getResultList().size() > 0) {
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
"Certaines lignes ne sont pas conformes (état différent de 'Conforme').");
"Vous avez une ligne en etat qurantaine");
}
}
public void CheckIfNotNotconforme(StockMove stockMove)
public void checkIfNonConformityTag(StockMove stockMove)
throws AxelorException {
Query sql =
JPA.em()
.createNativeQuery(
"SELECT LINE.ID"+
" FROM STOCK_STOCK_MOVE_LINE LINE LEFT JOIN STOCK_STOCK_LOCATION_LINE LOCATION_LINE ON LINE.TRACKING_NUMBER = LOCATION_LINE.TRACKING_NUMBER and LINE.product = LOCATION_LINE.product"+
" where LOCATION_LINE.DETAILS_STOCK_LOCATION = ?1 AND LOCATION_LINE.CONFORMITY_SELECT != 3 AND LINE.STOCK_MOVE = ?2");
sql.setParameter(1, stockMove.getFromStockLocation().getId());
sql.setParameter(2, stockMove.getId());
"SELECT LINE.ID" +
" FROM STOCK_STOCK_MOVE_LINE LINE LEFT JOIN STOCK_STOCK_LOCATION_LINE LOCATION_LINE ON LINE.TRACKING_NUMBER = LOCATION_LINE.TRACKING_NUMBER and LINE.INTERNAL_TRACKING_NUMBER = LOCATION_LINE.INTERNAL_TRACKING_NUMBER and LINE.product = LOCATION_LINE.product" +
" where LOCATION_LINE.DETAILS_STOCK_LOCATION = :location AND LOCATION_LINE.is_conform_tag is not true AND LINE.STOCK_MOVE = :move");
System.out.println("*****************CheckIfNotNotconforme******************");
System.out.println(sql.getResultList().size() > 0);
System.out.println("******************CheckIfNotNotconforme*****************");
if (sql.getResultList().size() > 0) {
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
"Toutes les lignes doivent être en état 'Non conforme'.");
}
}
public void checkIfNonConformityTag(StockMove stockMove)
throws AxelorException {
Query sql = JPA.em()
.createNativeQuery(
"SELECT LINE.ID" +
" FROM STOCK_STOCK_MOVE_LINE LINE" +
" LEFT JOIN STOCK_STOCK_LOCATION_LINE LOCATION_LINE" +
" ON LINE.TRACKING_NUMBER = LOCATION_LINE.TRACKING_NUMBER" +
" AND LINE.PRODUCT = LOCATION_LINE.PRODUCT" +
" WHERE LOCATION_LINE.DETAILS_STOCK_LOCATION = :location" +
" AND (LOCATION_LINE.IS_CONFORM_TAG IS NULL OR LOCATION_LINE.IS_CONFORM_TAG = FALSE)" +
" AND LINE.STOCK_MOVE = :move");
sql.setParameter("location", stockMove.getFromStockLocation().getId());
sql.setParameter("move", stockMove.getId());
System.out.println("*****************checkIfNonConformityTag*****************");
boolean hasNonTags = !sql.getResultList().isEmpty();
System.out.println("Has non conform tag: " + hasNonTags);
System.out.println("*****************checkIfNonConformityTag****************");
if (hasNonTags) {
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
"Vous avez une ligne non étiquetée");
}
sql.setParameter("location", stockMove.getFromStockLocation().getId());
sql.setParameter("move", stockMove.getId());
System.out.println("*****************checkIfNonConformityTag*****************");
System.out.println(sql.getResultList().size() > 0);
System.out.println("*****************checkIfNonConformityTag****************");
if (sql.getResultList().size() > 0) {
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
"Vous avez une ligne non étiquetée");
}
}
@Override
public void massPlan(List<Long> moveIds) throws AxelorException {

View File

@ -22,9 +22,11 @@ import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.stock.db.Inventory;
import com.axelor.apps.stock.db.InventoryLine;
import com.axelor.apps.stock.db.StockLocationLine;
import com.axelor.apps.stock.db.StockLocation;
import com.axelor.apps.stock.db.TrackingNumber;
import com.axelor.apps.stock.db.repo.InventoryLineRepository;
import com.axelor.apps.stock.db.repo.InventoryRepository;
import com.axelor.apps.stock.db.repo.StockLocationRepository;
import com.axelor.apps.stock.db.repo.TrackingNumberRepository;
import com.axelor.apps.stock.service.InventoryLineService;
import com.axelor.exception.AxelorException;
@ -38,6 +40,7 @@ import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.math.BigDecimal;
import java.util.Map;
import java.util.LinkedHashMap;
@Singleton
public class InventoryLineController {
@ -221,4 +224,29 @@ public class InventoryLineController {
response.setFlash("Updated Successfully");
// response.setReload(true);
}
public void consolidateInventoryLines(ActionRequest request, ActionResponse response){
Object object = request.getContext().get("stockLocation");
LinkedHashMap<String, Object> stockLocationMap = (LinkedHashMap<String, Object>) object;
Integer stockLocationIdInt = (Integer) stockLocationMap.get("id");
Long stockLocationId = stockLocationIdInt.longValue();
StockLocation stockLocation = Beans.get(StockLocationRepository.class).find(stockLocationId);
Beans.get(InventoryLineService.class).consolidateInventoryLines(stockLocation,false);
response.setFlash("Updated Successfully");
}
public void consolidateInventoryLinesWithInternalTrackingNumber(ActionRequest request, ActionResponse response){
Object object = request.getContext().get("stockLocation");
LinkedHashMap<String, Object> stockLocationMap = (LinkedHashMap<String, Object>) object;
Integer stockLocationIdInt = (Integer) stockLocationMap.get("id");
Long stockLocationId = stockLocationIdInt.longValue();
StockLocation stockLocation = Beans.get(StockLocationRepository.class).find(stockLocationId);
Beans.get(InventoryLineService.class).consolidateInventoryLines(stockLocation,true);
response.setFlash("Updated Successfully");
}
}

View File

@ -59,6 +59,7 @@
<integer name="conformitySelect" title="Conformity" selection="stock.move.line.conformity.select"/>
<integer name="stateSelect" title="State" selection="inventory.line.state.select"/>
<boolean name="isConsolidate" title="is Consolidate"/>
<track>

View File

@ -18,9 +18,6 @@
<many-to-one name="supplierVirtualStockLocation" ref="com.axelor.apps.stock.db.StockLocation" title="Supplier virtual stock location"/>
<many-to-one name="inventoryVirtualStockLocation" ref="com.axelor.apps.stock.db.StockLocation" title="Inventory virtual stock location"/>
<many-to-one name="nonCoreStockLocation" ref="com.axelor.apps.stock.db.StockLocation" title="Non-core stock location"/>
<many-to-one name="wasteStockLocationParent" ref="com.axelor.apps.stock.db.StockLocation" title="Parent waste stock location"/>
<many-to-one name="customsMassUnit" ref="com.axelor.apps.base.db.Unit" title="Unit of mass"/>
<boolean name="realizeStockMovesUponParcelPalletCollection" title="Realize stock moves upon parcel/pallet collection" />
@ -105,9 +102,6 @@
<field name="displayTrackNbrOnCertificateOfConformityPrinting" on="UPDATE"/>
<field name="displayExtRefOnCertificateOfConformityPrinting" on="UPDATE"/>
<field name="nonCoreStockLocation" on="UPDATE"/>
<field name="wasteStockLocationParent" on="UPDATE"/>
</track>
</entity>

View File

@ -21,8 +21,6 @@
<many-to-many name="stockLocationList" ref="com.axelor.apps.stock.db.StockLocation" title="Stock locations"/>
<many-to-one name="picture" ref="com.axelor.meta.db.MetaFile" title="Photo" index="false"/>
<boolean name="needCheckInVerification" title="Check-in verification required" default="false" massUpdate="true"/>
<finder-method name="findByCompany" using="company"/>
<finder-method name="findByPartner" using="partner"/>
@ -44,10 +42,5 @@
]]></extra-code>
<track on="UPDATE">
<field name="needCheckInVerification" />
</track>
</entity>
</domain-models>