757 lines
34 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gehGassi.Core.Interfaces;
using gehGassi.Domain.Advertisements;
using gehGassi.Domain.Common;
using gehGassi.Domain.Customers;
using gehGassi.Domain.Dogs;
using gehGassi.Domain.Shop;
using Microsoft.EntityFrameworkCore;
namespace gehGassi.Core.Services
{
/// <summary>
/// Service der die Verwaltung von Bestellungen realisiert
/// </summary>
public class OrderService : ServiceBase<Order>, IOrderService
{
private readonly IRepository<OrderItem> _itemRepository;
private readonly IRepository<Customer> _customerRepository;
private readonly IRepository<AppUser> _appUserRepository;
private readonly IRepository<Product> _productRepository;
private readonly IRepository<ProductWithNames> _productNamesRepository;
private readonly IRepository<Listing> _listingRepository;
private readonly IRepository<Banner> _bannerRepository;
private readonly IRepository<Advertisement> _advertisementRepository;
private readonly IRepository<Pin> _pinRepository;
private readonly IRepository<OrderPhysical> _physicalRepository;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
public OrderService(IUnitOfWork unitOfWork) : base(unitOfWork)
{
_itemRepository = unitOfWork.GetRepository<OrderItem>();
_customerRepository = unitOfWork.GetRepository<Customer>();
_appUserRepository = unitOfWork.GetRepository<AppUser>();
_productRepository = unitOfWork.GetRepository<Product>();
_productNamesRepository = unitOfWork.GetRepository<ProductWithNames>();
_listingRepository = unitOfWork.GetRepository<Listing>();
_bannerRepository = unitOfWork.GetRepository<Banner>();
_advertisementRepository = unitOfWork.GetRepository<Advertisement>();
_pinRepository = unitOfWork.GetRepository<Pin>();
_physicalRepository = unitOfWork.GetRepository<OrderPhysical>();
}
/// <summary>
/// Gibt eine gefilterte Liste von Bestellungen zurück
/// </summary>
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>List betroffener Bestellungen</returns>
public IQueryable<Order> Filter(string filter, bool includeDeleted)
{
if (includeDeleted)
return Repository.Query(c => c.CustomerName.Contains(filter) || c.AppUserName.Contains(filter));
else
return Repository.Query(c => c.Deleted == false && (c.CustomerName.Contains(filter) || c.AppUserName.Contains(filter)));
}
/// <summary>
/// Gibt eine gefilterte Liste von Bestellungen für einen Kunden zurück
/// </summary>
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
/// <param name="customerId">Id des Kunden</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>List betroffener Bestellungen</returns>
public IQueryable<Order> FilterByCustomer(string filter, long customerId, bool includeDeleted)
{
if (includeDeleted)
return Repository.Query(c => c.CustomerId == customerId && (c.CustomerName.Contains(filter)));
else
return Repository.Query(c => c.CustomerId == customerId && c.Deleted == false && (c.CustomerName.Contains(filter)));
}
/// <summary>
/// Gibt eine gefilterte Liste von Bestellungen für einen App-User zurück
/// </summary>
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
/// <param name="appUserId">Id des Hundebesitzers</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>List betroffener Bestellungen</returns>
public IQueryable<Order> FilterByAppUser(string filter, string appUserId, bool includeDeleted)
{
if (includeDeleted)
return Repository.Query(c => c.AppUserId == appUserId && (c.AppUserName.Contains(filter) || c.AppUserCompany.Contains(filter)));
else
return Repository.Query(c => c.AppUserId == appUserId && c.Deleted == false && (c.AppUserName.Contains(filter) || c.AppUserCompany.Contains(filter)));
}
/// <summary>
/// Erstellen einer Bestellung
/// </summary>
/// <returns>Bestellung</returns>
public Order Create()
{
var item = new Order
{
UniqueId = Guid.NewGuid(),
Total = 0,
TotalGross = 0,
Shipment = 0,
ShipmentGross = 0,
Created = DateTime.UtcNow,
LastUpdate = DateTime.UtcNow
};
return item;
}
/// <summary>
/// Erstellen einer Bestellung
/// </summary>
/// <param name="cart">Warenkorb</param>
/// <param name="cartItems">Artikel im Warenkorb</param>
/// <param name="paymentType">Zahlungsart</param>
/// <param name="paymentStatus">Status der Zahlung</param>
/// <param name="shipmentType">Art der Zustellung</param>
/// <param name="shipmentStatus">Versandstatus</param>
/// <param name="deliveryAddress">Lieferadresse</param>
/// <param name="billingAddress">Rechnungsadresse</param>
/// <param name="deliveryAddressIsBilling">Lieferadresse ist auch Rechnungsadresse</param>
/// <param name="language">Gewünschte Sprache</param>
/// <param name="fallback">Fallback Sprache</param>
/// <param name="userName">Benutzer der die Bestellung anlegt</param>
/// <returns>Bestellung</returns>
public async Task<Order> CreateAsync(Cart cart, List<CartItem> cartItems, PaymentType paymentType, PaymentStatus paymentStatus, ShipmentType shipmentType, ShipmentStatus shipmentStatus,
OrderAddress deliveryAddress, OrderAddress billingAddress, bool deliveryAddressIsBilling, string language, string fallback, string userName)
{
var order = Create();
order.OrderSource = cart.OrderSource;
order.Number = await GetNextNumberAsync();
order.Counter = await GetNextCounterAsync();
order.Subtotal = cart.Total;
order.SubtotalGross = cart.TotalGross;
order.Shipment = cart.Shipment;
order.ShipmentGross = cart.ShipmentGross;
order.Total = order.Subtotal + order.Shipment;
order.TotalGross = order.SubtotalGross + order.ShipmentGross;
order.OrderStatus = OrderStatus.Pending;
order.PaymentType = paymentType;
order.PaymentStatus = paymentStatus;
order.ShipmentType = shipmentType;
order.ShipmentStatus = shipmentStatus;
order.DeliveryAddress = deliveryAddress;
order.BillingAddress = billingAddress;
order.Comment = string.Empty;
order.TaxRatesJson = cart.TaxRatesJson;
order.DeliveryAddressIsBilling = deliveryAddressIsBilling;
order.Created = DateTime.UtcNow;
order.LastUpdate = DateTime.UtcNow;
order.AcceptTermsAndConditionsDate = DateTime.UtcNow;
order.AcceptGdprDate = DateTime.UtcNow;
order.CustomerId = null;
order.CustomerName = string.Empty;
order.AppUserId = string.Empty;
order.AppUserName = string.Empty;
order.AppUserCompany = string.Empty;
switch (order.OrderSource)
{
case OrderSource.Customer:
var customer = await _customerRepository.GetAsync(cart.CustomerId);
order.CustomerId = customer.Id;
order.CustomerName = customer.Name;
break;
case OrderSource.AppUserDogOwner:
case OrderSource.AppUserDogWalker:
case OrderSource.AppUserBoth:
var dogOwner = await _appUserRepository.GetAsync(cart.AppUserId);
order.AppUserId = dogOwner.Id;
order.AppUserName = $"{dogOwner.FirstName} {dogOwner.LastName}";
order.AppUserCompany = string.Empty;
break;
default:
throw new ArgumentOutOfRangeException();
}
Repository.Add(order);
await CommitAsync(userName);
//Items
foreach (var cartItem in cartItems)
{
var product = await _productRepository.FirstOrDefaultAsync(c => c.Id == cartItem.ProductId);
var orderItem = CreateItem();
orderItem.OrderId = order.Id;
orderItem.ProductId = cartItem.ProductId;
orderItem.ProductCategoryId = product.ProductCategoryId;
orderItem.Name = product.Name;
orderItem.NameDefault = product.Get("Name", fallback);
orderItem.Sku = product.Sku;
orderItem.ProductType = cartItem.ProductType;
orderItem.ItemId = cartItem.ItemId;
orderItem.TaxRateId = product.TaxRateId;
orderItem.IsTaxExempt = product.IsTaxExempt;
orderItem.IsShipEnabled = product.IsShipEnabled;
orderItem.IsFreeShipping = product.IsFreeShipping;
orderItem.AdditionalShippingCharge = product.AdditionalShippingCharge;
orderItem.Quantity = cartItem.Quantity;
orderItem.Price = cartItem.Price;
orderItem.PriceGross = cartItem.PriceGross;
orderItem.Price2 = cartItem.Price2;
orderItem.Price2Gross = cartItem.Price2Gross;
orderItem.Total = cartItem.Total;
orderItem.TotalGross = cartItem.TotalGross;
orderItem.Weight = product.Weight;
orderItem.Length = product.Length;
orderItem.Width = product.Width;
orderItem.Height = product.Height;
orderItem.Created = DateTimeOffset.UtcNow;
orderItem.LastUpdate = DateTimeOffset.UtcNow;
_itemRepository.Add(orderItem);
}
await CommitAsync(userName);
await SetOrderAndPaymentAsync(paymentType, paymentStatus, null, userName, order);
return order;
}
/// <summary>
/// Aktualisieren einer Bestellung
/// </summary>
/// <param name="orderId">Id der Bestellung die aktualisiert werden soll</param>
/// <param name="cart">Warenkorb</param>
/// <param name="cartItems">Artikel im Warenkorb</param>
/// <param name="paymentType">Zahlungsart</param>
/// <param name="paymentStatus">Status der Zahlung</param>
/// <param name="shipmentType">Art der Zustellung</param>
/// <param name="shipmentStatus">Versandstatus</param>
/// <param name="deliveryAddress">Lieferadresse</param>
/// <param name="billingAddress">Rechnungsadresse</param>
/// <param name="deliveryAddressIsBilling">Lieferadresse ist auch Rechnungsadresse</param>
/// <param name="language">Gewünschte Sprache</param>
/// <param name="fallback">Fallback Sprache</param>
/// <param name="userName">Benutzer der die Bestellung anlegt</param>
/// <returns>Bestellung</returns>
public async Task<Order> UpdateAsync(long orderId, Cart cart, List<CartItem> cartItems, PaymentType paymentType, PaymentStatus paymentStatus, ShipmentType shipmentType, ShipmentStatus shipmentStatus,
OrderAddress deliveryAddress, OrderAddress billingAddress, bool deliveryAddressIsBilling, string language, string fallback, string userName)
{
var order = await Repository.GetAsync(orderId);
order.Subtotal = cart.Total;
order.SubtotalGross = cart.TotalGross;
order.Shipment = cart.Shipment;
order.ShipmentGross = cart.ShipmentGross;
order.Total = order.Subtotal + order.Shipment;
order.TotalGross = order.SubtotalGross + order.ShipmentGross;
order.OrderStatus = OrderStatus.Pending;
order.PaymentType = paymentType;
order.PaymentStatus = paymentStatus;
order.ShipmentType = shipmentType;
order.ShipmentStatus = shipmentStatus;
order.BillingAddress.Title = billingAddress.Title;
order.BillingAddress.FirstName = billingAddress.FirstName;
order.BillingAddress.LastName = billingAddress.LastName;
order.BillingAddress.Company = billingAddress.Company;
order.BillingAddress.Vat = billingAddress.Vat;
order.BillingAddress.AddressLine1 = billingAddress.AddressLine1;
order.BillingAddress.AddressLine2 = billingAddress.AddressLine2;
order.BillingAddress.Zip = billingAddress.Zip;
order.BillingAddress.City = billingAddress.City;
order.BillingAddress.State = billingAddress.State;
order.BillingAddress.CountryCode = billingAddress.CountryCode;
order.DeliveryAddress.Title = deliveryAddress.Title;
order.DeliveryAddress.FirstName = deliveryAddress.FirstName;
order.DeliveryAddress.LastName = deliveryAddress.LastName;
order.DeliveryAddress.Company = deliveryAddress.Company;
order.DeliveryAddress.Vat = deliveryAddress.Vat;
order.DeliveryAddress.AddressLine1 = deliveryAddress.AddressLine1;
order.DeliveryAddress.AddressLine2 = deliveryAddress.AddressLine2;
order.DeliveryAddress.Zip = deliveryAddress.Zip;
order.DeliveryAddress.City = deliveryAddress.City;
order.DeliveryAddress.State = deliveryAddress.State;
order.DeliveryAddress.CountryCode = deliveryAddress.CountryCode;
order.Comment = string.Empty;
order.TaxRatesJson = cart.TaxRatesJson;
order.DeliveryAddressIsBilling = deliveryAddressIsBilling;
order.LastUpdate = DateTime.UtcNow;
order.AcceptTermsAndConditionsDate = DateTime.UtcNow;
order.AcceptGdprDate = DateTime.UtcNow;
await CommitAsync(userName);
//Zurücksetzen der Relationen weil neue OrderItems angelegt werden
await ResetOrderAsync(userName, order);
//Items
var oldItems = await _itemRepository.FindAsync(c => c.OrderId == orderId);
foreach (var orderItem in oldItems)
{
_itemRepository.Remove(orderItem);
}
await CommitAsync(userName);
//Items
foreach (var cartItem in cartItems)
{
var product = await _productRepository.FirstOrDefaultAsync(c => c.Id == cartItem.ProductId);
var orderItem = CreateItem();
orderItem.OrderId = order.Id;
orderItem.ProductId = cartItem.ProductId;
orderItem.ProductCategoryId = product.ProductCategoryId;
orderItem.Name = product.Name;
orderItem.NameDefault = product.Get("Name", fallback);
orderItem.Sku = product.Sku;
orderItem.ProductType = cartItem.ProductType;
orderItem.ItemId = cartItem.ItemId;
orderItem.TaxRateId = product.TaxRateId;
orderItem.IsTaxExempt = product.IsTaxExempt;
orderItem.IsShipEnabled = product.IsShipEnabled;
orderItem.IsFreeShipping = product.IsFreeShipping;
orderItem.AdditionalShippingCharge = product.AdditionalShippingCharge;
orderItem.Quantity = cartItem.Quantity;
orderItem.Price = cartItem.Price;
orderItem.PriceGross = cartItem.PriceGross;
orderItem.Price2 = cartItem.Price2;
orderItem.Price2Gross = cartItem.Price2Gross;
orderItem.Total = cartItem.Total;
orderItem.TotalGross = cartItem.TotalGross;
orderItem.Weight = product.Weight;
orderItem.Length = product.Length;
orderItem.Width = product.Width;
orderItem.Height = product.Height;
orderItem.Created = DateTimeOffset.UtcNow;
orderItem.LastUpdate = DateTimeOffset.UtcNow;
_itemRepository.Add(orderItem);
}
await CommitAsync(userName);
await SetOrderAndPaymentAsync(paymentType, paymentStatus, null, userName, order);
return order;
}
/// <summary>
/// Anlegen eines Artikels für eine Bestellung
/// </summary>
/// <returns>Bestellung Artikel</returns>
public OrderItem CreateItem()
{
var item = new OrderItem
{
Quantity = 0,
Total = 0,
TotalGross = 0,
Created = DateTime.UtcNow,
LastUpdate = DateTime.UtcNow
};
return item;
}
/// <summary>
/// Gibt einen Artikel in einer Bestellung zurück
/// </summary>
/// <param name="orderId">Id der Bestellung</param>
/// <param name="productId">Id des Artikels</param>
/// <returns>Artikel in der Bestellung oder null, wenn nicht gefunden</returns>
public async Task<OrderItem> GetItemAsync(long orderId, int productId)
{
return await _itemRepository.FirstOrDefaultAsync(c => c.OrderId == orderId && c.ProductId == productId).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Liste von Artikel in der Bestellung zurück
/// </summary>
/// <param name="orderId">Id der Bestellung</param>
/// <returns>Liste der Artikel in der Bestellung</returns>
public async Task<List<OrderItem>> GetItemsAsync(long orderId)
{
return (await _itemRepository.FindAsync(c => c.OrderId == orderId).ConfigureAwait(false)).ToList();
}
/// <summary>
/// Gibt den nächsten freien Bestell-spezifischen Zähler zurück
/// </summary>
/// <returns>Nächste freie Nummer</returns>
public async Task<long> GetNextCounterAsync()
{
long number = 1;
var last = await Repository.Query(c => c.Id > 0).OrderByDescending(c => c.Counter).FirstOrDefaultAsync();
if (last != null)
number = last.Counter + 1;
return number;
}
/// <summary>
/// Gibt die nächste freie Nummer für eine Bestellung als Bestellnummer zurück
/// </summary>
/// <returns>EndKunden-Nummer</returns>
public async Task<string> GetNextNumberAsync()
{
long number = 1;
var last = await Repository.Query(c => c.Id > 0).OrderByDescending(c => c.Id).FirstOrDefaultAsync();
if (last != null)
number = last.Counter + 1;
return $"{DateTime.UtcNow.Year}{DateTime.UtcNow.Month}-{number:000000}";
}
/// <summary>
/// Löschen einer Bestellung
/// </summary>
/// <param name="id">Id der Bestellung</param>
/// <param name="softDelete">Softdelete anwenden - Daten werden auf gelöscht gesetzt</param>
/// <returns>Task</returns>
public async Task DeleteAsync(long id, bool softDelete)
{
var order = await GetAsync(id);
if (order != null)
{
if (softDelete)
order.Deleted = true;
else
Repository.Remove(order);
}
}
/// <summary>
/// Löschen aller Bestellungen die einem Kunden zugeordnet sind
/// </summary>
/// <param name="customerId">Id des Kunden</param>
/// <param name="softDelete">Softdelete anwenden - Daten werden auf gelöscht gesetzt</param>
/// <returns>Task</returns>
public async Task DeleteByCustomerAsync(long customerId, bool softDelete)
{
var orders = await Repository.FindAsync(c => c.CustomerId == customerId && c.Deleted == false).ConfigureAwait(false);
if (orders.Any())
{
if (softDelete)
{
foreach (var order in orders)
{
order.Deleted = true;
}
}
else
Repository.RemoveRange(orders);
}
}
/// <summary>
/// Löschen aller Bestellungen die einem App-User zugeordnet sind
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="softDelete">Softdelete anwenden - Daten werden auf gelöscht gesetzt</param>
/// <returns>Task</returns>
public async Task DeleteByAppUserAsync(string appUserId, bool softDelete)
{
var orders = await Repository.FindAsync(c => c.AppUserId == appUserId && c.Deleted == false).ConfigureAwait(false);
if (orders.Any())
{
if (softDelete)
{
foreach (var order in orders)
{
order.Deleted = true;
}
}
else
Repository.RemoveRange(orders);
}
}
/// <summary>
/// Gibt die Anzahl aller Bestellungen im System zurück
/// </summary>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>Anzahl Bestellungen</returns>
public async Task<int> CountOrdersAsync(bool includeDeleted)
{
if (includeDeleted)
return await Repository.CountAsync().ConfigureAwait(false);
else
return await Repository.CountAsync(c => c.Deleted == false).ConfigureAwait(false);
}
/// <summary>
/// Gibt die Anzahl der Bestellungen in einem bestimmten Status zurück
/// </summary>
/// <param name="status">Gesuchter Status</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>Anzahl Bestellungen</returns>
public async Task<int> CountOrdersAsync(OrderStatus status, bool includeDeleted)
{
if (includeDeleted)
return await Repository.CountAsync(c => c.OrderStatus == status).ConfigureAwait(false);
else
return await Repository.CountAsync(c => c.OrderStatus == status && c.Deleted == false).ConfigureAwait(false);
}
/// <summary>
/// Gibt die Anzahl der Bestellungen in einem bestimmten Status für Kunden zurück
/// </summary>
/// <param name="customerId">Id des Kunden</param>
/// <param name="status">Gesuchter Status</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>Anzahl Bestellungen</returns>
public async Task<int> CountOrdersByCustomerAsync(long customerId, OrderStatus status, bool includeDeleted)
{
if (includeDeleted)
return await Repository.CountAsync(c => c.CustomerId == customerId && c.OrderStatus == status).ConfigureAwait(false);
else
return await Repository.CountAsync(c => c.CustomerId == customerId && c.OrderStatus == status && c.Deleted == false).ConfigureAwait(false);
}
/// <summary>
/// Gibt die Anzahl der Bestellungen in einem bestimmten Status für App-User zurück
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="status">Gesuchter Status</param>
/// <param name="includeDeleted">Gelöschte Daten inkludieren</param>
/// <returns>Anzahl Bestellungen</returns>
public async Task<int> CountOrdersByAppUserAsync(string appUserId, OrderStatus status, bool includeDeleted)
{
if (includeDeleted)
return await Repository.CountAsync(c => c.AppUserId == appUserId && c.OrderStatus == status).ConfigureAwait(false);
else
return await Repository.CountAsync(c => c.AppUserId == appUserId && c.OrderStatus == status && c.Deleted == false).ConfigureAwait(false);
}
/// <summary>
/// Setzt die ItemId für einen Artikel einer Bestellung auf null, wenn der Artikel gelöscht wird
/// </summary>
/// <param name="productId">Id des Artikels</param>
/// <returns>Task</returns>
public async Task ResetProductForOrderItemAsync(int productId)
{
var orderItems = await _itemRepository.FindAsync(c => c.ProductId == productId);
foreach (var orderItem in orderItems)
{
orderItem.ItemId = null;
}
}
/// <summary>
/// Gibt eine Bestellung anhand der PayPal-ID zurück
/// </summary>
/// <param name="payPalId">PayPal Id der Bestellung</param>
/// <returns>Order oder null, wenn nicht gefunden</returns>
public async Task<Order> GetByPayPalIdAsync(string payPalId)
{
return await Repository.FirstOrDefaultAsync(c => c.PayPalOrderId == payPalId).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Bestellung anhand der Unique-ID zurück
/// </summary>
/// <param name="uniqueId">Unique Id der Bestellung</param>
/// <returns>Order oder null, wenn nicht gefunden</returns>
public async Task<Order> GetByUniqueIdAsync(Guid uniqueId)
{
return await Repository.FirstOrDefaultAsync(c => c.UniqueId == uniqueId).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Bestellung anhand Bestellnummer zurück
/// </summary>
/// <param name="orderNumber">Bestellnummer</param>
/// <returns>Order oder null, wenn nicht gefunden</returns>
public async Task<Order> GetByOrderNumberAsync(string orderNumber)
{
return await Repository.FirstOrDefaultAsync(c => c.Number == orderNumber).ConfigureAwait(false);
}
/// <summary>
/// Setzt den "Versendet" Status für Bestellungen die via Klarna bezahlt wurden und welche keine physischen Produkte beinhalten!
/// </summary>
/// <returns>Task</returns>
public async Task SetShipmentForKlarnaDigitalOnlyAsync()
{
var ordersPhysical = await _physicalRepository.FindAsync(c => c.Deleted == false &&
c.PaymentType == PaymentType.Klarna &&
c.ShipmentStatus == ShipmentStatus.NotYetShipped &&
c.OrderStatus != OrderStatus.Cancelled &&
c.PaymentStatus == PaymentStatus.Paid && c.KlarnaShipmentError == false &&
c.PhysicalCount == 0).ConfigureAwait(false);
if (ordersPhysical.Any())
{
foreach (var orderPhysical in ordersPhysical)
{
var order = await Repository.GetAsync(orderPhysical.Id);
order.ShipmentStatus = ShipmentStatus.Shipped;
}
}
}
/// <summary>
/// Gibt eine Liste aller Klarna-Bestellungen zurück, für welche an Klarna der "versendet" Status gesendet werden soll
/// </summary>
/// <returns>Liste Bestellungen</returns>
public async Task<List<Order>> GetOrdersKlarnaToShipAsync()
{
var items = (await Repository.FindAsync(c => c.PaymentType == PaymentType.Klarna &&
c.ShipmentStatus == ShipmentStatus.Shipped &&
c.KlarnaShipmentSentDate == null &&
c.OrderStatus != OrderStatus.Cancelled &&
c.PaymentStatus == PaymentStatus.Paid &&
c.KlarnaShipmentError == false).ConfigureAwait(false)).ToList();
return items;
}
/// <summary>
/// Gibt zurück ob eine Bestellung nur digitale Produkte beinhaltet
/// </summary>
/// <param name="orderId">Id der Bestellung</param>
/// <returns>true wenn nur digital, false sonst</returns>
public async Task<bool> IsDigitaglOnlyAsync(long orderId)
{
var physicalOrder = await _physicalRepository.FirstOrDefaultAsync(c => c.Id == orderId && c.Deleted == false);
if (physicalOrder != null)
return physicalOrder.PhysicalCount == 0;
return false;
}
#region Private
/// <summary>
/// Setzen der Relation zu einer Bestellung und des Zahlungsstatus für spezielle Entitäten in einer Bestellung.
/// Das sind Listungen, Banner, Werbungen und Pins
/// </summary>
/// <param name="paymentType">Zahlungsart</param>
/// <param name="paymentStatus">Zahlungsstatus</param>
/// <param name="payedDate">Zahlunsdatum</param>
/// <param name="userName">Benutzer</param>
/// <param name="order">Bestellung</param>
/// <returns></returns>
private async Task SetOrderAndPaymentAsync(PaymentType paymentType, PaymentStatus paymentStatus, DateTimeOffset? payedDate, string userName, Order order)
{
var orderItems = await GetItemsAsync(order.Id);
foreach (var orderItem in orderItems)
{
if (orderItem.ProductType == ProductType.Listing)
{
var listing = await _listingRepository.GetAsync(orderItem.ItemId);
if (listing != null)
{
listing.OrderId = order.Id;
listing.OrderItemId = orderItem.Id;
listing.PaymentType = paymentType;
listing.PaymentStatus = paymentStatus;
listing.PayedDate = payedDate;
}
}
else if (orderItem.ProductType == ProductType.Advertisement)
{
var advertisement = await _advertisementRepository.GetAsync(orderItem.ItemId);
if (advertisement != null)
{
advertisement.OrderId = order.Id;
advertisement.OrderItemId = orderItem.Id;
advertisement.PaymentType = paymentType;
advertisement.PaymentStatus = paymentStatus;
advertisement.PayedDate = payedDate;
}
}
else if (orderItem.ProductType == ProductType.Banner)
{
var banner = await _bannerRepository.GetAsync(orderItem.ItemId);
if (banner != null)
{
banner.OrderId = order.Id;
banner.OrderItemId = orderItem.Id;
banner.PaymentType = paymentType;
banner.PaymentStatus = paymentStatus;
banner.PayedDate = payedDate;
}
}
else if (orderItem.ProductType == ProductType.Pin)
{
var pin = await _pinRepository.GetAsync(orderItem.ItemId);
if (pin != null)
{
pin.OrderId = order.Id;
pin.OrderItemId = orderItem.Id;
pin.PaymentType = paymentType;
pin.PaymentStatus = paymentStatus;
pin.PayedDate = payedDate;
}
}
}
await CommitAsync(userName);
}
/// <summary>
/// Zurücksetzen der Relation zwischen einer Bestellung und speziellen Entitäten.
/// Das sind Listungen, Banner, Werbungen und Pins
/// </summary>
/// <param name="userName">Benutzer</param>
/// <param name="order">Bestellung</param>
/// <returns></returns>
private async Task ResetOrderAsync(string userName, Order order)
{
var orderItems = await GetItemsAsync(order.Id);
foreach (var orderItem in orderItems)
{
if (orderItem.ProductType == ProductType.Listing)
{
var listing = await _listingRepository.GetAsync(orderItem.ItemId);
if (listing != null)
{
listing.OrderId = null;
listing.OrderItemId = null;
}
}
else if (orderItem.ProductType == ProductType.Advertisement)
{
var advertisement = await _advertisementRepository.GetAsync(orderItem.ItemId);
if (advertisement != null)
{
advertisement.OrderId = null;
advertisement.OrderItemId = null;
}
}
else if (orderItem.ProductType == ProductType.Banner)
{
var banner = await _bannerRepository.GetAsync(orderItem.ItemId);
if (banner != null)
{
banner.OrderId = null;
banner.OrderItemId = null;
}
}
else if (orderItem.ProductType == ProductType.Pin)
{
var pin = await _pinRepository.GetAsync(orderItem.ItemId);
if (pin != null)
{
pin.OrderId = null;
pin.OrderItemId = null;
}
}
}
await CommitAsync(userName);
}
#endregion
}
}