public async Task <ActionResult> fetchPrice(long id, [FromQuery] string currency, [FromQuery] string area) { try { FetchCustomizedProductPriceModelView fetchPrice = new FetchCustomizedProductPriceModelView(); fetchPrice.id = id; fetchPrice.currency = currency; fetchPrice.area = area; CustomizedProductFinalPriceModelView customizedProductPrice = await new core.application.CustomizedProductController().calculateCustomizedProductPrice(fetchPrice, clientFactory); return(Ok(customizedProductPrice)); } catch (ResourceNotFoundException e) { return(NotFound(new SimpleJSONMessageService(e.Message))); } catch (ArgumentException e) { return(BadRequest(new SimpleJSONMessageService(e.Message))); } catch (Exception) { return(StatusCode(500, new SimpleJSONMessageService(UNEXPECTED_ERROR))); } }
/// <summary> /// Calculates the final price of a customized product /// </summary> /// <param name="customizedProductTotalPriceModelView">ModelView containing the detailed info about the customized product's price</param> /// <param name="fetchCustomizedProductPriceModelView">ModelView containing information about currency/area conversion</param> /// <returns>PriceModelView containing the final price of a customized product</returns> private static PriceModelView calculateFinalPriceOfCustomizedProduct(CustomizedProductFinalPriceModelView customizedProductTotalPriceModelView, FetchCustomizedProductPriceModelView fetchCustomizedProductPriceModelView) { PriceModelView finalPriceModelView = new PriceModelView(); double finalPrice = 0; foreach (CustomizedProductPriceModelView customizedProductPrice in customizedProductTotalPriceModelView.customizedProducts) { finalPrice += customizedProductPrice.price.value; } finalPriceModelView.value = finalPrice; if (fetchCustomizedProductPriceModelView.currency != null && fetchCustomizedProductPriceModelView.area != null) { finalPriceModelView.currency = fetchCustomizedProductPriceModelView.currency; } else { finalPriceModelView.currency = CurrencyPerAreaConversionService.getBaseCurrency(); } return(finalPriceModelView); }
/// <summary> /// Calculates the price /// </summary> /// <param name="fetchCustomizedProductPrice">FetchCustomizedProductModelView with the necessary information to fetch the customized product's price</param> /// <returns>CustomizedProductPriceModelView with the price of the customized product</returns> public static async Task <CustomizedProductFinalPriceModelView> calculatePrice(FetchCustomizedProductPriceModelView fetchCustomizedProductPrice, IHttpClientFactory clientFactory) { if (fetchCustomizedProductPrice.currency != null) { CurrenciesService.checkCurrencySupport(fetchCustomizedProductPrice.currency); } if (fetchCustomizedProductPrice.area != null) { AreasService.checkAreaSupport(fetchCustomizedProductPrice.area); } CustomizedProduct customizedProduct = PersistenceContext.repositories().createCustomizedProductRepository().find(fetchCustomizedProductPrice.id); if (customizedProduct == null) { throw new ResourceNotFoundException ( string.Format(CUSTOMIZED_PRODUCT_NOT_FOUND, fetchCustomizedProductPrice.id) ); } if (customizedProduct.status == CustomizationStatus.PENDING) { throw new ArgumentException ( CUSTOMIZED_PRODUCT_NOT_FINISHED ); } //TODO Should the fetching of prices of customized products that aren't base products be allowed? MaterialPriceTableRepository materialPriceTableRepository = PersistenceContext.repositories().createMaterialPriceTableRepository(); FinishPriceTableRepository finishPriceTableRepository = PersistenceContext.repositories().createFinishPriceTableRepository(); CustomizedProductFinalPriceModelView customizedProductTotalPrice = new CustomizedProductFinalPriceModelView(); List <CustomizedProductPriceModelView> customizedProductPriceList = new List <CustomizedProductPriceModelView>(); MaterialPriceTableEntry materialPriceTableEntry = getCurrentMaterialPrice(materialPriceTableRepository, customizedProduct.customizedMaterial.material.Id); FinishPriceTableEntry finishPriceTableEntry = null; if (customizedProduct.customizedMaterial.finish != null) { finishPriceTableEntry = getCurrentFinishPrice(finishPriceTableRepository, customizedProduct.customizedMaterial.material.Finishes.Where(f => f.Equals(customizedProduct.customizedMaterial.finish)).SingleOrDefault().Id); } //TODO What should we do about doors? //TODO Should we consider that every component has a box geometry? //!For now the surface area of every product is being calculated as if it the product was a SIX FACED RIGHT RECTANGULAR PRISM CustomizedProductPriceModelView parentCustomizedProductModelView = await buildCustomizedProductPriceModelView(customizedProduct, fetchCustomizedProductPrice, materialPriceTableEntry, finishPriceTableEntry, clientFactory); customizedProductPriceList.Add(parentCustomizedProductModelView); if (customizedProduct.hasCustomizedProducts()) { List <CustomizedProductPriceModelView> childCustomizedProducts = new List <CustomizedProductPriceModelView>(); customizedProductPriceList.AddRange(await calculatePricesOfChildCustomizedProducts(childCustomizedProducts, customizedProduct, fetchCustomizedProductPrice, materialPriceTableRepository, finishPriceTableRepository, clientFactory)); } customizedProductTotalPrice.customizedProducts = customizedProductPriceList; customizedProductTotalPrice.finalPrice = calculateFinalPriceOfCustomizedProduct(customizedProductTotalPrice, fetchCustomizedProductPrice); return(customizedProductTotalPrice); }