using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using gehGassi.Common; using gehGassi.Core.Interfaces; using gehGassi.Domain.Shop; using Microsoft.Extensions.Options; namespace gehGassi.Core.Services { /// /// Service der die Verwaltung von Steuern realisiert /// public class TaxRateService : ServiceBase, ITaxRateService { private readonly IOptions _vatValidationOptions; private readonly IRepository _namesRepository; /// /// Erstellt eine Instanz /// /// Instanz eines IUnitOfWork /// Instanz von VatValidationSettings /// Instanz von ShopSettings public TaxRateService(IUnitOfWork unitOfWork, IOptions vatValidationOptions) : base(unitOfWork) { _vatValidationOptions = vatValidationOptions; _namesRepository = unitOfWork.GetRepository(); } /// /// Gibt eine gefilterte Liste von Steuern zurück /// /// Filterbegriff der in bestimmten Feldern gesucht wird /// List betroffener Steuern public IQueryable Filter(string filter) { return Repository.Query(c => c.Title.Contains(filter)); } /// /// Erstellen einer Steuer /// /// Steuer public TaxRate Create() { var item = new TaxRate { Value = 0 }; return item; } /// /// Gibt eine gefilterte Liste von Steuern zurück. Sucht nur im Titel /// /// Filterbegriff der in bestimmten Feldern gesucht wird /// List betroffener Hundeausführern public async Task> SearchAsync(string filter) { return (await Repository.FindAsync(c => c.Title.Contains(filter)).ConfigureAwait(false)).ToList(); } /// /// Gibt eine gefilterte Liste von Steuern mit Namen zurück in einer gewählten Sprache /// /// Filterbegriff der in bestimmten Feldern gesucht wird /// Gewünschte Sprache /// Fallback Sprache falls keine Übersetzung vorhanden /// Liste betroffener Steuern public IQueryable FilterWithNames(string filter, string language, string fallback) { language = language.ToUpperInvariant(); fallback = fallback.ToUpperInvariant(); var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_TaxRatesWithNames({0},{1})", c => c.Title.Contains(filter) || c.Name.Contains(filter), language, fallback); return baseQuery; } /// /// Prüft ob für ein Land schon eine Steuer mit einem Wert existiert /// /// Land ISO2 /// Steuer-Wert /// true wenn existiert, false sonst public async Task ExistsAsync(string countryIso, decimal value) { var existing = await Repository.FirstOrDefaultAsync(c => c.CountryIso == countryIso && c.Value == value); return existing != null; } /// /// Zurücksetzen wird für Versandkosten verwendet /// /// Id die ausgenommen werden soll /// Task public async Task ResetShipmentAsync(int excludeId) { var items = await Repository.FindAsync(c => c.Id != excludeId && c.UseForShipment).ConfigureAwait(false); foreach (var taxRate in items) { taxRate.UseForShipment = false; } } /// /// Gibt den Steuersatz für Versandkosten zurück /// /// Versandkosten-Steuersatz in Prozent public async Task GetForShipmentAsync() { var result = 0m; var item = await Repository.FirstOrDefaultAsync(c => c.UseForShipment).ConfigureAwait(false); if(item != null) result = item.Value; return result; } /// /// Berechnen eines Brutto-Wertes für einen Preis /// /// Preis netto /// Id der Steuerstufe /// QuellLand des Shops /// Zielland /// Brutto-Wert public async Task CalculateGrossAsync(decimal value, int taxRateId, string sourceCountry, string targetCountry) { var result = new TaxGrossResult() { Value = 0, TaxRate = 0, TaxValue = 0 }; var taxRate = await Repository.FirstOrDefaultAsync(c => c.Id == taxRateId); if (taxRate != null) { var isEuCountry = _vatValidationOptions.Value.Countries.Contains(targetCountry); var isNoTaxCountry = _vatValidationOptions.Value.NoTaxCountries.Contains(targetCountry); var isSameAsSource = sourceCountry == targetCountry; if ((!isEuCountry && !isNoTaxCountry) || isSameAsSource) { result.TaxRate = taxRate.Value; result.TaxValue = Math.Round(((value * taxRate.Value) / 100),2,MidpointRounding.AwayFromZero); result.Value = Math.Round(value + ((value * taxRate.Value) / 100),2,MidpointRounding.AwayFromZero); } } return result; } /// /// Berechnen eines Brutto-Wertes für Versandkosten /// /// Preis netto /// QuellLand des Shops /// Zielland /// Brutto-Wert public async Task CalculateShipmentGrossAsync(decimal value, string sourceCountry, string targetCountry) { var result = new TaxGrossResult() { Value = 0, TaxRate = 0, TaxValue = 0 }; var taxRate = await Repository.FirstOrDefaultAsync(c => c.UseForShipment); if (taxRate != null) { var isEuCountry = _vatValidationOptions.Value.Countries.Contains(targetCountry); var isNoTaxCountry = _vatValidationOptions.Value.NoTaxCountries.Contains(targetCountry); var isSameAsSource = sourceCountry == targetCountry; if ((!isEuCountry && !isNoTaxCountry) || isSameAsSource) { result.TaxRate = taxRate.Value; result.TaxValue = Math.Round(((value * taxRate.Value) / 100), 2, MidpointRounding.AwayFromZero); result.Value = Math.Round(value + ((value * taxRate.Value) / 100), 2, MidpointRounding.AwayFromZero); //var result = value + ((value * taxRate.Value) / 100); //return Math.Round(result, 2, MidpointRounding.AwayFromZero); } } return result; } } }