feat: Enhance Supply Chain Module with Analytic Move Line Features
- Added support for analytic move lines in InvoiceServiceSupplychainImpl. - Implemented methods to check for missing analytic move lines in PurchaseOrderController and PurchaseRequestController. - Introduced budget distribution line generation in PurchaseOrderController. - Updated SaleOrderController to generate analytic move lines. - Enhanced StockMoveController with budget distribution line generation. - Modified StockMoveLineController to include analytic account and axis handling. - Updated domain models to include references to analytic accounts and axes in Partner, StockLocation, and StockMoveLine. - Created unit tests for StockMoveLineServiceSupplychainImpl to ensure proper functionality of new features. - Added MockQuery class for testing purposes.
This commit is contained in:
@@ -1,26 +1,36 @@
|
||||
package com.axelor.apps.suppliermanagement.db.repo;
|
||||
|
||||
import com.axelor.apps.account.db.BudgetDistribution;
|
||||
import com.axelor.apps.suppliermanagement.db.PurchaseOrderSupplierLine;
|
||||
import com.axelor.apps.supplychain.service.BudgetSupplychainService;
|
||||
import com.axelor.inject.Beans;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.axelor.apps.account.db.BudgetDistribution;
|
||||
import com.axelor.apps.suppliermanagement.db.PurchaseOrderSupplierLine;
|
||||
public class PurchaseOrderSupplierLineManagementRepository
|
||||
extends PurchaseOrderSupplierLineRepository {
|
||||
|
||||
public class PurchaseOrderSupplierLineManagementRepository extends PurchaseOrderSupplierLineRepository {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> populate(Map<String, Object> json, Map<String, Object> context) {
|
||||
Long supplierLine = (Long) json.get("id");
|
||||
PurchaseOrderSupplierLine line = find(supplierLine);
|
||||
List<BudgetDistribution> budgetDistributiList = line.getPurchaseOrderLine().getBudgetDistributionList();
|
||||
BigDecimal totalBudgetAmountAvailable = BigDecimal.ZERO;
|
||||
for (BudgetDistribution budgetDistribution : budgetDistributiList) {
|
||||
totalBudgetAmountAvailable = totalBudgetAmountAvailable.add(budgetDistribution.getBudgetAmountAvailable());
|
||||
}
|
||||
json.put("budgetRemainingAmount", totalBudgetAmountAvailable);
|
||||
|
||||
return super.populate(json, context);
|
||||
@Override
|
||||
public Map<String, Object> populate(Map<String, Object> json, Map<String, Object> context) {
|
||||
Long supplierLine = (Long) json.get("id");
|
||||
PurchaseOrderSupplierLine line = find(supplierLine);
|
||||
List<BudgetDistribution> budgetDistributiList =
|
||||
line.getPurchaseOrderLine().getBudgetDistributionList();
|
||||
BigDecimal totalBudgetAmountAvailable = BigDecimal.ZERO;
|
||||
BigDecimal budgetRemainingAmountAfterValidation = BigDecimal.ZERO;
|
||||
for (BudgetDistribution budgetDistribution : budgetDistributiList) {
|
||||
Beans.get(BudgetSupplychainService.class)
|
||||
.computeBudgetDistributionSumAmount(
|
||||
budgetDistribution, line.getPurchaseOrderLine().getPurchaseOrder().getOrderDate());
|
||||
totalBudgetAmountAvailable =
|
||||
totalBudgetAmountAvailable.add(budgetDistribution.getBudgetAmountAvailable());
|
||||
}
|
||||
budgetRemainingAmountAfterValidation =
|
||||
totalBudgetAmountAvailable.subtract(line.getInTaxTotal());
|
||||
json.put("budgetRemainingAmount", totalBudgetAmountAvailable);
|
||||
json.put("budgetRemainingAmountAfterValidation", budgetRemainingAmountAfterValidation);
|
||||
|
||||
return super.populate(json, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,16 +99,18 @@ public class PurchaseOrderSupplierLineService {
|
||||
purchaseOrderSupplierLine.setAcceptanceDate(appPurchaseService.getTodayDate());
|
||||
purchaseOrderSupplierLine.setAcceptedByUser(AuthUtils.getUser());
|
||||
|
||||
if(!purchaseOrderLine.getBudgetDistributionList().isEmpty()){
|
||||
Beans.get(PurchaseOrderLineServiceSupplychainImpl.class)
|
||||
.computeBudgetDistributionSumAmount(purchaseOrderLine, purchaseOrderLine.getPurchaseOrder());
|
||||
}
|
||||
poSupplierLineRepo.save(purchaseOrderSupplierLine);
|
||||
|
||||
// Budget Module
|
||||
// if(!purchaseOrderLine.getBudgetDistributionList().isEmpty()){
|
||||
// Beans.get(PurchaseOrderLineServiceSupplychainImpl.class)
|
||||
// .computeBudgetDistributionSumAmount(purchaseOrderLine,purchaseOrderLine.getPurchaseOrder());
|
||||
// }
|
||||
|
||||
if(!purchaseOrderLine.getAnalyticMoveLineList().isEmpty()){
|
||||
Beans.get(PurchaseOrderLineServiceSupplychainImpl.class).computeAnalyticDistribution(purchaseOrderLine);
|
||||
}
|
||||
|
||||
poSupplierLineRepo.save(purchaseOrderSupplierLine);
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
*/
|
||||
package com.axelor.apps.suppliermanagement.service;
|
||||
|
||||
import com.axelor.apps.account.db.AnalyticMoveLine;
|
||||
import com.axelor.apps.account.db.Budget;
|
||||
import com.axelor.apps.account.db.BudgetDistribution;
|
||||
import com.axelor.apps.account.db.repo.AnalyticMoveLineRepository;
|
||||
import com.axelor.apps.account.db.repo.BudgetDistributionRepository;
|
||||
import com.axelor.apps.base.db.Blocking;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
@@ -33,7 +38,6 @@ import com.axelor.apps.purchase.db.SupplierCatalog;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseRequestRepository;
|
||||
import com.axelor.apps.purchase.service.PurchaseOrderLineService;
|
||||
import com.axelor.apps.purchase.service.app.AppPurchaseService;
|
||||
import com.axelor.apps.stock.service.StockLocationService;
|
||||
import com.axelor.apps.suppliermanagement.db.PurchaseOrderSupplierLine;
|
||||
@@ -231,9 +235,9 @@ public class PurchaseOrderSupplierService {
|
||||
}
|
||||
}
|
||||
// PurchaseOrderNew.setStatusSelect(0);//Approuve
|
||||
createPurchaseOrderSupplierLineTCO(
|
||||
PurchaseOrderNew.getPurchaseOrderLineList(),
|
||||
purchaseOrderLinesBySupplierPartner.get(supplierPartner));
|
||||
// createPurchaseOrderSupplierLineTCO(
|
||||
// PurchaseOrderNew.getPurchaseOrderLineList(),
|
||||
// purchaseOrderLinesBySupplierPartner.get(supplierPartner));
|
||||
}
|
||||
|
||||
purchaseRequest.setPurchaseOrderSet(hash_Set);
|
||||
@@ -323,7 +327,8 @@ public class PurchaseOrderSupplierService {
|
||||
"Création d'une ligne de commande fournisseur pour le produit : {}",
|
||||
new Object[] {purchaseOrderLine.getProductName()});
|
||||
|
||||
return purchaseOrderLineServiceSupplychainImpl.createPurchaseOrderLineFromSplit(purchaseOrderLine);
|
||||
return purchaseOrderLineServiceSupplychainImpl.createPurchaseOrderLineFromSplit(
|
||||
purchaseOrderLine);
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
@@ -392,8 +397,23 @@ public class PurchaseOrderSupplierService {
|
||||
"SOPHAL Création d'une ligne de commande fournisseur pour le produit : {}",
|
||||
new Object[] {purchaseOrderLine.getProductName()});
|
||||
|
||||
PurchaseOrderLine PurchaseOrderLineNew =
|
||||
purchaseOrderLineServiceSupplychainImpl.createPurchaseOrderLineFromSplit(purchaseOrderLine);
|
||||
PurchaseOrderLine PurchaseOrderLineNew = purchaseOrderLineServiceSupplychainImpl.createPurchaseOrderLineFromSplit(purchaseOrderLine);
|
||||
|
||||
// List<AnalyticMoveLine> analyticMoveLines = purchaseOrderLine.getAnalyticMoveLineList();
|
||||
// List<BudgetDistribution> budgetDistributions = purchaseOrderLine.getBudgetDistributionList();
|
||||
|
||||
// if (analyticMoveLines.size() != 0) {
|
||||
// for (AnalyticMoveLine analyticMoveLine : analyticMoveLines) {
|
||||
// AnalyticMoveLine analyticMoveLineCopy = Beans.get(AnalyticMoveLineRepository.class).copy(analyticMoveLine, false);
|
||||
// PurchaseOrderLineNew.addAnalyticMoveLineListItem(analyticMoveLineCopy);
|
||||
// }
|
||||
// }
|
||||
// if (budgetDistributions.size() != 0) {
|
||||
// for (BudgetDistribution budgetDistribution : budgetDistributions) {
|
||||
// BudgetDistribution budgetDistributionCopy = Beans.get(BudgetDistributionRepository.class).copy(budgetDistribution, false);
|
||||
// PurchaseOrderLineNew.addBudgetDistributionListItem(budgetDistributionCopy);
|
||||
// }
|
||||
// }
|
||||
|
||||
PurchaseOrderLineNew.setPrice(purchaseOrderLine.getPrice());
|
||||
PurchaseOrderLineNew.setInTaxPrice(purchaseOrderLine.getInTaxPrice());
|
||||
@@ -424,27 +444,29 @@ public class PurchaseOrderSupplierService {
|
||||
.fetch();
|
||||
|
||||
for (PurchaseOrderSupplierLine poLineSupplierParnet : PurchaseOrderSupplierLineParnetList) {
|
||||
PurchaseOrderSupplierLine po =
|
||||
Beans.get(PurchaseOrderSupplierLineRepository.class).copy(poLineSupplierParnet, false);
|
||||
|
||||
PurchaseOrderSupplierLine po = new PurchaseOrderSupplierLine();
|
||||
po.setPrice(poLineSupplierParnet.getPrice());
|
||||
po.setExTaxTotal(poLineSupplierParnet.getExTaxTotal());
|
||||
po.setInTaxTotal(poLineSupplierParnet.getInTaxTotal());
|
||||
po.setTaxTotal(poLineSupplierParnet.getTaxTotal());
|
||||
po.setAvailableQty(poLineSupplierParnet.getAvailableQty());
|
||||
// PurchaseOrderSupplierLine po = new PurchaseOrderSupplierLine();
|
||||
// po.setPrice(poLineSupplierParnet.getPrice());
|
||||
// po.setExTaxTotal(poLineSupplierParnet.getExTaxTotal());
|
||||
// po.setInTaxTotal(poLineSupplierParnet.getInTaxTotal());
|
||||
// po.setTaxTotal(poLineSupplierParnet.getTaxTotal());
|
||||
// po.setAvailableQty(poLineSupplierParnet.getAvailableQty());
|
||||
po.setPurchaseOrderLine(purchaseOrderLineNew.get(index));
|
||||
po.setStateSelect(poLineSupplierParnet.getStateSelect());
|
||||
po.setTaxLine(poLineSupplierParnet.getTaxLine());
|
||||
po.setSupplierPartner(poLineSupplierParnet.getSupplierPartner());
|
||||
po.setComments(poLineSupplierParnet.getComments());
|
||||
po.setArchived(poLineSupplierParnet.getArchived());
|
||||
po.setEstimatedDelivDate(poLineSupplierParnet.getEstimatedDelivDate());
|
||||
po.setAcceptanceDate(poLineSupplierParnet.getAcceptanceDate());
|
||||
po.setAcceptedByUser(poLineSupplierParnet.getAcceptedByUser());
|
||||
po.setRefusalDate(poLineSupplierParnet.getRefusalDate());
|
||||
po.setRefusedByUser(poLineSupplierParnet.getRefusedByUser());
|
||||
po.setAttrs(poLineSupplierParnet.getAttrs());
|
||||
po.setCurrency(poLineSupplierParnet.getCurrency());
|
||||
po.setPriceDiscounted(poLineSupplierParnet.getPriceDiscounted());
|
||||
// po.setStateSelect(poLineSupplierParnet.getStateSelect());
|
||||
// po.setTaxLine(poLineSupplierParnet.getTaxLine());
|
||||
// po.setSupplierPartner(poLineSupplierParnet.getSupplierPartner());
|
||||
// po.setComments(poLineSupplierParnet.getComments());
|
||||
// po.setArchived(poLineSupplierParnet.getArchived());
|
||||
// po.setEstimatedDelivDate(poLineSupplierParnet.getEstimatedDelivDate());
|
||||
// po.setAcceptanceDate(poLineSupplierParnet.getAcceptanceDate());
|
||||
// po.setAcceptedByUser(poLineSupplierParnet.getAcceptedByUser());
|
||||
// po.setRefusalDate(poLineSupplierParnet.getRefusalDate());
|
||||
// po.setRefusedByUser(poLineSupplierParnet.getRefusedByUser());
|
||||
// po.setAttrs(poLineSupplierParnet.getAttrs());
|
||||
// po.setCurrency(poLineSupplierParnet.getCurrency());
|
||||
// po.setPriceDiscounted(poLineSupplierParnet.getPriceDiscounted());
|
||||
// LOG.debug("purchaseOrderLineNew.getId(): {}",purchaseOrderLineNew.get(index).getId());
|
||||
Beans.get(PurchaseOrderSupplierLineRepository.class).save(po);
|
||||
}
|
||||
|
||||
@@ -95,9 +95,8 @@ public class PurchaseOrderController {
|
||||
PurchaseOrderLineRepository purchaseOrderLineRepo =
|
||||
Beans.get(PurchaseOrderLineRepository.class);
|
||||
for (HashMap map : selectedPurchaseOrderLineMapList) {
|
||||
PurchaseOrderLine purchaseOrderLine =
|
||||
(PurchaseOrderLine) Mapper.toBean(PurchaseOrderLine.class, map);
|
||||
purchaseOrderLineList.add(purchaseOrderLineRepo.find(purchaseOrderLine.getId()));
|
||||
PurchaseOrderLine poline = (PurchaseOrderLine) Mapper.toBean(PurchaseOrderLine.class, map);
|
||||
purchaseOrderLineList.add(purchaseOrderLineRepo.find(poline.getId()));
|
||||
}
|
||||
|
||||
if (purchaseOrderLineList.isEmpty()) {
|
||||
@@ -121,6 +120,7 @@ public class PurchaseOrderController {
|
||||
Beans.get(PurchaseOrderSupplierLineService.class)
|
||||
.setPurchaseOrderLinesPartner(purchaseOrderLineList, partner);
|
||||
response.setCanClose(true);
|
||||
response.setAlert(String.format(I18n.get("Purchase order lines set successfully to partner %s"),partner.getName()));
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.axelor.apps.suppliermanagement.db.repo.PurchaseOrderSupplierLineRepos
|
||||
import com.axelor.apps.suppliermanagement.service.PurchaseOrderSupplierLineService;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderServiceSupplychainImpl;
|
||||
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;
|
||||
@@ -66,6 +67,17 @@ public class PurchaseOrderSupplierLineController {
|
||||
|
||||
public void accept(ActionRequest request, ActionResponse response) {
|
||||
|
||||
// check if budgetRemainingAmountAfterValidation is less than zero then throw error
|
||||
if (request.getContext().get("budgetRemainingAmountAfterValidation") != null) {
|
||||
BigDecimal budgetRemainingAmountAfterValidation =
|
||||
new BigDecimal(
|
||||
String.valueOf(request.getContext().get("budgetRemainingAmountAfterValidation")));
|
||||
if (budgetRemainingAmountAfterValidation.compareTo(BigDecimal.ZERO) < 0) {
|
||||
response.setNotify(I18n.get(
|
||||
"The budget remaining amount after validation is less than zero. Cannot accept the supplier line."));
|
||||
}
|
||||
}
|
||||
|
||||
PurchaseOrderSupplierLine purchaseOrderSupplierLine =
|
||||
Beans.get(PurchaseOrderSupplierLineRepository.class)
|
||||
.find(request.getContext().asType(PurchaseOrderSupplierLine.class).getId());
|
||||
@@ -289,12 +301,13 @@ public class PurchaseOrderSupplierLineController {
|
||||
}
|
||||
}
|
||||
|
||||
public void computeBudgetDistribution(ActionRequest request, ActionResponse response) {
|
||||
|
||||
public void computeBudgetDistribution(ActionRequest request, ActionResponse response){
|
||||
|
||||
PurchaseOrderSupplierLine purchaseOrderSupplierLine = Beans.get(PurchaseOrderSupplierLineRepository.class)
|
||||
PurchaseOrderSupplierLine purchaseOrderSupplierLine =
|
||||
Beans.get(PurchaseOrderSupplierLineRepository.class)
|
||||
.find(request.getContext().asType(PurchaseOrderSupplierLine.class).getId());
|
||||
Beans.get(PurchaseOrderServiceSupplychainImpl.class).computeBudgetDistribution(purchaseOrderSupplierLine.getPurchaseOrderLine());
|
||||
Beans.get(PurchaseOrderServiceSupplychainImpl.class)
|
||||
.computeBudgetDistribution(purchaseOrderSupplierLine.getPurchaseOrderLine());
|
||||
response.setReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user