You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

531 lines
23 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Op.Entity;
namespace DS.WMS.Core.Fee.Dtos
{
/// <summary>
/// 费用汇总统计项
/// </summary>
public class FeeStatItem
{
/// <summary>
/// 应收款总计
/// </summary>
public decimal ReceivableTotal { get; set; }
/// <summary>
/// 应付款总计
/// </summary>
public decimal PayableTotal { get; set; }
/// <summary>
/// 利润总计
/// </summary>
public decimal ProfitTotal { get { return ReceivableTotal - PayableTotal; } }
/// <summary>
/// 利润率
/// </summary>
public string ProfitMargin
{
get
{
if (PayableTotal == 0)
return string.Empty;
//利润率=利润÷成本×100%
return string.Concat(Math.Round(ReceivableTotal / PayableTotal * 100, 2, MidpointRounding.AwayFromZero), "%");
}
}
/// <summary>
/// 人民币应收款
/// </summary>
public decimal ReceivableCNY { get; set; }
/// <summary>
/// 人民币应付款
/// </summary>
public decimal PayableCNY { get; set; }
/// <summary>
/// 人民币利润
/// </summary>
public decimal ProfitCNY { get { return ReceivableCNY - PayableCNY; } }
/// <summary>
/// 美元应收款
/// </summary>
public decimal ReceivableUSD { get; set; }
/// <summary>
/// 美元应付款
/// </summary>
public decimal PayableUSD { get; set; }
/// <summary>
/// 美元利润
/// </summary>
public decimal ProfitUSD { get { return ReceivableUSD - PayableUSD; } }
/// <summary>
/// 其他币种应收款
/// </summary>
public decimal ReceivableOther { get; set; }
/// <summary>
/// 其他币种应付款
/// </summary>
public decimal PayableOther { get; set; }
/// <summary>
/// 其他币种利润
/// </summary>
public decimal ProfitOther { get { return ReceivableOther - PayableOther; } }
}
/// <summary>
/// 费用汇总统计项(附不含税统计)
/// </summary>
public class NoTaxFeeStatItem : FeeStatItem
{
/// <summary>
/// 不含税应收款总计
/// </summary>
public decimal NoTaxReceivableTotal { get; set; }
/// <summary>
/// 不含税应付款总计
/// </summary>
public decimal NoTaxPayableTotal { get; set; }
/// <summary>
/// 不含税利润总计
/// </summary>
public decimal NoTaxProfitTotal { get { return NoTaxReceivableTotal - NoTaxPayableTotal; } }
/// <summary>
/// 不含税人民币应收款
/// </summary>
public decimal NoTaxReceivableCNY { get; set; }
/// <summary>
/// 不含税人民币应付款
/// </summary>
public decimal NoTaxPayableCNY { get; set; }
/// <summary>
/// 不含税人民币利润
/// </summary>
public decimal NoTaxProfitCNY { get { return NoTaxReceivableCNY - NoTaxPayableCNY; } }
/// <summary>
/// 不含税美元应收款
/// </summary>
public decimal NoTaxReceivableUSD { get; set; }
/// <summary>
/// 不含税美元应付款
/// </summary>
public decimal NoTaxPayableUSD { get; set; }
/// <summary>
/// 不含税美元利润
/// </summary>
public decimal NoTaxProfitUSD { get { return NoTaxReceivableUSD - NoTaxPayableUSD; } }
/// <summary>
/// 不含税其他币种应收款
/// </summary>
public decimal NoTaxReceivableOther { get; set; }
/// <summary>
/// 不含税其他币种应付款
/// </summary>
public decimal NoTaxPayableOther { get; set; }
/// <summary>
/// 不含税其他币种利润
/// </summary>
public decimal NoTaxProfitOther { get { return NoTaxReceivableOther - NoTaxPayableOther; } }
}
/// <summary>
/// 费用汇总统计模型
/// </summary>
public class FeeStatistics : NoTaxFeeStatItem
{
readonly IEnumerable<FeeRecord> _source;
/// <summary>
/// 使用指定的数据源初始化统计。
/// </summary>
/// <param name="source">数据源</param>
public FeeStatistics(IEnumerable<FeeRecord> source)
{
_source = source;
var localReceivable = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == x.LocalCurrency).Sum(x => x.Amount);
//其他币种按汇率转换为本币金额,下同
var otherReceivable = (from s in _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.Amount * x.Key.ExchangeRate)).GetValueOrDefault();
ReceivableTotal = localReceivable + otherReceivable;//应收合计
var localPayable = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == x.LocalCurrency).Sum(x => x.Amount);
var otherPayable = (from s in _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.Amount * x.Key.ExchangeRate)).GetValueOrDefault();
PayableTotal = localPayable + otherPayable;//应付合计
var localNoTaxReceivable = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == x.LocalCurrency).Sum(x => x.NoTaxAmount);
var otherNoTaxReceivable = (from s in _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.NoTaxAmount * x.Key.ExchangeRate)).GetValueOrDefault();
NoTaxReceivableTotal = localNoTaxReceivable + NoTaxReceivableTotal;
var localNoTaxPayable = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == x.LocalCurrency).Sum(x => x.NoTaxAmount);
var otherNoTaxPayable = (from s in _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.NoTaxAmount * x.Key.ExchangeRate)).GetValueOrDefault();
NoTaxPayableTotal = localNoTaxPayable + otherNoTaxPayable;
//人民币
ReceivableCNY = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.Amount);
PayableCNY = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.Amount);
NoTaxReceivableCNY = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.NoTaxAmount);
NoTaxPayableCNY = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.NoTaxAmount);
//美元
ReceivableUSD = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.Amount);
PayableUSD = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.Amount);
NoTaxReceivableUSD = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.NoTaxAmount);
NoTaxPayableUSD = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.NoTaxAmount);
//其他
ReceivableOther = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount);
PayableOther = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount);
NoTaxReceivableOther = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.NoTaxAmount);
NoTaxPayableOther = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.NoTaxAmount);
//按客户统计
ByCustomers = (from s in _source
group s by s.CustomerName into g
select new ByCustomerStat
{
CustomerName = g.Key,
ReceivableTotal = g.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount),
PayableTotal = g.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount),
ReceivableCNY = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.Amount),
PayableCNY = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.Amount),
ReceivableUSD = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.Amount),
PayableUSD = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.Amount)
}).ToList();
}
/// <summary>
/// 按客户统计
/// </summary>
public List<ByCustomerStat> ByCustomers { get; private set; }
}
/// <summary>
/// 用于费用审核的汇总统计模型
/// </summary>
public class FeeAuditStatistics : FeeStatItem
{
readonly IEnumerable<FeeRecordRes> _source;
/// <summary>
/// 销项金额
/// </summary>
public decimal AccValue => ReceivableTotal - Math.Round(ReceivableTotal * AccTaxRate.GetValueOrDefault(), 2, MidpointRounding.AwayFromZero);
/// <summary>
/// 销项税额
/// </summary>
public decimal? AccTaxRate { get; set; }
/// <summary>
/// 进项金额
/// </summary>
public decimal IncomeValue => PayableTotal - Math.Round(PayableTotal * IncomeTaxRate.GetValueOrDefault(), 2, MidpointRounding.AwayFromZero);
/// <summary>
/// 进项税额
/// </summary>
public decimal? IncomeTaxRate { get; set; }
/// <summary>
/// 使用指定的数据源初始化统计。
/// </summary>
/// <param name="source">数据源</param>
public FeeAuditStatistics(IEnumerable<FeeRecordRes> source)
{
_source = source;
AccTaxRate = source.FirstOrDefault()?.AccTaxRate;
IncomeTaxRate = source.FirstOrDefault()?.TaxRate;
var localReceivable = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == x.LocalCurrency).Sum(x => x.Amount).GetValueOrDefault();
//其他币种按汇率转换为本币金额,下同
var otherReceivable = (from s in _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.Amount * x.Key.ExchangeRate)).GetValueOrDefault();
ReceivableTotal = localReceivable + otherReceivable;//应收合计
var localPayable = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == x.LocalCurrency).Sum(x => x.Amount).GetValueOrDefault();
var otherPayable = (from s in _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.Amount * x.Key.ExchangeRate)).GetValueOrDefault();
PayableTotal = localPayable + otherPayable;//应付合计
//人民币
ReceivableCNY = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault();
PayableCNY = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault();
//美元
ReceivableUSD = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault();
PayableUSD = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault();
//其他
ReceivableOther = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount).GetValueOrDefault();
PayableOther = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount).GetValueOrDefault();
//按客户统计
ByCustomer = (from s in _source
group s by s.CustomerName into g
select new ByCustomerStat
{
CustomerName = g.Key,
ReceivableTotal = g.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount).GetValueOrDefault(),
PayableTotal = g.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount).GetValueOrDefault(),
ReceivableCNY = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault(),
PayableCNY = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault(),
ReceivableUSD = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault(),
PayableUSD = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault(),
ReceivableOther = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount * x.ExchangeRate).GetValueOrDefault(),
PayableOther = g.Where(x => x.FeeType == FeeType.Payable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount * x.ExchangeRate).GetValueOrDefault()
}).ToList();
ByCustomer.Add(new ByCustomerStat
{
CustomerName = "合计",
ReceivableTotal = ReceivableTotal,
PayableTotal = PayableTotal,
ReceivableCNY = ReceivableCNY,
PayableCNY = PayableCNY,
ReceivableUSD = ReceivableUSD,
PayableUSD = PayableUSD,
ReceivableOther = ReceivableOther,
PayableOther = PayableOther
});
//按业务统计
ByBusiness = (from s in _source
group s by s.BillNO into g
select new ByBusinessStat
{
BillNO = g.Key,
ReceivableTotal = g.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount).GetValueOrDefault(),
PayableTotal = g.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount).GetValueOrDefault(),
ReceivableCNY = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault(),
PayableCNY = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "CNY").Sum(x => x.Amount).GetValueOrDefault(),
ReceivableUSD = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault(),
PayableUSD = g.Where(x => x.FeeType == FeeType.Payable && x.Currency == "USD").Sum(x => x.Amount).GetValueOrDefault(),
ReceivableOther = g.Where(x => x.FeeType == FeeType.Receivable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount * x.ExchangeRate).GetValueOrDefault(),
PayableOther = g.Where(x => x.FeeType == FeeType.Payable && x.Currency != "USD" && x.Currency != "CNY").Sum(x => x.Amount * x.ExchangeRate).GetValueOrDefault()
}).ToList();
ByBusiness.Add(new ByBusinessStat
{
BillNO = "合计",
ReceivableTotal = ReceivableTotal,
PayableTotal = PayableTotal,
ReceivableCNY = ReceivableCNY,
PayableCNY = PayableCNY,
ReceivableUSD = ReceivableUSD,
PayableUSD = PayableUSD,
ReceivableOther = ReceivableOther,
PayableOther = PayableOther
});
//按币种统计
ByCurrency = (from s in _source
group s by s.Currency into g
select new ByCurrencyStat
{
Currency = g.Key,
ReceivableTotal = g.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.Amount).GetValueOrDefault(),
PayableTotal = g.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.Amount).GetValueOrDefault(),
NoTaxReceivableTotal = g.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.NoTaxAmount),
NoTaxPayableTotal = g.Where(x => x.FeeType == FeeType.Payable).Sum(x => x.NoTaxAmount),
}).ToList();
var bcs = new ByCurrencyStat
{
Currency = "合计",
ReceivableTotal = ReceivableTotal,
PayableTotal = PayableTotal,
NoTaxReceivableTotal = _source.Where(x => x.FeeType == FeeType.Receivable).Sum(x => x.NoTaxAmount),
};
var localNoTaxReceivable = _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency == x.LocalCurrency).Sum(x => x.NoTaxAmount);
//其他币种按汇率转换为本币金额,下同
var otherNoTaxReceivable = (from s in _source.Where(x => x.FeeType == FeeType.Receivable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.NoTaxAmount * x.Key.ExchangeRate)).GetValueOrDefault();
bcs.NoTaxReceivableTotal = localReceivable + otherReceivable;//不含税应收合计
var localNoTaxPayable = _source.Where(x => x.FeeType == FeeType.Payable && x.Currency == x.LocalCurrency).Sum(x => x.NoTaxAmount);
var otherNoTaxPayable = (from s in _source.Where(x => x.FeeType == FeeType.Payable && x.Currency != x.LocalCurrency)
group s by new { s.Currency, s.ExchangeRate } into g
select new
{
g.Key,
Items = g
}).Sum(x => x.Items.Sum(y => y.NoTaxAmount * x.Key.ExchangeRate)).GetValueOrDefault();
bcs.NoTaxPayableTotal = localPayable + otherPayable;//不含税应付合计
ByCurrency.Add(bcs);
}
/// <summary>
/// 按客户统计
/// </summary>
public List<ByCustomerStat> ByCustomer { get; private set; }
/// <summary>
/// 按业务统计
/// </summary>
public List<ByBusinessStat> ByBusiness { get; private set; }
/// <summary>
/// 按币种统计
/// </summary>
public List<ByCurrencyStat> ByCurrency { get; private set; }
}
/// <summary>
/// 按客户统计费用
/// </summary>
public class ByCustomerStat : FeeStatItem
{
/// <summary>
/// 客户名称
/// </summary>
public string CustomerName { get; set; }
}
/// <summary>
/// 按业务统计费用
/// </summary>
public class ByBusinessStat : FeeStatItem
{
/// <summary>
/// 业务编号
/// </summary>
public string BillNO { get; set; }
}
/// <summary>
/// 按业务统计费用
/// </summary>
public class ByCurrencyStat
{
/// <summary>
/// 币种
/// </summary>
public string Currency { get; set; }
/// <summary>
/// 应收款总计
/// </summary>
public decimal ReceivableTotal { get; set; }
/// <summary>
/// 应付款总计
/// </summary>
public decimal PayableTotal { get; set; }
/// <summary>
/// 利润总计
/// </summary>
public decimal ProfitTotal => ReceivableTotal - PayableTotal;
/// <summary>
/// 不含税应收款总计
/// </summary>
public decimal NoTaxReceivableTotal { get; set; }
/// <summary>
/// 不含税应付款总计
/// </summary>
public decimal NoTaxPayableTotal { get; set; }
/// <summary>
/// 不含税利润总计
/// </summary>
public decimal NoTaxProfitTotal => NoTaxReceivableTotal - NoTaxPayableTotal;
}
public class FeeStatisticsRequest
{
/// <summary>
/// 查询条件
/// </summary>
public string QueryCondition { get; set; }
}
public class FeeStatisticsRequestV2
{
/// <summary>
/// 业务ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 业务类型
/// </summary>
public BusinessType BusinessType { get; set; }
/// <summary>
/// 费用ID可空
/// </summary>
public long? FeeId { get; set; }
}
}