/// <summary> /// Determine the PriceCode value depending of PriceType of the calculated price. /// </summary> private static void DeterminePriceCode(PXCache cache, ref SalesPriceSet salesPriceSet, int?inventoryID) { if (salesPriceSet.PriceType == ID.PriceType.CUSTOMER) { List <object> args = new List <object>(); PXView appointmentRecordsView; BqlCommand customerBql = new Select <Customer, Where < Customer.bAccountID, Equal <Required <Customer.bAccountID> > > >(); appointmentRecordsView = new PXView(cache.Graph, true, customerBql); args.Add(salesPriceSet.CustomerID); Customer customerRow = (Customer)appointmentRecordsView.SelectSingle(args.ToArray()); salesPriceSet.PriceCode = customerRow.AcctCD; } else if (salesPriceSet.PriceType == ID.PriceType.BASE || salesPriceSet.PriceType == ID.PriceType.DEFAULT) { salesPriceSet.PriceCode = string.Empty; } }
/// <summary> /// Calculates the price retrieving the correct price depending of the price set for that item. /// </summary> public static SalesPriceSet CalculateSalesPriceWithCustomerContract( PXCache cache, int?serviceContractID, int?billServiceContractID, int?billContractPeriodID, int?customerID, int?customerLocationID, bool?lineRelatedToContract, int?inventoryID, int?siteID, decimal?quantity, string uom, DateTime date, decimal?currentUnitPrice, bool alwaysFromBaseCurrency, CurrencyInfo currencyInfo, bool catchSalesPriceException) { decimal?salesPrice; // It is necessary to set at midnight the time because the Effective Date nad Expiration Date are stored at midnight date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0); if (currencyInfo == null) { // Get the currency info in the company to retrieve the prices currencyInfo = new CurrencyInfo(); Company companyRow = PXSelect <Company> .Select(cache.Graph); currencyInfo.BaseCuryID = companyRow.BaseCuryID; currencyInfo.CuryID = companyRow.BaseCuryID; currencyInfo.CuryRate = 1; currencyInfo.CuryMultDiv = CuryMultDivType.Mult; currencyInfo.CuryEffDate = cache.Graph.Accessinfo.BusinessDate; } // If the item has a price from the Contract then retrieves that price salesPrice = GetCustomerContractPrice(cache, serviceContractID, billServiceContractID, billContractPeriodID, lineRelatedToContract, inventoryID); SalesPriceSet salesPriceSet; if (salesPrice == null) { // Calculates/Retrieves the price depending of the price set into Acumatica salesPriceSet = FSPriceManagement.CalculateSalesPrice(cache, customerID, customerLocationID, inventoryID, siteID, currencyInfo, quantity, uom, date, currentUnitPrice, alwaysFromBaseCurrency, catchSalesPriceException); DeterminePriceCode(cache, ref salesPriceSet, inventoryID); } else { salesPriceSet = new SalesPriceSet(string.Empty, salesPrice, ID.PriceType.CONTRACT, customerID, ID.PriceErrorCode.OK); } return(salesPriceSet); }
/// <summary> /// Calculates/Retrieves the price for an item depending on the price set for it. /// </summary> private static SalesPriceSet CalculateSalesPrice(PXCache cache, int?customerID, int?customerLocationID, int?inventoryID, int?siteID, CurrencyInfo currencyinfo, decimal?quantity, string uom, DateTime date, decimal?currentUnitPrice, bool alwaysFromBaseCurrency, bool catchSalesPriceException) { string custPriceClass = ARPriceClass.EmptyPriceClass; string errorCode = ID.PriceErrorCode.OK; // Check if it exists a price by customerID string priceType = CheckPriceByPriceType(cache, custPriceClass, customerID, inventoryID, currencyinfo.BaseCuryID, alwaysFromBaseCurrency ? currencyinfo.BaseCuryID : currencyinfo.CuryID, Math.Abs(quantity ?? 0m), uom, date, ID.PriceType.CUSTOMER, ref errorCode); // If it does not exist a price by customerID, then verify if it exists at least a Customer Price Class if (priceType == null) { custPriceClass = SingleFSPriceManagement.DetermineCustomerPriceClass(cache, customerID, customerLocationID, inventoryID, currencyinfo, quantity, uom, date, alwaysFromBaseCurrency); // If it does not exist a price by Customer Price Class for the item, then try to verify the BASE price or DEFAULT price if (custPriceClass == ARPriceClass.EmptyPriceClass) { priceType = CheckPriceByPriceType(cache, custPriceClass, customerID, inventoryID, currencyinfo.BaseCuryID, alwaysFromBaseCurrency ? currencyinfo.BaseCuryID : currencyinfo.CuryID, Math.Abs(quantity ?? 0m), uom, date, ID.PriceType.BASE, ref errorCode); } else { priceType = ID.PriceType.PRICE_CLASS; } } decimal?price = null; try { if (alwaysFromBaseCurrency == true) { price = ARSalesPriceMaint.CalculateSalesPrice(cache, custPriceClass, customerID, inventoryID, currencyinfo, quantity, uom, date, alwaysFromBaseCurrency: true); } else { price = ARSalesPriceMaint.CalculateSalesPrice(cache, custPriceClass, customerID, inventoryID, siteID, currencyinfo, uom, quantity, date, currentUnitPrice); } } catch (PXUnitConversionException exception) { if (catchSalesPriceException == true) { return(new SalesPriceSet(custPriceClass, price, priceType, customerID, ID.PriceErrorCode.UOM_INCONSISTENCY)); } else { throw exception; } } SalesPriceSet salesPriceSet = new SalesPriceSet(custPriceClass, price, priceType, customerID, errorCode); return(salesPriceSet); }
public static void X_CuryUnitPrice_FieldDefaulting <DAC, CuryUnitPrice>( PXCache cache, PXFieldDefaultingEventArgs e, decimal?qty, DateTime?docDate, FSServiceOrder fsServiceOrderRow, FSAppointment fsAppointmentRow, CurrencyInfo currencyInfo) where DAC : class, IBqlTable, IFSSODetBase, new() where CuryUnitPrice : class, IBqlField { if (e.Row == null) { return; } var row = (DAC)e.Row; // TODO: AC-97482 // FSSODet does not have PriceType nor PriceCode. FSAppointmentDet fsAppointmentDetRow = null; Type dacType = typeof(DAC); if (dacType == typeof(FSAppointmentDet) || dacType == typeof(FSAppointmentDetService) || dacType == typeof(FSAppointmentDetPart) || dacType == typeof(FSAppointmentInventoryItem)) { fsAppointmentDetRow = (FSAppointmentDet)e.Row; } if (row.InventoryID == null || row.UOM == null || (row.BillingRule == ID.BillingRule.NONE && row.ManualPrice != true)) { // Special cases with price 0 PXUIFieldAttribute.SetWarning <CuryUnitPrice>(cache, row, null); e.NewValue = 0m; // TODO: AC-97482 if (fsAppointmentDetRow != null) { fsAppointmentDetRow.PriceType = null; fsAppointmentDetRow.PriceCode = null; } } else if (row.ManualPrice != true && !cache.Graph.IsCopyPasteContext) { SalesPriceSet salesPriceSet = FSPriceManagement.CalculateSalesPriceWithCustomerContract( cache, fsServiceOrderRow.ServiceContractID, fsAppointmentRow != null ? fsAppointmentRow.BillServiceContractID : fsServiceOrderRow.BillServiceContractID, fsAppointmentRow != null ? fsAppointmentRow.BillContractPeriodID : fsServiceOrderRow.BillContractPeriodID, fsServiceOrderRow.BillCustomerID, fsServiceOrderRow.BillLocationID, row.ContractRelated, row.InventoryID, row.SiteID, qty, row.UOM, (DateTime)(docDate ?? cache.Graph.Accessinfo.BusinessDate), row.CuryUnitPrice, alwaysFromBaseCurrency: false, currencyInfo: currencyInfo.GetCM(), catchSalesPriceException: false); if (salesPriceSet.ErrorCode == ID.PriceErrorCode.UOM_INCONSISTENCY) { InventoryItem inventoryItemRow = SharedFunctions.GetInventoryItemRow(cache.Graph, row.InventoryID); throw new PXException(PXMessages.LocalizeFormat(TX.Error.INVENTORY_ITEM_UOM_INCONSISTENCY, inventoryItemRow.InventoryCD), PXErrorLevel.Error); } e.NewValue = salesPriceSet.Price ?? 0m; if (fsAppointmentDetRow != null) { // These fields are just report fields so they wouldn't have associated events // and therefore they don't need be assigned with SetValueExt. fsAppointmentDetRow.PriceType = salesPriceSet.PriceType; fsAppointmentDetRow.PriceCode = salesPriceSet.PriceCode; } ARSalesPriceMaint.CheckNewUnitPrice <DAC, CuryUnitPrice>(cache, row, salesPriceSet.Price); } else { e.NewValue = row.CuryUnitPrice ?? 0m; e.Cancel = row.CuryUnitPrice != null; return; } }