using System.Globalization; using System.Text.RegularExpressions; namespace JiDangJia.Core; public sealed record ConsignmentFees(decimal Service,decimal Storage,decimal Proceeds) { public decimal Total => Service+Storage; } public static class Consignment { public static void ValidateExpected(string value) { if(string.IsNullOrWhiteSpace(value))return; var match=Regex.Match(value.Trim(),@"^(\d+(?:\.\d{1,2})?)\s*(?:[-–—~~至]\s*(\d+(?:\.\d{1,2})?))?$"); if(!match.Success)throw new ArgumentException("客户期望金额请填写金额或区间,例如 4500-5000"); if(!decimal.TryParse(match.Groups[1].Value,NumberStyles.Number,CultureInfo.InvariantCulture,out var low) || !decimal.TryParse(match.Groups[2].Success?match.Groups[2].Value:match.Groups[1].Value,NumberStyles.Number,CultureInfo.InvariantCulture,out var high))throw new ArgumentException("客户期望金额超出范围"); if(low<=0 || high999999999)throw new ArgumentException("客户期望金额应大于零,区间上限不能小于下限"); } public static ConsignmentFees Calculate(DbRow row,bool requireSale=false) { var amount=row.Money("amount");var storage=row.Money("storageFee");var mode=row.Text("serviceFeeMode");var value=row.Money("serviceFeeValue"); if(amount<0 || amount>999999999 || storage<0 || storage>999999999 || value<0 || value>999999999)throw new ArgumentException("成交金额和费用应在 0 至 999,999,999 之间"); if(mode.Length>0 && mode is not ("FIXED" or "PERCENT"))throw new ArgumentException("请选择寄卖服务费收取方式"); if(mode=="PERCENT" && value>100)throw new ArgumentException("寄卖服务费比例应在 0% 至 100% 之间"); var service=mode=="PERCENT"?Fees.Round(amount*value/100):mode=="FIXED"?Fees.Round(value):row.Money("commission"); if(service<0)throw new ArgumentException("服务费不能为负数"); if(requireSale)BusinessService.Positive(amount,"实际成交金额"); if((requireSale || amount>0) && service+storage>amount)throw new ArgumentException("服务费和保管费合计不能超过实际成交金额"); return new(service,Fees.Round(storage),Fees.Round(amount-service-storage)); } }