757 lines
34 KiB
C#
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
|
|
}
|
|
}
|