add mrp (CBN)
This commit is contained in:
@@ -19,7 +19,9 @@ package com.axelor.apps.production.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.UnitConversionService;
|
||||
import com.axelor.apps.production.db.BillOfMaterial;
|
||||
import com.axelor.apps.production.db.ManufOrder;
|
||||
import com.axelor.apps.production.db.OperationOrder;
|
||||
@@ -36,11 +38,14 @@ import com.axelor.apps.stock.db.repo.StockRulesRepository;
|
||||
import com.axelor.apps.stock.service.StockLocationService;
|
||||
import com.axelor.apps.stock.service.StockRulesService;
|
||||
import com.axelor.apps.supplychain.db.Mrp;
|
||||
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.MrpLineSophal;
|
||||
import com.axelor.apps.supplychain.db.MrpLineType;
|
||||
import com.axelor.apps.supplychain.db.repo.MrpForecastRepository;
|
||||
import com.axelor.apps.supplychain.db.repo.MrpLineRepository;
|
||||
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.service.MrpLineService;
|
||||
@@ -48,12 +53,18 @@ import com.axelor.apps.supplychain.service.MrpServiceImpl;
|
||||
import com.axelor.apps.tool.StringTool;
|
||||
import com.axelor.db.JPA;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -437,4 +448,106 @@ public class MrpServiceProductionImpl extends MrpServiceImpl {
|
||||
this.createManufOrderMrpLines();
|
||||
return mrp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAvailableMrpLineSophal(Mrp mrp) throws AxelorException{
|
||||
super.createAvailableMrpLineSophal(mrp);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void createMrpLineSophal(Mrp mrp, Product product,Unit unit,BigDecimal qty,List<MrpForecast> mrpForecastList, Map<Long, Double> productQty) throws AxelorException{
|
||||
|
||||
if(mrp.getIncludeBOM()){
|
||||
|
||||
BillOfMaterial defaultBillOfMaterial = product.getDefaultBillOfMaterial();
|
||||
|
||||
if (defaultBillOfMaterial != null) {
|
||||
|
||||
for (BillOfMaterial billOfMaterial : defaultBillOfMaterial.getBillOfMaterialSet()) {
|
||||
List<MrpForecast> forecastList = mrpForecastList.stream().filter(t -> t.getProduct() == product).collect(Collectors.toList());
|
||||
|
||||
Product subProduct = billOfMaterial.getProduct();
|
||||
|
||||
if (this.isMrpProduct(subProduct)) {
|
||||
|
||||
Double prodQty = productQty.get(subProduct.getId()) == null ? Double.parseDouble("0") : productQty.get(subProduct.getId());
|
||||
BigDecimal reelQty =new BigDecimal(prodQty);
|
||||
|
||||
createMrpLineSophalProd(mrp, subProduct,product, reelQty ,billOfMaterial.getQty(),defaultBillOfMaterial.getQty(),forecastList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}else{
|
||||
super.createMrpLineSophal(mrp, product,unit, qty, mrpForecastList,productQty);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void createMrpLineSophalProd(Mrp mrp,Product product,Product parentProduct,BigDecimal qty,BigDecimal reorderdQty,BigDecimal defaultQty, List<MrpForecast> forecastList){
|
||||
MrpLineSophal mrpLineSophal = new MrpLineSophal();
|
||||
mrpLineSophal.setQty(qty);
|
||||
BigDecimal reelQty = qty;
|
||||
BigDecimal sumQty = BigDecimal.ZERO;
|
||||
for (MrpForecast forecast : forecastList) {
|
||||
|
||||
if(forecast.getProduct().getId() == parentProduct.getId()){
|
||||
BigDecimal dividedQty = (forecast.getQty().multiply(reorderdQty)).divide(defaultQty);
|
||||
reelQty = reelQty.subtract(dividedQty);
|
||||
sumQty = sumQty.add(dividedQty);
|
||||
BigDecimal displayedQty = reelQty;
|
||||
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.getPurchasesUnit());
|
||||
mrpLineSophal.setProductOrigin(parentProduct);
|
||||
|
||||
Stream<MrpForecast> filter = forecastList.stream().filter(t -> t.getProduct().getId() == parentProduct.getId());
|
||||
Long totalForecast = filter.count();
|
||||
|
||||
mrpLineSophal.setSecurityStock(sumQty.divide(new BigDecimal(totalForecast) ,5, RoundingMode.HALF_EVEN));
|
||||
Beans.get(MrpLineSophalRepository.class).save(mrpLineSophal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,15 +46,18 @@ 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.MrpLineSophal;
|
||||
import com.axelor.apps.supplychain.db.MrpLineType;
|
||||
import com.axelor.apps.supplychain.db.repo.MrpForecastRepository;
|
||||
import com.axelor.apps.supplychain.db.repo.MrpLineRepository;
|
||||
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.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;
|
||||
@@ -66,12 +69,14 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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;
|
||||
@@ -98,6 +103,7 @@ public class MrpServiceImpl implements MrpService {
|
||||
|
||||
protected List<StockLocation> stockLocationList;
|
||||
protected Map<Long, Integer> productMap;
|
||||
protected Map<Long, Double> productQty;
|
||||
protected Mrp mrp;
|
||||
protected LocalDate today;
|
||||
|
||||
@@ -171,6 +177,17 @@ public class MrpServiceImpl implements MrpService {
|
||||
mrpRepository.save(mrp);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void resetSophalLine(Mrp mrp) {
|
||||
|
||||
Beans.get(MrpLineSophalRepository.class).all().filter("self.mrp.id = ?1", mrp.getId()).remove();
|
||||
|
||||
|
||||
mrp.setStatusSelect(MrpRepository.STATUS_DRAFT);
|
||||
|
||||
mrpRepository.save(mrp);
|
||||
}
|
||||
|
||||
protected void completeMrp(Mrp mrp) throws AxelorException {
|
||||
|
||||
log.debug("Complete MRP");
|
||||
@@ -1096,4 +1113,128 @@ public class MrpServiceImpl implements MrpService {
|
||||
|
||||
return mrp;
|
||||
}
|
||||
|
||||
|
||||
public void createAvailableMrpLineSophal(Mrp mrp) throws AxelorException {
|
||||
this.resetSophalLine(mrp);
|
||||
today = appBaseService.getTodayDate();
|
||||
|
||||
Set<StockLocation> slList2 = Sets.newHashSet();
|
||||
this.mrp = mrp;
|
||||
try {
|
||||
this.assignProductAndLevel(this.getProductList());
|
||||
|
||||
} catch (AxelorException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
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())));
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.debug(e.toString());
|
||||
}
|
||||
|
||||
List<MrpForecast> mrpForecastList = new ArrayList<>();
|
||||
|
||||
if (mrp.getMrpForecastSet().isEmpty()) {
|
||||
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());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
mrpLineSophal.setSecurityStock(sumQty.divide(new BigDecimal(totalForecast),5, RoundingMode.HALF_EVEN));
|
||||
Beans.get(MrpLineSophalRepository.class).save(mrpLineSophal);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,25 @@
|
||||
*/
|
||||
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;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
@@ -31,6 +44,9 @@ 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 {
|
||||
@@ -121,4 +137,16 @@ public class MrpController {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
<datetime name="startDateTime" title="Calculation Start Date"/>
|
||||
<datetime name="endDateTime" title="Calculation End Date"/>
|
||||
<string name="mrpSeq" title="MRP number" readonly="true"/>
|
||||
<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"/>
|
||||
|
||||
<extra-code><![CDATA[
|
||||
|
||||
// STATUS SELECT
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<string name="note" title="Note" large="true" multiline="true"/>
|
||||
<many-to-one name="partner" ref="com.axelor.apps.base.db.Partner" title="Partner"/>
|
||||
<integer name="statusSelect" title="Status" selection="supplychain.mrp.forecast.status.select" readonly="true" default="1"/>
|
||||
<integer name="monthSelect" selection="iadministration.month.select"/>
|
||||
<integer name="scenario" title="Scenario" selection="mrp.scenario.select"/>
|
||||
|
||||
<extra-code><![CDATA[
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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="MrpLineSophal" 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="qty" title="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" />
|
||||
<!-- <integer name="scenario" title="Scenario" selection="mrp.scenario.select"/> -->
|
||||
<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" />
|
||||
<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>
|
||||
Reference in New Issue
Block a user