Feature repricing min max (#10)

amazon settlement import/export improvements
This commit is contained in:
2020-05-01 09:08:23 +01:00
committed by GitHub
parent 56647c7648
commit 43d61c2ef8
118 changed files with 7930 additions and 3021 deletions

View File

@@ -1,58 +1,86 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class AccountCode
public class AccountCode : IValidatableObject
{
private int? accountCodeId;
[Required(), Range(1, int.MaxValue)]
public int AccountCodeId
{
get { return (int)accountCodeId; }
set { accountCodeId = value; }
}
[Required(), MaxLength(150)]
public string Title
{
get;
set;
}
[MaxLength(500)]
public string Description
{
get;
set;
}
[Required(), MaxLength(50)]
public string Type
{
get;
set;
}
[Required(), MaxLength(50)]
public string BasicType
{
get;
set;
}
public bool IsSetAccountCodeId
{
get { return accountCodeId != null; }
}
public bool IsSetTitle
{
get { return Title != null; }
}
public bool IsSetDescription
{
get { return Description != null; }
}
public bool IsSetType
{
get { return Type != null; }
}
public bool IsSetBasicType
{
get { return BasicType != null; }
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var resultList = new List<ValidationResult>();
if (!IsSetAccountCodeId)
{
resultList.Add(new ValidationResult("Account Code is not set"));
}
return resultList;
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,6 +9,10 @@ namespace bnhtrade.Core.Model.Account
{
public interface IInvoice : IInvoiceHeader
{
decimal InvoiceNetAmount { get; }
decimal InvoiceTaxAmount { get; }
List<Invoice.InvoiceLine> InvoiceLineList { get; set; }
bool InvoiceLineListIsSet { get; }
@@ -17,163 +22,231 @@ namespace bnhtrade.Core.Model.Account
{
string ItemCode { get; set; }
bool ItemCodeIsSet { get; }
bool DescriptionIsSet { get; }
string Description { get; set; }
int Quantity { get; set; }
decimal? Quantity { get; set; }
bool QuantityIsSet { get; }
decimal? UnitAmount { get; set; }
decimal TotalNetAmount { get; set; }
Model.Account.AccountCode AccountCode { get; set; }
bool TotalNetAmountIsSet { get; }
Model.Account.TaxCodeInfo TaxCode { get; set; }
bool AccountCodeIsSet { get; }
decimal? TaxAmountAdjust { get; set; }
int AccountCode { get; set; }
decimal? TaxAmount { get; }
bool TaxCodeIsSet { get; }
string TaxCode { get; set; }
decimal TaxAmountAdjust { get; set; }
bool TaxAmountAdjustIsSet { get; }
decimal TaxAmount { get; }
bool TaxAmountIsSet { get; }
decimal GrossTotalAmount { get; }
bool GrossTotalAmountIsSet { get; }
decimal LineTotalAmount { get; }
}
public abstract class Invoice : InvoiceHeader, IInvoice
{
private bool unitAmountIsTaxExclusive = true;
public decimal InvoiceNetAmount { get; }
public decimal InvoiceTaxAmount { get; }
public bool UnitAmountIsTaxExclusive
{
get { return unitAmountIsTaxExclusive; }
set
{
unitAmountIsTaxExclusive = value;
if (InvoiceLineList != null)
{
for (int i = 0; i < InvoiceLineList.Count; i++)
{
InvoiceLineList[i].UnitAmountIsTaxExclusive = unitAmountIsTaxExclusive;
}
}
}
}
public List<InvoiceLine> InvoiceLineList { get; set; } = new List<InvoiceLine>();
public bool InvoiceLineListIsSet
{
get
{
if (InvoiceLineList == null || !InvoiceLineList.Any())
{ return false; }
else
{ return true; }
if (InvoiceLineList == null || !InvoiceLineList.Any()) { return false; }
else { return true; }
}
}
public class InvoiceLine : IInvoiceLine
public class InvoiceLine : IInvoiceLine, IValidatableObject
{
private int? accountCode;
private decimal? netAmount;
private decimal? taxAmount;
private decimal? unitAmount;
private Model.Account.TaxCodeInfo taxCode;
private decimal? taxAmountAdjust;
private int? quantity;
private decimal? discount;
private decimal? quantity;
public string ItemCode
public InvoiceLine(bool unitAmountIsTaxExclusive)
{
get;
set;
UnitAmountIsTaxExclusive = unitAmountIsTaxExclusive;
}
public bool ItemCodeIsSet
public string ItemCode { get; set; }
public string Description { get; set; }
[Required(), Range(0, 9999999.99)]
public decimal? Quantity
{
get { return ItemCode != null; }
get { return quantity; }
set
{
if (value == null) { quantity = null; }
else { quantity = decimal.Round((decimal)value, 4, MidpointRounding.AwayFromZero); }
}
}
public string Description
{
get;
set;
[Required()]
public decimal? UnitAmount
{
get { return unitAmount; }
set
{
if (value == null) { unitAmount = null; }
else { unitAmount = decimal.Round(value.GetValueOrDefault(), 4, MidpointRounding.AwayFromZero); }
}
}
public bool DescriptionIsSet
{
get { return Description != null; }
public bool UnitAmountIsTaxExclusive { get; set; }
[Required()]
public Model.Account.AccountCode AccountCode
{
get;
set;
}
public int Quantity
{
get { return (int)quantity.GetValueOrDefault(); }
set { quantity = value; }
[Required()]
public Model.Account.TaxCodeInfo TaxCode
{
get { return taxCode; }
set
{
if (value == null || TaxCode == null || value.TaxCode != taxCode.TaxCode)
{
TaxAmountAdjust = 0;
}
taxCode = value;
}
}
public bool QuantityIsSet
[Required()]
public decimal? TaxAmount
{
get { return quantity != null; }
get
{
return TaxAmountAdjust + GetCalculatedTax();
}
}
public decimal TotalNetAmount
public decimal? TaxAmountAdjust
{
get { return (decimal)netAmount.GetValueOrDefault(); }
set { netAmount = value; }
get { return taxAmountAdjust; }
set
{
if (value == null) { taxAmountAdjust = null; }
else { taxAmountAdjust = decimal.Round((decimal)value, 2, MidpointRounding.AwayFromZero); }
}
}
public bool TotalNetAmountIsSet
public decimal LineTotalAmount
{
get { return netAmount != null; }
get
{
if (CanCalculateLine())
{
return ((decimal)Quantity * (decimal)UnitAmount) + (decimal)TaxAmount;
}
else { return 0; }
}
}
public int AccountCode
private bool CanCalculateLine()
{
get { return (int)accountCode.GetValueOrDefault(); }
set { accountCode = value; }
if (Quantity == null || UnitAmount == null || TaxCode == null) { return false; }
else { return true; }
}
public bool AccountCodeIsSet
private decimal GetCalculatedTax()
{
get { return accountCode != null; }
decimal calculatedTax = 0;
if (CanCalculateLine())
{
if (UnitAmountIsTaxExclusive)
{
calculatedTax = ((decimal)Quantity * (decimal)UnitAmount) * (TaxCode.TaxRate / 100);
}
else
{
calculatedTax = ((decimal)Quantity * (decimal)UnitAmount) * (TaxCode.TaxRate / (100 + TaxCode.TaxRate));
}
return decimal.Round(calculatedTax, 2, MidpointRounding.AwayFromZero);
}
else
{
return 0;
}
}
public string TaxCode
public void SetTaxAmountAdjust(decimal lineTaxAmount)
{
get;
set;
decimal adjustedAmount = lineTaxAmount - GetCalculatedTax();
if (adjustedAmount == 0) { TaxAmountAdjust = null; }
else { TaxAmountAdjust = adjustedAmount; }
}
public bool TaxCodeIsSet
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
get { return TaxCode != null; }
throw new NotImplementedException();
var resultList = new List<ValidationResult>();
if (TaxAmount > LineTotalAmount / 2)
{
resultList.Add(new ValidationResult("Line tax amount is greater than net amount"));
}
}
}
public new IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var subResult = base.Validate(validationContext);
var resultList = new List<ValidationResult>();
resultList.AddRange(subResult);
// loop though lines and check sum totals
if (!InvoiceLineListIsSet)
{
resultList.Add(new ValidationResult("No lines set on Invoice"));
}
else
{
decimal lineTotal = 0;
foreach (var line in InvoiceLineList)
{
lineTotal += line.LineTotalAmount;
if (UnitAmountIsTaxExclusive != line.UnitAmountIsTaxExclusive)
{
resultList.Add(new ValidationResult("Invalid UnitAmountIsTaxExclusive"));
}
}
// check totals
if (InvoiceTotalAmount != lineTotal)
{ resultList.Add(new ValidationResult("Invoice line total does not equal invoice total")); }
}
public decimal TaxAmount
{
get { return (decimal)taxAmount.GetValueOrDefault(); }
set { taxAmount = decimal.Round(value, 2); }
}
public bool TaxAmountIsSet
{
get { return taxAmount != null; }
}
public decimal TaxAmountAdjust
{
get { return (decimal)taxAmountAdjust.GetValueOrDefault(); }
set { taxAmountAdjust = decimal.Round(value, 2); }
}
public bool TaxAmountAdjustIsSet
{
get { return taxAmountAdjust != null; }
}
public decimal GrossTotalAmount
{
get { return (decimal)netAmount.GetValueOrDefault() + TaxAmount; }
}
public bool GrossTotalAmountIsSet
{
get { return (TotalNetAmountIsSet && TaxAmountIsSet); }
}
return resultList;
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -9,31 +10,24 @@ namespace bnhtrade.Core.Model.Account
public interface IInvoiceHeader
{
string ContactName { get; set; }
bool ContactNameIsSet { get; }
decimal InvoiceAmount { get; set; }
bool InvoiceAmountIsSet { get; }
decimal? InvoiceTotalAmount { get; set; }
string InvoiceCurrencyCode { get; set; }
bool InvoiceCurrencyCodeIsSet { get; }
DateTime InvoiceDate { get; set; }
bool InvoiceDateIsSet { get; }
DateTime InvoiceDueDate { get; set; }
bool InvoiceDueDateIsSet { get; }
DateTimeKind InvoiceDateKind { get; set; }
bool InvoiceDateKindIsSet { get; }
DateTime? InvoiceDate { get; set; }
DateTime? InvoiceDueDate { get; set; }
string InvoiceNumber { get; set; }
bool InvoiceNumberIsSet { get; }
string InvoiceReference { get; set; }
bool InvoiceReferenceIsSet { get; }
bool IsCreditNote { get; set; }
bool IsCreditNoteIsSet { get; }
}
public abstract class InvoiceHeader : IInvoiceHeader
public abstract class InvoiceHeader :IInvoiceHeader, IValidatableObject
{
private string invoiceCurrencyCode;
private DateTime? invoiceDate;
private DateTime? invoiceDueDate;
private DateTimeKind? invoiceDateKind = DateTimeKind.Utc;
private decimal? invoiceAmount;
public InvoiceHeader()
@@ -41,95 +35,51 @@ namespace bnhtrade.Core.Model.Account
IsCreditNote = false;
}
[Required()]
public string ContactName { get; set; }
public bool ContactNameIsSet
{
get { return ContactName != null; }
}
[Required()]
public DateTime? InvoiceDate { get; set; }
public DateTime InvoiceDate
{
get { return (DateTime)invoiceDate.GetValueOrDefault(); }
set { invoiceDate = value; }
}
[Required()]
public DateTime? InvoiceDueDate { get; set; }
public bool InvoiceDateIsSet
{
get { return invoiceDate != null; }
}
public DateTime InvoiceDueDate
{
get { return (DateTime)invoiceDueDate.GetValueOrDefault(); }
set { invoiceDueDate = value; }
}
public bool InvoiceDueDateIsSet
{
get { return invoiceDueDate != null; }
}
public DateTimeKind InvoiceDateKind
{
get { return (DateTimeKind)invoiceDateKind; }
set { invoiceDateKind = value; }
}
public bool InvoiceDateKindIsSet
{
get { return invoiceDateKind != null; }
}
public string InvoiceCurrencyCode
{
get { return invoiceCurrencyCode; }
set
{
if (!string.IsNullOrWhiteSpace(value))
{
invoiceCurrencyCode = value.ToUpper();
}
}
}
public bool InvoiceCurrencyCodeIsSet
{
get { return InvoiceCurrencyCode != null; }
}
[Required(), MinLength(3), MaxLength(3)]
public string InvoiceCurrencyCode { get; set; }
[Required()]
public string InvoiceNumber { get; set; }
public bool InvoiceNumberIsSet
{
get { return InvoiceNumber != null; }
}
public string InvoiceReference { get; set; }
public bool InvoiceReferenceIsSet
{
get { return InvoiceReference != null; }
}
public decimal InvoiceAmount
[Required()]
public decimal? InvoiceTotalAmount
{
get { return (decimal)invoiceAmount; }
set { invoiceAmount = value; }
set
{
if (value == null) { invoiceAmount = null; }
else { invoiceAmount = decimal.Round((decimal)value, 2, MidpointRounding.AwayFromZero); }
}
}
public bool InvoiceAmountIsSet
[Required()]
public bool IsCreditNote { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
get { return invoiceAmount != null; }
}
public bool IsCreditNote
{
get;
set;
}
public bool IsCreditNoteIsSet
{
get { return true; }
var resultList = new List<ValidationResult>();
if (IsCreditNote && InvoiceTotalAmount > 0)
{
resultList.Add(new ValidationResult("Credit Note amount cannot be greater than zero"));
}
else if (!IsCreditNote && InvoiceTotalAmount < 0)
{
resultList.Add(new ValidationResult("Invoice amount cannot be less than zero"));
}
return resultList;
}
}
}

View File

@@ -1,47 +1,70 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class InvoiceLineItem
public class InvoiceLineItem : IValidatableObject
{
[Required()]
public string ItemCode
{
get;
set;
}
public string Title
[Required()]
public string Name
{
get;
set;
}
public string Description
{
get;
set;
}
[Required()]
public bool IsNewReviewRequired
{
get;
set;
}
[Required()]
public bool InvoiceLineEntryEnabled
{
get;
set;
}
public int DefaultAccountCode
[Required()]
public Model.Account.AccountCode DefaultAccountCode
{
get;
set;
}
public string DefaultTaxCode
[Required()]
public Model.Account.TaxCodeInfo DefaultTaxCode
{
get;
set;
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var resultList = new List<ValidationResult>();
resultList.AddRange(DefaultAccountCode.Validate(validationContext));
resultList.AddRange(DefaultTaxCode.Validate(validationContext));
return resultList;
}
}
}

View File

@@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class TaxCode
{
private decimal? netAmountMultiplier = null;
private decimal? grossAmountMultiplier = null;
private bool? isActive = null;
private bool? isValidOnExpense = null;
private bool? isValidOnIncome = null;
public string TaxCodeId { get; set; }
public string TaxRateDescription { get; set; }
public string TaxRateTitle { get; set; }
public string TaxType { get; set; }
public decimal NetAmountMultiplier
{
get { return (decimal)netAmountMultiplier; }
set { netAmountMultiplier = value; }
}
public decimal GrossAmountMultiplier
{
get { return (decimal)grossAmountMultiplier; }
set { grossAmountMultiplier = value; }
}
public bool IsActive
{
get { return (bool)isActive; }
set { isActive = value; }
}
public bool IsSetAll
{
get
{
if (IsSetGrossAmountMultiplier
&& IsSetIsActive
&& IsSetIsValidOnExpense
&& IsSetIsValidOnIncome
&& IsSetNetAmountMultiplier
&& IsSetTaxCodeId
&& IsSetTaxRateTitle
&& IsSetTaxRateDescription
)
{
return true;
}
else { return false; }
}
}
public bool IsSetGrossAmountMultiplier
{
get { return grossAmountMultiplier != null; }
}
public bool IsSetIsActive
{
get { return isActive != null; }
}
public bool IsSetIsValidOnExpense
{
get { return isValidOnExpense != null; }
}
public bool IsSetIsValidOnIncome
{
get { return isValidOnIncome != null; }
}
public bool IsSetNetAmountMultiplier
{
get { return netAmountMultiplier != null; }
}
public bool IsSetTaxCodeId
{
get { return TaxCodeId != null; }
}
public bool IsSetTaxRateTitle
{
get { return TaxRateTitle != null; }
}
public bool IsSetTaxRateDescription
{
get { return TaxRateDescription != null; }
}
public bool IsSetTaxType
{
get { return TaxType != null; }
}
public bool IsValidOnExpense
{
get { return (bool)isValidOnExpense; }
set { isValidOnExpense = value; }
}
public bool IsValidOnIncome
{
get { return (bool)isValidOnIncome; }
set { isValidOnIncome = value; }
}
}
}

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class TaxCodeInfo : IValidatableObject
{
public TaxCodeInfo(string taxCodeId, string title, string description, decimal taxRatePercent, bool isMarginSchemeRate,
bool isValidOnExpense, bool isValidOnIncome, string taxType, bool isActive)
{
if (TaxRate < 0)
{
throw new Exception("Tax rate is less than zero");
}
if (TaxRate >= 100)
{
// 100% rate has been used where the line total is all tax
// you need to do somemore coding when this facility is required
throw new Exception("Tax rate is >= 100%");
}
TaxCode = taxCodeId;
TaxCodeDescription = description;
TaxRate = taxRatePercent;
IsMarginScheme = isMarginSchemeRate;
TaxCodeName = title;
TaxType = taxType;
IsActive = isActive;
IsValidOnExpense = isValidOnExpense;
IsValidOnIncome = isValidOnIncome;
}
/// <summary>
/// Unique identifier
/// </summary>
[Required()]
public string TaxCode { get; private set; }
[Required()]
public string TaxCodeName { get; private set; }
public string TaxCodeDescription { get; private set; }
/// <summary>
/// Tax rate as a percentage
/// </summary>
[Required(), Range(0, 100)]
public decimal TaxRate { get; private set; }
public bool IsMarginScheme { get; private set; }
[Required()]
public string TaxType { get; private set; }
public bool IsValidOnExpense { get; private set; }
public bool IsValidOnIncome { get; private set; }
public bool IsActive { get; private set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var resultList = new List<ValidationResult>();
return resultList;
}
}
}