private async Task PayFor(Appointment appointment) { var availablePayments = await _checkoutService.GetAppointmentPaymentMethodsAsync(appointment.Id); var summary = await _priceCalculationService.CalculatePriceAsync(appointment); var paymentMethod = summary.Total == decimal.Zero ? availablePayments.SingleOrDefault(payment => payment.Type == PaymentType.FreePayment) : GetAutoPaymentMethod(availablePayments); if (paymentMethod is null) { _logger.LogCritical( "No auto-payment method found for patient {patientId}, appointment {appointmentId}", appointment.Patient.Id, appointment.Id); return; } _logger.LogDebug("Found payment-method {paymentMethod}", paymentMethod.Type); var paymentInfo = new ProcessPaymentInfo(paymentMethod); try { var transaction = await _checkoutService.ProcessAppointmentPaymentAsync(appointment, paymentInfo); _logger.LogInformation("Auto-payment is completed with {transactionId}", transaction.Id); } catch (Exception exception) { _logger.LogError(exception, "Auto-payment Failed to process payment."); } }
/// <summary> /// Gets the base price info for a product. /// </summary> /// <param name="priceCalculationService">Price calculation service.</param> /// <param name="product">The product to get the base price info for.</param> /// <param name="options">Price calculation options. The default options are used if <c>null</c>.</param> /// <returns>Base price info.</returns> public static async Task <string> GetBasePriceInfoAsync(this IPriceCalculationService priceCalculationService, Product product, PriceCalculationOptions options = null) { Guard.NotNull(priceCalculationService, nameof(priceCalculationService)); Guard.NotNull(product, nameof(product)); if (!product.BasePriceHasValue || product.BasePriceAmount == 0) { return(string.Empty); } options ??= priceCalculationService.CreateDefaultOptions(false); var context = new PriceCalculationContext(product, options); var price = await priceCalculationService.CalculatePriceAsync(context); return(priceCalculationService.GetBasePriceInfo(product, price.FinalPrice, options.TargetCurrency)); }
/// <summary> /// Calculates the price adjustments of product attributes, usually <see cref="ProductVariantAttributeValue.PriceAdjustment"/>. /// Typically used to display price adjustments of selected attributes on the cart page. /// The calculated adjustment is always a unit price. /// </summary> /// <param name="priceCalculationService">Price calculation service.</param> /// <param name="product">The product.</param> /// <param name="selection">Attribute selection. If <c>null</c> then the price adjustments of all attributes of <paramref name="product"/> are determined.</param> /// <param name="quantity"> /// The product quantity. May have impact on the price, e.g. if tier prices are applied to price adjustments. /// Note that the calculated price is always the unit price. /// </param> /// <param name="options">Price calculation options. The default options are used if <c>null</c>.</param> /// <returns>Price adjustments of selected attributes. Key: <see cref="ProductVariantAttributeValue.Id"/>, value: attribute price adjustment.</returns> public static async Task <IDictionary <int, CalculatedPriceAdjustment> > CalculateAttributePriceAdjustmentsAsync( this IPriceCalculationService priceCalculationService, Product product, ProductVariantAttributeSelection selection = null, int quantity = 1, PriceCalculationOptions options = null) { Guard.NotNull(priceCalculationService, nameof(priceCalculationService)); options ??= priceCalculationService.CreateDefaultOptions(false); var context = new PriceCalculationContext(product, quantity, options); context.Options.DeterminePriceAdjustments = true; context.Options.TaxFormat = null; context.AddSelectedAttributes(selection, product.Id); var price = await priceCalculationService.CalculatePriceAsync(context); return(price.AttributePriceAdjustments.ToDictionarySafe(x => x.AttributeValue.Id)); }