temporary branch

This commit is contained in:
BACHIR SOULDI
2024-10-17 11:30:20 +01:00
parent cd115a234b
commit 742ec3e75e
212 changed files with 18396 additions and 1899 deletions

View File

@@ -21,14 +21,20 @@ import static com.axelor.apps.base.service.administration.AbstractBatch.FETCH_LI
import com.axelor.apps.account.db.Account;
import com.axelor.apps.account.db.AccountConfig;
import com.axelor.apps.account.db.AccountManagement;
import com.axelor.apps.account.db.AnalyticDistributionTemplate;
import com.axelor.apps.account.db.AnalyticMoveLine;
import com.axelor.apps.account.db.Journal;
import com.axelor.apps.account.db.Move;
import com.axelor.apps.account.db.MoveLine;
import com.axelor.apps.account.db.Tax;
import com.axelor.apps.account.db.TaxLine;
import com.axelor.apps.account.db.repo.AccountManagementRepository;
import com.axelor.apps.account.db.repo.AccountRepository;
import com.axelor.apps.account.db.repo.AnalyticMoveLineRepository;
import com.axelor.apps.account.db.repo.JournalRepository;
import com.axelor.apps.account.db.repo.MoveRepository;
import com.axelor.apps.account.exception.IExceptionMessage;
import com.axelor.apps.account.service.AccountManagementAccountService;
import com.axelor.apps.account.service.AnalyticMoveLineService;
import com.axelor.apps.account.service.ReconcileService;
@@ -52,8 +58,11 @@ import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
import com.axelor.apps.sale.db.SaleOrder;
import com.axelor.apps.sale.db.SaleOrderLine;
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
import com.axelor.apps.stock.db.InventoryLine;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.InventoryLineRepository;
import com.axelor.apps.stock.db.repo.StockLocationRepository;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.supplychain.db.repo.SupplychainBatchRepository;
@@ -61,6 +70,9 @@ import com.axelor.apps.supplychain.service.config.AccountConfigSupplychainServic
import com.axelor.db.JPA;
import com.axelor.db.Query;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
@@ -69,8 +81,10 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class AccountingCutOffServiceImpl implements AccountingCutOffService {
@@ -640,4 +654,347 @@ public class AccountingCutOffServiceImpl implements AccountingCutOffService {
}
return stockMoveLineIdList;
}
@Transactional(rollbackOn = {Exception.class})
public Move generateStockAccountMove(StockMove stockMove) throws AxelorException {
List<StockMoveLine> stockMoveLines = stockMove.getStockMoveLineList();
Map<StockMoveLine, Map<String, Account>> stockAccounts = new HashMap<>();
Company company = stockMove.getCompany();
Currency currency = stockMove.getCompany().getCurrency();
Partner partner = stockMove.getPartner();
LocalDate moveDate = stockMove.getEstimatedDate();
Journal journal = this.setJournal(stockMove);
for (StockMoveLine line : stockMoveLines) {
Map<String, Account> accountMap = new HashMap<String, Account>();
AccountManagement accountManagement =
Beans.get(AccountManagementRepository.class)
.all()
.filter("self.product = ?1 and self.company = ?2", line.getProduct(), company)
.fetchOne();
if(stockMove.getToStockLocation().getTypeSelect() == StockLocationRepository.TYPE_EXTERNAL){
Account stockAccount = null ;
if(line.getProduct().getFamilleProduit().getId() == 67L || line.getProduct().getFamilleProduit().getId() == 68L){
stockAccount = Beans.get(AccountRepository.class).find(595L);
}else if(line.getProduct().getFamilleProduit().getId() == 59L){
stockAccount = Beans.get(AccountRepository.class).find(3518L);
}else{
stockAccount = Beans.get(AccountRepository.class).find(4113L);
}
accountMap.put("stockAccount", stockAccount);
}else{
accountMap.put("stockAccount", accountManagement.getStockAccount());
}
accountMap.put("purchaseAccount", accountManagement.getPurchaseAccount());
accountMap.put("consumptionAccount", accountManagement.getConsumptionAccount());
stockAccounts.put(line, accountMap);
}
Move move =
moveCreateService.createMove(
journal,
company,
currency,
partner,
moveDate,
null,
MoveRepository.TECHNICAL_ORIGIN_AUTOMATIC);
int counter = 0;
for (StockMoveLine line : stockMoveLines) {
Account acc = stockAccounts.get(line).get("purchaseAccount");
Account acc2 = stockAccounts.get(line).get("stockAccount");
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING
&& stockMove.getPartner() == stockMove.getCompany().getPartner()) {
acc = stockAccounts.get(line).get("consumptionAccount");
acc2 = stockAccounts.get(line).get("stockAccount");
} else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING
&& stockMove.getPartner() != stockMove.getCompany().getPartner()) {
acc2 = stockAccounts.get(line).get("stockAccount");
acc = stockAccounts.get(line).get("purchaseAccount");
} else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING
&& stockMove.getPartner() == stockMove.getCompany().getPartner()) {
acc = stockAccounts.get(line).get("consumptionAccount");
acc2 = stockAccounts.get(line).get("stockAccount");
}
BigDecimal amountInCurrency = line.getUnitPriceUntaxed().multiply(line.getRealQty());
String description = stockMove.getStockMoveSeq() + "-" + line.getProduct().getCode();
if (line.getTrackingNumber() != null) {
description += "-" + line.getTrackingNumber().getTrackingNumberSeq();
}
if(line.getRealQty().compareTo(BigDecimal.ZERO) > 0 ){
MoveLine moveLine =
moveLineService.createMoveLine(
move,
partner,
acc,
amountInCurrency,
isDebit(stockMove),
moveDate,
++counter,
stockMove.getStockMoveSeq(),
description);
moveLine.setDate(moveDate);
moveLine.setDueDate(moveDate);
moveLine.setAccountId(acc.getId());
moveLine.setAccountCode(acc.getCode());
MoveLine moveLine2 =
moveLineService.createMoveLine(
move,
partner,
acc2,
amountInCurrency,
!isDebit(stockMove),
moveDate,
++counter,
stockMove.getStockMoveSeq(),
description);
moveLine2.setDate(moveDate);
moveLine2.setDueDate(moveDate);
moveLine2.setAccountId(acc2.getId());
moveLine2.setAccountCode(acc2.getCode());
move.addMoveLineListItem(moveLine);
move.addMoveLineListItem(moveLine2);
}
}
stockMove.setIsVentilated(true);
move.setIgnoreInAccountingOk(false);
move.setStatusSelect(MoveRepository.STATUS_DAYBOOK);
move.setStockMove(stockMove);
return move;
}
public List<Long> massGenerationMove(List<Long> ids) throws AxelorException {
List<Long> movesId = new ArrayList<>();
for (Long id : ids) {
StockMove stockMove = Beans.get(StockMoveRepository.class).find(id);
Move move = this.generateStockAccountMove(stockMove);
movesId.add(move.getId());
}
;
return movesId;
}
public boolean isDebit(StockMove stockMove) throws AxelorException {
boolean isDebit;
// stockMove.getToStockLocation().getTypeSelect() == StockLocationRepository.TYPE_VIRTUAL
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING) {
isDebit = false;
} else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING) {
isDebit = true;
} else
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get(IExceptionMessage.MOVE_1),
stockMove.getId());
return isDebit;
}
public Journal setJournal(StockMove stockMove) throws AxelorException {
Journal journal;
// stockMove.getToStockLocation().getTypeSelect() == StockLocationRepository.TYPE_VIRTUAL
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING) {
journal = Beans.get(JournalRepository.class).find(10L);
} else if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING) {
journal = Beans.get(JournalRepository.class).find(30L);
} else
throw new AxelorException(
stockMove,
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get(IExceptionMessage.MOVE_1),
stockMove.getId());
return journal;
}
public boolean isDebitInventoryLine(InventoryLine inventoryLine) throws AxelorException {
boolean isDebit;
// stockMove.getToStockLocation().getTypeSelect() == StockLocationRepository.TYPE_VIRTUAL
if (inventoryLine.getGap().compareTo(BigDecimal.ZERO) < 0) {
isDebit = false;
} else if (inventoryLine.getGap().compareTo(BigDecimal.ZERO) > 0) {
isDebit = true;
} else
throw new AxelorException(
inventoryLine,
TraceBackRepository.CATEGORY_MISSING_FIELD,
"Ecart = 0",
inventoryLine.getId());
return isDebit;
}
public Boolean isGapPositive(InventoryLine line){
if(line.getGap().compareTo(BigDecimal.ZERO) > 0){
return true;
}else{
return false;
}
}
@Transactional(rollbackOn = {Exception.class})
public Move generateInventoryLineMove(InventoryLine inventoryLine) throws AxelorException {
Map<InventoryLine, Map<String, Account>> stockAccounts = new HashMap<>();
Company company = inventoryLine.getInventory().getCompany();
Currency currency = inventoryLine.getInventory().getCompany().getCurrency();
Partner partner = inventoryLine.getInventory().getCompany().getPartner();
LocalDate moveDate = inventoryLine.getInventory().getPlannedEndDateT().toLocalDate();
Journal journal = Beans.get(JournalRepository.class).find(10L);
Map<String, Account> accountMap = new HashMap<String, Account>();
AccountManagement accountManagement =
Beans.get(AccountManagementRepository.class)
.all()
.filter("self.product = ?1 and self.company = ?2", inventoryLine.getProduct(), company)
.fetchOne();
if(accountManagement.getStockAccount() == null || accountManagement.getConsumptionAccount() == null){
throw new AxelorException(
inventoryLine,
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get(IExceptionMessage.VENTILATE_STATE_6),
inventoryLine.getProduct().getFullName());
}
accountMap.put("stockAccount", accountManagement.getStockAccount());
accountMap.put("consumptionAccount", accountManagement.getConsumptionAccount());
stockAccounts.put(inventoryLine, accountMap);
Move move =
moveCreateService.createMove(
journal,
company,
currency,
partner,
moveDate,
null,
MoveRepository.TECHNICAL_ORIGIN_AUTOMATIC);
int counter = 0;
Account acc = stockAccounts.get(inventoryLine).get("consumptionAccount");
Account acc2 = stockAccounts.get(inventoryLine).get("stockAccount");
if(inventoryLine.getJustifiedGap()){
if(isGapPositive(inventoryLine)){
acc = stockAccounts.get(inventoryLine).get("consumptionAccount");
acc2 = stockAccounts.get(inventoryLine).get("stockAccount");
}else if(!isGapPositive(inventoryLine)){
acc = stockAccounts.get(inventoryLine).get("stockAccount");
acc2 = stockAccounts.get(inventoryLine).get("consumptionAccount");
}
}else{
if(isGapPositive(inventoryLine)){
acc = Beans.get(AccountRepository.class).find(1360L);
acc2 = stockAccounts.get(inventoryLine).get("stockAccount");
}else if(!isGapPositive(inventoryLine)){
acc = stockAccounts.get(inventoryLine).get("stockAccount");
acc2 = Beans.get(AccountRepository.class).find(1400L);
}
}
BigDecimal amountInCurrency = inventoryLine.getGapValue().multiply(inventoryLine.getGap());
String description = inventoryLine.getInventory().getInventorySeq() + "-" + inventoryLine.getProduct().getCode();
if (inventoryLine.getTrackingNumber() != null) {
description += "-" + inventoryLine.getTrackingNumber().getTrackingNumberSeq();
}
MoveLine moveLine =
moveLineService.createMoveLine(
move,
partner,
acc,
amountInCurrency,
isDebitInventoryLine(inventoryLine),
moveDate,
++counter,
inventoryLine.getInventory().getInventorySeq(),
description);
moveLine.setDescription(description);
moveLine.setDate(moveDate);
moveLine.setDueDate(moveDate);
moveLine.setAccountId(acc.getId());
moveLine.setAccountCode(acc.getCode());
moveLine.setAccountName(acc.getName());
MoveLine moveLine2 =
moveLineService.createMoveLine(
move,
partner,
acc2,
amountInCurrency,
!isDebitInventoryLine(inventoryLine),
moveDate,
++counter,
inventoryLine.getInventory().getInventorySeq(),
description);
moveLine2.setDescription(description);
moveLine2.setDate(moveDate);
moveLine2.setDueDate(moveDate);
moveLine2.setAccountId(acc2.getId());
moveLine2.setAccountCode(acc2.getCode());
moveLine2.setAccountName(acc2.getName());
move.addMoveLineListItem(moveLine);
move.addMoveLineListItem(moveLine2);
move.setInventoryLine(inventoryLine);
inventoryLine.setIsVentilated(true);
move.setIgnoreInAccountingOk(false);
move.setStatusSelect(MoveRepository.STATUS_DAYBOOK);
return move;
}
public List<Long> massGenerationInventoryLineMove(List<Long> ids) throws AxelorException {
List<Long> movesId = new ArrayList<>();
for (Long id : ids) {
InventoryLine line = Beans.get(InventoryLineRepository.class).find(id);
Move move = this.generateInventoryLineMove(line);
movesId.add(move.getId());
}
return movesId;
}
// public boolean isPurchase(StockMove stockMove){
// boolean isPurchase;
// Partner partner = stockMove.getPartner() ;
// if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING && stockMove.getPartner()
// == stockMove.getCompany().getPartner()) {
// isPurchase = false;
// }
// else if(stockMove.getTypeSelect() == StockMoveRepository.TYPE_INCOMING &&
// stockMove.getPartner() != stockMove.getCompany().getPartner()){
// isPurchase = true;
// }else if(stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING &&
// stockMove.getPartner() == stockMove.getCompany().getPartner()){
// }
// }
}

View File

@@ -179,14 +179,23 @@ public class BudgetSupplychainService extends BudgetService {
return;
}
purchaseOrderLineList
.stream()
.flatMap(x -> x.getBudgetDistributionList().stream())
.forEach(
budgetDistribution -> {
Budget budget = budgetDistribution.getBudget();
updateLines(budget);
computeTotalAmountCommitted(budget);
});
}
boolean idbudgetDistExist = true;
for (PurchaseOrderLine line : purchaseOrderLineList) {
if(line.getBudgetDistributionList() == null){
idbudgetDistExist = false;
}
}
if(idbudgetDistExist){
purchaseOrderLineList
.stream()
.flatMap(x -> x.getBudgetDistributionList().stream())
.forEach(
budgetDistribution -> {
Budget budget = budgetDistribution.getBudget();
updateLines(budget);
computeTotalAmountCommitted(budget);
});
}
}
}

View File

@@ -0,0 +1,495 @@
package com.axelor.apps.supplychain.service;
import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.apps.account.db.Account;
import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.db.InvoiceTemplate;
import com.axelor.apps.account.db.PaymentVoucher;
import com.axelor.apps.account.db.TaxLine;
import com.axelor.apps.account.db.repo.AccountRepository;
import com.axelor.apps.account.db.repo.InvoiceLineRepository;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.apps.account.db.repo.PaymentVoucherRepository;
import com.axelor.apps.account.db.repo.TaxLineRepository;
import com.axelor.apps.account.service.InvoiceTemplateService;
import com.axelor.apps.account.service.invoice.InvoiceLineServiceImpl;
import com.axelor.apps.account.service.invoice.InvoiceServiceImpl;
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
import com.axelor.apps.account.service.payment.paymentvoucher.PaymentVoucherConfirmService;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Wizard;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.purchase.db.ImportationFolder;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.stock.db.ImportationFolderCostPrice;
import com.axelor.apps.stock.db.StockLocation;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.stock.db.repo.ImportationFolderCostPriceRepository;
import com.axelor.apps.purchase.db.repo.ImportationFolderRepository;
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
import com.axelor.apps.purchase.service.PurchaseOrderLineService;
import com.axelor.apps.purchase.service.PurchaseOrderService;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.supplychain.service.invoice.generator.InvoiceLineGeneratorSupplyChain;
import com.axelor.auth.AuthUtils;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.schema.actions.ActionView;
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import wslite.json.JSONException;
public class ImportationFolderServiceImpl {
@Inject protected ImportationFolderRepository importationFolderRepository;
private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Transactional
public List<Long> calculateAvgPriceAndGenerateInvoice(List<StockMoveLine> stockMoveLines, ImportationFolder importationFolder)
throws MalformedURLException, JSONException, AxelorException {
Set<StockMove> stockMovesSet = new HashSet<>();
HashMap<String,List<StockMove>> stockMovesMap = new HashMap<>();
for (StockMoveLine stockMoveLine : stockMoveLines) {
stockMovesSet.add(stockMoveLine.getStockMove());
}
List<Long> invoiceIds = new ArrayList<>();
for (StockMove stockMove : stockMovesSet) {
// Use the 'ref' as the key, and add the object to the corresponding list
stockMovesMap
.computeIfAbsent(stockMove.getSupplierShipmentRef(), k -> new ArrayList<>())
.add(stockMove);
}
stockMovesMap.forEach((ref, stockMoveList) -> {
// List<StockMove> stockMoveList = new ArrayList<>(stockMovesSet);
if(stockMoveList.size() > 0) {
Optional<Invoice> invoiceOpt;
try {
invoiceOpt = Beans.get(StockMoveMultiInvoiceService.class).createInvoiceFromMultiIncomingStockMove(stockMoveList);
Invoice invoice = invoiceOpt.get();
Product product = Beans.get(ProductRepository.class).find(8931L);
BigDecimal freightPrice = importationFolder.getFreight();
StockLocation stockLocation = importationFolder.getStockMoveLineList().get(0).getStockMove().getToStockLocation();
TaxLine taxLine = null;
if(stockLocation.getId() == 61 || stockLocation.getId() == 60){
taxLine = Beans.get(TaxLineRepository.class).find(27L);
}else{
if(importationFolder.getStockMoveLineList().get(0).getPurchaseOrderLine() == null){
throw new AxelorException(
importationFolder,
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
"Purchase order missing",
I18n.get(com.axelor.apps.base.exceptions.IExceptionMessage.EXCEPTION));
}
taxLine = importationFolder.getStockMoveLineList().get(0).getPurchaseOrderLine().getTaxLine();
}
InvoiceLineGenerator invoiceLineGenerator =
new InvoiceLineGeneratorSupplyChain(
invoice,
product,
product.getName(),
freightPrice,
freightPrice,
freightPrice,
"",
BigDecimal.ONE,
product.getUnit(),
taxLine,
100,
BigDecimal.ZERO,
0,
freightPrice,
freightPrice,
false,
null,
null,
null,
false,
null) {
@Override
public List<InvoiceLine> creates() throws AxelorException {
InvoiceLine invoiceLine = this.createInvoiceLine();
invoiceLine.setPrice(stockMoveList.get(0).getStockMoveLineList().get(0).getFreight());
Long categoryId = importationFolder.getStockMoveLineList().get(0).getProduct().getFamilleProduit().getId();
Account account = null;
switch (categoryId.intValue()) {
case 67:
account= Beans.get(AccountRepository.class).find(1430L);
break;
case 68:
account= Beans.get(AccountRepository.class).find(1430L);
break;
case 59:
account= Beans.get(AccountRepository.class).find(1431L);
break;
default:
account= Beans.get(AccountRepository.class).find(1431L);
break;
}
invoiceLine.setAccount(account);
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
invoiceLines.add(invoiceLine);
return invoiceLines;
}
};
List<InvoiceLine> invoiceLines = invoiceLineGenerator.creates();
invoice.addInvoiceLineListItem(invoiceLines.get(0));
logger.debug("invoice.getInvoiceLineList() ********** ",invoice.getInvoiceLineList());
BigDecimal inTaxTotal = BigDecimal.ZERO;
BigDecimal exTaxTotal = BigDecimal.ZERO;
BigDecimal taxTotal = BigDecimal.ZERO;
for (InvoiceLine invoiceLine : invoice.getInvoiceLineList()) {
BigDecimal currencyRate = BigDecimal.ZERO;
// if(invoiceLine.getProduct().getId() == product.getId()){
currencyRate = importationFolder.getStockMoveLineList().get(0).getCurrencyRate();
// }else{
// currencyRate = invoiceLine.getStockMoveLine().getCurrencyRate();
// }
inTaxTotal = inTaxTotal.add(invoiceLine.getInTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
exTaxTotal = exTaxTotal.add(invoiceLine.getExTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
taxTotal = taxTotal.add(inTaxTotal.subtract(exTaxTotal));
BigDecimal price = (invoiceLine.getPrice().multiply(currencyRate)).setScale(2,RoundingMode.HALF_UP);
invoiceLine.setPrice(price);
invoiceLine.setPriceDiscounted(invoiceLine.getPriceDiscounted().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
invoiceLine.setInTaxTotal(invoiceLine.getInTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
invoiceLine.setExTaxTotal(invoiceLine.getExTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
invoiceLine.setInTaxPrice(invoiceLine.getInTaxPrice().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
invoiceLine.setCompanyExTaxTotal(invoiceLine.getCompanyExTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
invoiceLine.setCompanyInTaxTotal(invoiceLine.getCompanyInTaxTotal().multiply(currencyRate).setScale(2,RoundingMode.HALF_UP));
Beans.get(InvoiceLineRepository.class).save(invoiceLine);
logger.debug("currencyRate****** {}",currencyRate);
logger.debug("Invoice line in importation folder {}",invoiceLine.toString());
}
invoice.setInTaxTotal(inTaxTotal);
invoice.setExTaxTotal(exTaxTotal);
invoice.setCompanyExTaxTotal(exTaxTotal);
invoice.setCompanyInTaxTotal(inTaxTotal);
invoice.setAmountRemaining(inTaxTotal);
invoice.setCurrency(invoice.getCompany().getCurrency());
invoice.setTaxTotal(taxTotal);
invoice.setImportationFolder(importationFolder);
invoice.setIsImportationPartnerInvoice(true);
importationFolder.setInvoicedFolder(true);
Invoice generatedInvoice = Beans.get(InvoiceRepository.class).save(invoice);
invoiceIds.add(generatedInvoice.getId());
} catch (AxelorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
return invoiceIds;
}
public String computeCostPrice(ImportationFolder importationFolder) {
List<StockMoveLine> stockMoveLines = importationFolder.getStockMoveLineList();
String message = "";
BigDecimal costPrice = BigDecimal.ZERO;
Set<Product> productSet = new HashSet<>();
for (StockMoveLine line : stockMoveLines) {
productSet.add(line.getProduct());
}
this.resetCostPriceList(importationFolder);
if(productSet.size() > 1) {
List<Invoice> supplierInvoices = importationFolder.getInvoices().stream().filter(t -> t.getIsImportationPartnerInvoice()).collect(Collectors.toList());
// BigDecimal totalQty = stockMoveLines.stream().map(StockMoveLine::getRealQty).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalNetMass = stockMoveLines.stream().map(StockMoveLine::getNetMass).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalVolume = stockMoveLines.stream().map(StockMoveLine::getVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal freight = importationFolder.getFreight().multiply(stockMoveLines.get(0).getCurrencyRate()).setScale(2,RoundingMode.HALF_EVEN);
Map<Product,Double> splitting = new HashMap<>();
Map<Product,Double> splittingQty = new HashMap<>();
List<InvoiceLine> invoiceLines = new ArrayList<>();
BigDecimal totalInvoiceWithoutFreight = BigDecimal.ZERO;
BigDecimal totalQty = BigDecimal.ZERO;
for (Invoice supplierInvoice : supplierInvoices) {
BigDecimal freightInvoice = BigDecimal.ZERO;
Optional<InvoiceLine> invoiceLine = supplierInvoice.getInvoiceLineList().stream().filter(t -> t.getProduct().getId() == 8931L).findAny();
if(invoiceLine.isPresent()){
freightInvoice = invoiceLine.get().getInTaxTotal();
}
BigDecimal invoiceWithoutFreight = supplierInvoice.getInTaxTotal().subtract(freightInvoice).setScale(2, RoundingMode.HALF_EVEN);
totalInvoiceWithoutFreight = totalInvoiceWithoutFreight.add(invoiceWithoutFreight);
invoiceLines.addAll(supplierInvoice.getInvoiceLineList());
// total qty without freight qty = 1
}
totalQty =invoiceLines.stream().filter(t -> t.getProduct().getId() != 8931L).map(InvoiceLine::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
splittingQty = invoiceLines.stream().collect(
Collectors.groupingBy(
t -> t.getProduct(),
Collectors.summingDouble(o -> o.getQty().doubleValue())));
if(importationFolder.getValorisation() == 1){
splitting = invoiceLines.stream().collect(
Collectors.groupingBy(
t -> t.getProduct(),
Collectors.summingDouble(o -> o.getInTaxTotal().doubleValue())));
}else if(importationFolder.getValorisation() == 2){
splitting = invoiceLines.stream().collect(
Collectors.groupingBy(
t -> t.getProduct(),
Collectors.summingDouble(o -> o.getQty().doubleValue())));
}else if(importationFolder.getValorisation() == 3){
splitting = stockMoveLines.stream().collect(
Collectors.groupingBy(
t -> t.getProduct(),
Collectors.summingDouble(o -> o.getNetMass().doubleValue())));
}else if(importationFolder.getValorisation() == 4){
splitting = stockMoveLines.stream().collect(
Collectors.groupingBy(
t -> t.getProduct(),
Collectors.summingDouble(o -> o.getVolume().doubleValue())));
}
List<Invoice> invoices = importationFolder.getInvoices().stream().filter(t -> !t.getIsImportationPartnerInvoice()).collect(Collectors.toList());
BigDecimal totalApproachs = invoices.stream().map(Invoice::getInTaxTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
for (Product product : productSet) {
Stream<InvoiceLine> invoiceLineStream = invoiceLines.stream().filter(t -> t.getProduct() == product);
BigDecimal productQty = new BigDecimal(splitting.get(product));
BigDecimal productQty2 = new BigDecimal(splittingQty.get(product));
BigDecimal freightSplit = BigDecimal.ZERO;
// BigDecimal freightPerInvoiceForProduct= invoiceLineStream.findFirst().get().getInvoice().getInvoiceLineList().stream().filter(t -> t.getProduct().getId() == 8931L).findFirst().get().getInTaxTotal();
// total per product
BigDecimal totalInvoiceProduct = invoiceLineStream.map(InvoiceLine::getInTaxTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal percent = BigDecimal.ZERO;
if(totalInvoiceWithoutFreight.compareTo(BigDecimal.ZERO) == 0){
percent = productQty.divide(totalQty,10,RoundingMode.HALF_EVEN);
}else{
switch (importationFolder.getValorisation()) {
case 1:
percent = totalInvoiceProduct.divide(totalInvoiceWithoutFreight,10,RoundingMode.HALF_EVEN);
break;
case 2:
percent = productQty.divide(totalQty,2,RoundingMode.HALF_EVEN);
break;
case 3:
percent = productQty.divide(totalNetMass,2,RoundingMode.HALF_EVEN);
break;
case 4:
percent = productQty.divide(totalVolume,2,RoundingMode.HALF_EVEN);
break;
default:
break;
}
}
freightSplit = freight.multiply(percent).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal totalApproachsPerProduct = totalApproachs.multiply(percent).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal allPerProduct = totalApproachsPerProduct.add(totalInvoiceProduct).add(freightSplit);
System.out.println("---------------------------------------------------------------------");
System.out.println("allPerProduct *************"+allPerProduct.toString());
System.out.println("totalApproachsPerProduct *************"+totalApproachsPerProduct.toString());
System.out.println("totalInvoiceProduct *************"+totalInvoiceProduct.toString());
System.out.println("freightSplit *************"+freightSplit.toString());
System.out.println("productQty2 *************"+productQty2.toString());
System.out.println("---------------------------------------------------------------------");
costPrice = allPerProduct.divide(productQty2,10, RoundingMode.HALF_EVEN);
message += "Cost price of " + product.getName() + " is " + costPrice + " || ";
List<StockMoveLine> lines = stockMoveLines.stream().filter(t -> t.getProduct() == product).collect(Collectors.toList());
for (StockMoveLine line : lines) {
this.computeCostPriceAndPersist(importationFolder, line, freightSplit,percent, totalInvoiceProduct,totalInvoiceProduct,costPrice);
}
}
}else{
List<Invoice> invoices = importationFolder.getInvoices();
BigDecimal inTaxTotal = invoices.stream().map(Invoice::getInTaxTotal).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2,RoundingMode.HALF_UP);
BigDecimal totalQty = stockMoveLines.stream().map(StockMoveLine::getRealQty).reduce(BigDecimal.ZERO, BigDecimal::add);
costPrice = inTaxTotal.divide(totalQty,10, RoundingMode.HALF_UP);
// this.resetCostPriceList(importationFolder);
for (StockMoveLine stockMoveLine : stockMoveLines) {
this.computeCostPriceAndPersist(importationFolder, stockMoveLine,null,null,null,null, costPrice);
}
message = "CostPrice is : " + costPrice.toString();
}
return message;
}
@Transactional
public void setStockMoveLineCurrenyRate(List<StockMoveLine> stockMoveLineList, BigDecimal currencyRate) {
for (StockMoveLine stockMoveLine : stockMoveLineList) {
stockMoveLine.setCurrencyRate(currencyRate);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
}
@Transactional
public void setStockMoveLineFreight(List<StockMoveLine> stockMoveLineList, BigDecimal freight) {
for (StockMoveLine stockMoveLine : stockMoveLineList) {
stockMoveLine.setFreight(freight);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
}
@Transactional
public void resetCostPriceList(ImportationFolder importationFolder){
importationFolder.getImportationFolderCostPriceList().clear();
}
@Transactional
public void computeCostPriceAndPersist(ImportationFolder importationFolder,StockMoveLine stockMoveLine,BigDecimal freightSplit,BigDecimal precent,BigDecimal totalApproachsPerProduct,BigDecimal totalInvoiceProduct,BigDecimal costPrice) {
ImportationFolderCostPrice importationFolderCostPrice = new ImportationFolderCostPrice();
importationFolderCostPrice.setImportationFolder(importationFolder);
importationFolderCostPrice.setStockMoveLine(stockMoveLine);
importationFolderCostPrice.setCostPrice(costPrice);
importationFolderCostPrice.setValorisation(importationFolder.getValorisation());
importationFolderCostPrice.setPercent(precent);
importationFolderCostPrice.setFreightSplit(freightSplit);
importationFolderCostPrice.setTotalApproach(totalApproachsPerProduct);
importationFolderCostPrice.setTotalInvoice(totalInvoiceProduct);
importationFolderCostPrice.setProduct(stockMoveLine.getProduct());
importationFolder.addImportationFolderCostPriceListItem(importationFolderCostPrice);
importationFolderRepository.save(importationFolder);
}
// public void valisateCostPrice(ActionRequest request, ActionResponse response) {
@Transactional
public void validateCostPrice(ImportationFolderCostPrice importationFolderCostPrice) {
ImportationFolderCostPriceRepository importationFolderCostPriceRepository = Beans.get(ImportationFolderCostPriceRepository.class);
StockMove stockMove = importationFolderCostPrice.getStockMoveLine().getStockMove();
Long productId = importationFolderCostPrice.getProduct().getId();
Long stockMoveId = stockMove.getId();
LocalDate toDate = LocalDate.now();
BigDecimal costPrice = importationFolderCostPrice.getCostPrice();
try {
Beans.get(StockMoveLineServiceSupplychainImpl.class).resetValorization(productId, stockMoveId, toDate,false);
Beans.get(StockMoveLineServiceSupplychainImpl.class).fillStockMoveLines(productId, toDate, stockMoveId,false);
Beans.get(StockMoveLineServiceSupplychainImpl.class).valorize(productId, stockMoveId, toDate, costPrice,false,false);
importationFolderCostPrice.setStatusSelect(2);
importationFolderCostPrice.setValidationDate(LocalDate.now());
importationFolderCostPriceRepository.save(importationFolderCostPrice);
// response.setReload(true);
} catch (Exception e) {
logger.debug(e.toString());
}
}
@Transactional
public void setStockMoveLineNetMass(List<StockMoveLine> stockMoveLineList, BigDecimal netMass) {
for (StockMoveLine stockMoveLine : stockMoveLineList) {
stockMoveLine.setNetMass(netMass);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
}
@Transactional
public void setStockMoveLineVolume(List<StockMoveLine> stockMoveLineList, BigDecimal volume) {
for (StockMoveLine stockMoveLine : stockMoveLineList) {
stockMoveLine.setVolume(volume);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
}
@Transactional
public void rejectImportationFolder(ImportationFolder importationFolder, String rejectionRaison) {
importationFolder.setStatusSelect(ImportationFolderRepository.STATUS_REJECTED);
importationFolder.setRejectionRaison(rejectionRaison);
importationFolder.setRejectedDate(LocalDate.now());
importationFolder.setRejectedByUser(AuthUtils.getUser());
importationFolder.setRejectedInstanceSelect(1);
importationFolderRepository.save(importationFolder);
}
@Transactional
public Invoice generateFromModel(ImportationFolder importationFolder,InvoiceTemplate invoiceTemplate) throws AxelorException{
Invoice invoice = Beans.get(InvoiceTemplateService.class).generateInvoiceFromTemplate(invoiceTemplate);
invoice.setImportationFolder(importationFolder);
invoice.setIsInvoiceApproach(true);
return Beans.get(InvoiceRepository.class).save(invoice);
}
}

View File

@@ -154,6 +154,7 @@ public class MrpLineServiceImpl implements MrpLineService {
maturityDate,
"MRP-" + appBaseService.getTodayDate().toString(), // TODO sequence on mrp
null,
"",
stockLocation,
appBaseService.getTodayDate(),
Beans.get(PartnerPriceListService.class)

View File

@@ -17,10 +17,14 @@
*/
package com.axelor.apps.supplychain.service;
import com.axelor.apps.base.db.ABCAnalysis;
import com.axelor.apps.base.db.ABCAnalysisLine;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Unit;
import com.axelor.apps.base.db.repo.ABCAnalysisLineRepository;
import com.axelor.apps.base.db.repo.ABCAnalysisRepository;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.base.service.UnitConversionService;
import com.axelor.apps.base.service.app.AppBaseService;
@@ -46,18 +50,23 @@ import com.axelor.apps.supplychain.db.MrpFamily;
import com.axelor.apps.supplychain.db.MrpForecast;
import com.axelor.apps.supplychain.db.MrpLine;
import com.axelor.apps.supplychain.db.MrpLineOrigin;
import com.axelor.apps.supplychain.db.MrpLineSaleAndMargin;
import com.axelor.apps.supplychain.db.MrpLineSophal;
import com.axelor.apps.supplychain.db.MrpLineType;
import com.axelor.apps.supplychain.db.ProductionMasterPlan;
import com.axelor.apps.supplychain.db.SalesMasterPlan;
import com.axelor.apps.supplychain.db.repo.MrpForecastRepository;
import com.axelor.apps.supplychain.db.repo.MrpLineRepository;
import com.axelor.apps.supplychain.db.repo.MrpLineSaleAndMarginRepository;
import com.axelor.apps.supplychain.db.repo.MrpLineSophalRepository;
import com.axelor.apps.supplychain.db.repo.MrpLineTypeRepository;
import com.axelor.apps.supplychain.db.repo.MrpRepository;
import com.axelor.apps.supplychain.db.repo.ProductionMasterPlanRepository;
import com.axelor.apps.supplychain.db.repo.SalesMasterPlanRepository;
import com.axelor.apps.supplychain.exception.IExceptionMessage;
import com.axelor.apps.tool.StringTool;
import com.axelor.db.JPA;
import com.axelor.db.Model;
import com.axelor.db.Query;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.i18n.I18n;
@@ -71,12 +80,17 @@ import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Month;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
@@ -106,6 +120,8 @@ public class MrpServiceImpl implements MrpService {
protected Map<Long, Double> productQty;
protected Mrp mrp;
protected LocalDate today;
public List<MrpForecast> mrpForecastListAll;
@Inject
public MrpServiceImpl(
@@ -181,7 +197,9 @@ public class MrpServiceImpl implements MrpService {
public void resetSophalLine(Mrp mrp) {
Beans.get(MrpLineSophalRepository.class).all().filter("self.mrp.id = ?1", mrp.getId()).remove();
Beans.get(MrpLineSaleAndMarginRepository.class).all().filter("self.mrp.id = ?1", mrp.getId()).remove();
Beans.get(SalesMasterPlanRepository.class).all().filter("self.mrp.id = ?1", mrp.getId()).remove();
Beans.get(ProductionMasterPlanRepository.class).all().filter("self.mrp.id = ?1", mrp.getId()).remove();
mrp.setStatusSelect(MrpRepository.STATUS_DRAFT);
@@ -1113,11 +1131,11 @@ public class MrpServiceImpl implements MrpService {
return mrp;
}
public void createAvailableMrpLineSophal(Mrp mrp) throws AxelorException {
this.resetSophalLine(mrp);
today = appBaseService.getTodayDate();
LocalDate endDate = mrp.getEndDate();
Set<StockLocation> slList2 = Sets.newHashSet();
this.mrp = mrp;
@@ -1128,17 +1146,31 @@ public class MrpServiceImpl implements MrpService {
e.printStackTrace();
}
this.productQty = new HashMap<>();
this.productQty = new HashMap<>();
try {
stockLocationLineRepository.all().filter("self.product.id in ?1 and self.stockLocation is not null and self.currentQty > 0 and self.stockLocation.isNotInMrp is false",this.productMap.keySet())
.fetch().forEach(t ->slList2.add(t.getStockLocation()));
this.productQty = stockLocationLineRepository.all()
.filter("self.product.id in (?1) and self.stockLocation is not null and self.currentQty > 0 and self.stockLocation.isNotInMrp is false",this.productMap.keySet())
.fetch().stream().filter(t -> !t.getStockLocation().getIsNotInMrp()).collect(Collectors.groupingBy(t -> t.getProduct().getId(),Collectors.summingDouble(o->o.getCurrentQty().doubleValue())));
stockLocationLineRepository
.all()
.filter(
"self.product.id in ?1 and self.stockLocation is not null and self.currentQty > 0 and self.stockLocation.isNotInMrp is false",
this.productMap.keySet())
.fetch()
.forEach(t -> slList2.add(t.getStockLocation()));
this.productQty =
stockLocationLineRepository
.all()
.filter(
"self.product.id in (?1) and self.stockLocation is not null and self.currentQty > 0 and self.stockLocation.isNotInMrp is false",
this.productMap.keySet())
.fetch()
.stream()
.filter(t -> !t.getStockLocation().getIsNotInMrp())
.collect(
Collectors.groupingBy(
t -> t.getProduct().getId(),
Collectors.summingDouble(o -> o.getCurrentQty().doubleValue())));
} catch (Exception e) {
log.debug(e.toString());
@@ -1150,91 +1182,413 @@ public class MrpServiceImpl implements MrpService {
Integer scenario = mrp.getScenario();
mrpForecastList.addAll(
mrpForecastRepository
.all()
.filter(
"self.product.id in (?1) AND self.stockLocation in (?2) AND self.forecastDate "+( scenario == 3 ? "<=" : ">=")+" ?3 AND self.statusSelect = ?4 AND self.scenario = ?5",
this.productMap.keySet(),
slList2.stream().collect(Collectors.toList()),
today,
MrpForecastRepository.STATUS_CONFIRMED,
scenario)
.order("monthSelect")
.fetch());
log.debug(mrpForecastList.toString());
mrpForecastRepository
.all()
.filter(
"self.product.id in (?1) AND self.stockLocation in (?2) AND self.forecastDate "
+ (scenario == 3 ? "<=" : ">=")
+ " ?3 AND self.statusSelect = ?4 AND self.scenario = ?5",
this.productMap.keySet(),
slList2.stream().collect(Collectors.toList()),
today,
MrpForecastRepository.STATUS_CONFIRMED,
scenario)
.order("monthSelect")
.fetch());
mrpForecastListAll = new ArrayList<>();
mrpForecastListAll.addAll( mrpForecastRepository
.all()
.filter(
"self.product.id in (?1) AND self.stockLocation in (?2) AND self.statusSelect = ?3 AND self.forecastDate < ?4",
this.productMap.keySet(),
slList2.stream().collect(Collectors.toList()),
MrpForecastRepository.STATUS_CONFIRMED,
LocalDate.parse(String.valueOf(LocalDate.now().getYear())+"-01-01")
)
.order("monthSelect")
.fetch());
log.debug(mrpForecastList.toString());
}
for (Map.Entry<Long, Double> entry : productQty.entrySet()) {
Product product = productRepository.find(entry.getKey());
BigDecimal qty = new BigDecimal(entry.getValue());
if(this.productMap.get(product.getId()) == 0){
this.createMrpLineSophal(mrp, product,product.getUnit(), qty,mrpForecastList,productQty);
if (this.productMap.get(product.getId()) == 0) {
this.createMrpLineSophal(mrp, product, product.getUnit(), qty, mrpForecastList, productQty);
}
}
}
@Transactional
public void createMrpLineSophal(Mrp mrp, Product product,Unit unit,BigDecimal qty,List<MrpForecast> mrpForecastList, Map<Long, Double> productQty) throws AxelorException {
MrpLineSophal mrpLineSophal = new MrpLineSophal();
mrpLineSophal.setQty(qty);
BigDecimal reelQty = qty;
BigDecimal sumQty = BigDecimal.ZERO;
for (MrpForecast forecast : mrpForecastList) {
if(forecast.getProduct() == product){
reelQty = reelQty.subtract(forecast.getQty());
BigDecimal displayedQty = reelQty;
sumQty = sumQty.add(forecast.getQty());
switch (forecast.getMonthSelect()) {
case 1:
mrpLineSophal.setJanuary(displayedQty);
break;
case 2:
mrpLineSophal.setFebruary(displayedQty);
break;
case 3:
mrpLineSophal.setMarch(displayedQty);
break;
case 4:
mrpLineSophal.setApril(displayedQty);
case 5:
mrpLineSophal.setMay(displayedQty);
case 6:
mrpLineSophal.setJuin(displayedQty);
break;
case 7:
mrpLineSophal.setJuly(displayedQty);
break;
case 8:
mrpLineSophal.setAugust(displayedQty);
break;
case 9:
mrpLineSophal.setSeptember(displayedQty);
break;
case 10:
mrpLineSophal.setOctober(displayedQty);
break;
case 11:
mrpLineSophal.setNovember(displayedQty);
break;
case 12:
mrpLineSophal.setDecember(displayedQty);
break;
default:
break;
}
public void createMrpLineSophal(
Mrp mrp,
Product product,
Unit unit,
BigDecimal qty,
List<MrpForecast> mrpForecastList,
Map<Long, Double> productQty)
throws AxelorException {
MrpLineSophal mrpLineSophal = new MrpLineSophal();
mrpLineSophal.setQty(qty);
BigDecimal reelQty = qty;
BigDecimal sumQty = BigDecimal.ZERO;
Collections.sort(mrpForecastList, Comparator.comparingInt(MrpForecast ::getMonthSelect));
for (MrpForecast forecast : mrpForecastList){
if (forecast.getProduct() == product) {
reelQty = reelQty.subtract(forecast.getQty());
BigDecimal displayedQty = reelQty;
sumQty = sumQty.add(forecast.getQty());
switch (forecast.getMonthSelect()) {
case 1:
mrpLineSophal.setJanuary(displayedQty);
break;
case 2:
mrpLineSophal.setFebruary(displayedQty);
break;
case 3:
mrpLineSophal.setMarch(displayedQty);
break;
case 4:
mrpLineSophal.setApril(displayedQty);
case 5:
mrpLineSophal.setMay(displayedQty);
case 6:
mrpLineSophal.setJuin(displayedQty);
break;
case 7:
mrpLineSophal.setJuly(displayedQty);
break;
case 8:
mrpLineSophal.setAugust(displayedQty);
break;
case 9:
mrpLineSophal.setSeptember(displayedQty);
break;
case 10:
mrpLineSophal.setOctober(displayedQty);
break;
case 11:
mrpLineSophal.setNovember(displayedQty);
break;
case 12:
mrpLineSophal.setDecember(displayedQty);
break;
default:
break;
}
}
mrpLineSophal.setMrp(mrp);
mrpLineSophal.setProduct(product);
mrpLineSophal.setUnit(product.getUnit());
mrpLineSophal.setCompany(mrp.getStockLocation().getCompany());
}
mrpLineSophal.setMrp(mrp);
mrpLineSophal.setProduct(product);
mrpLineSophal.setUnit(product.getUnit());
mrpLineSophal.setCompany(mrp.getStockLocation().getCompany());
Long totalForecast = mrpForecastList.stream().filter(t -> t.getProduct() == product).count();
Long totalForecast = mrpForecastList.stream().filter(t -> t.getProduct() == product).count();
mrpLineSophal.setSecurityStock(sumQty.divide(new BigDecimal(totalForecast),5, RoundingMode.HALF_EVEN));
Beans.get(MrpLineSophalRepository.class).save(mrpLineSophal);
mrpLineSophal.setSecurityStock(
sumQty.divide(new BigDecimal(totalForecast), 5, RoundingMode.HALF_EVEN));
Beans.get(MrpLineSophalRepository.class).save(mrpLineSophal);
}
@Transactional
public void createMargeAndSaleLineSophal(
Mrp mrp,
Product product,
List<MrpForecast> mrpForecastList,
BigDecimal qty
)
throws AxelorException {
MrpLineSaleAndMargin mrpLineSaleAndMargin = new MrpLineSaleAndMargin();
ArrayList<Integer> lastThreeMonths = new ArrayList<>();
lastThreeMonths.add(10);
lastThreeMonths.add(11);
lastThreeMonths.add(12);
BigDecimal totalLastThree = BigDecimal.ZERO;
BigDecimal avgLastThree = BigDecimal.ZERO;
totalLastThree = mrpForecastList.stream().filter(t -> (t.getForecastDate().getYear() == (LocalDate.now().getYear() - 1)) && (t.getProduct().getId() == product.getId()) && lastThreeMonths.contains(t.getMonthSelect())).map(MrpForecast::getQty)
.reduce(BigDecimal.ZERO, BigDecimal::add);
avgLastThree = totalLastThree.divide(new BigDecimal("3"),2,RoundingMode.HALF_UP);
log.debug("******* mrpForecastList {}",mrpForecastList);
log.debug("******* lastThreeMonths {}",lastThreeMonths);
log.debug("******* totalLastThree {}",totalLastThree);
log.debug("******* avgLastThree {}",avgLastThree);
BigDecimal maxJan = getMaxOfMonth(1, product, mrpForecastList);
BigDecimal maxFeb = getMaxOfMonth(2, product, mrpForecastList);
BigDecimal maxMar = getMaxOfMonth(3, product, mrpForecastList);
BigDecimal maxApril = getMaxOfMonth(4, product, mrpForecastList);
BigDecimal maxMay = getMaxOfMonth(5, product, mrpForecastList);
BigDecimal maxJune = getMaxOfMonth(6, product, mrpForecastList);
BigDecimal maxJuly = getMaxOfMonth(7, product, mrpForecastList);
BigDecimal maxAugust = getMaxOfMonth(8, product, mrpForecastList);
BigDecimal maxSep = getMaxOfMonth(9, product, mrpForecastList);
BigDecimal maxOct = getMaxOfMonth(10, product, mrpForecastList);
BigDecimal maxNov = getMaxOfMonth(11, product, mrpForecastList);
BigDecimal maxDec = getMaxOfMonth(12, product, mrpForecastList);
BigDecimal maxFirstQuarter = maxJan.add(maxFeb).add(maxMar).divide(new BigDecimal("3"), RoundingMode.HALF_UP);
BigDecimal maxSecQuarter = maxJune.add(maxApril).add(maxMay).divide(new BigDecimal("3"), RoundingMode.HALF_UP);
BigDecimal maxthirdQuarter = maxSep.add(maxJuly).add(maxAugust).divide(new BigDecimal("3"), RoundingMode.HALF_UP);
BigDecimal maxforthQuarter = maxOct.add(maxNov).add(maxDec).divide(new BigDecimal("3"), RoundingMode.HALF_UP);
if(maxFirstQuarter.compareTo(avgLastThree) > 0){
mrpLineSaleAndMargin.setFirstQuarterMax(maxFirstQuarter);
}else{
maxFirstQuarter = avgLastThree;
mrpLineSaleAndMargin.setFirstQuarterMax(maxFirstQuarter);
}
mrpLineSaleAndMargin.setSecondQuarterMax(maxSecQuarter);
mrpLineSaleAndMargin.setThirdQuarterMax(maxthirdQuarter);
mrpLineSaleAndMargin.setForthQuarterMax(maxforthQuarter);
String className = "";
List<ABCAnalysisLine> abcAnalysisLines = Beans.get(ABCAnalysisLineRepository.class).all().fetch();
ABCAnalysisLine abcAnalysisLine = abcAnalysisLines.stream().filter(t -> t.getProduct() == product).findFirst().get();
if(abcAnalysisLine == null) {
throw new AxelorException(
mrp,
TraceBackRepository.CATEGORY_NO_VALUE,
"ABC classification needed");
}else{
className = abcAnalysisLine.getAbcAnalysisClass().getName();
}
BigDecimal firstQuarterMargin = BigDecimal.ZERO;
BigDecimal secondQuarterMargin = BigDecimal.ZERO;
BigDecimal thirdQuarterMargin = BigDecimal.ZERO;
BigDecimal fourthQuarterMargin = BigDecimal.ZERO;
switch (className) {
case "A":
firstQuarterMargin = maxFirstQuarter.add(maxFirstQuarter.multiply(new BigDecimal("0.15")));
secondQuarterMargin = maxSecQuarter.add(maxSecQuarter.multiply(new BigDecimal("0.20"))) ;
thirdQuarterMargin = maxthirdQuarter.add(maxthirdQuarter.multiply(new BigDecimal("0.15")));
fourthQuarterMargin = maxforthQuarter.add(maxforthQuarter.multiply(new BigDecimal("0.15")));
break;
case "B":
firstQuarterMargin = maxFirstQuarter.add(maxFirstQuarter.multiply(new BigDecimal("0.10")));
secondQuarterMargin = maxSecQuarter.add(maxSecQuarter.multiply(new BigDecimal("0.10"))) ;
thirdQuarterMargin = maxthirdQuarter.add(maxthirdQuarter.multiply(new BigDecimal("0.10")));
fourthQuarterMargin = maxforthQuarter.add(maxforthQuarter.multiply(new BigDecimal("0.10")));
break;
case "C":
firstQuarterMargin = maxFirstQuarter.add(maxFirstQuarter.multiply(new BigDecimal("0.05")));
secondQuarterMargin = maxSecQuarter.add(maxSecQuarter.multiply(new BigDecimal("0.05"))) ;
thirdQuarterMargin = maxthirdQuarter.add(maxthirdQuarter.multiply(new BigDecimal("0.05")));
fourthQuarterMargin = maxforthQuarter.add(maxforthQuarter.multiply(new BigDecimal("0.05")));
break;
default:
firstQuarterMargin = maxFirstQuarter;
secondQuarterMargin = maxSecQuarter;
thirdQuarterMargin = maxthirdQuarter;
fourthQuarterMargin = maxforthQuarter;
break;
}
BigDecimal j = getMaxLastYear(2, product, mrpForecastList);
BigDecimal f = getMaxLastYear(3, product, mrpForecastList);
BigDecimal max = j.max(f);
log.debug("sssssss margin {} max : {} class {} ",firstQuarterMargin,maxFirstQuarter,className);
log.debug("last year jan {} feb {}",j,f);
log.debug("maxxxxxxxxxxx {}",max);
firstQuarterMargin = firstQuarterMargin.add(max);
mrpLineSaleAndMargin.setFirstQuarterMarge(firstQuarterMargin.setScale(0,RoundingMode.CEILING));
mrpLineSaleAndMargin.setSecondQuarterMarge(secondQuarterMargin.setScale(0,RoundingMode.CEILING));
mrpLineSaleAndMargin.setThirdQuarterMarge(thirdQuarterMargin.setScale(0,RoundingMode.CEILING));
mrpLineSaleAndMargin.setForthQuarterMarge(fourthQuarterMargin.setScale(0,RoundingMode.CEILING));
this.createdSalesMasterPlanLine(firstQuarterMargin, secondQuarterMargin, thirdQuarterMargin, fourthQuarterMargin, product, mrp);
mrpLineSaleAndMargin.setProduct(product);
mrpLineSaleAndMargin.setProductOrigin(product);
mrpLineSaleAndMargin.setMrp(mrp);
Beans.get(MrpLineSaleAndMarginRepository.class).save(mrpLineSaleAndMargin);
}
@Transactional
public void createdProductionMasterPlan(Product product,Mrp mrp,BigDecimal qty, BigDecimal batchQty) throws AxelorException {
this.createMargeAndSaleLineSophal(mrp, product, mrpForecastListAll,qty);
ProductionMasterPlan productionMasterPlan = new ProductionMasterPlan();
int currentMonth = LocalDate.now().getMonth().getValue();
BigDecimal decreasingQty = qty;
BigDecimal currentMargin= BigDecimal.ZERO;
BigDecimal remaining= BigDecimal.ZERO;
BigDecimal annualQty= BigDecimal.ZERO;
BigDecimal batchQtyPerMonth = BigDecimal.ZERO;
for (int index = currentMonth; index < 13; index++) {
currentMargin = getCurrentSaleMargin(product, mrp, index);
if(decreasingQty.compareTo(currentMargin) > 0) {
remaining = decreasingQty.subtract(currentMargin);
decreasingQty = BigDecimal.ZERO;
}else{
remaining = BigDecimal.ZERO;
decreasingQty = currentMargin.subtract(decreasingQty);
}
batchQtyPerMonth = decreasingQty.divide(batchQty,0,RoundingMode.UP);
annualQty = annualQty.add(decreasingQty);
switch (index) {
case 1:
productionMasterPlan.setJanuary(decreasingQty);
productionMasterPlan.setJanuaryBatchQty(batchQtyPerMonth);
break;
case 2:
productionMasterPlan.setFebruary(decreasingQty);
productionMasterPlan.setFebruaryBatchQty(batchQtyPerMonth);
break;
case 3:
productionMasterPlan.setMarch(decreasingQty);
productionMasterPlan.setMarchBatchQty(batchQtyPerMonth);
break;
case 4:
productionMasterPlan.setApril(decreasingQty);
productionMasterPlan.setAprilBatchQty(batchQtyPerMonth);
case 5:
productionMasterPlan.setMay(decreasingQty);
productionMasterPlan.setMayBatchQty(batchQtyPerMonth);
case 6:
productionMasterPlan.setJuin(decreasingQty);
productionMasterPlan.setJuinBatchQty(batchQtyPerMonth);
break;
case 7:
productionMasterPlan.setJuly(decreasingQty);
productionMasterPlan.setJulyBatchQty(batchQtyPerMonth);
break;
case 8:
productionMasterPlan.setAugust(decreasingQty);
productionMasterPlan.setAugustBatchQty(batchQtyPerMonth);
break;
case 9:
productionMasterPlan.setSeptember(decreasingQty);
productionMasterPlan.setSeptemberBatchQty(batchQtyPerMonth);
break;
case 10:
productionMasterPlan.setOctober(decreasingQty);
productionMasterPlan.setOctoberBatchQty(batchQtyPerMonth);
break;
case 11:
productionMasterPlan.setNovember(decreasingQty);
productionMasterPlan.setNovemberBatchQty(batchQtyPerMonth);
break;
case 12:
productionMasterPlan.setDecember(decreasingQty);
productionMasterPlan.setDecemberBatchQty(batchQtyPerMonth);
break;
default:
break;
}
if(remaining.compareTo(BigDecimal.ZERO) > 0){
decreasingQty = decreasingQty.add(remaining);
}else{
decreasingQty = BigDecimal.ZERO;
}
}
productionMasterPlan.setAnnualQty(annualQty);
productionMasterPlan.setMrp(mrp);
productionMasterPlan.setProduct(product);
Beans.get(ProductionMasterPlanRepository.class).save(productionMasterPlan);
}
BigDecimal getMaxOfMonth(int monthSelect,Product product,List<MrpForecast> mrpForecastList){
return mrpForecastList.stream().filter(t -> t.getProduct() == product && t.getMonthSelect() == monthSelect).map(t -> t.getQty()).max(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
}
BigDecimal getMaxLastYear(int monthSelect,Product product,List<MrpForecast> mrpForecastList){
int lastYear = LocalDate.now().getYear() - 1;
return mrpForecastList.stream().filter(t -> t.getProduct() == product && t.getMonthSelect() == monthSelect && t.getForecastDate().getYear() == lastYear).map(t -> t.getQty()).max(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
}
@Transactional
public void createdSalesMasterPlanLine(BigDecimal firstQuarterMargin,BigDecimal secondQuarterMargin,BigDecimal thirdQuarterMargin,BigDecimal fourthQuarterMargin,Product product,Mrp mrp){
SalesMasterPlan salesMasterPlan = new SalesMasterPlan();
salesMasterPlan.setJanuary(firstQuarterMargin);
salesMasterPlan.setFebruary(firstQuarterMargin);
salesMasterPlan.setMarch(firstQuarterMargin);
salesMasterPlan.setApril(secondQuarterMargin);
salesMasterPlan.setMay(secondQuarterMargin);
salesMasterPlan.setJuin(secondQuarterMargin);
salesMasterPlan.setJuly(thirdQuarterMargin);
salesMasterPlan.setAugust(thirdQuarterMargin);
salesMasterPlan.setSeptember(thirdQuarterMargin);
salesMasterPlan.setOctober(fourthQuarterMargin);
salesMasterPlan.setNovember(fourthQuarterMargin);
salesMasterPlan.setDecember(fourthQuarterMargin);
salesMasterPlan.setAnnualQty((firstQuarterMargin.add(secondQuarterMargin).add(thirdQuarterMargin).add(fourthQuarterMargin)).multiply(new BigDecimal("3")));
salesMasterPlan.setMrp(mrp);
salesMasterPlan.setProduct(product);
Beans.get(SalesMasterPlanRepository.class).save(salesMasterPlan);
}
private BigDecimal getCurrentSaleMargin(Product product,Mrp mrp,int monthSelect){
MrpLineSaleAndMargin mrpLineSaleAndMargin = Beans.get(MrpLineSaleAndMarginRepository.class).all().fetchStream().filter(t -> t.getProduct() == product && t.getMrp() == mrp).findFirst().orElse(null);
if(mrpLineSaleAndMargin != null){
if(monthSelect == 1 || monthSelect == 2 || monthSelect == 3){
return mrpLineSaleAndMargin.getFirstQuarterMarge();
}else if(monthSelect == 4 || monthSelect == 5 || monthSelect == 6){
return mrpLineSaleAndMargin.getSecondQuarterMarge();
}else if(monthSelect == 7 || monthSelect == 8 || monthSelect == 9){
return mrpLineSaleAndMargin.getThirdQuarterMarge();
}else if(monthSelect == 10 || monthSelect == 11 || monthSelect == 12){
return mrpLineSaleAndMargin.getForthQuarterMarge();
}else{
return BigDecimal.ZERO;
}
}
return BigDecimal.ZERO;
}
public boolean contains(final Object[] objects, final int key)
{
return Arrays.stream(objects).anyMatch(n-> (int) n ==key);
}
}

View File

@@ -227,7 +227,7 @@ public class ProductStockLocationServiceImpl implements ProductStockLocationServ
return sumSaleOrderQty;
}
protected BigDecimal getPurchaseOrderQty(
public BigDecimal getPurchaseOrderQty(
Product product, Company company, StockLocation stockLocation) throws AxelorException {
if (product == null || product.getUnit() == null) {
return BigDecimal.ZERO;

View File

@@ -23,6 +23,7 @@ import com.axelor.apps.account.db.BudgetLine;
import com.axelor.apps.account.db.repo.BudgetDistributionRepository;
import com.axelor.apps.account.service.app.AppAccountService;
import com.axelor.apps.account.service.config.AccountConfigService;
import com.axelor.apps.base.db.CancelReason;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Currency;
import com.axelor.apps.base.db.Partner;
@@ -31,6 +32,7 @@ import com.axelor.apps.base.db.TradingName;
import com.axelor.apps.base.service.app.AppBaseService;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.purchase.db.PurchaseRequest;
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
import com.axelor.apps.purchase.service.PurchaseOrderServiceImpl;
import com.axelor.apps.sale.db.SaleOrder;
@@ -42,24 +44,31 @@ import com.axelor.apps.supplychain.service.app.AppSupplychainService;
import com.axelor.apps.tool.date.DateTool;
import com.axelor.auth.AuthUtils;
import com.axelor.auth.db.User;
import com.axelor.db.EntityHelper;
import com.axelor.db.Query;
import com.axelor.dms.db.DMSFile;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.db.MetaFile;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import wslite.json.JSONException;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wslite.json.JSONException;
public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImpl {
@@ -97,6 +106,7 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
LocalDate deliveryDate,
String internalReference,
String externalReference,
String notes,
StockLocation stockLocation,
LocalDate orderDate,
PriceList priceList,
@@ -119,6 +129,7 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
deliveryDate,
internalReference,
externalReference,
notes, // notes
orderDate,
priceList,
supplierPartner,
@@ -174,11 +185,19 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
throws AxelorException {
String numSeq = "";
String externalRef = "";
String notes = "";
int statusSelect = 1;
Set<PurchaseRequest> purchaseRequestSet = new HashSet<PurchaseRequest>();
for (PurchaseOrder purchaseOrderLocal : purchaseOrderList) {
if (!numSeq.isEmpty()) {
numSeq += "-";
}
numSeq += purchaseOrderLocal.getPurchaseOrderSeq();
numSeq +=
purchaseOrderLocal.getPurchaseOrderSeq()
+ (purchaseOrderLocal.getInternalReference() == null
? ""
: purchaseOrderLocal.getInternalReference() + "-");
if (!externalRef.isEmpty()) {
externalRef += "|";
@@ -186,6 +205,12 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
if (purchaseOrderLocal.getExternalReference() != null) {
externalRef += purchaseOrderLocal.getExternalReference();
}
purchaseRequestSet.addAll(
purchaseOrderLocal.getPurchaseRequestSet().stream().collect(Collectors.toSet()));
if (purchaseOrderLocal.getNotes() != null) {
notes += purchaseOrderLocal.getNotes() + " ";
}
statusSelect = purchaseOrderLocal.getStatusSelect();
}
PurchaseOrder purchaseOrderMerged =
@@ -197,23 +222,48 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
null,
numSeq,
externalRef,
notes,
stockLocation,
LocalDate.now(),
priceList,
supplierPartner,
tradingName);
super.attachPurchaseRequestToNewOrder(
purchaseRequestSet, purchaseOrderMerged, purchaseOrderList);
super.attachToNewPurchaseOrder(purchaseOrderList, purchaseOrderMerged);
this.computePurchaseOrder(purchaseOrderMerged);
purchaseOrderMerged.setStatusSelect(statusSelect);
purchaseOrderRepo.save(purchaseOrderMerged);
this.attachAttachment(purchaseOrderList, purchaseOrderMerged);
super.removeOldPurchaseOrders(purchaseOrderList);
return purchaseOrderMerged;
}
public Set<MetaFile> getMetaFiles(PurchaseOrder po) throws AxelorException, IOException {
List<DMSFile> metaAttachments =
Query.of(DMSFile.class)
.filter(
"self.relatedId = ?1 AND self.relatedModel = ?2",
po.getId(),
EntityHelper.getEntityClass(po).getName())
.fetch();
Set<MetaFile> metaFiles = Sets.newHashSet();
for (DMSFile metaAttachment : metaAttachments) {
if (!metaAttachment.getIsDirectory()) metaFiles.add(metaAttachment.getMetaFile());
}
return metaFiles;
}
public void updateAmountToBeSpreadOverTheTimetable(PurchaseOrder purchaseOrder) {
List<Timetable> timetableList = purchaseOrder.getTimetableList();
BigDecimal totalHT = purchaseOrder.getExTaxTotal();
@@ -340,7 +390,8 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
@Override
@Transactional(rollbackOn = {Exception.class})
public void validatePurchaseOrder(PurchaseOrder purchaseOrder) throws AxelorException, MalformedURLException, JSONException {
public void validatePurchaseOrder(PurchaseOrder purchaseOrder)
throws AxelorException, MalformedURLException, JSONException {
super.validatePurchaseOrder(purchaseOrder);
if (appSupplychainService.getAppSupplychain().getSupplierStockMoveGenerationAuto()
@@ -379,4 +430,12 @@ public class PurchaseOrderServiceSupplychainImpl extends PurchaseOrderServiceImp
purchaseOrderLine.setBudget(budget);
}
}
public void finishSockMoves(
PurchaseOrder purchaseOrder, CancelReason raison, String cancelReasonStr)
throws AxelorException {
Beans.get(PurchaseOrderStockServiceImpl.class)
.cancelReceiptWithRaison(purchaseOrder, raison, cancelReasonStr);
this.finishPurchaseOrder(purchaseOrder, cancelReasonStr);
}
}

View File

@@ -19,6 +19,7 @@ package com.axelor.apps.supplychain.service;
import com.axelor.apps.account.db.TaxLine;
import com.axelor.apps.base.db.Address;
import com.axelor.apps.base.db.CancelReason;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.db.Product;
@@ -464,6 +465,25 @@ public class PurchaseOrderStockServiceImpl implements PurchaseOrderStockService
}
}
public void cancelReceiptWithRaison(
PurchaseOrder purchaseOrder, CancelReason cancelReason, String cancelReasonStr)
throws AxelorException {
List<StockMove> stockMoveList =
Beans.get(StockMoveRepository.class)
.all()
.filter(
"self.originTypeSelect = ? AND self.originId = ? AND self.statusSelect = 2",
StockMoveRepository.ORIGIN_PURCHASE_ORDER,
purchaseOrder.getId())
.fetch();
for (StockMove stockMove : stockMoveList) {
stockMoveService.cancel(stockMove, cancelReason, cancelReasonStr);
}
}
public boolean isStockMoveProduct(PurchaseOrderLine purchaseOrderLine) throws AxelorException {
return isStockMoveProduct(purchaseOrderLine, purchaseOrderLine.getPurchaseOrder());
}

View File

@@ -125,6 +125,7 @@ public class SaleOrderPurchaseServiceImpl implements SaleOrderPurchaseService {
null,
saleOrder.getSaleOrderSeq(),
saleOrder.getExternalReference(),
saleOrder.getDescription(),
saleOrder.getDirectOrderLocation()
? saleOrder.getStockLocation()
: Beans.get(StockLocationService.class)

View File

@@ -126,7 +126,7 @@ public class SaleOrderServiceSupplychainImpl extends SaleOrderServiceImpl {
IExceptionMessage.SUPPLYCHAIN_MISSING_CANCEL_REASON_ON_CHANGING_SALE_ORDER);
}
for (StockMove stockMove : stockMoves) {
stockMoveService.cancel(stockMove, cancelReason);
stockMoveService.cancel(stockMove, cancelReason, "");
stockMoveRepository.remove(stockMove);
}
}
@@ -191,67 +191,63 @@ public class SaleOrderServiceSupplychainImpl extends SaleOrderServiceImpl {
}
}
// same move
@Transactional(rollbackOn = {Exception.class})
public StockMove splitInto2SameMove(
StockMove originalStockMove, List<StockMoveLine> modifiedStockMoveLines)
throws AxelorException {
// same move
@Transactional(rollbackOn = {Exception.class})
public StockMove splitInto2SameMove(
StockMove originalStockMove, List<StockMoveLine> modifiedStockMoveLines)
throws AxelorException {
StockMoveRepository stockMoveRepo = Beans.get(StockMoveRepository.class);
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
StockMoveRepository stockMoveRepo = Beans.get(StockMoveRepository.class);
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
modifiedStockMoveLines =
modifiedStockMoveLines
.stream()
.filter(stockMoveLine -> stockMoveLine.getQty().compareTo(BigDecimal.ZERO) != 0)
.collect(Collectors.toList());
for (StockMoveLine moveLine : modifiedStockMoveLines) {
StockMoveLine newStockMoveLine = new StockMoveLine();
// Set quantity in new stock move line
newStockMoveLine = stockMoveLineRepo.copy(moveLine, false);
newStockMoveLine.setQty(moveLine.getQty());
newStockMoveLine.setRealQty(moveLine.getQty());
newStockMoveLine.setProductTypeSelect(moveLine.getProductTypeSelect());
newStockMoveLine.setSaleOrderLine(moveLine.getSaleOrderLine());
// add stock move line
originalStockMove.addStockMoveLineListItem(newStockMoveLine);
// find the original move line to update it
Optional<StockMoveLine> correspondingMoveLine =
originalStockMove
.getStockMoveLineList()
modifiedStockMoveLines =
modifiedStockMoveLines
.stream()
.filter(stockMoveLine -> stockMoveLine.getId().equals(moveLine.getId()))
.findFirst();
if (BigDecimal.ZERO.compareTo(moveLine.getQty()) > 0
|| (correspondingMoveLine.isPresent()
&& moveLine.getQty().compareTo(correspondingMoveLine.get().getRealQty()) > 0)) {
throw new AxelorException(
TraceBackRepository.CATEGORY_INCONSISTENCY,
I18n.get(""),
originalStockMove);
}
.filter(stockMoveLine -> stockMoveLine.getQty().compareTo(BigDecimal.ZERO) != 0)
.collect(Collectors.toList());
for (StockMoveLine moveLine : modifiedStockMoveLines) {
StockMoveLine newStockMoveLine = new StockMoveLine();
// Set quantity in new stock move line
newStockMoveLine = stockMoveLineRepo.copy(moveLine, false);
newStockMoveLine.setQty(moveLine.getQty());
newStockMoveLine.setRealQty(moveLine.getQty());
newStockMoveLine.setProductTypeSelect(moveLine.getProductTypeSelect());
newStockMoveLine.setSaleOrderLine(moveLine.getSaleOrderLine());
// add stock move line
originalStockMove.addStockMoveLineListItem(newStockMoveLine);
if (correspondingMoveLine.isPresent()) {
// Update quantity in original stock move.
// If the remaining quantity is 0, remove the stock move line
BigDecimal remainingQty = correspondingMoveLine.get().getQty().subtract(moveLine.getQty());
if (BigDecimal.ZERO.compareTo(remainingQty) == 0) {
// Remove the stock move line
originalStockMove.removeStockMoveLineListItem(correspondingMoveLine.get());
} else {
correspondingMoveLine.get().setQty(remainingQty);
correspondingMoveLine.get().setRealQty(remainingQty);
// find the original move line to update it
Optional<StockMoveLine> correspondingMoveLine =
originalStockMove
.getStockMoveLineList()
.stream()
.filter(stockMoveLine -> stockMoveLine.getId().equals(moveLine.getId()))
.findFirst();
if (BigDecimal.ZERO.compareTo(moveLine.getQty()) > 0
|| (correspondingMoveLine.isPresent()
&& moveLine.getQty().compareTo(correspondingMoveLine.get().getRealQty()) > 0)) {
throw new AxelorException(
TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(""), originalStockMove);
}
if (correspondingMoveLine.isPresent()) {
// Update quantity in original stock move.
// If the remaining quantity is 0, remove the stock move line
BigDecimal remainingQty = correspondingMoveLine.get().getQty().subtract(moveLine.getQty());
if (BigDecimal.ZERO.compareTo(remainingQty) == 0) {
// Remove the stock move line
originalStockMove.removeStockMoveLineListItem(correspondingMoveLine.get());
} else {
correspondingMoveLine.get().setQty(remainingQty);
correspondingMoveLine.get().setRealQty(remainingQty);
}
}
}
}
if (!originalStockMove.getStockMoveLineList().isEmpty()) {
return stockMoveRepo.save(originalStockMove);
} else {
return null;
if (!originalStockMove.getStockMoveLineList().isEmpty()) {
return stockMoveRepo.save(originalStockMove);
} else {
return null;
}
}
}
}

View File

@@ -358,7 +358,7 @@ public class SaleOrderStockServiceImpl implements SaleOrderStockService {
@Override
public StockMoveLine createStockMoveLine(
StockMove stockMove, SaleOrderLine saleOrderLine, BigDecimal qty) throws AxelorException {
int scale = Beans.get(AppBaseService.class).getNbDecimalDigitForSalePrice();
int scale = Beans.get(AppBaseService.class).getNbDecimalDigitForSalePrice();
if (this.isStockMoveProduct(saleOrderLine)) {
@@ -374,11 +374,7 @@ public class SaleOrderStockServiceImpl implements SaleOrderStockService {
saleOrderLine.getUnit(), unit, qty, qty.scale(), saleOrderLine.getProduct());
priceDiscounted =
unitConversionService.convert(
unit,
saleOrderLine.getUnit(),
priceDiscounted,
scale,
saleOrderLine.getProduct());
unit, saleOrderLine.getUnit(), priceDiscounted, scale, saleOrderLine.getProduct());
requestedReservedQty =
unitConversionService.convert(
saleOrderLine.getUnit(),
@@ -397,10 +393,7 @@ public class SaleOrderStockServiceImpl implements SaleOrderStockService {
companyUnitPriceUntaxed =
saleOrderLine
.getCompanyExTaxTotal()
.divide(
saleOrderLine.getQty(),
scale,
RoundingMode.HALF_EVEN);
.divide(saleOrderLine.getQty(), scale, RoundingMode.HALF_EVEN);
}
StockMoveLine stockMoveLine =

View File

@@ -21,18 +21,15 @@ import com.axelor.apps.account.db.AccountConfig;
import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.apps.account.service.AccountService;
import com.axelor.apps.account.service.config.AccountConfigService;
import com.axelor.apps.account.service.invoice.InvoiceService;
import com.axelor.apps.account.service.invoice.generator.InvoiceGenerator;
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
import com.axelor.apps.account.service.invoice.workflow.ventilate.VentilateState;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Sequence;
import com.axelor.apps.base.service.AddressService;
import com.axelor.apps.base.service.administration.SequenceService;
import com.axelor.apps.base.service.app.AppBaseService;
import com.axelor.apps.base.service.app.AppService;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
@@ -191,8 +188,11 @@ public class StockMoveInvoiceServiceImpl implements StockMoveInvoiceService {
invoice.setNote(saleOrder.getInvoiceComments());
invoice.setProformaComments(saleOrder.getProformaComments());
//todo sophal
invoice.setInvoiceId(Beans.get(SequenceService.class).getSequenceNumber(getSequence(invoice), Beans.get(AppBaseService.class).getTodayDate()));
// todo sophal
invoice.setInvoiceId(
Beans.get(SequenceService.class)
.getSequenceNumber(
getSequence(invoice), Beans.get(AppBaseService.class).getTodayDate()));
if (invoice != null) {
Set<StockMove> stockMoveSet = invoice.getStockMoveSet();
@@ -230,10 +230,10 @@ public class StockMoveInvoiceServiceImpl implements StockMoveInvoiceService {
this.extendInternalReference(stockMove, invoice);
invoice.setAddressStr(
Beans.get(AddressService.class).computeAddressStr(invoice.getAddress()));
invoice.setPayerPartner(stockMove.getPayerPartner());
invoice.setDeliveryPartner(stockMove.getDeliveryPartner());
invoice.setStamp(stockMove.getStamp());
invoice.setFixTax(stockMove.getFixTax());
invoice.setPayerPartner(stockMove.getPayerPartner());
invoice.setDeliveryPartner(stockMove.getDeliveryPartner());
invoice.setStamp(stockMove.getStamp());
invoice.setFixTax(stockMove.getFixTax());
if (invoice != null) {
Set<StockMove> stockMoveSet = invoice.getStockMoveSet();
if (stockMoveSet == null) {
@@ -572,24 +572,23 @@ public class StockMoveInvoiceServiceImpl implements StockMoveInvoiceService {
AccountConfig accountConfig = accountConfigService.getAccountConfig(invoice.getCompany());
switch (invoice.getOperationTypeSelect()) {
case InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE:
return accountConfigService.getSuppInvSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE:
return accountConfigService.getSuppInvSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_SUPPLIER_REFUND:
return accountConfigService.getSuppRefSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_SUPPLIER_REFUND:
return accountConfigService.getSuppRefSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_CLIENT_SALE:
return accountConfigService.getCustInvSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_CLIENT_REFUND:
return accountConfigService.getCustRefSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_CLIENT_SALE:
return accountConfigService.getCustInvSequence(accountConfig);
case InvoiceRepository.OPERATION_TYPE_CLIENT_REFUND:
return accountConfigService.getCustRefSequence(accountConfig);
default:
throw new AxelorException(
invoice,
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get("Invoice type missing %s"),
invoice.getInvoiceId());
}
default:
throw new AxelorException(
invoice,
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get("Invoice type missing %s"),
invoice.getInvoiceId());
}
}
}

View File

@@ -20,11 +20,18 @@ package com.axelor.apps.supplychain.service;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Unit;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.base.service.PriceListService;
import com.axelor.apps.base.service.UnitConversionService;
import com.axelor.apps.base.service.app.AppBaseService;
import com.axelor.apps.base.service.tax.AccountManagementService;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
import com.axelor.apps.purchase.service.PurchaseOrderLineService;
import com.axelor.apps.purchase.service.PurchaseOrderLineServiceImpl;
import com.axelor.apps.purchase.service.PurchaseOrderServiceImpl;
import com.axelor.apps.sale.db.SaleOrderLine;
import com.axelor.apps.stock.db.StockLocation;
import com.axelor.apps.stock.db.StockLocationLine;
@@ -32,26 +39,37 @@ import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.TrackingNumber;
import com.axelor.apps.stock.db.TrackingNumberConfiguration;
import com.axelor.apps.stock.db.repo.StockLocationLineRepository;
import com.axelor.apps.stock.db.repo.StockLocationRepository;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.stock.db.repo.TrackingNumberRepository;
import com.axelor.apps.stock.service.StockLocationLineService;
import com.axelor.apps.stock.service.StockLocationLineServiceImpl;
import com.axelor.apps.stock.service.StockMoveLineServiceImpl;
import com.axelor.apps.stock.service.StockMoveToolService;
import com.axelor.apps.stock.service.TrackingNumberService;
import com.axelor.apps.stock.service.WeightedAveragePriceService;
import com.axelor.apps.stock.service.app.AppStockService;
import com.axelor.apps.supplychain.exception.IExceptionMessage;
import com.axelor.db.JPA;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.google.inject.servlet.RequestScoped;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RequestScoped
public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImpl
@@ -59,6 +77,9 @@ public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImp
protected AccountManagementService accountManagementService;
protected PriceListService priceListService;
protected PurchaseOrderLineRepository purchaseOrderLineRepo;
protected PurchaseOrderLineService purchaseOrderLineService;
protected List<StockMoveLine> stockMoveLines;
@Inject
public StockMoveLineServiceSupplychainImpl(
@@ -72,6 +93,8 @@ public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImp
WeightedAveragePriceService weightedAveragePriceService,
TrackingNumberRepository trackingNumberRepo,
AccountManagementService accountManagementService,
PurchaseOrderLineRepository purchaseOrderLineRepository,
PurchaseOrderLineService purchaseOrderLineService,
PriceListService priceListService) {
super(
trackingNumberService,
@@ -85,6 +108,7 @@ public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImp
trackingNumberRepo);
this.accountManagementService = accountManagementService;
this.priceListService = priceListService;
this.stockMoveLines = new ArrayList<>();
}
@Override
@@ -121,7 +145,7 @@ public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImp
stockMoveLine.setRequestedReservedQty(BigDecimal.ZERO);
stockMoveLine.setSaleOrderLine(saleOrderLine);
stockMoveLine.setPurchaseOrderLine(purchaseOrderLine);
if(saleOrderLine != null){
if (saleOrderLine != null) {
stockMoveLine.setShp(saleOrderLine.getShp());
stockMoveLine.setPpa(saleOrderLine.getPpa());
stockMoveLine.setPvg(saleOrderLine.getPvg());
@@ -456,4 +480,421 @@ public class StockMoveLineServiceSupplychainImpl extends StockMoveLineServiceImp
stockMoveLine.setAvailableStatusSelect(1);
}
}
@Transactional
public void resetValorization(Long productId, Long stockMoveId, LocalDate toDateTime,Boolean excludeValotisationStocklocation) {
StockMove stockMove = Beans.get(StockMoveRepository.class).find(stockMoveId);
Product product = Beans.get(ProductRepository.class).find(productId);
if(excludeValotisationStocklocation){
this.stockMoveLines = getStockMoveLines(product, toDateTime, stockMove,true);
}else{
this.stockMoveLines = getStockMoveLines(product, toDateTime, stockMove,false);
}
List<StockMoveLine> lines = new ArrayList<>();
if(this.stockMoveLines.size() > 1){
lines = sliceStockMoveLines(this.stockMoveLines,stockMoveId,product);
}else{
lines.addAll(stockMoveLines);
}
for (StockMoveLine stockMoveLine : lines) {
stockMoveLine.setIsWapUpdated(false);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
}
public void fillStockMoveLines(Long productId,LocalDate toDateTime,Long stockMoveId,Boolean excludeValotisationStocklocation){
StockMove stockMove = Beans.get(StockMoveRepository.class).find(stockMoveId);
Product product = Beans.get(ProductRepository.class).find(productId);
this.stockMoveLines = getStockMoveLines(product, toDateTime, stockMove,excludeValotisationStocklocation);
System.out.println("***********************stockMoveLines****************************");
System.out.println(this.stockMoveLines);
System.out.println("***********************stockMoveLines****************************");
}
@Transactional
public void valorize(Long productId, Long stockMoveId, LocalDate toDateTime, BigDecimal price,Boolean updatePo,Boolean excludeValotisationStocklocation)
throws AxelorException {
StockMove stockMove = Beans.get(StockMoveRepository.class).find(stockMoveId);
Product product = Beans.get(ProductRepository.class).find(productId);
int scale = appBaseService.getNbDecimalDigitForUnitPrice();
this.updateStockMoveLinePrices(product, price, stockMove, false, null);
// if(updatePo){
// this.updatePurchaseOrderPrices(stockMove, product, price);
// }
List<StockMoveLine> lines = sliceStockMoveLines(this.stockMoveLines,stockMoveId,product);
BigDecimal currentQty = this.getTotalQty(product, stockMove.getCompany(),false);
BigDecimal oldWap = this.getPreviousWap(lines.get(0),false);
if(excludeValotisationStocklocation){
currentQty = this.getTotalQty(product, stockMove.getCompany(),true);
oldWap = this.getPreviousWap(lines.get(0),true);
}
for (StockMoveLine stockMoveLine : lines) {
if (stockMoveLine.getStockMove().getFromStockLocation().getTypeSelect()
== StockLocationRepository.TYPE_VIRTUAL && stockMoveLine.getStockMove().getToStockLocation().getId() != 6L) {
currentQty = currentQty.subtract(stockMoveLine.getRealQty());
} else if (stockMoveLine.getStockMove().getToStockLocation().getTypeSelect()
== StockLocationRepository.TYPE_VIRTUAL || (stockMoveLine.getStockMove().getToStockLocation().getId() == 6L && stockMoveLine.getStockMove().getFromStockLocation().getTypeSelect()
!= StockLocationRepository.TYPE_VIRTUAL)) {
currentQty = currentQty.add(stockMoveLine.getRealQty());
}
System.out.println("..................>>>>>>>>>>>>>>>><<<<<"+currentQty.toString());
}
BigDecimal newQty = lines.get(0).getRealQty();
BigDecimal newPrice = price;
BigDecimal newWap =
newQty
.multiply(newPrice)
.add(currentQty.multiply(oldWap))
.divide(currentQty.add(newQty), scale, BigDecimal.ROUND_HALF_UP);
this.updateStockMoveLinePrices(product, price, stockMove, true, newWap);
int index = 1;
List<StockMoveLine> lines2 = new ArrayList<>();
if(lines.size() > 1){
lines2 = this.stockMoveLineStartingFromIndex(index, lines);
}
for (StockMoveLine stockMoveLine : lines2) {
// stockMoveLine.getStockMove().getFromStockLocation().getTypeSelect() !=
// StockLocationRepository.TYPE_VIRTUAL &&
if (stockMoveLine.getStockMove().getPartner() == stockMove.getCompany().getPartner()
|| stockMoveLine.getStockMove().getPartner() == null) {
stockMoveLine.setUnitPriceTaxed(newWap);
stockMoveLine.setUnitPriceUntaxed(newWap);
stockMoveLine.setCompanyUnitPriceUntaxed(newWap);
stockMoveLine.setWapPrice(newWap);
stockMoveLine.setIsWapUpdated(true);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
} else if (stockMoveLine.getStockMove().getPartner().getId()
!= stockMove.getCompany().getPartner().getId()
&& stockMoveLine.getIsWapUpdated() == false) {
index++;
this.valorize(
productId,
stockMoveLine.getStockMove().getId(),
toDateTime,
stockMoveLine.getUnitPriceUntaxed(),updatePo,excludeValotisationStocklocation);
break;
}
}
}
private void updatePurchaseOrderPrices(StockMove stockMove, Product product, BigDecimal price)
throws AxelorException {
if (StockMoveRepository.ORIGIN_PURCHASE_ORDER.equals(stockMove.getOriginTypeSelect())
&& stockMove.getOriginId() != null) {
PurchaseOrder purchaseOrder =
Beans.get(PurchaseOrderRepository.class).find(stockMove.getOriginId());
purchaseOrder.setCurrency(purchaseOrder.getCompany().getCurrency());
List<PurchaseOrderLine> purchaseOrderLines =
purchaseOrder
.getPurchaseOrderLineList()
.stream()
.filter(t -> t.getProduct().getId() == product.getId())
.collect(Collectors.toList());
// if(purchaseOrderLines == null || purchaseOrderLines.isEmpty()){
// return;
// }
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLines) {
this.updatePrice(purchaseOrderLine, price);
}
Beans.get(PurchaseOrderRepository.class).save(purchaseOrder);
Beans.get(PurchaseOrderServiceImpl.class)._computePurchaseOrder(purchaseOrder);
}
}
public List<StockMoveLine> stockMoveLineStartingFromIndex(
int index, List<StockMoveLine> stockMoveLines) {
List<StockMoveLine> newStockMoveLines = new ArrayList<>();
if (index > stockMoveLines.size()) {
return newStockMoveLines;
}
for (int i = index; i < stockMoveLines.size(); i++) {
newStockMoveLines.add(stockMoveLines.get(i));
}
return newStockMoveLines;
}
@Transactional
private void updateStockMoveLinePrices(
Product product,
BigDecimal price,
StockMove stockMove,
boolean updatePmp,
BigDecimal newWapPrice) {
List<StockMoveLine> stockMoveLines =
// stockMoveLineRepository
// .all()
// .filter(
// "self.stockMove.id = ?1 and self.product.id = ?2 and self.stockMove.statusSelect = 3 and self.realQty > 0",
// stockMoveId,
// productId)
// .fetch();
stockMove.getStockMoveLineList().stream().filter(t -> (t.getProduct().getId() == product.getId() && t.getRealQty().compareTo(BigDecimal.ZERO) > 0)).collect(Collectors.toList());
if (!updatePmp) {
for (StockMoveLine stockMoveLine : stockMoveLines) {
stockMoveLine.setCompanyUnitPriceUntaxed(price);
stockMoveLine.setUnitPriceTaxed(price);
stockMoveLine.setUnitPriceUntaxed(price);
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
}
stockMove.setExTaxTotal(stockMoveToolService.compute(stockMove));
Beans.get(StockMoveRepository.class).save(stockMove);
} else {
// Product product = Beans.get(ProductRepository.class).find(productId);
for (StockMoveLine stockMoveLine : stockMoveLines) {
stockMoveLine.setWapPrice(newWapPrice);
stockMoveLine.setIsWapUpdated(true);
product.setAvgPrice(newWapPrice);
List<StockLocationLine> locationLines =
Beans.get(StockLocationLineServiceImpl.class).getStockLocationLines(product);
for (StockLocationLine stockLocationLine : locationLines) {
stockLocationLine.setAvgPrice(newWapPrice);
Beans.get(StockLocationLineRepository.class).save(stockLocationLine);
}
Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
Beans.get(ProductRepository.class).save(product);
}
}
}
@Transactional
public void updatePrice(PurchaseOrderLine purchaseOrderLine, BigDecimal price)
throws AxelorException {
System.out.println("updateOrderLinePrices......................");
System.out.println(purchaseOrderLine.toString());
purchaseOrderLine.setPrice(price);
purchaseOrderLine.setPriceDiscounted(price);
Beans.get(PurchaseOrderLineServiceImpl.class)
.compute(purchaseOrderLine, purchaseOrderLine.getPurchaseOrder());
Beans.get(PurchaseOrderLineRepository.class).save(purchaseOrderLine);
}
public List<StockMoveLine> getStockMoveLines(
Product product, LocalDate toDate, StockMove stockMove,Boolean excludeValotisationStocklocation) {
String query =
"self.stockMove.statusSelect = ?1 AND self.stockMove.realDate <= ?2 AND self.product = ?3 AND self.stockMove.realDate >= ?4 AND self.realQty > 0 AND (self.archived is null OR self.archived is false)";
if (excludeValotisationStocklocation) {
query += " AND (self.stockMove.toStockLocation.excludeValorisation is true or self.stockMove.fromStockLocation.excludeValorisation is true)";
}else{
query += " AND ((self.stockMove.toStockLocation.excludeValorisation is false or self.stockMove.toStockLocation.excludeValorisation is null) AND (self.stockMove.fromStockLocation.excludeValorisation is false or self.stockMove.fromStockLocation.excludeValorisation is null))";
}
System.out.println("***************getStockMoveLines************");
System.out.println(query);
System.out.println("***************getStockMoveLines************");
List<Object> params = Lists.newArrayList();
params.add(StockMoveRepository.STATUS_REALIZED);
params.add(toDate);
params.add(product);
params.add(stockMove.getRealDate());
// params.add(stockMove.getRealDate());
// params.add(stockMove.getId());
List<StockMoveLine> lines =
stockMoveLineRepository
.all()
.filter(query, params.toArray())
.order("stockMove.realDate")
// .order("id")
.fetch();
return lines;
}
public BigDecimal getPreviousWap(StockMoveLine stockMoveLine,Boolean excludeValotisationStocklocation) {
String query =
"self.stockMove.statusSelect = ?1 AND self.product = ?2 and self.stockMove.realDate < ?3 AND self.realQty > 0";
if (excludeValotisationStocklocation) {
query += " AND (self.stockMove.toStockLocation.excludeValorisation is true or self.stockMove.fromStockLocation.excludeValorisation is true)";
}
StockMoveLine l = stockMoveLineRepository.find(stockMoveLine.getId());
List<Object> params = Lists.newArrayList();
params.add(StockMoveRepository.STATUS_REALIZED);
params.add(l.getProduct());
params.add(l.getStockMove().getRealDate());
StockMoveLine line =
stockMoveLineRepository
.all()
.order("-stockMove.realDate")
.order("-id")
.filter(query, params.toArray())
.fetchOne();
if (line == null || line.getWapPrice() == null) {
return stockMoveLine.getUnitPriceUntaxed();
}
return line.getWapPrice();
}
@SuppressWarnings({"unchecked", "rawtypes"})
public BigDecimal getTotalQty(Product product, Company company,Boolean excludeValotisationStocklocation) {
Long productId = product.getId();
String query =
"SELECT new list(self.id, self.avgPrice, self.currentQty) FROM StockLocationLine as self "
+ "WHERE self.product.id = "
+ productId
+ "AND self.stockLocation.id not in (6) AND self.stockLocation.typeSelect != "
+ StockLocationRepository.TYPE_VIRTUAL;
if (excludeValotisationStocklocation) {
query += " AND (self.stockLocation.excludeValorisation is true)";
}else{
query += " AND (self.stockLocation.excludeValorisation is false or self.stockLocation.excludeValorisation is null)";
}
if (company != null) {
query += " AND self.stockLocation.company = " + company.getId();
}
BigDecimal qtyTot = BigDecimal.ZERO;
List<List<Object>> results = JPA.em().createQuery(query).getResultList();
if (results.isEmpty()) {
return BigDecimal.ZERO;
}
for (List<Object> result : results) {
BigDecimal qty = (BigDecimal) result.get(2);
qtyTot = qtyTot.add(qty);
}
if (qtyTot.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
System.out.println("***************query*************");
System.out.println(query);
System.out.println("***************qtyTot*************");
System.out.println(qtyTot);
return qtyTot;
}
// lines
public List<StockMoveLine> lines = new ArrayList<>();
public void showLines(Long productId, Long stockMoveId, LocalDate toDateTime, BigDecimal price) {
StockMove stockMove = Beans.get(StockMoveRepository.class).find(stockMoveId);
Product product = Beans.get(ProductRepository.class).find(productId);
List<StockMoveLine> lines = getStockMoveLines(product, toDateTime, stockMove,false);
System.out.println("*****************************************************");
for (StockMoveLine line : lines) {
System.out.println(line.getStockMove().getStockMoveSeq());
}
System.out.println("*****************************************************");
int index = 1;
List<StockMoveLine> lines2 = this.stockMoveLineStartingFromIndex(index, lines);
System.out.println("********************lines2*********************************");
for (StockMoveLine stockMoveLine : lines2) {
if (stockMoveLine.getStockMove().getPartner() == stockMove.getCompany().getPartner()
|| stockMoveLine.getStockMove().getPartner() == null) {
System.out.println("Interne ***** " + stockMoveLine.getStockMove().getStockMoveSeq());
} else if (stockMoveLine.getStockMove().getPartner().getId()
!= stockMove.getCompany().getPartner().getId()) {
index++;
System.out.println(
"Externe ***** "
+ stockMoveLine.getStockMove().getStockMoveSeq()
+ " ,id : "
+ stockMoveLine.getStockMove().getId());
this.showLines(productId, stockMoveLine.getStockMove().getId(), toDateTime, price);
break;
}
}
System.out.println("***********************lines2******************************");
}
public void valorizeAll(LocalDate fromDateTime, Long productCategoryId) throws AxelorException {
// ,67
String query =
"self.stockMove.statusSelect = ?1 "+
"and self.stockMove.realDate >= ?2 and self.realQty > 0 and "+
"self.product.familleProduit.id in ("+String.valueOf(productCategoryId)+") and self.stockMove.fromStockLocation.id = 12 and self.stockMove.partner.id != 853";
List<Object> params = Lists.newArrayList();
params.add(StockMoveRepository.STATUS_REALIZED);
params.add(fromDateTime);
List<StockMoveLine> lines =
stockMoveLineRepository
.all()
.filter(query, params.toArray())
.order("stockMove.realDate")
.order("id")
.fetch();
List<StockMoveLine> distinctLines = new ArrayList<>();
List<Product> products = new ArrayList<>();
for (StockMoveLine line : lines) {
if(products.indexOf(line.getProduct()) == -1){
distinctLines.add(line);
products.add(line.getProduct());
}
}
int index = lines.size();
for (StockMoveLine line : distinctLines) {
System.out.println("Starting ............... "+String.valueOf(index));
System.out.println("Size ............... "+String.valueOf(distinctLines.size()));
System.out.println(line.getStockMove().getStockMoveSeq());
System.out.println(line.getProductName());
System.out.println(line.getProduct().getId());
this.resetValorization(line.getProduct().getId(), line.getStockMove().getId(), LocalDate.now(),false);
this.fillStockMoveLines(line.getProduct().getId(), LocalDate.now(), line.getStockMove().getId(),false);
this.valorize(line.getProduct().getId(), line.getStockMove().getId(), LocalDate.now(), line.getUnitPriceUntaxed(), false,false);
System.out.println("End .....................");
index --;
}
}
public List<StockMoveLine> sliceStockMoveLines(List<StockMoveLine> lines,Long stockMoveId,Product product){
StockMoveLine emp = lines.stream().filter((t) -> {
return t.getStockMove().getId() == stockMoveId && t.getProduct() == product;
}).findFirst().orElse(null);
int index = lines.indexOf(emp);
List<StockMoveLine> slicedLines = new ArrayList<>();
for (int i = index; i < lines.size(); i++) {
slicedLines.add(lines.get(i));
}
return slicedLines;
}
}

View File

@@ -34,7 +34,6 @@ import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
import com.axelor.apps.sale.db.SaleOrder;
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.supplychain.exception.IExceptionMessage;
import com.axelor.apps.tool.StringTool;
@@ -46,7 +45,6 @@ import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.HashMap;
@@ -523,16 +521,17 @@ public class StockMoveMultiInvoiceServiceImpl implements StockMoveMultiInvoiceSe
} else {
stockMoveList.forEach(
stockMove -> {
Set<Invoice> invoiceSet = new HashSet<>();
invoiceSet.add(invoice);
stockMove.setInvoiceSet(invoiceSet);
String sqlString = String.format("INSERT INTO public.account_invoice_stock_move_set( invoice_set, stock_move_set) VALUES (:invoiceSet, :stockMoveSet)");
javax.persistence.Query query = JPA.em().createNativeQuery(sqlString);
query.setParameter("invoiceSet", invoice.getId());
query.setParameter("stockMoveSet", stockMove.getId());
JPA.runInTransaction(query::executeUpdate);
Set<Invoice> invoiceSet = new HashSet<>();
invoiceSet.add(invoice);
stockMove.setInvoiceSet(invoiceSet);
String sqlString =
String.format(
"INSERT INTO public.account_invoice_stock_move_set( invoice_set, stock_move_set) VALUES (:invoiceSet, :stockMoveSet)");
javax.persistence.Query query = JPA.em().createNativeQuery(sqlString);
query.setParameter("invoiceSet", invoice.getId());
query.setParameter("stockMoveSet", stockMove.getId());
JPA.runInTransaction(query::executeUpdate);
});
return Optional.of(invoice);
}
@@ -679,7 +678,9 @@ public class StockMoveMultiInvoiceServiceImpl implements StockMoveMultiInvoiceSe
/** This method will throw an exception if the given stock move is already invoiced. */
protected void checkIfAlreadyInvoiced(StockMove stockMove) throws AxelorException {
if (stockMove.getInvoiceSet() != null
&& stockMove.getInvoiceSet().stream()
&& stockMove
.getInvoiceSet()
.stream()
.anyMatch(invoice -> invoice.getStatusSelect() != InvoiceRepository.STATUS_CANCELED)) {
String templateMessage;
if (stockMove.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING) {
@@ -827,7 +828,11 @@ public class StockMoveMultiInvoiceServiceImpl implements StockMoveMultiInvoiceSe
? purchaseOrderRepository.find(stockMove.getOriginId())
: null;
if (purchaseOrder != null) {
externalRefList.add(purchaseOrder.getExternalReference());
if (purchaseOrder.getExternalReference() != null) {
if (!purchaseOrder.getExternalReference().isEmpty()) {
externalRefList.add(purchaseOrder.getExternalReference());
}
}
}
internalRefList.add(
stockMove.getStockMoveSeq()

View File

@@ -443,73 +443,69 @@ public class StockMoveServiceSupplychainImpl extends StockMoveServiceImpl
}
// same move
@Transactional(rollbackOn = {Exception.class})
public StockMove splitInto2SameMove(
StockMove originalStockMove, List<StockMoveLine> modifiedStockMoveLines)
throws AxelorException {
@Transactional(rollbackOn = {Exception.class})
public StockMove splitInto2SameMove(
StockMove originalStockMove, List<StockMoveLine> modifiedStockMoveLines)
throws AxelorException {
StockMoveRepository stockMoveRepo = Beans.get(StockMoveRepository.class);
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
StockMoveRepository stockMoveRepo = Beans.get(StockMoveRepository.class);
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
modifiedStockMoveLines =
modifiedStockMoveLines
.stream()
.filter(stockMoveLine -> stockMoveLine.getQty().compareTo(BigDecimal.ZERO) != 0)
.collect(Collectors.toList());
for (StockMoveLine moveLine : modifiedStockMoveLines) {
StockMoveLine newStockMoveLine = new StockMoveLine();
// Set quantity in new stock move line
newStockMoveLine = stockMoveLineRepo.copy(moveLine, false);
newStockMoveLine.setQty(moveLine.getQty());
newStockMoveLine.setRealQty(moveLine.getQty());
newStockMoveLine.setProductTypeSelect(moveLine.getProductTypeSelect());
newStockMoveLine.setSaleOrderLine(moveLine.getSaleOrderLine());
newStockMoveLine.setPurchaseOrderLine(moveLine.getPurchaseOrderLine());
newStockMoveLine.setCompanyUnitPriceUntaxed(moveLine.getCompanyUnitPriceUntaxed());
newStockMoveLine.setUg(moveLine.getUg());
newStockMoveLine.setPpa(moveLine.getPpa());
newStockMoveLine.setPvg(moveLine.getPvg());
newStockMoveLine.setStklim(moveLine.getStklim());
newStockMoveLine.setShp(moveLine.getShp());
// add stock move line
originalStockMove.addStockMoveLineListItem(newStockMoveLine);
// find the original move line to update it
Optional<StockMoveLine> correspondingMoveLine =
originalStockMove
.getStockMoveLineList()
modifiedStockMoveLines =
modifiedStockMoveLines
.stream()
.filter(stockMoveLine -> stockMoveLine.getId().equals(moveLine.getId()))
.findFirst();
if (BigDecimal.ZERO.compareTo(moveLine.getQty()) > 0
|| (correspondingMoveLine.isPresent()
&& moveLine.getQty().compareTo(correspondingMoveLine.get().getRealQty()) > 0)) {
throw new AxelorException(
TraceBackRepository.CATEGORY_INCONSISTENCY,
I18n.get(""),
originalStockMove);
}
.filter(stockMoveLine -> stockMoveLine.getQty().compareTo(BigDecimal.ZERO) != 0)
.collect(Collectors.toList());
for (StockMoveLine moveLine : modifiedStockMoveLines) {
StockMoveLine newStockMoveLine = new StockMoveLine();
// Set quantity in new stock move line
newStockMoveLine = stockMoveLineRepo.copy(moveLine, false);
newStockMoveLine.setQty(moveLine.getQty());
newStockMoveLine.setRealQty(moveLine.getQty());
newStockMoveLine.setProductTypeSelect(moveLine.getProductTypeSelect());
newStockMoveLine.setSaleOrderLine(moveLine.getSaleOrderLine());
newStockMoveLine.setPurchaseOrderLine(moveLine.getPurchaseOrderLine());
newStockMoveLine.setCompanyUnitPriceUntaxed(moveLine.getCompanyUnitPriceUntaxed());
newStockMoveLine.setUg(moveLine.getUg());
newStockMoveLine.setPpa(moveLine.getPpa());
newStockMoveLine.setPvg(moveLine.getPvg());
newStockMoveLine.setStklim(moveLine.getStklim());
newStockMoveLine.setShp(moveLine.getShp());
// add stock move line
originalStockMove.addStockMoveLineListItem(newStockMoveLine);
if (correspondingMoveLine.isPresent()) {
// Update quantity in original stock move.
// If the remaining quantity is 0, remove the stock move line
BigDecimal remainingQty = correspondingMoveLine.get().getQty().subtract(moveLine.getQty());
if (BigDecimal.ZERO.compareTo(remainingQty) == 0) {
// Remove the stock move line
originalStockMove.removeStockMoveLineListItem(correspondingMoveLine.get());
} else {
correspondingMoveLine.get().setQty(remainingQty);
correspondingMoveLine.get().setRealQty(remainingQty);
// find the original move line to update it
Optional<StockMoveLine> correspondingMoveLine =
originalStockMove
.getStockMoveLineList()
.stream()
.filter(stockMoveLine -> stockMoveLine.getId().equals(moveLine.getId()))
.findFirst();
if (BigDecimal.ZERO.compareTo(moveLine.getQty()) > 0
|| (correspondingMoveLine.isPresent()
&& moveLine.getQty().compareTo(correspondingMoveLine.get().getRealQty()) > 0)) {
throw new AxelorException(
TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(""), originalStockMove);
}
if (correspondingMoveLine.isPresent()) {
// Update quantity in original stock move.
// If the remaining quantity is 0, remove the stock move line
BigDecimal remainingQty = correspondingMoveLine.get().getQty().subtract(moveLine.getQty());
if (BigDecimal.ZERO.compareTo(remainingQty) == 0) {
// Remove the stock move line
originalStockMove.removeStockMoveLineListItem(correspondingMoveLine.get());
} else {
correspondingMoveLine.get().setQty(remainingQty);
correspondingMoveLine.get().setRealQty(remainingQty);
}
}
}
}
if (!originalStockMove.getStockMoveLineList().isEmpty()) {
return stockMoveRepo.save(originalStockMove);
} else {
return null;
if (!originalStockMove.getStockMoveLineList().isEmpty()) {
return stockMoveRepo.save(originalStockMove);
} else {
return null;
}
}
}
}

View File

@@ -167,6 +167,7 @@ public class StockRulesServiceSupplychainImpl extends StockRulesServiceImpl {
supplierPartner.getCurrency(),
today.plusDays(supplierPartner.getDeliveryDelay()),
stockRules.getName(),
"",
null,
stockLocation,
today,

View File

@@ -0,0 +1,28 @@
/*
* 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.supplychain.service;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.supplychain.db.SupplierRating;
public interface SupplierRatingService {
public void calculatRating(SupplierRating supplierRating);
public void createRating(StockMove stockMove);
}

View File

@@ -0,0 +1,426 @@
package com.axelor.apps.supplychain.service;
import com.axelor.apps.account.db.PaymentCondition;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.supplychain.db.SupplierRating;
import com.axelor.apps.supplychain.db.repo.SupplierRatingRepository;
import com.axelor.inject.Beans;
import com.google.inject.persist.Transactional;
import com.thoughtworks.xstream.mapper.Mapper;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class SupplierRatingServiceImpl implements SupplierRatingService {
public final int COEF_PAYMENT_DELAY = 1;
public final int COEF_DELIVERY_TIME = 1;
public final int COEF_COMPLIANCE_WITH_TECHNICAL_SPECIFICATIONS = 3;
public final int COEF_PRICE = 3;
public final int COEF_QUANTITY_COMPLIANCE = 1;
public final int COEF_COMPLAINT_MANAGEMENT = 1;
public final int COEF_PRICE_STABILITY = 1;
public final int SUM_COEF =
COEF_PAYMENT_DELAY
+ COEF_DELIVERY_TIME
+ COEF_COMPLIANCE_WITH_TECHNICAL_SPECIFICATIONS
+ COEF_PRICE
+ COEF_QUANTITY_COMPLIANCE
+ COEF_COMPLAINT_MANAGEMENT
+ COEF_PRICE_STABILITY;
public void calculatRating(SupplierRating supplierRating) {
Integer paymentDelayRatingSelect = supplierRating.getPaymentDelayRatingSelect();
Integer deliveryTimeRatingSelect = supplierRating.getDeliveryTimeRatingSelect();
Integer complianceWithTechnicalSpecificationsRatingSelect =
supplierRating.getComplianceWithTechnicalSpecificationsRatingSelect();
Integer priceRatingSelect = supplierRating.getPriceRatingSelect();
Integer quantityComplianceRatingSelect = supplierRating.getQuantityComplianceRatingSelect();
Integer complaintManagementRatingSelect = supplierRating.getComplaintManagementRatingSelect();
Integer priceStabilityRatingSelect = supplierRating.getPriceStabilityRatingSelect();
// Calculate the overall score based on ratings
int score =
(paymentDelayRatingSelect * COEF_PAYMENT_DELAY)
+ (deliveryTimeRatingSelect * COEF_DELIVERY_TIME)
+ (complianceWithTechnicalSpecificationsRatingSelect
* COEF_COMPLIANCE_WITH_TECHNICAL_SPECIFICATIONS)
+ (priceRatingSelect * COEF_PRICE)
+ (quantityComplianceRatingSelect * COEF_QUANTITY_COMPLIANCE)
+ (complaintManagementRatingSelect * COEF_COMPLAINT_MANAGEMENT)
+ (priceStabilityRatingSelect * COEF_PRICE_STABILITY);
// Set the overall score
BigDecimal overallScore =
BigDecimal.valueOf(score * 20)
.divide(BigDecimal.valueOf(SUM_COEF * 3), 2, BigDecimal.ROUND_HALF_UP);
supplierRating.setOverallScore(overallScore);
}
@Transactional
public void createRating(StockMove stockMove) {
StockMove stockMoveOrigin = stockMove.getStockMoveOrigin();
Boolean isWithBackorder = stockMove.getIsWithBackorder();
if (stockMoveOrigin == null) {
LocalDateTime realDate;
if (isWithBackorder == true) {
realDate = stockMove.getRealDate();
} else {
realDate = LocalDateTime.now();
}
Partner partner = stockMove.getPartner();
// Stock Move Lines
List<StockMoveLine> stockMoveLinesList = stockMove.getStockMoveLineList();
// Purchase Order
Long originId = stockMove.getOriginId();
PurchaseOrder purchaseOrder = Beans.get(PurchaseOrderRepository.class).find(originId);
// Purchase Order Lines
List<PurchaseOrderLine> purchaseOrderLinesList = purchaseOrder.getPurchaseOrderLineList();
// Délai de payment
PaymentCondition paymentCondition = purchaseOrder.getPaymentCondition();
Integer paymentTime = paymentCondition.getPaymentTime();
Integer paymentDelayRatingSelect = calculatPaymentDelayRatingSelect(paymentTime);
// Date
LocalDate estimatedDate = purchaseOrder.getDeliveryDate();
Integer deliveryTimeRatingSelect = calculatDeliveryTimeRatingSelect(estimatedDate, realDate);
// Quantité
Integer quantityComplianceRatingSelect =
calculatQuantityComplianceRatingSelect(stockMoveLinesList);
// Stabilité des prix
Integer priceStabilityRatingSelect =
calculatPriceStabilityRatingSelectLastPrice(purchaseOrderLinesList, partner);
// Creation
SupplierRating supplierRating = new SupplierRating();
supplierRating.setPaymentDelayRatingSelect(paymentDelayRatingSelect);
supplierRating.setDeliveryTimeRatingSelect(deliveryTimeRatingSelect);
supplierRating.setQuantityComplianceRatingSelect(quantityComplianceRatingSelect);
supplierRating.setPriceStabilityRatingSelect(priceStabilityRatingSelect);
supplierRating.setPurchaseOrder(purchaseOrder);
supplierRating.setSupplierPartner(partner);
Beans.get(SupplierRatingRepository.class).save(supplierRating);
} else {
// Purchase Order
Long originId = stockMove.getOriginId();
PurchaseOrder purchaseOrder = Beans.get(PurchaseOrderRepository.class).find(originId);
List<StockMove> originStockMoves =
Beans.get(StockMoveRepository.class)
.all()
.fetch()
.stream()
.filter(t -> t.getOriginId() == originId && t.getStatusSelect() == 3)
.collect(Collectors.toList());
// Purchase Order Lines
List<PurchaseOrderLine> purchaseOrderLinesList = purchaseOrder.getPurchaseOrderLineList();
// Related Stock Moves Lines
List<StockMoveLine> originStockMovesLines = new ArrayList<>();
for (StockMove originStockMove : originStockMoves) {
// Stock Move Lines
List<StockMoveLine> originStockMovesLinesList = originStockMove.getStockMoveLineList();
originStockMovesLines.addAll(originStockMovesLinesList);
}
// Quantité
Integer quantityComplianceRatingSelect =
calculatQuantityComplianceRatingSelect(purchaseOrderLinesList, originStockMovesLines);
// update
SupplierRating supplierRating = purchaseOrder.getSupplierRating();
supplierRating.setQuantityComplianceRatingSelect(quantityComplianceRatingSelect);
}
}
private Integer calculatPaymentDelayRatingSelect(Integer paymentTime) {
Integer paymentDelayRatingSelect;
if (paymentTime == 0) {
paymentDelayRatingSelect = 0;
} else if (paymentTime <= 15) {
paymentDelayRatingSelect = 1;
} else if (paymentTime <= 30) {
paymentDelayRatingSelect = 2;
} else {
paymentDelayRatingSelect = 3;
}
return paymentDelayRatingSelect;
}
private Integer calculatDeliveryTimeRatingSelect(LocalDate estimatedDate, LocalDateTime realDate) {
int deliveryTimeRatingSelect;
if (realDate.toLocalDate().isBefore(estimatedDate.plusDays(1))) {
deliveryTimeRatingSelect = 3;
} else if (realDate.toLocalDate().isBefore(estimatedDate.plusDays(5))) {
deliveryTimeRatingSelect = 2;
} else if (realDate.toLocalDate().isBefore(estimatedDate.plusDays(15))) {
deliveryTimeRatingSelect = 1;
} else {
deliveryTimeRatingSelect = 0;
}
return deliveryTimeRatingSelect;
}
private Integer calculatQuantityComplianceRatingSelect(List<StockMoveLine> stockMoveLinesList) {
// Calculate total ordered quantity
BigDecimal totalOrderedQty = BigDecimal.ZERO;
BigDecimal totalReceivedQty = BigDecimal.ZERO;
for (StockMoveLine stockMoveLine : stockMoveLinesList) {
BigDecimal orderedQty = stockMoveLine.getQty();
totalOrderedQty = totalOrderedQty.add(orderedQty);
BigDecimal receivedQty = stockMoveLine.getRealQty();
totalReceivedQty = totalReceivedQty.add(receivedQty);
}
// Calculate quantity compliance
BigDecimal compliancePercentage;
if (totalOrderedQty.compareTo(BigDecimal.ZERO) != 0) {
compliancePercentage =
totalReceivedQty
.divide(totalOrderedQty, 2, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
} else {
// Handle division by zero if necessary
compliancePercentage = BigDecimal.ZERO;
}
System.out.println("totalOrderedQty1:" + totalOrderedQty);
System.out.println("totalReceivedQty1:" + totalReceivedQty);
System.out.println("compliancePercentage1:" + compliancePercentage);
// Determine quantityComplianceRatingSelect based on compliancePercentage
Integer quantityComplianceRatingSelect;
if (compliancePercentage.compareTo(BigDecimal.valueOf(100)) >= 0) {
quantityComplianceRatingSelect = 3;
} else if (compliancePercentage.compareTo(BigDecimal.valueOf(80)) >= 0) {
quantityComplianceRatingSelect = 2;
} else if (compliancePercentage.compareTo(BigDecimal.valueOf(70)) >= 0) {
quantityComplianceRatingSelect = 1;
} else {
quantityComplianceRatingSelect = 0;
}
return quantityComplianceRatingSelect;
}
private Integer calculatQuantityComplianceRatingSelect(
List<PurchaseOrderLine> purchaseOrderLineslist, List<StockMoveLine> stockMoveLinesList) {
// Calculate total ordered quantity
BigDecimal totalOrderedQty = BigDecimal.ZERO;
BigDecimal totalReceivedQty = BigDecimal.ZERO;
for (StockMoveLine stockMoveLine : stockMoveLinesList) {
BigDecimal receivedQty = stockMoveLine.getRealQty();
totalReceivedQty = totalReceivedQty.add(receivedQty);
}
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLineslist) {
BigDecimal orderedQty = purchaseOrderLine.getQty();
totalOrderedQty = totalOrderedQty.add(orderedQty);
}
// Calculate quantity compliance
BigDecimal compliancePercentage;
if (totalOrderedQty.compareTo(BigDecimal.ZERO) != 0) {
compliancePercentage =
totalReceivedQty
.divide(totalOrderedQty, 2, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
} else {
// Handle division by zero if necessary
compliancePercentage = BigDecimal.ZERO;
}
System.out.println("totalOrderedQty2:" + totalOrderedQty);
System.out.println("totalReceivedQty2:" + totalReceivedQty);
System.out.println("compliancePercentage2:" + compliancePercentage);
// Determine quantityComplianceRatingSelect based on compliancePercentage
Integer quantityComplianceRatingSelect;
if (compliancePercentage.compareTo(BigDecimal.valueOf(100)) >= 0) {
quantityComplianceRatingSelect = 3;
} else if (compliancePercentage.compareTo(BigDecimal.valueOf(80)) >= 0) {
quantityComplianceRatingSelect = 2;
} else if (compliancePercentage.compareTo(BigDecimal.valueOf(70)) >= 0) {
quantityComplianceRatingSelect = 1;
} else {
quantityComplianceRatingSelect = 0;
}
return quantityComplianceRatingSelect;
}
private Integer calculatPriceStabilityRatingSelect(
List<PurchaseOrderLine> purchaseOrderLinesList, Partner partner) {
List<Product> products = new ArrayList<>();
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLinesList) {
Product product = purchaseOrderLine.getProduct();
products.add(product);
}
List<BigDecimal> averages = new ArrayList<>();
for (Product product : products) {
BigDecimal avg = calculateAvgProduct(product, partner);
averages.add(avg);
}
List<BigDecimal> differences = new ArrayList<>();
for (int i = 0; i < purchaseOrderLinesList.size(); i++) {
BigDecimal price = purchaseOrderLinesList.get(i).getPrice();
BigDecimal avg = averages.get(i);
BigDecimal difference = price.subtract(avg);
BigDecimal percentage =
difference.divide(avg, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
differences.add(percentage.abs());
}
BigDecimal totalDifference = BigDecimal.ZERO;
for (BigDecimal difference : differences) {
totalDifference = totalDifference.add(difference);
}
// Calculate the average percentage difference
BigDecimal averageDifference =
totalDifference.divide(BigDecimal.valueOf(differences.size()), 2, BigDecimal.ROUND_HALF_UP);
// Determine priceStabilityRatingSelect based on the average percentage difference
Integer priceStabilityRatingSelect;
if (averageDifference.compareTo(BigDecimal.ZERO) <= 0) {
priceStabilityRatingSelect = 3; // Stable prices
} else if (averageDifference.compareTo(BigDecimal.valueOf(5)) <= 0) {
priceStabilityRatingSelect = 2; // Moderately stable prices
} else if (averageDifference.compareTo(BigDecimal.valueOf(10)) <= 0) {
priceStabilityRatingSelect = 1; // Unstable prices
} else {
priceStabilityRatingSelect = 0;
}
return priceStabilityRatingSelect;
}
private Integer calculatPriceStabilityRatingSelectLastPrice(
List<PurchaseOrderLine> purchaseOrderLinesList, Partner partner) {
List<Product> products = new ArrayList<>();
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLinesList) {
Product product = purchaseOrderLine.getProduct();
products.add(product);
}
List<BigDecimal> lastPrices = new ArrayList<>();
for (Product product : products) {
BigDecimal lastPrice = getLastPriceProduct(product, partner);
lastPrices.add(lastPrice);
}
List<BigDecimal> differences = new ArrayList<>();
for (int i = 0; i < purchaseOrderLinesList.size(); i++) {
BigDecimal price = purchaseOrderLinesList.get(i).getPrice();
BigDecimal lastPrice = lastPrices.get(i);
BigDecimal difference = price.subtract(lastPrice);
BigDecimal percentage =
difference
.divide(lastPrice, 4, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
differences.add(percentage);
}
BigDecimal totalDifference = BigDecimal.ZERO;
for (BigDecimal difference : differences) {
totalDifference = totalDifference.add(difference);
}
// Calculate the average percentage difference
BigDecimal averageDifference =
totalDifference.divide(BigDecimal.valueOf(differences.size()), 2, BigDecimal.ROUND_HALF_UP);
// Determine priceStabilityRatingSelect based on the average percentage difference
Integer priceStabilityRatingSelect;
if (averageDifference.compareTo(BigDecimal.ZERO) <= 0) {
priceStabilityRatingSelect = 3; // Stable prices
} else if (averageDifference.compareTo(BigDecimal.valueOf(5)) <= 0) {
priceStabilityRatingSelect = 2; // Moderately stable prices
} else if (averageDifference.compareTo(BigDecimal.valueOf(10)) <= 0) {
priceStabilityRatingSelect = 1; // Unstable prices
} else {
priceStabilityRatingSelect = 0;
}
return priceStabilityRatingSelect;
}
private BigDecimal calculateAvgProduct(Product product, Partner partner) {
// Beans.get(PurchaseOrderRepository.class).find(originId);
/*List<PurchaseOrderLine> purchaseOrderLines = Beans.get(PurchaseOrderLineRepository.class)
.all()
.filter("self.purchaseOrder.supplierPartner = :partner AND self.product = :product")
.bind("partner", partner)
.bind("product", product)
.fetch();*/
List<PurchaseOrderLine> purchaseOrderLines =
Beans.get(PurchaseOrderLineRepository.class)
.all()
.fetch()
.stream()
.filter(
t ->
t.getPurchaseOrder().getSupplierPartner() == partner
&& t.getProduct() == product)
.collect(Collectors.toList());
if (purchaseOrderLines != null && !purchaseOrderLines.isEmpty()) {
BigDecimal total = BigDecimal.ZERO;
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLines) {
BigDecimal price = purchaseOrderLine.getPrice();
total = total.add(price);
}
BigDecimal avgPrice =
total.divide(BigDecimal.valueOf(purchaseOrderLines.size()), 2, BigDecimal.ROUND_HALF_UP);
return avgPrice;
}
// Handle the case where there are no purchase order lines for the given product and partner
return BigDecimal.ZERO;
}
private BigDecimal getLastPriceProduct(Product product, Partner partner) {
List<PurchaseOrderLine> purchaseOrderLines = Beans.get(PurchaseOrderLineRepository.class)
.all()
.filter("self.purchaseOrder.supplierPartner = :partner AND self.product = :product")
.bind("partner", partner)
.bind("product", product)
.fetch();
PurchaseOrderLine lastPurchaseOrderLine =
purchaseOrderLines.isEmpty() ? null : purchaseOrderLines.get(purchaseOrderLines.size() - 1);
if (lastPurchaseOrderLine != null) {
BigDecimal price = lastPurchaseOrderLine.getPrice();
return price;
} else {
return BigDecimal.ZERO;
}
}
}

View File

@@ -0,0 +1,365 @@
package com.axelor.apps.supplychain.web;
import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.db.InvoiceTemplate;
import com.axelor.apps.account.db.PaymentVoucher;
import com.axelor.apps.account.db.repo.InvoiceTemplateRepository;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Wizard;
import com.axelor.apps.purchase.db.ImportationFolder;
import com.axelor.apps.purchase.db.repo.ImportationFolderRepository;
import com.axelor.apps.purchase.service.print.ImportationFolderPrintService;
import com.axelor.apps.report.engine.ReportSettings;
import com.axelor.apps.stock.db.ImportationFolderCostPrice;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.StockProductionRequest;
import com.axelor.apps.stock.db.repo.ImportationFolderCostPriceRepository;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.stock.exception.IExceptionMessage;
import com.axelor.apps.stock.service.StockMoveService;
import com.axelor.apps.stock.service.stockmove.print.StockProductionRequestPrintService;
import com.axelor.apps.supplychain.service.ImportationFolderServiceImpl;
import com.axelor.apps.supplychain.service.StockMoveLineServiceSupplychainImpl;
import com.axelor.apps.supplychain.service.app.AppSupplychainService;
import com.axelor.common.ObjectUtils;
import com.axelor.db.mapper.Mapper;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.schema.actions.ActionView;
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.axelor.rpc.Context;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import wslite.json.JSONException;
public class ImportationFolderController {
private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public void calculateAvgPrice(ActionRequest request, ActionResponse response)
throws MalformedURLException, JSONException, AxelorException {
ImportationFolder iimportationFolder =
(ImportationFolder) request.getContext().asType(ImportationFolder.class);
ImportationFolder importationFolder =
Beans.get(ImportationFolderRepository.class).find(iimportationFolder.getId());
List<StockMoveLine> stockMoveLines = importationFolder.getStockMoveLineList();
List<Long> invoiceIds =
Beans.get(ImportationFolderServiceImpl.class).calculateAvgPriceAndGenerateInvoice(stockMoveLines, importationFolder);
response.setView(
ActionView.define("Invoice")
.model(Invoice.class.getName())
.add("grid", "invoice-grid")
.add("form", "invoice-form")
.domain("self.id in (" + Joiner.on(",").join(invoiceIds) + ")")
.param("forceEdit", "true")
.context("todayDate", Beans.get(AppSupplychainService.class).getTodayDate())
.map());
}
public void computeCostPrice(ActionRequest request, ActionResponse response)
throws MalformedURLException, JSONException, AxelorException {
ImportationFolder iimportationFolder =
(ImportationFolder) request.getContext().asType(ImportationFolder.class);
ImportationFolder importationFolder =
Beans.get(ImportationFolderRepository.class).find(iimportationFolder.getId());
String msg = Beans.get(ImportationFolderServiceImpl.class).computeCostPrice(importationFolder);
response.setAlert(msg);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void setStockMoveLineCurrenyRate(ActionRequest request, ActionResponse response) {
try {
List<HashMap> selectedStockMoveLineMapList =
(List<HashMap>) request.getContext().get("stockMoveLineList");
Map importationFolderMap = (Map<String, Object>) request.getContext().get("importationFolder");
if (selectedStockMoveLineMapList == null) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_14));
return;
}
List<StockMoveLine> stockMoveLineList = new ArrayList<>();
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
for (HashMap map : selectedStockMoveLineMapList) {
StockMoveLine stockMoveLine = (StockMoveLine) Mapper.toBean(StockMoveLine.class, map);
stockMoveLineList.add(stockMoveLineRepo.find(stockMoveLine.getId()));
}
if (stockMoveLineList.isEmpty()) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_15));
return;
}
BigDecimal currencyRate = new BigDecimal(request.getContext().get("currencyRate").toString());
if (currencyRate == null || currencyRate.compareTo(BigDecimal.ZERO) < 0) {
response.setFlash("Please enter a valid currency rate");
return;
}
ImportationFolder importationFolder = Mapper.toBean(ImportationFolder.class, importationFolderMap);
importationFolder = Beans.get(ImportationFolderRepository.class).find(importationFolder.getId());
Beans.get(ImportationFolderServiceImpl.class)
.setStockMoveLineCurrenyRate(stockMoveLineList, currencyRate);
response.setCanClose(true);
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void setStockMoveLineFreight(ActionRequest request, ActionResponse response) {
try {
List<HashMap> selectedStockMoveLineMapList =
(List<HashMap>) request.getContext().get("stockMoveLineList");
Map importationFolderMap = (Map<String, Object>) request.getContext().get("importationFolder");
if (selectedStockMoveLineMapList == null) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_14));
return;
}
List<StockMoveLine> stockMoveLineList = new ArrayList<>();
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
for (HashMap map : selectedStockMoveLineMapList) {
StockMoveLine stockMoveLine = (StockMoveLine) Mapper.toBean(StockMoveLine.class, map);
stockMoveLineList.add(stockMoveLineRepo.find(stockMoveLine.getId()));
}
if (stockMoveLineList.isEmpty()) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_15));
return;
}
BigDecimal freight = new BigDecimal(request.getContext().get("freight").toString());
if (freight == null || freight.compareTo(BigDecimal.ZERO) < 0) {
response.setFlash("Please enter a valid freight");
return;
}
ImportationFolder importationFolder = Mapper.toBean(ImportationFolder.class, importationFolderMap);
importationFolder = Beans.get(ImportationFolderRepository.class).find(importationFolder.getId());
Beans.get(ImportationFolderServiceImpl.class).setStockMoveLineFreight(stockMoveLineList, freight);
response.setCanClose(true);
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void setStockMoveLineNetMass(ActionRequest request, ActionResponse response) {
try {
List<HashMap> selectedStockMoveLineMapList =
(List<HashMap>) request.getContext().get("stockMoveLineList");
Map importationFolderMap = (Map<String, Object>) request.getContext().get("importationFolder");
if (selectedStockMoveLineMapList == null) {
response.setFlash("No selected move line");
return;
}
List<StockMoveLine> stockMoveLineList = new ArrayList<>();
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
for (HashMap map : selectedStockMoveLineMapList) {
StockMoveLine stockMoveLine = (StockMoveLine) Mapper.toBean(StockMoveLine.class, map);
stockMoveLineList.add(stockMoveLineRepo.find(stockMoveLine.getId()));
}
if (stockMoveLineList.isEmpty()) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_15));
return;
}
BigDecimal netMass = new BigDecimal(request.getContext().get("netMass").toString());
if (netMass == null || netMass.compareTo(BigDecimal.ZERO) < 0) {
response.setFlash("Please enter a valid mass");
return;
}
ImportationFolder importationFolder = Mapper.toBean(ImportationFolder.class, importationFolderMap);
importationFolder = Beans.get(ImportationFolderRepository.class).find(importationFolder.getId());
Beans.get(ImportationFolderServiceImpl.class)
.setStockMoveLineNetMass(stockMoveLineList, netMass);
response.setCanClose(true);
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void setStockMoveLineVolume(ActionRequest request, ActionResponse response) {
try {
List<HashMap> selectedStockMoveLineMapList =
(List<HashMap>) request.getContext().get("stockMoveLineList");
Map importationFolderMap = (Map<String, Object>) request.getContext().get("importationFolder");
if (selectedStockMoveLineMapList == null) {
response.setFlash("No selected move line");
return;
}
List<StockMoveLine> stockMoveLineList = new ArrayList<>();
StockMoveLineRepository stockMoveLineRepo = Beans.get(StockMoveLineRepository.class);
for (HashMap map : selectedStockMoveLineMapList) {
StockMoveLine stockMoveLine = (StockMoveLine) Mapper.toBean(StockMoveLine.class, map);
stockMoveLineList.add(stockMoveLineRepo.find(stockMoveLine.getId()));
}
if (stockMoveLineList.isEmpty()) {
response.setFlash(I18n.get(IExceptionMessage.STOCK_MOVE_15));
return;
}
BigDecimal volume = new BigDecimal(request.getContext().get("volume").toString());
if (volume == null || volume.compareTo(BigDecimal.ZERO) < 0) {
response.setFlash("Please enter a valid mass");
return;
}
ImportationFolder importationFolder = Mapper.toBean(ImportationFolder.class, importationFolderMap);
importationFolder = Beans.get(ImportationFolderRepository.class).find(importationFolder.getId());
Beans.get(ImportationFolderServiceImpl.class)
.setStockMoveLineVolume(stockMoveLineList, volume);
response.setCanClose(true);
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
public void validateCostPrice(ActionRequest request, ActionResponse response) {
ImportationFolderCostPrice importationFolderCostPrice =
Beans.get(ImportationFolderCostPriceRepository.class)
.find(request.getContext().asType(ImportationFolderCostPrice.class).getId());
// sophal refresh purchase order price
try {
Beans.get(ImportationFolderServiceImpl.class).validateCostPrice(importationFolderCostPrice);
response.setReload(true);
} catch (Exception e) {
System.out.println(e.toString());
}
}
public void confirmRejectView(ActionRequest request, ActionResponse response) {
ImportationFolder ImportationFolderContext = request.getContext().asType(ImportationFolder.class);
ImportationFolder importationFolder =
Beans.get(ImportationFolderRepository.class).find(ImportationFolderContext.getId());
ActionViewBuilder confirmView =
ActionView.define("Confirm rejection")
.model(Wizard.class.getName())
.add("form", "action-importation-folder-rejection-form")
.param("popup", "true")
.param("show-toolbar", "false")
.param("show-confirm", "false")
.param("popup-save", "false")
.param("forceEdit", "true");
confirmView.context("importationFolderId", importationFolder.getId());
response.setView(confirmView.map());
}
public void rejectImportationFolder(ActionRequest request, ActionResponse response)
throws AxelorException {
int importationFolderId = (int) request.getContext().get("importationFolderId");
String rejectionRaison = (String) request.getContext().get("rejectionRaison");
String rejectionInstance = (String) request.getContext().get("$rejectedInstanceSelect");
ImportationFolder importationFolder =
Beans.get(ImportationFolderRepository.class).find((long) importationFolderId);
Beans.get(ImportationFolderServiceImpl.class).rejectImportationFolder(importationFolder, rejectionRaison);
response.setCanClose(true);
}
public void print(ActionRequest request, ActionResponse response) {
Context context = request.getContext();
String fileLink;
String title;
ImportationFolderPrintService importationFolderPrintService = Beans.get(ImportationFolderPrintService.class);
try {
if (context.get("id") != null) {
ImportationFolder importationFolder = request.getContext().asType(ImportationFolder.class);
title = importationFolderPrintService.getFileName(importationFolder);
fileLink =
importationFolderPrintService.printCostPriceSheet(
importationFolder, ReportSettings.FORMAT_PDF);
logger.debug("Printing " + title);
} else {
throw new AxelorException(
TraceBackRepository.CATEGORY_MISSING_FIELD,
I18n.get(IExceptionMessage.INVENTORY_3_DATA_NULL_OR_EMPTY));
}
response.setView(ActionView.define(title).add("html", fileLink).map());
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
public void generateFromModel(ActionRequest request, ActionResponse response) throws AxelorException{
Long importationFolderId = (Long) request.getContext().get("id");
ImportationFolder importationFolder =
Beans.get(ImportationFolderRepository.class).find((long) importationFolderId);
InvoiceTemplate template = (InvoiceTemplate) request.getContext().get("$invoiceTemplate");
InvoiceTemplate invoiceTemplate = Beans.get(InvoiceTemplateRepository.class).find(template.getId());
Invoice invoice = Beans.get(ImportationFolderServiceImpl.class).generateFromModel(importationFolder, invoiceTemplate);
response.setView(
ActionView.define("Invoice")
.model(Invoice.class.getName())
.add("grid", "invoice-grid")
.add("form", "invoice-form")
.param("forceEdit", "true")
.context("_showRecord", String.valueOf(invoice.getId()))
.context("_operationTypeSelect", invoice.getOperationTypeSelect())
.context("todayDate", Beans.get(AppSupplychainService.class).getTodayDate())
.map());
}
}

View File

@@ -0,0 +1,5 @@
package com.axelor.apps.supplychain.web;
public class ImportationFolderCostPriceController {
}

View File

@@ -17,23 +17,11 @@
*/
package com.axelor.apps.supplychain.web;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.axelor.apps.ReportFactory;
import com.axelor.apps.base.db.Function;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.report.engine.ReportSettings;
import com.axelor.apps.supplychain.db.Mrp;
import com.axelor.apps.supplychain.db.repo.MrpForecastRepository;
import com.axelor.apps.supplychain.db.repo.MrpLineRepository;
import com.axelor.apps.supplychain.db.repo.MrpRepository;
import com.axelor.apps.supplychain.report.IReport;
import com.axelor.apps.supplychain.service.MrpLineServiceImpl;
import com.axelor.apps.supplychain.service.MrpService;
import com.axelor.apps.supplychain.service.MrpServiceImpl;
import com.axelor.exception.AxelorException;
@@ -44,9 +32,6 @@ import com.axelor.meta.schema.actions.ActionView;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.google.inject.Singleton;
import com.google.inject.persist.Transactional;
import com.axelor.apps.supplychain.db.MrpForecast;
import com.axelor.apps.supplychain.db.MrpLineSophal;
@Singleton
public class MrpController {
@@ -143,10 +128,10 @@ public class MrpController {
* @param response
* @throws AxelorException
*/
public void calculationCbn(ActionRequest request, ActionResponse response) throws AxelorException {
Mrp mrp = Beans.get(MrpRepository.class).find(request.getContext().asType(Mrp.class).getId());
Beans.get(MrpServiceImpl.class).createAvailableMrpLineSophal(mrp);
response.setReload(true);
public void calculationCbn(ActionRequest request, ActionResponse response)
throws AxelorException {
Mrp mrp = Beans.get(MrpRepository.class).find(request.getContext().asType(Mrp.class).getId());
Beans.get(MrpServiceImpl.class).createAvailableMrpLineSophal(mrp);
response.setReload(true);
}
}

View File

@@ -19,6 +19,7 @@ package com.axelor.apps.supplychain.web;
import com.axelor.apps.account.service.app.AppAccountService;
import com.axelor.apps.base.db.AppBudget;
import com.axelor.apps.base.db.CancelReason;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Currency;
import com.axelor.apps.base.db.Partner;
@@ -176,6 +177,9 @@ public class PurchaseOrderController {
// purchase orders
boolean existLocationDiff = false;
boolean allTradingNamesAreNull = true;
// determine diff in status select
boolean eqStatusSelect = true;
int statusSelect = -1;
PurchaseOrder purchaseOrderTemp;
int count = 1;
@@ -191,7 +195,11 @@ public class PurchaseOrderController {
commonLocation = purchaseOrderTemp.getStockLocation();
commonTradingName = purchaseOrderTemp.getTradingName();
allTradingNamesAreNull = commonTradingName == null;
statusSelect = purchaseOrderTemp.getStatusSelect();
} else {
if (purchaseOrderTemp.getStatusSelect() != statusSelect) {
eqStatusSelect = false;
}
if (commonCurrency != null && !commonCurrency.equals(purchaseOrderTemp.getCurrency())) {
commonCurrency = null;
}
@@ -255,6 +263,12 @@ public class PurchaseOrderController {
com.axelor.apps.purchase.exception.IExceptionMessage
.PURCHASE_ORDER_MERGE_ERROR_TRADING_NAME));
}
if (!eqStatusSelect) {
fieldErrors.append(
I18n.get(
com.axelor.apps.purchase.exception.IExceptionMessage
.PURCHASE_ORDER_MERGE_ERROR_STATUS_SELECT));
}
if (fieldErrors.length() > 0) {
response.setFlash(fieldErrors.toString());
@@ -414,4 +428,20 @@ public class PurchaseOrderController {
TraceBackService.trace(response, e, ResponseMessageType.ERROR);
}
}
public void finishPurchaseOrder(ActionRequest request, ActionResponse response) {
try {
PurchaseOrder purchaseOrder = request.getContext().asType(PurchaseOrder.class);
purchaseOrder = Beans.get(PurchaseOrderRepository.class).find(purchaseOrder.getId());
CancelReason cancelReason = (CancelReason) request.getContext().get("cancelReason");
String cancelReasonStr = (String) request.getContext().get("cancelReasonStr");
System.out.println(">>>>>>>>>>>>>>>>>>> " + cancelReasonStr);
Beans.get(PurchaseOrderServiceSupplychainImpl.class)
.finishSockMoves(purchaseOrder, cancelReason, cancelReasonStr);
response.setReload(true);
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
}

View File

@@ -21,13 +21,10 @@ import com.axelor.apps.base.db.Company;
import com.axelor.apps.sale.db.SaleOrder;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.stock.service.StockMoveService;
import com.axelor.apps.supplychain.db.SupplyChainConfig;
import com.axelor.apps.supplychain.exception.IExceptionMessage;
import com.axelor.apps.supplychain.service.SaleOrderReservedQtyService;
import com.axelor.apps.supplychain.service.SaleOrderServiceSupplychainImpl;
import com.axelor.apps.supplychain.service.SaleOrderStockService;
import com.axelor.apps.supplychain.service.StockMoveServiceSupplychain;
import com.axelor.apps.supplychain.service.StockMoveServiceSupplychainImpl;
@@ -38,8 +35,6 @@ import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

View File

@@ -17,15 +17,22 @@
*/
package com.axelor.apps.supplychain.web;
import com.axelor.apps.base.db.repo.FamilleProduitRepository;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.supplychain.service.StockMoveLineServiceSupplychainImpl;
import com.axelor.exception.service.TraceBackService;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.axelor.rpc.Context;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import org.apache.xpath.operations.Bool;
public class StockMoveLineController {
@@ -175,4 +182,60 @@ public class StockMoveLineController {
}
response.setValue("subLineList", subLines);
}
@SuppressWarnings({"rawtypes", "unchecked"})
public void valorize(ActionRequest request, ActionResponse response) {
try {
Long productId = new Long((Integer) ((Map) request.getContext().get("product")).get("id"));
Long stockMoveId =
new Long((Integer) ((Map) request.getContext().get("stockMove")).get("id"));
LocalDate fromDateTime = LocalDate.parse(request.getContext().get("fromDateTime").toString());
BigDecimal val = new BigDecimal(request.getContext().get("val").toString());
Boolean updatePo = false;
if(request.getContext().get("updatePo") != null){
updatePo = (Boolean) request.getContext().get("updatePo");
}
Beans.get(StockMoveLineServiceSupplychainImpl.class).resetValorization(productId, stockMoveId, fromDateTime,false);
Beans.get(StockMoveLineServiceSupplychainImpl.class).fillStockMoveLines(productId, fromDateTime, stockMoveId,false);
Beans.get(StockMoveLineServiceSupplychainImpl.class).valorize(productId, stockMoveId, fromDateTime, val,updatePo,false);
response.setNotify("Recalcul Terminé");
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
public void valorizeAll(ActionRequest request, ActionResponse response) {
try {
LocalDate fromDateTime = LocalDate.parse(request.getContext().get("fromDateTime").toString());
Long productCategoryId = new Long((Integer) ((Map) request.getContext().get("productCategory")).get("id"));
Beans.get(StockMoveLineServiceSupplychainImpl.class).valorizeAll(fromDateTime,productCategoryId);
response.setNotify("Recalcul Terminé");
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
public void showLines(ActionRequest request, ActionResponse response) {
try {
Long productId = new Long((Integer) ((Map) request.getContext().get("product")).get("id"));
Long stockMoveId =
new Long((Integer) ((Map) request.getContext().get("stockMove")).get("id"));
LocalDate fromDateTime = LocalDate.parse(request.getContext().get("fromDateTime").toString());
BigDecimal val = new BigDecimal(request.getContext().get("val").toString());
Beans.get(StockMoveLineServiceSupplychainImpl.class)
.resetValorization(productId, stockMoveId, fromDateTime,false);
Beans.get(StockMoveLineServiceSupplychainImpl.class)
.showLines(productId, stockMoveId, fromDateTime, val);
response.setNotify("Recalcul Terminé");
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
}

View File

@@ -0,0 +1,59 @@
package com.axelor.apps.supplychain.web;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.supplychain.db.SupplierRating;
import com.axelor.apps.supplychain.service.SupplierRatingServiceImpl;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import javax.inject.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SupplierRatingController {
private static final Logger LOG = LoggerFactory.getLogger(SupplierRatingController.class);
private SupplierRatingServiceImpl service;
@Inject
public SupplierRatingController(SupplierRatingServiceImpl service) {
this.service = service;
}
public void rating(ActionRequest request, ActionResponse response) {
SupplierRating supplierRating = request.getContext().asType(SupplierRating.class);
Integer paymentDelayRatingSelect = supplierRating.getPaymentDelayRatingSelect();
Integer deliveryTimeRatingSelect = supplierRating.getDeliveryTimeRatingSelect();
Integer complianceWithTechnicalSpecificationsRatingSelect =
supplierRating.getComplianceWithTechnicalSpecificationsRatingSelect();
Integer priceRatingSelect = supplierRating.getPriceRatingSelect();
Integer quantityComplianceRatingSelect = supplierRating.getQuantityComplianceRatingSelect();
Integer complaintManagementRatingSelect = supplierRating.getComplaintManagementRatingSelect();
Integer priceStabilityRatingSelect = supplierRating.getPriceStabilityRatingSelect();
if (paymentDelayRatingSelect != null
&& deliveryTimeRatingSelect != null
&& complianceWithTechnicalSpecificationsRatingSelect != null
&& priceRatingSelect != null
&& quantityComplianceRatingSelect != null
&& complaintManagementRatingSelect != null
&& priceStabilityRatingSelect != null) {
service.calculatRating(supplierRating);
response.setValue("overallScore", supplierRating.getOverallScore());
} else {
String message = "You should fill all Fields First.";
response.setFlash(message);
}
}
public void rateSupplier(ActionRequest request, ActionResponse response) {
System.out.println("Start");
StockMove stockMovetemp = request.getContext().asType(StockMove.class);
StockMove stockMove = Beans.get(StockMoveRepository.class).find(stockMovetemp.getId());
service.createRating(stockMove);
}
}

View File

@@ -17,14 +17,27 @@
*/
package com.axelor.apps.supplychain.web;
import com.axelor.apps.account.db.Move;
import com.axelor.apps.account.exception.IExceptionMessage;
import com.axelor.apps.base.db.Batch;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
import com.axelor.apps.supplychain.db.SupplychainBatch;
import com.axelor.apps.supplychain.db.repo.SupplychainBatchRepository;
import com.axelor.apps.supplychain.service.AccountingCutOffServiceImpl;
import com.axelor.apps.supplychain.service.batch.SupplychainBatchService;
import com.axelor.common.ObjectUtils;
import com.axelor.exception.AxelorException;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.schema.actions.ActionView;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.google.common.base.Joiner;
import com.google.inject.Singleton;
import java.util.List;
import java.util.stream.Collectors;
@Singleton
public class SupplychainBatchController {
@@ -53,4 +66,75 @@ public class SupplychainBatchController {
response.setFlash(batch.getComments());
response.setReload(true);
}
public void generateMove(ActionRequest request, ActionResponse response) throws AxelorException {
StockMove stockMove = request.getContext().asType(StockMove.class);
stockMove = Beans.get(StockMoveRepository.class).find(stockMove.getId());
Move move = Beans.get(AccountingCutOffServiceImpl.class).generateStockAccountMove(stockMove);
response.setView(
ActionView.define(stockMove.getStockMoveSeq())
.model(Move.class.getName())
.add("form", "move-form")
.add("grid", "move-grid")
.param("forceTitle", "true")
.context("_showRecord", move.getId().toString())
.domain("self.id = " + move.getId())
.map());
}
public void massGenerationMove(ActionRequest request, ActionResponse response) {
try {
@SuppressWarnings("unchecked")
List<Long> ids =
(List)
(((List) request.getContext().get("_ids"))
.stream()
.filter(ObjectUtils::notEmpty)
.map(input -> Long.parseLong(input.toString()))
.collect(Collectors.toList()));
List<Long> moveList = Beans.get(AccountingCutOffServiceImpl.class).massGenerationMove(ids);
if (moveList != null && !moveList.isEmpty()) {
response.setView(
ActionView.define(I18n.get(IExceptionMessage.MOVE_TEMPLATE_3))
.model(Move.class.getName())
.add("grid", "move-grid")
.add("form", "move-form")
.domain("self.id in (" + Joiner.on(",").join(moveList) + ")")
.map());
}
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
public void generateInventoryLineMove(ActionRequest request, ActionResponse response) {
try {
@SuppressWarnings("unchecked")
List<Long> ids =
(List)
(((List) request.getContext().get("_ids"))
.stream()
.filter(ObjectUtils::notEmpty)
.map(input -> Long.parseLong(input.toString()))
.collect(Collectors.toList()));
List<Long> moveList = Beans.get(AccountingCutOffServiceImpl.class).massGenerationInventoryLineMove(ids);
if (moveList != null && !moveList.isEmpty()) {
response.setView(
ActionView.define(I18n.get(IExceptionMessage.MOVE_TEMPLATE_3))
.model(Move.class.getName())
.add("grid", "move-grid")
.add("form", "move-form")
.domain("self.id in (" + Joiner.on(",").join(moveList) + ")")
.map());
}
} catch (Exception e) {
TraceBackService.trace(response, e);
}
}
}

View File

@@ -46,6 +46,7 @@ import com.axelor.inject.Beans;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@@ -113,7 +114,7 @@ public class ImportSupplyChain {
StockMove stockMove = Beans.get(StockMoveRepository.class).find(id);
stockMoveService.copyQtyToRealQty(stockMove);
stockMoveService.realize(stockMove);
stockMove.setRealDate(purchaseOrder.getDeliveryDate());
stockMove.setRealDate(LocalDateTime.now());
}
purchaseOrder.setValidationDate(purchaseOrder.getOrderDate());
purchaseOrder.setValidatedByUser(AuthUtils.getUser());
@@ -137,7 +138,7 @@ public class ImportSupplyChain {
invoice.setOriginDate(date.minusDays(15));
invoiceService.validateAndVentilate(invoice);
purchaseOrderServiceSupplychainImpl.finishPurchaseOrder(purchaseOrder);
purchaseOrderServiceSupplychainImpl.finishPurchaseOrder(purchaseOrder, "");
}
} catch (Exception e) {
@@ -187,7 +188,7 @@ public class ImportSupplyChain {
stockMoveService.copyQtyToRealQty(stockMove);
stockMoveService.validate(stockMove);
if (saleOrder.getConfirmationDateTime() != null) {
stockMove.setRealDate(saleOrder.getConfirmationDateTime().toLocalDate());
stockMove.setRealDate(LocalDateTime.now());
}
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="testUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/bdd_sophal" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="Ijlv=bB^hSG@PV$,9jkhHzO*74" />
<!--
value="create" to build a new database on each run;
value="update" to modify an existing database;
value="create-drop" means the same as "create" but also drops tables when Hibernate closes;
value="validate" makes no changes to the database
-->
<property name="hibernate.hbm2ddl.auto" value="update" />
<!--
<property name="hibernate.show_sql" value="true"/>
-->
</properties>
</persistence-unit>
</persistence>

View File

@@ -8,6 +8,7 @@
<entity sequential="true" name="Move" lang="java">
<many-to-one name="stockMove" ref="com.axelor.apps.stock.db.StockMove" title="Stock move"/>
<many-to-one name="inventoryLine" ref="com.axelor.apps.stock.db.InventoryLine" title="Stock inventory line"/>
</entity>
</domain-models>

View File

@@ -19,6 +19,10 @@
<integer name="scenario" title="Scenario" selection="mrp.scenario.select"/>
<boolean name="displayProductWithoutProposal" title="Display product without proposal" default="false"/>
<boolean name="includeBOM" title="Include Bom" default="false"/>
<boolean name="includePurchaseQty" title="Include Purchase qty" default="false"/>
<boolean name="includeFutureQty" title="Include Future qty" default="false"/>
<boolean name="includeBomWaste" title="Include Bom waste" default="false"/>
<boolean name="includeStockRule" title="Include stock rule" default="false"/>
<extra-code><![CDATA[

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
<module name="supplychain" package="com.axelor.apps.supplychain.db"/>
<entity name="MrpLineSaleAndMargin" lang="java">
<many-to-one name="mrp" ref="com.axelor.apps.supplychain.db.Mrp" title="Mrp"/>
<many-to-one name="product" ref="com.axelor.apps.base.db.Product" title="Product"/>
<decimal name="firstQuarterMax" title="First Quarter" />
<decimal name="secondQuarterMax" title="Second Quarter" />
<decimal name="thirdQuarterMax" title="Third Quarter" />
<decimal name="forthQuarterMax" title="Forth Quarter" />
<decimal name="firstQuarterMarge" title="First Quarter" />
<decimal name="secondQuarterMarge" title="Second Quarter" />
<decimal name="thirdQuarterMarge" title="Third Quarter" />
<decimal name="forthQuarterMarge" title="Forth Quarter" />
<many-to-one name="company" ref="com.axelor.apps.base.db.Company" title="Company" transient="true"/>
<many-to-one name="unit" ref="com.axelor.apps.base.db.Unit" title="Unit" transient="true"/>
<many-to-one name="productOrigin" ref="com.axelor.apps.base.db.Product" title="Product Origin"/>
<extra-code><![CDATA[
// AVAILABLE SCENARIOS
public static final int MIN = 1;
public static final int MAX = 2;
public static final int HIST = 3;
]]></extra-code>
</entity>
</domain-models>

View File

@@ -7,6 +7,9 @@
<many-to-one name="mrp" ref="com.axelor.apps.supplychain.db.Mrp" title="Mrp"/>
<many-to-one name="product" ref="com.axelor.apps.base.db.Product" title="Product"/>
<decimal name="qty" title="Qty"/>
<decimal name="initialQty" title="Initial Qty"/>
<decimal name="purchaseOrderQty" title="Purchase Order Qty"/>
<decimal name="futureQty" title="Future Qty"/>
<decimal name="january" title="January" />
<decimal name="february" title="February" />
<decimal name="march" title="March" />
@@ -23,6 +26,7 @@
<many-to-one name="company" ref="com.axelor.apps.base.db.Company" title="Company" transient="true"/>
<many-to-one name="unit" ref="com.axelor.apps.base.db.Unit" title="Unit" transient="true"/>
<decimal name="securityStock" title="Security Stock" />
<decimal name="totalQtyUsed" title="Total qty used" />
<many-to-one name="productOrigin" ref="com.axelor.apps.base.db.Product" title="Product Origin"/>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
<module name="base" package="com.axelor.apps.base.db"/>
<entity name="Partner" lang="java">
<one-to-many name="supplierRatingList" title="Supplier Rating List" ref="com.axelor.apps.supplychain.db.SupplierRating" mappedBy="supplierPartner"/>
</entity>
</domain-models>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
<module name="supplychain" package="com.axelor.apps.supplychain.db"/>
<entity name="ProductionMasterPlan" lang="java">
<many-to-one name="mrp" ref="com.axelor.apps.supplychain.db.Mrp" title="Mrp"/>
<many-to-one name="product" ref="com.axelor.apps.base.db.Product" title="Product"/>
<decimal name="annualQty" title="Annual Qty"/>
<decimal name="annualBatchQty" title="Annual batch Qty"/>
<decimal name="january" title="January" />
<decimal name="february" title="February" />
<decimal name="march" title="March" />
<decimal name="april" title="April" />
<decimal name="may" title="May" />
<decimal name="juin" title="Juin" />
<decimal name="july" title="July" />
<decimal name="august" title="August" />
<decimal name="september" title="September" />
<decimal name="october" title="October" />
<decimal name="november" title="November" />
<decimal name="december" title="December" />
<decimal name="januaryBatchQty" title="January batch qty" />
<decimal name="februaryBatchQty" title="February batch qty" />
<decimal name="marchBatchQty" title="March batch qty" />
<decimal name="aprilBatchQty" title="April batch qty" />
<decimal name="mayBatchQty" title="May batch qty" />
<decimal name="juinBatchQty" title="Juin batch qty" />
<decimal name="julyBatchQty" title="July batch qty" />
<decimal name="augustBatchQty" title="August batch qty" />
<decimal name="septemberBatchQty" title="September batch qty" />
<decimal name="octoberBatchQty" title="October batch qty" />
<decimal name="novemberBatchQty" title="November batch qty" />
<decimal name="decemberBatchQty" title="December batch qty" />
</entity>
</domain-models>

View File

@@ -20,6 +20,9 @@
<boolean name="interco" title="Interco"/>
<boolean name="createdByInterco" default="false"/>
<!-- Supplier Rating -->
<one-to-one name="supplierRating" title="Supplier Rating List" ref="com.axelor.apps.supplychain.db.SupplierRating" mappedBy="purchaseOrder"/>
<many-to-one name="budget" ref="com.axelor.apps.account.db.Budget" title="Budget"/>
<long name="generatedSaleOrderId"/>
</entity>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
<module name="supplychain" package="com.axelor.apps.supplychain.db"/>
<entity name="SalesMasterPlan" lang="java">
<many-to-one name="mrp" ref="com.axelor.apps.supplychain.db.Mrp" title="Mrp"/>
<many-to-one name="product" ref="com.axelor.apps.base.db.Product" title="Product"/>
<decimal name="annualQty" title="Annual Qty"/>
<decimal name="january" title="January" />
<decimal name="february" title="February" />
<decimal name="march" title="March" />
<decimal name="april" title="April" />
<decimal name="may" title="May" />
<decimal name="juin" title="Juin" />
<decimal name="july" title="July" />
<decimal name="august" title="August" />
<decimal name="september" title="September" />
<decimal name="october" title="October" />
<decimal name="november" title="November" />
<decimal name="december" title="December" />
</entity>
</domain-models>

View File

@@ -21,6 +21,8 @@
<one-to-many name="subLineList" ref="com.axelor.apps.stock.db.StockMoveLine"
mappedBy="parentLine" title="Pack lines" />
<many-to-one name="account" ref="com.axelor.apps.account.db.Account" title="Accounting.Account"/>
<finder-method name="findAllBySaleOrder"
using="com.axelor.apps.sale.db.SaleOrder:saleOrder" all="true"
filter="self.stockMove.originTypeSelect LIKE 'com.axelor.apps.sale.db.SaleOrder' AND self.stockMove.originId = :saleOrder.id" />

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
<module name="supplychain" package="com.axelor.apps.supplychain.db"/>
<entity name="SupplierRating" lang="java">
<many-to-one name="supplierPartner" ref="com.axelor.apps.base.db.Partner" required="true" title="Supplier"/>
<one-to-one name="purchaseOrder" ref="com.axelor.apps.purchase.db.PurchaseOrder" required="true" title="Order"/>
<integer name="paymentDelayRatingSelect" title="Delay payment rating" selection="supplier.rating.icon.select"/>
<integer name="deliveryTimeRatingSelect" title="Delivery time rating" selection="supplier.rating.icon.select"/>
<integer name="complianceWithTechnicalSpecificationsRatingSelect" title="Compliance with technical specifications rating" selection="supplier.rating.icon.select"/>
<integer name="priceRatingSelect" title="Price rating" selection="supplier.rating.icon.select"/>
<integer name="quantityComplianceRatingSelect" title="Quantity compliance rating" selection="supplier.rating.icon.select"/>
<integer name="complaintManagementRatingSelect" title="Complaint management rating" selection="supplier.rating.icon.select"/>
<integer name="priceStabilityRatingSelect" title="Price stability rating" selection="supplier.rating.icon.select"/>
<string name="description" title="Description" large="true"/>
<decimal name="overallScore" title="Overall score"/>
<track>
<field name="paymentDelayRatingSelect" />
<field name="deliveryTimeRatingSelect" />
<field name="complianceWithTechnicalSpecificationsRatingSelect" />
<field name="priceRatingSelect" />
<field name="quantityComplianceRatingSelect" />
<field name="complaintManagementRatingSelect" />
<field name="priceStabilityRatingSelect" />
<field name="description" />
<field name="overallScore" />
</track>
</entity>
</domain-models>

View File

@@ -0,0 +1,75 @@
package com.axelor.apps.supplychain;
import static org.junit.Assert.assertNotNull;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.app.AxelorModule;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.base.module.AdminModule;
import com.axelor.apps.base.module.BaseModule;
import com.axelor.apps.base.service.ProductService;
import com.axelor.apps.base.service.ProductServiceImpl;
import com.axelor.apps.base.service.user.UserService;
import com.axelor.apps.message.module.MessageModule;
import com.axelor.apps.stock.module.StockModule;
import com.axelor.apps.stock.service.StockMoveService;
import com.axelor.apps.supplychain.TestStockMove.MyModule;
import com.axelor.apps.tool.module.ToolModule;
import com.axelor.db.JPA;
import com.axelor.db.JpaModule;
import com.axelor.exception.AxelorException;
import com.axelor.inject.Beans;
import com.axelor.rpc.ObjectMapperProvider;
import com.axelor.test.GuiceModules;
import com.axelor.test.GuiceRunner;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.repo.StockMoveRepository;
@RunWith(GuiceRunner.class)
@GuiceModules({MyModule.class})
public class TestStockMove {
protected final Logger log = LoggerFactory.getLogger(getClass());
static ProductRepository productRepository ;
@Inject
public StockMoveRepository stockMoveRepository;
public static class MyModule extends AxelorModule {
@Override
protected void configure() {
bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class);
install(new JpaModule("testUnit", true, true));
bind(Beans.class).asEagerSingleton();
install(new ToolModule());
install(new MessageModule());
install(new AdminModule());
install(new BaseModule());
}
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void testFunc() throws AxelorException {
assertNotNull(productRepository.all().fetch().get(0));
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.supplychain.db;
import com.axelor.db.JPA;
import com.axelor.db.JpaModel;
import com.axelor.db.Query;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "STOCK_MOVE")
public class StockMove extends JpaModel {
public StockMove() {}
}

View File

@@ -2,17 +2,25 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="testUnit" transaction-type="RESOURCE_LOCAL">
<persistence-unit name="baseProduct" transaction-type="RESOURCE_LOCAL">
<description>
Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<!-- Provided in latest release of hibernate
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
-->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/axelor-test" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/bdd_sophal" />
<property name="javax.persistence.jdbc.user" value="axelor" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="Ijlv=bB^hSG@PV$,9jkhHzO*74" />
<!--
value="create" to build a new database on each run;