public virtual bool AddPOOrderLines(IEnumerable <POLineRS> lines) { bool hasAdded = false; foreach (POLineRS line in lines.Where(l => (l.CuryExtCost + l.CuryRetainageAmt > l.CuryReqPrepaidAmt) && (l.Billed == false || l.LineType == POLineType.Service && l.Closed == false))) { var tran = new APTran { InventoryID = line.InventoryID, ProjectID = line.ProjectID, TaskID = line.TaskID, CostCodeID = line.CostCodeID, TaxID = line.TaxID, TaxCategoryID = line.TaxCategoryID, TranDesc = line.TranDesc, UOM = line.UOM, CuryUnitCost = line.CuryUnitCost, DiscPct = line.DiscPct, ManualPrice = true, ManualDisc = true, FreezeManualDisc = true, DiscountID = line.DiscountID, DiscountSequenceID = line.DiscountSequenceID, RetainagePct = line.RetainagePct, POOrderType = line.OrderType, PONbr = line.OrderNbr, POLineNbr = line.LineNbr, }; decimal?billedAndPrepaidQty = line.ReqPrepaidQty + line.OrderBilledQty; tran.Qty = (line.OrderQty <= billedAndPrepaidQty) ? line.OrderQty : line.OrderQty - billedAndPrepaidQty; decimal?billedAndPrepaidAmt = line.CuryReqPrepaidAmt + line.CuryOrderBilledAmt; if (billedAndPrepaidAmt == 0m) { tran.CuryLineAmt = line.CuryLineAmt; tran.CuryDiscAmt = line.CuryDiscAmt; } else if (line.CuryExtCost + line.CuryRetainageAmt <= billedAndPrepaidAmt) { tran.CuryLineAmt = 0m; tran.CuryDiscAmt = 0m; tran.CuryRetainageAmt = 0m; tran.CuryTranAmt = 0m; } else { decimal?prepaymentRatio = (line.CuryExtCost + line.CuryRetainageAmt - billedAndPrepaidAmt) / (line.CuryExtCost + line.CuryRetainageAmt); tran.CuryLineAmt = PXCurrencyAttribute.Round(Base.Transactions.Cache, tran, (prepaymentRatio * line.CuryLineAmt) ?? 0m, CMPrecision.TRANCURY); tran.CuryDiscAmt = PXCurrencyAttribute.Round(Base.Transactions.Cache, tran, (prepaymentRatio * line.CuryDiscAmt) ?? 0m, CMPrecision.TRANCURY); } Base.Transactions.Insert(tran); hasAdded = true; } Base.AutoRecalculateDiscounts(); return(hasAdded); }
protected virtual decimal CalcDiscountAmount(PXCache sender, string lineDiscountTarget, AmountLineFields lineAmountsFields, DiscountLineFields lineDiscountFields) { if (lineDiscountTarget == AP.LineDiscountTargetType.SalesPrice && lineAmountsFields.CuryUnitPrice != 0 && lineAmountsFields.Quantity != 0) // If sales price is available. { decimal extPrice = PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * (lineAmountsFields.CuryUnitPrice ?? 0m), CMPrecision.TRANCURY); decimal lineAmt = PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * ((lineAmountsFields.CuryUnitPrice ?? 0m) - PXDBPriceCostAttribute.Round((lineAmountsFields.CuryUnitPrice ?? 0m) * (lineDiscountFields.DiscPct ?? 0m) * 0.01m)), CMPrecision.TRANCURY); return(extPrice - lineAmt); } else { return((lineAmountsFields.CuryExtPrice ?? 0m) * (lineDiscountFields.DiscPct ?? 0m) * 0.01m); } }
public virtual void RowUpdated(PXCache sender, PXRowUpdatedEventArgs e) { AmountLineFields lineAmountsFields = GetDiscountDocumentLine(sender, e.Row); if (lineAmountsFields.FreezeManualDisc == true) { lineAmountsFields.FreezeManualDisc = false; return; } DiscountLineFields lineDiscountFields = GetDiscountedLine(sender, e.Row); if (lineDiscountFields.LineType == SOLineType.Discount) { return; } AmountLineFields oldLineAmountsFields = GetDiscountDocumentLine(sender, e.OldRow); DiscountLineFields oldLineDiscountFields = GetDiscountedLine(sender, e.OldRow); LineEntitiesFields lineEntities = LineEntitiesFields.GetMapFor(e.Row, sender); LineEntitiesFields oldLineEntities = LineEntitiesFields.GetMapFor(e.OldRow, sender); bool manualMode = false; //by default AutoMode. bool useDiscPct = false; //by default value in DiscAmt has higher priority than DiscPct when both are modified. bool keepDiscountID = true; //should be set to true if user changes discount code code manually bool manualDiscUnchecked = false; //Force Auto Mode if (lineDiscountFields.ManualDisc == false && oldLineDiscountFields.ManualDisc == true) { manualMode = false; manualDiscUnchecked = true; } //Change to Manual Mode based on fields changed: if (lineDiscountFields.ManualDisc == true || sender.Graph.IsCopyPasteContext) { manualMode = true; } //if (row.IsFree == true && oldRow.IsFree != true) // manualMode = true; if (lineDiscountFields.DiscPct != oldLineDiscountFields.DiscPct && lineEntities.InventoryID == oldLineEntities.InventoryID) { manualMode = true; useDiscPct = true; } //use DiscPct when only Quantity/CuryUnitPrice/CuryExtPrice was changed if (lineDiscountFields.DiscPct == oldLineDiscountFields.DiscPct && lineDiscountFields.CuryDiscAmt == oldLineDiscountFields.CuryDiscAmt && (lineAmountsFields.Quantity != oldLineAmountsFields.Quantity || lineAmountsFields.CuryUnitPrice != oldLineAmountsFields.CuryUnitPrice || lineAmountsFields.CuryExtPrice != oldLineAmountsFields.CuryExtPrice)) { useDiscPct = true; } if (lineDiscountFields.CuryDiscAmt != oldLineDiscountFields.CuryDiscAmt && lineAmountsFields.Quantity == oldLineAmountsFields.Quantity && lineAmountsFields.CuryUnitPrice == oldLineAmountsFields.CuryUnitPrice) { manualMode = true; useDiscPct = false; } if (e.ExternalCall && (((Math.Abs((lineDiscountFields.CuryDiscAmt ?? 0m) - (oldLineDiscountFields.CuryDiscAmt ?? 0m)) > 0.0000005m) || (Math.Abs((lineDiscountFields.DiscPct ?? 0m) - (oldLineDiscountFields.DiscPct ?? 0m)) > 0.0000005m)) && lineDiscountFields.DiscountID == oldLineDiscountFields.DiscountID)) { keepDiscountID = false; } //if only CuryLineAmt (Ext.Price) was changed for a line with DiscoutAmt<>0 //for Contracts Qty * UnitPrice * Prorate(<>1) = ExtPrice if (lineAmountsFields.CuryLineAmount != oldLineAmountsFields.CuryLineAmount && lineAmountsFields.Quantity == oldLineAmountsFields.Quantity && lineAmountsFields.CuryUnitPrice == oldLineAmountsFields.CuryUnitPrice && lineAmountsFields.CuryExtPrice == oldLineAmountsFields.CuryExtPrice && lineDiscountFields.DiscPct == oldLineDiscountFields.DiscPct && lineDiscountFields.CuryDiscAmt == oldLineDiscountFields.CuryDiscAmt && lineDiscountFields.CuryDiscAmt != 0) { manualMode = true; } decimal?validLineAmtRaw; decimal?validLineAmt = null; if (lineAmountsFields.CuryLineAmount != oldLineAmountsFields.CuryLineAmount) { if (useDiscPct) { decimal val = lineAmountsFields.CuryExtPrice ?? 0; decimal disctAmt; if (GetLineDiscountTarget(sender, lineEntities) == LineDiscountTargetType.SalesPrice) { disctAmt = PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * (lineAmountsFields.CuryUnitPrice ?? 0m), CMPrecision.TRANCURY) - PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * PXDBPriceCostAttribute.Round((lineAmountsFields.CuryUnitPrice ?? 0m) * (1 - (lineDiscountFields.DiscPct ?? 0m) * 0.01m)), CMPrecision.TRANCURY); } else { disctAmt = val * (lineDiscountFields.DiscPct ?? 0m) * 0.01m; disctAmt = PXCurrencyAttribute.Round(sender, lineDiscountFields, disctAmt, CMPrecision.TRANCURY); } validLineAmtRaw = lineAmountsFields.CuryExtPrice - disctAmt; validLineAmt = PXCurrencyAttribute.Round(sender, lineAmountsFields, validLineAmtRaw ?? 0, CMPrecision.TRANCURY); } else { if (lineDiscountFields.CuryDiscAmt > lineAmountsFields.CuryExtPrice) { validLineAmtRaw = lineAmountsFields.CuryExtPrice; } else { validLineAmtRaw = lineAmountsFields.CuryExtPrice - lineDiscountFields.CuryDiscAmt; } validLineAmt = PXCurrencyAttribute.Round(sender, lineAmountsFields, validLineAmtRaw ?? 0, CMPrecision.TRANCURY); } if (lineAmountsFields.CuryLineAmount != validLineAmt && lineDiscountFields.DiscPct != oldLineDiscountFields.DiscPct) { manualMode = true; } } sender.SetValue(e.Row, this.FieldName, manualMode); //Process only Manual Mode: if (manualMode || sender.Graph.IsCopyPasteContext) { if (manualMode && !keepDiscountID && !sender.Graph.IsImport) { lineDiscountFields.DiscountID = null; lineDiscountFields.DiscountSequenceID = null; } //Update related fields: if (lineAmountsFields.Quantity == 0 && oldLineAmountsFields.Quantity != 0) { sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), 0m); sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), 0m); } else if (lineAmountsFields.CuryLineAmount != oldLineAmountsFields.CuryLineAmount && !useDiscPct) { decimal?extAmt = lineAmountsFields.CuryExtPrice ?? 0; decimal?lineAmt = lineAmountsFields.CuryLineAmount ?? 0; if (extAmt - lineAmountsFields.CuryLineAmount >= 0) { if (lineDiscountFields.CuryDiscAmt > Math.Abs(extAmt ?? 0m)) { sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), lineAmountsFields.CuryExtPrice); PXUIFieldAttribute.SetWarning <DiscountLineFields.curyDiscAmt>(sender, e.Row, PXMessages.LocalizeFormatNoPrefix(AR.Messages.LineDiscountAmtMayNotBeGreaterExtPrice, lineAmountsFields.ExtPriceDisplayName)); } else { sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), extAmt - lineAmountsFields.CuryLineAmount); } if (extAmt != 0 && !sender.Graph.IsCopyPasteContext) { decimal?pct = 100 * lineDiscountFields.CuryDiscAmt / extAmt; sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), pct); } } else if (extAmt != 0 && !sender.Graph.IsCopyPasteContext) { if (lineDiscountFields.CuryDiscAmt != oldLineDiscountFields.CuryDiscAmt) { decimal?pct = 100 * lineDiscountFields.CuryDiscAmt / extAmt; sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), (pct ?? 0m) < -100m ? -100m : pct); if ((pct ?? 0m) < -100m) { sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), -lineAmountsFields.CuryExtPrice); PXUIFieldAttribute.SetWarning <DiscountLineFields.curyDiscAmt>(sender, e.Row, PXMessages.LocalizeFormatNoPrefix(AR.Messages.LineDiscountAmtMayNotBeGreaterExtPrice, lineAmountsFields.ExtPriceDisplayName)); } } else { sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), 0m); sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), 0m); sender.SetValueExt(e.Row, sender.GetField(typeof(curyLineAmt)), lineAmt); } } } else if (lineDiscountFields.CuryDiscAmt != oldLineDiscountFields.CuryDiscAmt) { if (lineAmountsFields.CuryExtPrice != 0 && !sender.Graph.IsCopyPasteContext) { if (lineAmountsFields.CuryExtPrice != 0 && !sender.Graph.IsCopyPasteContext) { decimal?pct = (lineDiscountFields.CuryDiscAmt ?? 0) * 100 / lineAmountsFields.CuryExtPrice; sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), pct); } } } else if (lineDiscountFields.DiscPct != oldLineDiscountFields.DiscPct) { decimal val = lineAmountsFields.CuryExtPrice ?? 0; decimal amt; if (GetLineDiscountTarget(sender, lineEntities) == LineDiscountTargetType.SalesPrice) { if (lineAmountsFields.CuryUnitPrice != 0 && lineAmountsFields.Quantity != 0)//if sales price is available { amt = PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * (lineAmountsFields.CuryUnitPrice ?? 0m), CMPrecision.TRANCURY) - PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * PXDBPriceCostAttribute.Round((lineAmountsFields.CuryUnitPrice ?? 0m) * (1 - (lineDiscountFields.DiscPct ?? 0m) * 0.01m)), CMPrecision.TRANCURY); } else { amt = val * (lineDiscountFields.DiscPct ?? 0m) * 0.01m; } } else { amt = val * (lineDiscountFields.DiscPct ?? 0m) * 0.01m; } sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), amt); } else if (validLineAmt != null && lineAmountsFields.CuryLineAmount != validLineAmt) { decimal val = lineAmountsFields.CuryExtPrice ?? 0; decimal amt; if (GetLineDiscountTarget(sender, lineEntities) == LineDiscountTargetType.SalesPrice) { if (lineAmountsFields.CuryUnitPrice != 0 && lineAmountsFields.Quantity != 0)//if sales price is available { amt = PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * (lineAmountsFields.CuryUnitPrice ?? 0m), CMPrecision.TRANCURY) - PXCurrencyAttribute.Round(sender, lineAmountsFields, (lineAmountsFields.Quantity ?? 0m) * PXDBPriceCostAttribute.Round((lineAmountsFields.CuryUnitPrice ?? 0m) * (1 - (lineDiscountFields.DiscPct ?? 0m) * 0.01m)), CMPrecision.TRANCURY); } else { amt = val * (lineDiscountFields.DiscPct ?? 0m) * 0.01m; } } else { amt = val * (lineDiscountFields.DiscPct ?? 0m) * 0.01m; } sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), amt); } } else if (manualDiscUnchecked && lineDiscountFields.DiscountID == null) { sender.SetValueExt(e.Row, sender.GetField(typeof(discPct)), 0m); sender.SetValueExt(e.Row, sender.GetField(typeof(curyDiscAmt)), 0m); } }
public virtual void RowInserted(PXCache sender, PXRowInsertedEventArgs e) { //When a new row is inserted there is 2 possible ways of handling it: //1. Sync the Discounts fields DiscAmt and DiscPct and calculate LineAmt as ExtPrice - DiscAmt. If DiscAmt <> 0 then ManualDisc flag is set. //2. Add line as is without changing any of the fields. //First Mode is typically executed when a user adds a line to Invoice from UI. Moreover the user enters Only Ext.Amt on the UI. //Second Mode is when a line from SOOrder is added to SOInvoice - in this case all discounts must be freezed and line must be added as is. //Set ManualDisc flag to true when feature is disabled if ((discountFeatureTypeE == DiscountFeatureType.CustomerDiscount && !PXAccess.FeatureInstalled <CS.FeaturesSet.customerDiscounts>()) || (discountFeatureTypeE == DiscountFeatureType.VendorDiscount && !PXAccess.FeatureInstalled <CS.FeaturesSet.vendorDiscounts>())) { sender.SetValue(e.Row, this.FieldName, true); } if (!sender.Graph.IsCopyPasteContext) { AmountLineFields lineAmountsFields = GetDiscountDocumentLine(sender, e.Row); if (lineAmountsFields.FreezeManualDisc == true) { lineAmountsFields.FreezeManualDisc = false; return; } DiscountLineFields lineDiscountFields = GetDiscountedLine(sender, e.Row); if (lineDiscountFields.LineType == SOLineType.Discount) { return; } if (lineDiscountFields.CuryDiscAmt != null && lineDiscountFields.CuryDiscAmt != 0 && lineAmountsFields.CuryExtPrice != 0) { decimal?revCuryDiscAmt = null; if (lineDiscountFields.DiscPct != null) { revCuryDiscAmt = PXDBCurrencyAttribute.RoundCury(sender, e.Row, (decimal)((lineAmountsFields.CuryExtPrice ?? 0m) / 100 * lineDiscountFields.DiscPct)); } if (revCuryDiscAmt != null && revCuryDiscAmt != lineDiscountFields.CuryDiscAmt) { lineDiscountFields.DiscPct = 100 * lineDiscountFields.CuryDiscAmt / lineAmountsFields.CuryExtPrice; } if (sender.Graph.IsContractBasedAPI) { sender.SetValue(e.Row, lineDiscountFields.GetField <DiscountLineFields.manualDisc>().Name, true); sender.SetValueExt(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice - lineDiscountFields.CuryDiscAmt); } else { sender.SetValue(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice - lineDiscountFields.CuryDiscAmt); } } else if (lineDiscountFields.DiscPct != null && lineDiscountFields.DiscPct != 0) { decimal curyDiscAmt = (lineAmountsFields.CuryExtPrice ?? 0) * (lineDiscountFields.DiscPct ?? 0) * 0.01m; sender.SetValueExt(e.Row, lineDiscountFields.GetField <DiscountLineFields.curyDiscAmt>().Name, PXCurrencyAttribute.Round(sender, lineDiscountFields, curyDiscAmt, CMPrecision.TRANCURY)); if (sender.Graph.IsContractBasedAPI) { sender.SetValue(e.Row, lineDiscountFields.GetField <DiscountLineFields.manualDisc>().Name, true); sender.SetValueExt(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice - lineDiscountFields.CuryDiscAmt); } else { sender.SetValue(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice - lineDiscountFields.CuryDiscAmt); } } else if (lineAmountsFields.CuryExtPrice != null && lineAmountsFields.CuryExtPrice != 0m && (lineAmountsFields.CuryLineAmount == null || lineAmountsFields.CuryLineAmount == 0m)) { if (sender.Graph.IsContractBasedAPI) { sender.SetValueExt(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice); } else { sender.SetValue(e.Row, lineAmountsFields.GetField <AmountLineFields.curyLineAmount>().Name, lineAmountsFields.CuryExtPrice); } } } }