Move logic out the the class libs
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class BodyModel
|
||||
{
|
||||
public ProductModel[] products { get; set; }
|
||||
public float totalPrice { get; set; }
|
||||
public float totalVat { get; set; }
|
||||
public int receiptNumber { get; set; }
|
||||
public string receiptTime { get; set; }
|
||||
public string staff { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class FooterModel
|
||||
{
|
||||
public string value { get; set; }
|
||||
public PrintStylesModel printStyles { get; set; }
|
||||
public int textAlignment { get; set; }
|
||||
public int feedingLines { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class HeaderModel
|
||||
{
|
||||
public string value { get; set; }
|
||||
public PrintStylesModel printStyles { get; set; }
|
||||
public int textAlignment { get; set; }
|
||||
public int feedingLines { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class PosReceipt
|
||||
{
|
||||
public string logoBase64 { get; set; }
|
||||
public HeaderModel[] header { get; set; }
|
||||
public BodyModel bodyModel { get; set; } = new();
|
||||
public FooterModel[] footer { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class PrintStylesModel
|
||||
{
|
||||
public bool fontB { get; set; }
|
||||
public bool bold { get; set; }
|
||||
public bool doubleHeight { get; set; }
|
||||
public bool doubleWidth { get; set; }
|
||||
public bool underline { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class ProductModel
|
||||
{
|
||||
public string product { get; set; }
|
||||
public string noOfProduct { get; set; }
|
||||
public float price { get; set; }
|
||||
public float totalPrice { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pos.Json
|
||||
{
|
||||
public class SaleOfDayModel
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public int TotalCustomers { get; set; }
|
||||
public decimal TotalSale { get; set; }
|
||||
public List<SaleOfDayDetail> SaleOfDayDetail { get; set; } = new List<SaleOfDayDetail>();
|
||||
}
|
||||
|
||||
public class SaleOfDayDetail
|
||||
{
|
||||
public string Category { get; set; }
|
||||
public decimal TotalSale { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class AmountGridModel
|
||||
{
|
||||
public string PaymentMethodText { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string AmountText { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Pos.Models;
|
||||
|
||||
public enum PaymentMethod
|
||||
{
|
||||
Cash,
|
||||
Card,
|
||||
GiftCard,
|
||||
MobilePay
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class PriceLineModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int NumberProducts { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int Id { get; set; }
|
||||
public bool IsProductGroup { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class SaleGridInternalModel
|
||||
{
|
||||
public decimal InternPrice { get; set; }
|
||||
public int InternPieces { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class SaleGridModel
|
||||
{
|
||||
public string Navn { get; set; }
|
||||
public string Stk { get; set; }
|
||||
public string Pris { get; set; }
|
||||
public string Total { get; set; }
|
||||
public SaleGridInternalModel SaleGridInternalModel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class TotalSaleCategory
|
||||
{
|
||||
public string Category { get; set; }
|
||||
public decimal Sale { get; set; }
|
||||
public string SaleString { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pos.Models
|
||||
{
|
||||
public class TotalSaleDetail
|
||||
{
|
||||
public decimal TotalSale { get; set; }
|
||||
public int TotalCustomer { get; set; }
|
||||
public List<TotalSaleCategory> TotalSaleCategories { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,10 @@
|
||||
<None Remove="Icons\settings.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RestSharp" Version="108.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Database\Database.csproj" />
|
||||
<ProjectReference Include="..\..\Pos.Models\Pos.Models.csproj" />
|
||||
<ProjectReference Include="..\..\Pos.Service\Pos.Service.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Database.Models;
|
||||
using Database.Repository;
|
||||
|
||||
namespace Pos.Service
|
||||
{
|
||||
public static class CacheService
|
||||
{
|
||||
|
||||
private static bool _invalidEmployee = false;
|
||||
private static bool _invalidProductGroup = false;
|
||||
private static List<EmployeeEntity> _employees;
|
||||
private static List<ProductGroupEntity> _productGroups;
|
||||
|
||||
|
||||
public static void Invalidate()
|
||||
{
|
||||
_invalidEmployee = true;
|
||||
_invalidProductGroup = true;
|
||||
}
|
||||
|
||||
public static ObservableCollection<EmployeeEntity> GetEmployee()
|
||||
{
|
||||
ObservableCollection<EmployeeEntity> obsEmployees = new ObservableCollection<EmployeeEntity>();
|
||||
if (_invalidEmployee)
|
||||
{
|
||||
EmployeeRepository employeeRepository = new EmployeeRepository();
|
||||
_employees = employeeRepository.GetAll();
|
||||
foreach (EmployeeEntity employee in _employees)
|
||||
{
|
||||
obsEmployees.Add(employee);
|
||||
}
|
||||
_invalidEmployee = false;
|
||||
}
|
||||
|
||||
return obsEmployees;
|
||||
}
|
||||
|
||||
public static ObservableCollection<ProductGroupEntity> GetProductGroupsIncludeProducts()
|
||||
{
|
||||
ObservableCollection<ProductGroupEntity> obsProductGroups = new ObservableCollection<ProductGroupEntity>();
|
||||
if(_invalidProductGroup)
|
||||
{
|
||||
ProductGroupRepository productGroupRepository = new ProductGroupRepository();
|
||||
_productGroups = productGroupRepository.GetAll();
|
||||
_invalidProductGroup = false;
|
||||
foreach (ProductGroupEntity productGroup in _productGroups)
|
||||
{
|
||||
obsProductGroups.Add(productGroup);
|
||||
}
|
||||
}
|
||||
|
||||
return obsProductGroups;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Database.Models;
|
||||
using Database.Repository;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Pos.Json;
|
||||
using Pos.Models;
|
||||
using RestSharp;
|
||||
using BodyModel = Pos.Json.BodyModel;
|
||||
using FooterModel = Pos.Json.FooterModel;
|
||||
using HeaderModel = Pos.Json.HeaderModel;
|
||||
|
||||
namespace Pos.Service
|
||||
{
|
||||
public class SaleService
|
||||
{
|
||||
private float _totalPrice = 0;
|
||||
private SaleRepository _saleRepository = new SaleRepository();
|
||||
|
||||
public void Save(List<SaleGridModel> saleGridModels, List<AmountGridModel> amountGridModels, int employeeNo)
|
||||
{
|
||||
SaleRepository saleRepository = new SaleRepository();
|
||||
SaleEntity saleEntity = saleRepository.New(employeeNo);
|
||||
|
||||
foreach (SaleGridModel model in saleGridModels)
|
||||
{
|
||||
if(String.IsNullOrEmpty(model.Navn))
|
||||
continue;
|
||||
|
||||
SaleLineEntity saleLineEntity = new SaleLineEntity();
|
||||
saleLineEntity.SaleId = saleEntity.Id;
|
||||
saleLineEntity.Price = model.SaleGridInternalModel.InternPrice;
|
||||
saleLineEntity.Product = model.Navn;
|
||||
saleLineEntity.Pieces = model.SaleGridInternalModel.InternPieces;
|
||||
saleLineEntity.Total = saleLineEntity.Pieces * saleLineEntity.Price;
|
||||
saleRepository.SaveSaleLine(saleLineEntity);
|
||||
}
|
||||
|
||||
foreach (AmountGridModel model in amountGridModels)
|
||||
{
|
||||
PaymentEntity payment = new PaymentEntity();
|
||||
payment.Amount = model.Amount;
|
||||
payment.Type = model.PaymentMethodText;
|
||||
payment.SaleId = saleEntity.Id;
|
||||
saleRepository.SavePayment(payment);
|
||||
}
|
||||
}
|
||||
|
||||
public void PrintReceipt()
|
||||
{
|
||||
|
||||
SaleEntity sale = _saleRepository.GetLatest();
|
||||
if (sale == null)
|
||||
return;
|
||||
|
||||
BuildSaleReceipt(sale);
|
||||
}
|
||||
|
||||
public void PrintReceipt(int saleId)
|
||||
{
|
||||
SaleEntity sale = _saleRepository.Get(saleId);
|
||||
BuildSaleReceipt(sale);
|
||||
}
|
||||
|
||||
public void PrintSaleOfDay(DateTime selectedDate, TotalSaleDetail totalSaleDetail)
|
||||
{
|
||||
SaleOfDayModel saleOfDayModel = new SaleOfDayModel();
|
||||
saleOfDayModel.Date = selectedDate;
|
||||
saleOfDayModel.TotalSale = totalSaleDetail.TotalSale;
|
||||
saleOfDayModel.TotalCustomers = totalSaleDetail.TotalCustomer;
|
||||
foreach (TotalSaleCategory category in totalSaleDetail.TotalSaleCategories)
|
||||
{
|
||||
SaleOfDayDetail saleOfDayDetail = new SaleOfDayDetail();
|
||||
saleOfDayDetail.TotalSale = category.Sale;
|
||||
saleOfDayDetail.Category = category.Category;
|
||||
saleOfDayModel.SaleOfDayDetail.Add(saleOfDayDetail);
|
||||
}
|
||||
|
||||
LoadConfig loadConfig = new LoadConfig();
|
||||
IConfiguration config = loadConfig.ByEnvironment();
|
||||
string url = config["API:URL"];
|
||||
|
||||
RestClient restClient = new RestClient($"{url}/api/PosPrinter/SaleOfDay");
|
||||
RestRequest request = new RestRequest();
|
||||
request.AddJsonBody(saleOfDayModel);
|
||||
request.Method = Method.Post;
|
||||
EnsurePrintSucceeded(restClient.Post(request));
|
||||
}
|
||||
|
||||
public TotalSaleDetail TotalSale(DateTime selectedDate)
|
||||
{
|
||||
List<SaleEntity> sales = _saleRepository.GetByDateRange(selectedDate);
|
||||
TotalSaleDetail totalSaleDetail = new TotalSaleDetail();
|
||||
totalSaleDetail.TotalCustomer = sales.Count;
|
||||
foreach (SaleEntity sale in sales)
|
||||
{
|
||||
List<SaleLineEntity> saleLineBySaleId = _saleRepository.GetSaleLineBySaleId(sale.Id);
|
||||
foreach (SaleLineEntity saleLine in saleLineBySaleId)
|
||||
{
|
||||
|
||||
if (totalSaleDetail.TotalSaleCategories.Any(c => c.Category.Contains(saleLine.Product)))
|
||||
{
|
||||
TotalSaleCategory totalSaleCategory = totalSaleDetail.TotalSaleCategories.Single(c => c.Category.Contains(saleLine.Product));
|
||||
totalSaleCategory.Sale += saleLine.Total;
|
||||
totalSaleCategory.SaleString = "Kr. " + totalSaleCategory.Sale.ToString("0.00");
|
||||
}
|
||||
else
|
||||
{
|
||||
TotalSaleCategory totalSaleCategory = new TotalSaleCategory();
|
||||
totalSaleCategory.Sale = saleLine.Total;
|
||||
totalSaleCategory.SaleString ="Kr. " + totalSaleCategory.Sale.ToString("0.00");
|
||||
totalSaleCategory.Category = saleLine.Product;
|
||||
totalSaleDetail.TotalSaleCategories.Add(totalSaleCategory);
|
||||
}
|
||||
|
||||
totalSaleDetail.TotalSale += saleLine.Total;
|
||||
}
|
||||
}
|
||||
|
||||
return totalSaleDetail;
|
||||
}
|
||||
|
||||
public string LastAndTotalSale()
|
||||
{
|
||||
SaleEntity saleEntity = _saleRepository.GetLatest();
|
||||
List<SaleLineEntity> saleLineBySaleId = _saleRepository.GetSaleLineBySaleId(saleEntity.Id);
|
||||
decimal lastSale = 0;
|
||||
foreach (SaleLineEntity saleLine in saleLineBySaleId)
|
||||
{
|
||||
lastSale += saleLine.Total;
|
||||
}
|
||||
TotalSaleDetail totalSale = TotalSale(DateTime.Now);
|
||||
string todaySale = $"Sidste salg: kr. {lastSale.ToString("N")} - Dagens salg: kr. {totalSale.TotalSale.ToString("N")}";
|
||||
return todaySale;
|
||||
}
|
||||
|
||||
private void BuildSaleReceipt(SaleEntity sale)
|
||||
{
|
||||
EmployeeRepository employeeRepository = new EmployeeRepository();
|
||||
EmployeeEntity employee = employeeRepository.Get(sale.EmployeeId);
|
||||
|
||||
|
||||
List<SaleLineEntity> salesLines = _saleRepository.GetSaleLineBySaleId(sale.Id);
|
||||
List<PaymentEntity> payments = _saleRepository.GetPaymentBySaleId(sale.Id);
|
||||
|
||||
PosReceipt posReceipt = new PosReceipt();
|
||||
posReceipt.header = BuildReceiptHeader().ToArray();
|
||||
ProductModel[] productModels = BuildSaleLines(salesLines).ToArray();
|
||||
posReceipt.bodyModel = BuildBody(sale, employee.Name);
|
||||
posReceipt.bodyModel.products = productModels;
|
||||
posReceipt.footer = BuildFooter().ToArray();
|
||||
posReceipt.logoBase64 = String.Empty;
|
||||
|
||||
LoadConfig loadConfig = new LoadConfig();
|
||||
IConfiguration config = loadConfig.ByEnvironment();
|
||||
string apiUrl = config["API:URL"];
|
||||
string url = $"{apiUrl}/api/PosPrinter/Receipt";
|
||||
|
||||
RestClient restClient = new RestClient(url);
|
||||
RestRequest request = new RestRequest();
|
||||
request.AddJsonBody(posReceipt);
|
||||
request.Method = Method.Post;
|
||||
EnsurePrintSucceeded(restClient.Post(request));
|
||||
}
|
||||
|
||||
private static void EnsurePrintSucceeded(RestResponse response)
|
||||
{
|
||||
if (response.IsSuccessful)
|
||||
return;
|
||||
|
||||
string message = response.ErrorMessage ?? response.Content ?? "Ukendt fejl";
|
||||
throw new InvalidOperationException(
|
||||
$"Printer-API kald fejlede ({(int)response.StatusCode} {response.StatusCode}): {message}",
|
||||
response.ErrorException);
|
||||
}
|
||||
private List<FooterModel> BuildFooter()
|
||||
{
|
||||
List<FooterModel> footerModels = new List<FooterModel>();
|
||||
FooterModel model = new FooterModel();
|
||||
model.value = "Tak for handlen";
|
||||
model.printStyles = new PrintStylesModel
|
||||
{
|
||||
bold = false,
|
||||
fontB = false,
|
||||
doubleHeight = false,
|
||||
doubleWidth = false,
|
||||
underline = false
|
||||
};
|
||||
model.feedingLines = 0;
|
||||
model.textAlignment = 0;
|
||||
footerModels.Add(model);
|
||||
return footerModels;
|
||||
}
|
||||
|
||||
private List<ProductModel> BuildSaleLines(List<SaleLineEntity> salesLines)
|
||||
{
|
||||
List<ProductModel> products = new List<ProductModel>();
|
||||
foreach (SaleLineEntity salesLine in salesLines)
|
||||
{
|
||||
ProductModel productModel = new ProductModel();
|
||||
productModel.noOfProduct = salesLine.Pieces.ToString();
|
||||
productModel.price = (float)salesLine.Price;
|
||||
productModel.totalPrice = salesLine.Pieces * productModel.price;
|
||||
_totalPrice += productModel.totalPrice;
|
||||
productModel.product = salesLine.Product;
|
||||
products.Add(productModel);
|
||||
}
|
||||
|
||||
return products;
|
||||
}
|
||||
|
||||
private BodyModel BuildBody(SaleEntity sale, string employeeName)
|
||||
{
|
||||
BodyModel body = new BodyModel
|
||||
{
|
||||
receiptNumber = sale.Id,
|
||||
receiptTime = sale.Time.ToString("HH:mm dd-MM-yyyy"),
|
||||
staff = employeeName,
|
||||
totalPrice = _totalPrice,
|
||||
totalVat = (_totalPrice / 100) * 25
|
||||
};
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
private List<HeaderModel> BuildReceiptHeader()
|
||||
{
|
||||
List<HeaderModel> headerModels = new List<HeaderModel>();
|
||||
|
||||
HeaderModel headerModel = new HeaderModel
|
||||
{
|
||||
feedingLines = 1,
|
||||
textAlignment = 1,
|
||||
value = "Blomster Til Alt"
|
||||
};
|
||||
PrintStylesModel printStylesModel = new PrintStylesModel
|
||||
{
|
||||
bold = true,
|
||||
fontB = false,
|
||||
doubleHeight = true,
|
||||
doubleWidth = true,
|
||||
underline = false
|
||||
};
|
||||
headerModel.printStyles = printStylesModel;
|
||||
headerModels.Add(headerModel);
|
||||
|
||||
printStylesModel = new PrintStylesModel
|
||||
{
|
||||
bold = false,
|
||||
fontB = false,
|
||||
doubleHeight = false,
|
||||
doubleWidth = false,
|
||||
underline = false
|
||||
};
|
||||
|
||||
headerModel = new HeaderModel
|
||||
{
|
||||
feedingLines = 0,
|
||||
textAlignment = 1,
|
||||
value = "Adelgade 91",
|
||||
printStyles = printStylesModel
|
||||
};
|
||||
headerModels.Add(headerModel);
|
||||
|
||||
headerModel = new HeaderModel
|
||||
{
|
||||
feedingLines = 0,
|
||||
textAlignment = 1,
|
||||
value = "5400 Bogense",
|
||||
printStyles = printStylesModel
|
||||
};
|
||||
headerModels.Add(headerModel);
|
||||
|
||||
headerModel = new HeaderModel
|
||||
{
|
||||
feedingLines = 0,
|
||||
textAlignment = 1,
|
||||
value = "Tlf: 41 82 71 66",
|
||||
printStyles = printStylesModel
|
||||
};
|
||||
headerModels.Add(headerModel);
|
||||
|
||||
headerModel = new HeaderModel
|
||||
{
|
||||
feedingLines = 0,
|
||||
textAlignment = 1,
|
||||
value = "CVR: 37 14 44 36",
|
||||
printStyles = printStylesModel
|
||||
};
|
||||
headerModels.Add(headerModel);
|
||||
|
||||
return headerModels;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Pos.Models;
|
||||
|
||||
namespace Pos.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Holder styr på den igangværende handel og dens beregninger.
|
||||
/// Servicen har ingen afhængighed til WPF eller web.
|
||||
/// </summary>
|
||||
public class SalesTransactionService
|
||||
{
|
||||
private readonly List<PriceLineModel> _saleLines = new List<PriceLineModel>();
|
||||
private readonly List<AmountGridModel> _payments = new List<AmountGridModel>();
|
||||
|
||||
public IReadOnlyList<PriceLineModel> SaleLines => _saleLines;
|
||||
public IReadOnlyList<AmountGridModel> Payments => _payments;
|
||||
|
||||
public decimal TotalPrice =>
|
||||
_saleLines.Sum(line =>
|
||||
CalculateLineTotal(line.Price, line.NumberProducts));
|
||||
|
||||
public decimal AmountPaid =>
|
||||
_payments.Sum(payment => payment.Amount);
|
||||
|
||||
public decimal RemainingAmount =>
|
||||
Math.Max(TotalPrice - AmountPaid, 0);
|
||||
|
||||
public decimal Change =>
|
||||
Math.Max(AmountPaid - TotalPrice, 0);
|
||||
|
||||
public bool IsFullyPaid =>
|
||||
TotalPrice > 0 && AmountPaid >= TotalPrice;
|
||||
|
||||
/// <summary>
|
||||
/// Beregner totalen for en enkelt salgslinje.
|
||||
/// Parsing og visning af resultatet er fortsat UI-ansvar.
|
||||
/// </summary>
|
||||
public decimal CalculateLineTotal(decimal price, int numberOfProducts)
|
||||
{
|
||||
ValidatePriceAndQuantity(price, numberOfProducts);
|
||||
return price * numberOfProducts;
|
||||
}
|
||||
|
||||
public PriceLineModel AddSaleLine(
|
||||
int id,
|
||||
string name,
|
||||
int numberOfProducts,
|
||||
decimal price,
|
||||
bool isProductGroup)
|
||||
{
|
||||
if (id <= 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(id),
|
||||
"Id skal være større end 0.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
throw new ArgumentException(
|
||||
"Navn skal være udfyldt.",
|
||||
nameof(name));
|
||||
|
||||
ValidatePriceAndQuantity(price, numberOfProducts);
|
||||
|
||||
PriceLineModel saleLine = new PriceLineModel
|
||||
{
|
||||
Id = id,
|
||||
Name = name,
|
||||
NumberProducts = numberOfProducts,
|
||||
Price = price,
|
||||
IsProductGroup = isProductGroup
|
||||
};
|
||||
|
||||
_saleLines.Add(saleLine);
|
||||
return saleLine;
|
||||
}
|
||||
|
||||
public void RemoveSaleLineAt(int index)
|
||||
{
|
||||
if (index < 0 || index >= _saleLines.Count)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
|
||||
_saleLines.RemoveAt(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registrerer en betaling. Hvis amount er null, betales restbeløbet.
|
||||
/// </summary>
|
||||
public AmountGridModel AddPayment(
|
||||
PaymentMethod paymentMethod,
|
||||
decimal? amount = null)
|
||||
{
|
||||
if (_saleLines.Count == 0)
|
||||
throw new InvalidOperationException(
|
||||
"Der kan ikke registreres betaling på et tomt salg.");
|
||||
|
||||
decimal paymentAmount = amount ?? RemainingAmount;
|
||||
|
||||
if (paymentAmount <= 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(amount),
|
||||
"Betalingsbeløbet skal være større end 0.");
|
||||
|
||||
AmountGridModel payment = new AmountGridModel
|
||||
{
|
||||
Amount = paymentAmount,
|
||||
PaymentMethodText = GetPaymentMethodText(paymentMethod)
|
||||
};
|
||||
|
||||
_payments.Add(payment);
|
||||
return payment;
|
||||
}
|
||||
|
||||
public void RemovePaymentAt(int index)
|
||||
{
|
||||
if (index < 0 || index >= _payments.Count)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
|
||||
_payments.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void EnsureCanComplete()
|
||||
{
|
||||
if (_saleLines.Count == 0)
|
||||
throw new InvalidOperationException(
|
||||
"Et tomt salg kan ikke afsluttes.");
|
||||
|
||||
if (!IsFullyPaid)
|
||||
throw new InvalidOperationException(
|
||||
"Salget er ikke fuldt betalt.");
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_saleLines.Clear();
|
||||
_payments.Clear();
|
||||
}
|
||||
|
||||
private static void ValidatePriceAndQuantity(
|
||||
decimal price,
|
||||
int numberOfProducts)
|
||||
{
|
||||
if (price < 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(price),
|
||||
"Prisen må ikke være negativ.");
|
||||
|
||||
if (numberOfProducts <= 0)
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(numberOfProducts),
|
||||
"Antal skal være større end 0.");
|
||||
}
|
||||
|
||||
private static string GetPaymentMethodText(PaymentMethod paymentMethod)
|
||||
{
|
||||
switch (paymentMethod)
|
||||
{
|
||||
case PaymentMethod.Card:
|
||||
return "Kort";
|
||||
case PaymentMethod.Cash:
|
||||
return "Kontant";
|
||||
case PaymentMethod.GiftCard:
|
||||
return "Gavekort";
|
||||
case PaymentMethod.MobilePay:
|
||||
return "MobilePay";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(paymentMethod));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
//public class Rootobject
|
||||
//{
|
||||
// public string logoBase64 { get; set; }
|
||||
// public Header[] header { get; set; }
|
||||
// public Bodymodel bodyModel { get; set; }
|
||||
// public Footer[] footer { get; set; }
|
||||
//}
|
||||
|
||||
//public class Bodymodel
|
||||
//{
|
||||
// public Product[] products { get; set; }
|
||||
// public int totalPrice { get; set; }
|
||||
// public int totalVat { get; set; }
|
||||
// public int receiptNumber { get; set; }
|
||||
// public string receiptTime { get; set; }
|
||||
// public string staff { get; set; }
|
||||
//}
|
||||
|
||||
//public class Product
|
||||
//{
|
||||
// public string product { get; set; }
|
||||
// public string noOfProduct { get; set; }
|
||||
// public float price { get; set; }
|
||||
// public float totalPrice { get; set; }
|
||||
//}
|
||||
|
||||
//public class Header
|
||||
//{
|
||||
// public string value { get; set; }
|
||||
// public Printstyles printStyles { get; set; }
|
||||
// public int textAlignment { get; set; }
|
||||
// public int feedingLines { get; set; }
|
||||
//}
|
||||
|
||||
//public class Printstyles
|
||||
//{
|
||||
// public bool fontB { get; set; }
|
||||
// public bool bold { get; set; }
|
||||
// public bool doubleHeight { get; set; }
|
||||
// public bool doubleWidth { get; set; }
|
||||
// public bool underline { get; set; }
|
||||
//}
|
||||
|
||||
//public class Footer
|
||||
//{
|
||||
// public string value { get; set; }
|
||||
// public Printstyles1 printStyles { get; set; }
|
||||
// public int textAlignment { get; set; }
|
||||
// public int feedingLines { get; set; }
|
||||
//}
|
||||
|
||||
//public class Printstyles1
|
||||
//{
|
||||
// public bool fontB { get; set; }
|
||||
// public bool bold { get; set; }
|
||||
// public bool doubleHeight { get; set; }
|
||||
// public bool doubleWidth { get; set; }
|
||||
// public bool underline { get; set; }
|
||||
//}
|
||||
Reference in New Issue
Block a user