protected virtual void LandedCostCode_RowDeleting(PXCache sender, PXRowDeletingEventArgs e) { LandedCostTran costTran = PXSelect <LandedCostTran, Where <LandedCostTran.landedCostCodeID, Equal <Current <LandedCostCode.landedCostCodeID> > > > .SelectWindowed(this, 0, 1); if (costTran != null) { throw new PXException(Messages.ThisEntityNotBeDeletedBecauseItIsUsedIn, Messages.LandedCostCode, Messages.LandedCostTran); } APTran apTran = PXSelect <APTran, Where <APTran.landedCostCodeID, Equal <Current <LandedCostCode.landedCostCodeID> > > > .SelectWindowed(this, 0, 1); if (costTran != null) { throw new PXException(Messages.ThisEntityNotBeDeletedBecauseItIsUsedIn, Messages.LandedCostCode, AP.Messages.APTran); } }
public List <LandedCostHelper.POReceiptLineAdjustment> AllocateLCOverRCTLines(IEnumerable <POReceiptLine> aLines, LandedCostCode aLCCode, LandedCostTran aTran, IEnumerable <LandedCostTranSplit> aSplits) { Decimal toDistribute = aTran.LCAmount.Value; Decimal baseTotal = decimal.Zero; foreach (POReceiptLine iDet in aLines) { if (IsApplicable(aTran, aSplits, aLCCode, iDet)) { baseTotal += GetBaseValue(aLCCode, iDet); } } List <POReceiptLineAdjustment> result = new List <POReceiptLineAdjustment>(); Decimal leftToDistribute = toDistribute; foreach (POReceiptLine iDet in aLines) { var poreceipt = (POReceipt)PXSelect <POReceipt, Where <POReceipt.receiptType, Equal <Current <POReceiptLine.receiptType> >, And <POReceipt.receiptNbr, Equal <Current <POReceiptLine.receiptNbr> > > > > .SelectSingleBound(this._graph, new object[] { iDet }); if (!IsApplicable(aTran, aSplits, aLCCode, iDet)) { continue; } leftToDistribute -= AllocateOverRCTLine(result, iDet, CalcAllocationValue(aLCCode, iDet, baseTotal, toDistribute), poreceipt.BranchID); } AllocateRestOverRCTLines(result, leftToDistribute); return(result); }
public bool IsApplicable(LandedCostTran aTran, IEnumerable <LandedCostTranSplit> aSplits, LandedCostCode aCode, POReceiptLine aLine) { if (!IsApplicable(aCode, aLine)) { return(false); } bool passes = false; if (aSplits != null) { foreach (LandedCostTranSplit it in aSplits) { if (it.POReceiptNbr == aLine.ReceiptNbr) { passes = true; if (passes && it.POReceiptLineNbr.HasValue) { if (it.POReceiptLineNbr != aLine.LineNbr) { passes = false; } } if (passes && it.InventoryID.HasValue) { if (it.InventoryID != aLine.InventoryID) { passes = false; } } } if (passes) { break; } } } if (!passes) { if (String.IsNullOrEmpty(aTran.POReceiptNbr) || (aTran.POReceiptNbr != aLine.ReceiptNbr)) { return(false); } if (aTran.POReceiptLineNbr.HasValue) { if (aTran.POReceiptLineNbr != aLine.LineNbr) { return(false); } } if (aTran.InventoryID.HasValue) { if (aTran.InventoryID != aLine.InventoryID) { return(false); } } passes = true; } if (passes) { if (aTran.SiteID.HasValue) { if (aTran.SiteID != aLine.SiteID) { return(false); } } if (aTran.LocationID.HasValue) { if (aTran.LocationID != aLine.LocationID) { return(false); } } } return(passes); }
public bool IsApplicable(LandedCostTran aTran, LandedCostCode aCode, POReceiptLine aLine) { return(IsApplicable(aTran, null, aCode, aLine)); }
protected virtual void GetReceiptLinesToAllocate(List <POReceiptLine> aReceiptLines, List <LandedCostTranSplit> aSplits, LandedCostTran aTran) { Dictionary <string, int> used = new Dictionary <string, int>(); foreach (POReceiptLine it in this.poLines.Select(aTran.POReceiptNbr)) { aReceiptLines.Add(it); used[aTran.POReceiptNbr] = 1; } foreach (LandedCostTranSplit iSplit in PXSelect <LandedCostTranSplit, Where <LandedCostTranSplit.lCTranID, Equal <Required <LandedCostTranSplit.lCTranID> > > > .Select(this, aTran.LCTranID)) { aSplits.Add(iSplit); if (used.ContainsKey(iSplit.POReceiptNbr)) { used[iSplit.POReceiptNbr] += 1; continue; } foreach (POReceiptLine it in this.poLines.Select(iSplit.POReceiptNbr)) { aReceiptLines.Add(it); used[iSplit.POReceiptNbr] = 1; } } }
public virtual void CreateAdjustmentTran(INAdjustmentEntry inGraph, List <LandedCostHelper.POReceiptLineAdjustment> pOLinesToProcess, LandedCostCode aLCCode, LandedCostTran aTran, string ReasonCode) { foreach (LandedCostHelper.POReceiptLineAdjustment poreceiptline in pOLinesToProcess) { INTran intran = new INTran(); bool isLCTran = aTran != null; INTran origtran = LandedCostHelper.GetOriginalInTran(inGraph, poreceiptline.Item1.ReceiptNbr, poreceiptline.Item1.LineNbr); bool isDropShip = (poreceiptline.Item1.LineType == POLineType.GoodsForDropShip || poreceiptline.Item1.LineType == POLineType.NonStockForDropShip); if (!isDropShip && origtran == null) { throw new PXException(AP.Messages.CannotFindINReceipt, poreceiptline.Item1.ReceiptNbr); } //Drop-Ships are considered non-stocks if (poreceiptline.Item1.IsStockItem()) { intran.TranType = INTranType.ReceiptCostAdjustment; } else { //Landed cost and PPV for non-stock items are handled in special way in the inventory. //They should create a GL Batch, but for convinience and unforminty this functionality is placed into IN module //Review this part when the functionality is implemented in IN module intran.IsCostUnmanaged = true; intran.TranType = INTranType.Adjustment; intran.InvtMult = 0; } intran.InventoryID = poreceiptline.Item1.InventoryID; intran.SubItemID = poreceiptline.Item1.SubItemID; intran.SiteID = poreceiptline.Item1.SiteID; intran.BAccountID = isLCTran ? aTran.VendorID : poreceiptline.Item1.VendorID; intran.BranchID = poreceiptline.BranchID; if (isDropShip && intran.SiteID != null) { INSite invSite = PXSelect <INSite, Where <INSite.siteID, Equal <Required <POReceiptLine.siteID> > > > .Select(inGraph, intran.SiteID); if (invSite.DropShipLocationID == null) { throw new PXException(SO.Messages.NoDropShipLocation, invSite.SiteCD); } intran.LocationID = invSite.DropShipLocationID; } else { intran.LocationID = poreceiptline.Item1.LocationID ?? origtran.LocationID; } intran.LotSerialNbr = poreceiptline.Item1.LotSerialNbr; intran.POReceiptType = poreceiptline.Item1.ReceiptType; intran.POReceiptNbr = poreceiptline.Item1.ReceiptNbr; intran.POReceiptLineNbr = poreceiptline.Item1.LineNbr; //tran.Qty = poreceiptline.ReceiptQty; intran.TranDesc = isLCTran ? aTran.Descr : poreceiptline.Item1.TranDesc; //tran.UnitCost = PXDBPriceCostAttribute.Round(inGraph.transactions.Cache, (decimal)(poreceiptline.ExtCost / poreceiptline.ReceiptQty)); intran.TranCost = poreceiptline.Item2; intran.ReasonCode = ReasonCode; if (origtran != null && origtran.DocType == INDocType.Issue) { intran.ARDocType = origtran.ARDocType; intran.ARRefNbr = origtran.ARRefNbr; intran.ARLineNbr = origtran.ARLineNbr; } if (!isDropShip) { intran.OrigTranType = origtran.DocType; intran.OrigRefNbr = origtran.RefNbr; } int?acctID = null; int?subID = null; if (isLCTran) { intran.AcctID = aLCCode.LCAccrualAcct; intran.SubID = aLCCode.LCAccrualSub; GetLCVarianceAccountSub(ref acctID, ref subID, inGraph, poreceiptline.Item1); } else { //Set AcctID and SubID = POAccrual Acct/Sub from orig. INTran if (origtran != null) { intran.AcctID = origtran.AcctID; intran.SubID = origtran.SubID; } else if (isDropShip) { intran.AcctID = poreceiptline.Item1.POAccrualAcctID; intran.SubID = poreceiptline.Item1.POAccrualSubID; } ReasonCode reasonCode = PXSelect <ReasonCode, Where <ReasonCode.reasonCodeID, Equal <Required <ReasonCode.reasonCodeID> > > > .Select(inGraph, ReasonCode); if (reasonCode == null) { throw new PXException(AP.Messages.ReasonCodeCannotNotFound, ReasonCode); } AP.APReleaseProcess.GetPPVAccountSub(ref acctID, ref subID, inGraph, poreceiptline.Item1, reasonCode); } intran.COGSAcctID = acctID; intran.COGSSubID = subID; intran = inGraph.transactions.Insert(intran); } }
protected virtual void CreateCostAjustment(INAdjustmentEntry inGraph, LandedCostCode aLCCode, LandedCostTran aTran, List <LandedCostHelper.POReceiptLineAdjustment> aAllocatedLines) { inGraph.Clear(); inGraph.FieldVerifying.AddHandler <INTran.inventoryID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); inGraph.FieldVerifying.AddHandler <INTran.origRefNbr>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); inGraph.insetup.Current.RequireControlTotal = false; inGraph.insetup.Current.HoldEntry = false; INRegister newdoc = new INRegister(); newdoc.DocType = INDocType.Adjustment; newdoc.OrigModule = BatchModule.PO; newdoc.SiteID = null; newdoc.TranDate = aTran.InvoiceDate; inGraph.adjustment.Insert(newdoc); CreateAdjustmentTran(inGraph, aAllocatedLines, aLCCode, aTran, aLCCode.ReasonCode); }
public virtual void ReleaseLCTrans(IEnumerable <LandedCostTran> aTranSet, DocumentList <INRegister> aINCreated, DocumentList <APInvoice> aAPCreated) { Dictionary <int, APInvoiceEntry> apGraphs = new Dictionary <int, APInvoiceEntry>(); Dictionary <int, INAdjustmentEntry> inGraphs = new Dictionary <int, INAdjustmentEntry>(); Dictionary <int, int> combinations = new Dictionary <int, int>(); List <APRegister> forReleaseAP = new List <APRegister>(); List <INRegister> forReleaseIN = new List <INRegister>(); DocumentList <APInvoice> apDocuments = new DocumentList <APInvoice>(this); POSetup poSetupR = this.poSetup.Select(); bool autoReleaseIN = poSetupR.AutoReleaseLCIN.Value; bool autoReleaseAP = poSetupR.AutoReleaseAP.Value; bool noApplicableItems = false; bool noApplicableTransfers = false; foreach (LandedCostTran iTran in aTranSet) { LandedCostCode lcCode = PXSelect <LandedCostCode, Where <LandedCostCode.landedCostCodeID, Equal <Required <LandedCostCode.landedCostCodeID> > > > .Select(this, iTran.LandedCostCodeID); if ((string.IsNullOrEmpty(iTran.APDocType) || string.IsNullOrEmpty(iTran.APRefNbr)) && iTran.PostponeAP == false) { APInvoiceEntry apGraph = null; foreach (KeyValuePair <int, APInvoiceEntry> iGraph in apGraphs) { APInvoice apDoc = iGraph.Value.Document.Current; string terms = String.IsNullOrEmpty(iTran.TermsID) ? lcCode.TermsID : iTran.TermsID; if (apDoc.VendorID == iTran.VendorID && apDoc.VendorLocationID == iTran.VendorLocationID && apDoc.InvoiceNbr == iTran.InvoiceNbr && apDoc.CuryID == iTran.CuryID && apDoc.DocDate == iTran.InvoiceDate && apDoc.TermsID == terms && (apDoc.DocType == AP.APDocType.Invoice && iTran.CuryLCAmount > Decimal.Zero)) { combinations.Add(iTran.LCTranID.Value, iGraph.Key); apGraph = iGraph.Value; } } if (apGraph == null) { apGraph = PXGraph.CreateInstance <APInvoiceEntry>(); if (autoReleaseAP) { apGraph.APSetup.Current.RequireControlTotal = false; apGraph.APSetup.Current.RequireControlTaxTotal = false; apGraph.APSetup.Current.HoldEntry = false; } apGraphs[iTran.LCTranID.Value] = apGraph; } apGraph.InvoiceLandedCost(iTran, null, false); apDocuments.Add(apGraph.Document.Current); } if (lcCode.AllocationMethod != LandedCostAllocationMethod.None) { List <POReceiptLine> receiptLines = new List <POReceiptLine>(); List <LandedCostTranSplit> lcTranSplits = new List <LandedCostTranSplit>(); GetReceiptLinesToAllocate(receiptLines, lcTranSplits, iTran); var lch = new LandedCostHelper(this, false); List <LandedCostHelper.POReceiptLineAdjustment> result = lch.AllocateLCOverRCTLines(receiptLines, lcCode, iTran, lcTranSplits); if (result.Count > 0) { if (result.Count == 1 && !result[0].Item1.InventoryID.HasValue) { noApplicableTransfers = !lch.HasApplicableTransfers; noApplicableItems = true; //Skip Cost adjustment creation; } else { INAdjustmentEntry inGraph = PXGraph.CreateInstance <INAdjustmentEntry>(); if (autoReleaseIN) { inGraph.insetup.Current.RequireControlTotal = false; inGraph.insetup.Current.HoldEntry = false; } CreateCostAjustment(inGraph, lcCode, iTran, result); inGraphs[iTran.LCTranID.Value] = inGraph; } } } } using (PXConnectionScope cs = new PXConnectionScope()) { using (PXTransactionScope ts = new PXTransactionScope()) { foreach (LandedCostTran iTran in aTranSet) { bool needUpdate = false; LandedCostTran tran = this.landedCostTrans.Select(iTran.LCTranID); if (apGraphs.ContainsKey(tran.LCTranID.Value)) { APInvoiceEntry apGraph = apGraphs[iTran.LCTranID.Value]; apGraph.Save.Press(); tran.APDocType = apGraph.Document.Current.DocType; tran.APRefNbr = apGraph.Document.Current.RefNbr; if (!tran.APCuryInfoID.HasValue) { tran.APCuryInfoID = apGraph.Document.Current.CuryInfoID; } tran.Processed = true; if (apGraph.Document.Current.Hold != true) { forReleaseAP.Add(apGraph.Document.Current); } if (aAPCreated != null) { aAPCreated.Add(apGraph.Document.Current); } needUpdate = true; } else if (combinations.ContainsKey(tran.LCTranID.Value)) { //Its already saved at this point APInvoiceEntry apGraph = apGraphs[combinations[tran.LCTranID.Value]]; tran.APDocType = apGraph.Document.Current.DocType; tran.APRefNbr = apGraph.Document.Current.RefNbr; if (!tran.APCuryInfoID.HasValue) { tran.APCuryInfoID = apGraph.Document.Current.CuryInfoID; } tran.Processed = true; needUpdate = true; } if (inGraphs.ContainsKey(tran.LCTranID.Value)) { INAdjustmentEntry inGraph = inGraphs[iTran.LCTranID.Value]; inGraph.Save.Press(); tran.INDocType = inGraph.adjustment.Current.DocType; tran.INRefNbr = inGraph.adjustment.Current.RefNbr; tran.Processed = true; forReleaseIN.Add(inGraph.adjustment.Current); if (aINCreated != null) { aINCreated.Add(inGraph.adjustment.Current); } needUpdate = true; } if (!needUpdate && tran.PostponeAP == true) { LandedCostCode lcCode = PXSelect <LandedCostCode, Where <LandedCostCode.landedCostCodeID, Equal <Required <LandedCostCode.landedCostCodeID> > > > .Select(this, iTran.LandedCostCodeID); if (lcCode.AllocationMethod == LandedCostAllocationMethod.None) { tran.Processed = true; needUpdate = true; //This combination needs no processing here but must be updated } } if (needUpdate) { LandedCostTran copy = (LandedCostTran)this.landedCostTrans.Cache.CreateCopy(tran); tran = this.landedCostTrans.Update(copy); } } this.Actions.PressSave(); ts.Complete(); } } if (noApplicableTransfers == true) { throw new NoApplicableSourceException(Messages.LandedCostCannotBeDistributed); } if (noApplicableItems == true) { throw new NoApplicableSourceException(Messages.LandedCostAmountRemainderCannotBeDistributedMultyLines); } if (autoReleaseAP) { if (forReleaseAP.Count > 0) { APDocumentRelease.ReleaseDoc(forReleaseAP, true); } } if (autoReleaseIN) { if (forReleaseIN.Count > 0) { INDocumentRelease.ReleaseDoc(forReleaseIN, false); } } }
public static List <INCostAdjustmentInfo> AllocateOverRCTLines(IEnumerable <POReceiptLine> aLines, PXCache aCache, LandedCostCode aLCCode, LandedCostTran aTran, IEnumerable <LandedCostTranSplit> aSplits) { List <INCostAdjustmentInfo> result = new List <INCostAdjustmentInfo>(); Decimal toDistribute = aTran.LCAmount.Value; Decimal baseTotal = decimal.Zero; int distributeCount = 0; foreach (POReceiptLine iDet in aLines) { if (LandedCostUtils.IsApplicable(aTran, aSplits, aLCCode, iDet)) { baseTotal += LandedCostUtils.GetBaseValue(aLCCode, iDet); distributeCount++; } } Decimal leftToDistribute = toDistribute; INCostAdjustmentInfo last = null; foreach (POReceiptLine iDet in aLines) { if (LandedCostUtils.IsApplicable(aTran, aSplits, aLCCode, iDet)) { decimal shareAmt = Decimal.Zero; if (distributeCount > 1) { shareAmt = LandedCostUtils.CalcAllocationValue(aLCCode, iDet, baseTotal, toDistribute); shareAmt = PXDBCurrencyAttribute.BaseRound(aCache.Graph, shareAmt); } else { shareAmt = toDistribute; } if (shareAmt != Decimal.Zero) { leftToDistribute -= shareAmt; INCostAdjustmentInfo newLine = new INCostAdjustmentInfo(iDet); //POReceiptLine newLine = (POReceiptLine)aCache.CreateCopy(iDet); //newLine.CuryExtCost = shareAmt; //newLine.ExtCost = shareAmt; newLine.AdjustmentAmount = shareAmt; if (last == null || Math.Abs(last.AdjustmentAmount) < Math.Abs(newLine.AdjustmentAmount)) { last = newLine; } result.Add(newLine); } } } if (leftToDistribute != Decimal.Zero) { if (last == null) { last = new INCostAdjustmentInfo(); last.AdjustmentAmount = leftToDistribute; result.Add(last); } else { last.AdjustmentAmount += leftToDistribute; } } return(result); }
protected static void CreateCostAjustment(INAdjustmentEntry inGraph, LandedCostCode aLCCode, LandedCostTran aTran, List <LandedCostUtils.INCostAdjustmentInfo> aAllocatedLines) { inGraph.Clear(); inGraph.insetup.Current.RequireControlTotal = false; inGraph.insetup.Current.HoldEntry = false; INRegister newdoc = new INRegister(); newdoc.DocType = INDocType.Adjustment; newdoc.OrigModule = BatchModule.PO; newdoc.SiteID = null; newdoc.TranDate = aTran.InvoiceDate; inGraph.adjustment.Insert(newdoc); //Find IN Receipt (released??) for the LCTran's POReceipt foreach (LandedCostUtils.INCostAdjustmentInfo it in aAllocatedLines) { PXResult <INRegister, INTran> res = (PXResult <INRegister, INTran>) PXSelectJoin <INRegister, InnerJoin <INTran, On <INTran.docType, Equal <INRegister.docType>, And <INTran.refNbr, Equal <INRegister.refNbr> > > >, Where <INRegister.docType, NotEqual <INDocType.adjustment>, And <INTran.pOReceiptNbr, Equal <Required <INTran.pOReceiptNbr> > > > > .SelectWindowed(inGraph, 0, 1, it.POReceiptNbr); INRegister inReceipt = new INRegister(); if (res == null || (inReceipt = res).Released != true) { throw new PXException(Messages.INReceiptMustBeReleasedBeforeLCProcessing, inReceipt.RefNbr, aTran.POReceiptNbr); } INTran origtran = res; INTran tran = new INTran(); if (it.IsStockItem) { tran.TranType = INTranType.ReceiptCostAdjustment; } else { //Landed cost for non-stock items are handled in special way in the inventory. //They should create a GL Batch, but for convinience and unforminty this functionality is placed into IN module //Review this part when the functionality is implemented in IN module tran.TranType = INTranType.Adjustment; tran.InvtMult = 0; } tran.InventoryID = it.InventoryID; tran.SubItemID = it.SubItemID; tran.SiteID = it.SiteID; tran.BAccountID = aTran.VendorID; tran.LocationID = it.LocationID ?? origtran.LocationID; tran.LotSerialNbr = it.LotSerialNbr; tran.POReceiptNbr = it.POReceiptNbr; tran.POReceiptLineNbr = it.POReceiptLineNbr; tran.ARDocType = (origtran.DocType == INDocType.Issue) ? origtran.ARDocType : null; tran.ARRefNbr = (origtran.DocType == INDocType.Issue) ? origtran.ARRefNbr : null; tran.ARLineNbr = (origtran.DocType == INDocType.Issue) ? origtran.ARLineNbr : null; //tran.Qty = it.ReceiptQty; tran.TranDesc = aTran.Descr; //tran.UnitCost = PXDBPriceCostAttribute.Round(inGraph.transactions.Cache, (decimal)(it.ExtCost / it.ReceiptQty)); tran.TranCost = it.AdjustmentAmount; tran.ReasonCode = aLCCode.ReasonCode; tran.OrigTranType = inReceipt.DocType; tran.OrigRefNbr = inReceipt.RefNbr; tran.AcctID = aLCCode.LCAccrualAcct; tran.SubID = aLCCode.LCAccrualSub; int?acctID = null; int?subID = null; GetLCVarianceAccountSub(ref acctID, ref subID, inGraph, it); tran.COGSAcctID = acctID; tran.COGSSubID = subID; tran = inGraph.transactions.Insert(tran); } }