use of org.compiere.model.MOrderLine in project adempiere by adempiere.
the class MPPMRP method deleteMRP.
public static void deleteMRP(PO po) {
String tableName = po.get_TableName();
int no = DB.executeUpdateEx("DELETE FROM " + Table_Name + " WHERE " + tableName + "_ID=? AND AD_Client_ID=?", new Object[] { po.get_ID(), po.getAD_Client_ID() }, po.get_TrxName());
s_log.finest("Deleted " + tableName + " #" + no);
// Delete generated manufacturing order
if (po instanceof MOrderLine) {
MOrderLine ol = (MOrderLine) po;
MPPOrder order = MPPOrder.forC_OrderLine_ID(ol.getCtx(), ol.getC_OrderLine_ID(), ol.getM_Product_ID(), ol.get_TrxName());
if (order != null && !order.isProcessed()) {
order.deleteEx(true);
}
}
}
use of org.compiere.model.MOrderLine in project adempiere by adempiere.
the class WebOrder method createOrder.
/**
* Create Order from Basket
* @param wu web User
* @param wb web basket
* @return true if created & processed
*/
private boolean createOrder(WebUser wu, WebBasket wb) {
m_order = new MOrder(m_ctx, 0, null);
log.fine("AD_Client_ID=" + m_order.getAD_Client_ID() + ",AD_Org_ID=" + m_order.getAD_Org_ID() + " - " + m_order);
//
m_order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Prepay);
m_order.setPaymentRule(MOrder.PAYMENTRULE_CreditCard);
m_order.setDeliveryRule(MOrder.DELIVERYRULE_AfterReceipt);
m_order.setInvoiceRule(MOrder.INVOICERULE_Immediate);
m_order.setIsSelfService(true);
if (wb.getM_PriceList_ID() > 0)
m_order.setM_PriceList_ID(wb.getM_PriceList_ID());
if (wb.getSalesRep_ID() != 0)
m_order.setSalesRep_ID(wb.getSalesRep_ID());
// BPartner
m_order.setC_BPartner_ID(wu.getC_BPartner_ID());
m_order.setC_BPartner_Location_ID(wu.getC_BPartner_Location_ID());
m_order.setAD_User_ID(wu.getAD_User_ID());
//
m_order.setSendEMail(true);
m_order.setDocAction(MOrder.DOCACTION_Prepare);
m_order.saveEx();
log.fine("ID=" + m_order.getC_Order_ID() + ", DocNo=" + m_order.getDocumentNo());
ArrayList<WebBasketLine> lines = wb.getLines();
for (int i = 0; i < lines.size(); i++) {
WebBasketLine wbl = lines.get(i);
MOrderLine ol = new MOrderLine(m_order);
ol.setM_Product_ID(wbl.getM_Product_ID(), true);
ol.setQty(wbl.getQuantity());
ol.setPrice();
ol.setPrice(wbl.getPrice());
ol.setTax();
ol.saveEx();
}
// for all lines
boolean ok = m_order.processIt(MOrder.DOCACTION_Prepare);
m_order.saveEx();
// Web User = Customer
if (!wu.isCustomer()) {
// log.info("-------------------------------------- " + wu.isCustomer());
wu.setIsCustomer(true);
wu.save();
// log.info("-------------------------------------- " + wu.isCustomer());
}
BigDecimal amt = m_order.getGrandTotal();
log.info("Amt=" + amt);
return ok;
}
use of org.compiere.model.MOrderLine in project adempiere by adempiere.
the class PromotionRule method addGiftLine.
/**
* addGiftLine
* Free products are added to the Order with price according to discount (price is calculated from discount).
* If there is an order line with the same product and discount, only the quantity is added.
*
* @author Mario Calderon (SHW)
* @date 14.07.2013
* @param order Sales Order
* @param ol Sales Order line
* @param discount Discount in %
* @param qty Quantity of promotion
* @param C_Charge_ID Charge for the promotion - not used; just for legacy. Can be refactored later.
* @param promotion Promotion object
* @return void
*
*/
private static void addGiftLine(MOrder order, MOrderLine ol, BigDecimal discount, BigDecimal qty, int C_Charge_ID, I_M_Promotion promotion) throws Exception {
MOrderLine nol;
if (discount.scale() > 2)
discount = discount.setScale(2, BigDecimal.ROUND_HALF_UP);
// Calculate discount
BigDecimal actualPrice = ol.getPriceActual();
actualPrice = actualPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal multiplicator = Env.ONEHUNDRED.subtract(discount).divide(Env.ONEHUNDRED);
actualPrice = actualPrice.multiply(multiplicator);
//Look for same product and discount as calculated
nol = new Query(Env.getCtx(), MTable.get(order.getCtx(), MOrderLine.Table_ID), "C_OrderLine.C_Order_ID=? AND C_OrderLine.m_product_id=? " + " AND C_OrderLine.discount=" + discount.toString() + " AND C_OrderLine.IsActive='Y'", order.get_TrxName()).setParameters(ol.getC_Order_ID(), ol.getM_Product_ID()).firstOnly();
if (nol != null) {
// just add one to he Order line
nol.setQty(nol.getQtyEntered().add(qty));
nol.saveEx();
return;
}
// No discounted product before: create a new line
nol = new MOrderLine(order.getCtx(), 0, order.get_TrxName());
nol.setC_Order_ID(order.getC_Order_ID());
nol.setOrder(order);
nol.setM_Product_ID(ol.getM_Product_ID());
nol.setC_UOM_ID(ol.getC_UOM_ID());
nol.setQty(qty);
nol.setPriceActual(Env.ZERO);
nol.setPriceEntered(Env.ZERO);
nol.setPriceList(ol.getPriceList());
// the discount is actually calculated and thus not needed
nol.setDiscount(discount);
if (ol != null && Integer.toString(ol.getLine()).endsWith("0")) {
for (int i = 0; i < 9; i++) {
int line = ol.getLine() + i + 1;
int r = DB.getSQLValue(order.get_TrxName(), "SELECT C_OrderLine_ID FROM C_OrderLine WHERE C_Order_ID = ? AND Line = ?", order.getC_Order_ID(), line);
if (r <= 0) {
nol.setLine(line);
break;
}
}
}
String description = promotion.getName();
if (ol != null)
description += (", " + ol.getName());
nol.setDescription(description + ". Gift.");
nol.set_ValueOfColumn("M_Promotion_ID", promotion.getM_Promotion_ID());
if (promotion.getC_Campaign_ID() > 0) {
nol.setC_Campaign_ID(promotion.getC_Campaign_ID());
}
nol.saveEx();
}
use of org.compiere.model.MOrderLine in project adempiere by adempiere.
the class PromotionRule method findPromotionLine.
/**
*
* @param promotion_ID
* @param order
* @return List<M_PromotionLine_ID>
* @throws SQLException
*/
private static List<Integer> findPromotionLine(int promotion_ID, MOrder order) throws SQLException {
Query query = new Query(Env.getCtx(), MTable.get(order.getCtx(), I_M_PromotionLine.Table_ID), " M_PromotionLine.M_Promotion_ID = ? AND M_PromotionLine.IsActive = 'Y'", order.get_TrxName());
query.setParameters(new Object[] { promotion_ID });
List<MPromotionLine> plist = query.<MPromotionLine>list();
//List<M_PromotionLine_ID>
List<Integer> applicable = new ArrayList<Integer>();
MOrderLine[] lines = order.getLines();
for (MPromotionLine pl : plist) {
boolean match = false;
if (pl.getM_PromotionGroup_ID() > 0) {
String sql = "SELECT DISTINCT C_OrderLine.C_OrderLine_ID FROM M_PromotionGroup INNER JOIN M_PromotionGroupLine" + " ON (M_PromotionGroup.M_PromotionGroup_ID = M_PromotionGroupLine.M_PromotionGroup_ID AND M_PromotionGroupLine.IsActive = 'Y')" + " INNER JOIN C_OrderLine ON (M_PromotionGroupLine.M_Product_ID = C_OrderLine.M_Product_ID)" + " INNER JOIN M_PromotionLine ON (M_PromotionLine.M_PromotionGroup_ID = M_PromotionGroup.M_PromotionGroup_ID)" + " WHERE M_PromotionLine.M_PromotionLine_ID = ? AND C_OrderLine.C_Order_ID = ?" + " AND M_PromotionLine.IsActive = 'Y'" + " AND M_PromotionGroup.IsActive = 'Y'";
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = DB.prepareStatement(sql, order.get_TrxName());
stmt.setInt(1, pl.getM_PromotionLine_ID());
stmt.setInt(2, order.getC_Order_ID());
rs = stmt.executeQuery();
BigDecimal orderAmt = BigDecimal.ZERO;
while (rs.next()) {
if (pl.getMinimumAmt() != null && pl.getMinimumAmt().signum() > 0) {
int C_OrderLine_ID = rs.getInt(1);
for (MOrderLine ol : lines) {
if (ol.getC_OrderLine_ID() == C_OrderLine_ID) {
orderAmt = orderAmt.add(ol.getLineNetAmt());
break;
}
}
if (orderAmt.compareTo(pl.getMinimumAmt()) >= 0) {
match = true;
break;
}
} else {
match = true;
break;
}
}
} finally {
DB.close(rs, stmt);
}
} else if (pl.getMinimumAmt() != null && pl.getMinimumAmt().compareTo(order.getGrandTotal()) <= 0) {
match = true;
}
if (!match && pl.isMandatoryPL()) {
applicable.clear();
break;
}
if (match)
applicable.add(pl.getM_PromotionLine_ID());
}
return applicable;
}
use of org.compiere.model.MOrderLine in project adempiere by adempiere.
the class PromotionRule method applyPromotions.
public static void applyPromotions(MOrder order) throws Exception {
//key = C_OrderLine, value = Qty to distribution
Map<Integer, BigDecimal> orderLineQty = new LinkedHashMap<Integer, BigDecimal>();
Map<Integer, MOrderLine> orderLineIndex = new HashMap<Integer, MOrderLine>();
MOrderLine[] lines = order.getLines();
boolean hasDeleteLine = false;
for (MOrderLine ol : lines) {
if (ol.getM_Product_ID() > 0) {
if (ol.getQtyOrdered().signum() > 0) {
orderLineQty.put(ol.getC_OrderLine_ID(), ol.getQtyOrdered());
orderLineIndex.put(ol.getC_OrderLine_ID(), ol);
}
} else if (ol.getC_Charge_ID() > 0) {
Number id = (Number) ol.get_Value("M_Promotion_ID");
if (id != null && id.intValue() > 0) {
ol.delete(false);
hasDeleteLine = true;
}
}
}
if (orderLineQty.isEmpty())
return;
//refresh order
if (hasDeleteLine) {
order.getLines(true, null);
order.getTaxes(true);
order.setGrandTotal(DB.getSQLValueBD(order.get_TrxName(), "SELECT GrandTotal From C_Order WHERE C_Order_ID = ?", order.getC_Order_ID()));
}
Map<Integer, List<Integer>> promotions = PromotionRule.findM_Promotion_ID(order);
if (promotions == null || promotions.isEmpty())
return;
BigDecimal orderAmount = order.getGrandTotal();
//key = M_PromotionDistribution_ID, value = C_OrderLine_ID and Qty
Map<Integer, DistributionSet> distributions = new LinkedHashMap<Integer, DistributionSet>();
//<M_PromotionDistribution_ID, DistributionSorting>
Map<Integer, String> sortingType = new HashMap<Integer, String>();
OrderLineComparator olComparator = new OrderLineComparator(orderLineIndex);
//distribute order lines
for (Map.Entry<Integer, List<Integer>> entry : promotions.entrySet()) {
Query query = new Query(Env.getCtx(), MTable.get(order.getCtx(), I_M_PromotionDistribution.Table_ID), "M_PromotionDistribution.M_Promotion_ID = ? AND M_PromotionDistribution.IsActive = 'Y'", order.get_TrxName());
query.setParameters(new Object[] { entry.getKey() });
query.setOrderBy("SeqNo");
List<MPromotionDistribution> list = query.<MPromotionDistribution>list();
Query rewardQuery = new Query(Env.getCtx(), MTable.get(order.getCtx(), I_M_PromotionReward.Table_ID), "M_PromotionReward.M_Promotion_ID = ? AND M_PromotionReward.IsActive = 'Y'", order.get_TrxName());
rewardQuery.setParameters(new Object[] { entry.getKey() });
rewardQuery.setOrderBy("SeqNo");
List<MPromotionReward> rewardList = rewardQuery.<MPromotionReward>list();
List<MPromotionLine> promotionLines = new ArrayList<MPromotionLine>();
for (Integer M_PromotionLine_ID : entry.getValue()) {
MPromotionLine promotionLine = new MPromotionLine(order.getCtx(), M_PromotionLine_ID, order.get_TrxName());
promotionLines.add(promotionLine);
}
while (true) {
boolean hasDistributionSet = false;
Set<Integer> promotionLineSet = new HashSet<Integer>();
Set<Integer> mandatoryLineSet = new HashSet<Integer>();
boolean mandatoryLineNotFound = false;
List<Integer> validPromotionLineIDs = new ArrayList<Integer>();
for (MPromotionLine promotionLine : promotionLines) {
if (promotionLine.getM_PromotionGroup_ID() == 0 && promotionLine.getMinimumAmt() != null && promotionLine.getMinimumAmt().signum() >= 0) {
if (orderAmount.compareTo(promotionLine.getMinimumAmt()) >= 0) {
orderAmount = orderAmount.subtract(promotionLine.getMinimumAmt());
validPromotionLineIDs.add(promotionLine.getM_PromotionLine_ID());
} else if (promotionLine.isMandatoryPL()) {
mandatoryLineNotFound = true;
break;
}
}
}
if (mandatoryLineNotFound) {
break;
}
for (MPromotionDistribution pd : list) {
if (entry.getValue().contains(pd.getM_PromotionLine_ID())) {
//sort available orderline base on distribution sorting type
List<Integer> orderLineIdList = new ArrayList<Integer>();
orderLineIdList.addAll(orderLineQty.keySet());
if (pd.getDistributionSorting() != null) {
Comparator<Integer> cmp = olComparator;
if (pd.getDistributionSorting().equals(MPromotionDistribution.DISTRIBUTIONSORTING_Descending))
cmp = Collections.reverseOrder(cmp);
Collections.sort(orderLineIdList, cmp);
}
DistributionSet prevSet = distributions.get(pd.getM_PromotionDistribution_ID());
DistributionSet distributionSet = PromotionRule.calculateDistributionQty(pd, prevSet, validPromotionLineIDs, orderLineQty, orderLineIdList, order.get_TrxName());
if (distributionSet != null && distributionSet.setQty.signum() > 0) {
hasDistributionSet = true;
promotionLineSet.add(pd.getM_PromotionLine_ID());
} else {
if (pd.getM_PromotionLine().isMandatoryPL()) {
mandatoryLineSet.add(pd.getM_PromotionLine_ID());
}
}
distributions.put(pd.getM_PromotionDistribution_ID(), distributionSet);
sortingType.put(pd.getM_PromotionDistribution_ID(), pd.getDistributionSorting());
}
}
if (!hasDistributionSet)
break;
if (mandatoryLineSet != null) {
mandatoryLineNotFound = false;
for (Integer id : mandatoryLineSet) {
if (!promotionLineSet.contains(id)) {
mandatoryLineNotFound = true;
break;
}
}
if (mandatoryLineNotFound) {
break;
}
}
for (MPromotionReward pr : rewardList) {
if (pr.isForAllDistribution()) {
Collection<DistributionSet> all = distributions.values();
BigDecimal totalPrice = BigDecimal.ZERO;
for (DistributionSet distributionSet : all) {
for (Map.Entry<Integer, BigDecimal> olMap : distributionSet.orderLines.entrySet()) {
BigDecimal qty = (BigDecimal) olMap.getValue();
int C_OrderLine_ID = (Integer) olMap.getKey();
for (MOrderLine ol : lines) {
if (ol.getC_OrderLine_ID() == C_OrderLine_ID) {
totalPrice = totalPrice.add(ol.getPriceActual().multiply(qty));
break;
}
}
distributionSet.orderLines.put(olMap.getKey(), BigDecimal.ZERO);
}
}
BigDecimal discount = BigDecimal.ZERO;
if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_AbsoluteAmount)) {
if (pr.getAmount().compareTo(totalPrice) < 0) {
discount = totalPrice.subtract(pr.getAmount());
}
} else if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_FlatDiscount)) {
discount = pr.getAmount();
} else if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_Percentage)) {
discount = pr.getAmount().divide(BigDecimal.valueOf(100.00)).multiply(totalPrice);
}
if (discount.signum() > 0) {
addDiscountLine(order, null, discount, BigDecimal.valueOf(1.00), pr.getC_Charge_ID(), pr.getM_Promotion());
}
} else {
int M_PromotionDistribution_ID = pr.getM_PromotionDistribution_ID();
if (!distributions.containsKey(M_PromotionDistribution_ID))
continue;
int targetDistributionID = M_PromotionDistribution_ID;
if (!pr.isSameDistribution()) {
targetDistributionID = pr.getM_TargetDistribution_ID();
if (!distributions.containsKey(targetDistributionID))
continue;
}
DistributionSet distributionSet = distributions.get(targetDistributionID);
//sort by reward distribution sorting
if (pr.getDistributionSorting() != null) {
Comparator<Integer> cmp = new OrderLineComparator(orderLineIndex);
if (pr.getDistributionSorting().equals(MPromotionReward.DISTRIBUTIONSORTING_Descending))
cmp = Collections.reverseOrder(cmp);
Set<Integer> keySet = distributionSet.orderLines.keySet();
List<Integer> keyList = new ArrayList<Integer>();
keyList.addAll(keySet);
Collections.sort(keyList, cmp);
Map<Integer, BigDecimal> sortedMap = new LinkedHashMap<Integer, BigDecimal>();
for (Integer id : keyList) {
sortedMap.put(id, distributionSet.orderLines.get(id));
}
distributionSet.orderLines = sortedMap;
}
BigDecimal setBalance = distributionSet.setQty;
BigDecimal toApply = pr.getQty();
if (toApply == null || toApply.signum() == 0)
toApply = BigDecimal.valueOf(-1.0);
BigDecimal totalPrice = BigDecimal.ZERO;
for (Map.Entry<Integer, BigDecimal> olMap : distributionSet.orderLines.entrySet()) {
BigDecimal qty = olMap.getValue();
int C_OrderLine_ID = olMap.getKey();
if (qty == null || qty.signum() <= 0)
continue;
if (qty.compareTo(setBalance) >= 0) {
qty = setBalance;
setBalance = BigDecimal.ZERO;
} else {
setBalance = setBalance.subtract(qty);
}
if (toApply.signum() > 0) {
if (toApply.compareTo(qty) <= 0) {
qty = toApply;
toApply = BigDecimal.ZERO;
} else {
toApply = toApply.subtract(qty);
}
BigDecimal newQty = olMap.getValue();
newQty = newQty.subtract(qty);
distributionSet.orderLines.put(olMap.getKey(), newQty);
}
for (MOrderLine ol : lines) {
if (ol.getC_OrderLine_ID() == C_OrderLine_ID) {
if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_Percentage)) {
BigDecimal priceActual = ol.getPriceActual();
BigDecimal discount = priceActual.multiply(pr.getAmount().divide(BigDecimal.valueOf(100.00)));
addDiscountLine(order, ol, discount, qty, pr.getC_Charge_ID(), pr.getM_Promotion());
} else if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_FlatDiscount)) {
addDiscountLine(order, ol, pr.getAmount(), BigDecimal.valueOf(1.00), pr.getC_Charge_ID(), pr.getM_Promotion());
} else if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_AbsoluteAmount)) {
BigDecimal priceActual = ol.getPriceActual();
totalPrice = totalPrice.add(priceActual.multiply(qty));
} else {
// : Gift line
BigDecimal qtyreward = pr.getM_PromotionDistribution().getQty();
BigDecimal qtymodulo = ol.getQtyOrdered().divide(qtyreward, 0);
addGiftLine(order, ol, pr.getAmount(), pr.getQty().multiply(qtymodulo), pr.getC_Charge_ID(), pr.getM_Promotion());
}
}
}
if (toApply.signum() == 0)
break;
if (setBalance.signum() == 0)
break;
}
if (pr.getRewardType().equals(MPromotionReward.REWARDTYPE_AbsoluteAmount)) {
if (pr.getAmount().compareTo(totalPrice) < 0) {
addDiscountLine(order, null, totalPrice.subtract(pr.getAmount()), BigDecimal.valueOf(1.00), pr.getC_Charge_ID(), pr.getM_Promotion());
}
}
}
}
}
}
}
Aggregations