using System.Text.Json;
namespace JiDangJia.Core;
public static class ItemCatalog
{
public static readonly Dictionary<string,string> Categories = new()
{ ["METAL"]="贵金属", ["LUXURY"]="奢侈品", ["JEWELRY"]="珠宝/饰品", ["WATCH"]="名表", ["ELECTRONICS"]="电子产品", ["VEHICLE"]="车辆", ["PROPERTY"]="房产", ["OTHER"]="其他" };
public static readonly Dictionary<string,string> Materials = new()
{ ["GOLD"]="黄金", ["SILVER"]="白银", ["PLATINUM"]="铂金", ["OTHER"]="其他" };
public static readonly Dictionary<string,string> AttributeLabels = new()
{ ["model"]="型号", ["purity"]="成色", ["certificate"]="证书编号", ["storage"]="存储容量", ["condition"]="品相", ["plateNo"]="车牌号", ["vin"]="车架号", ["mileage"]="里程(公里)", ["address"]="房产地址", ["area"]="面积(平方米)", ["certNo"]="产权证号" };
public static Dictionary<string,string> Choices(string kind) => kind=="CONSIGN"
? new[]{"METAL","LUXURY","WATCH","JEWELRY","ELECTRONICS","VEHICLE","OTHER"}.ToDictionary(k=>k,k=>Categories[k])
: Categories.Where(p=>kind is not ("RECYCLE" or "PURCHASE") || p.Key is not ("VEHICLE" or "PROPERTY")).ToDictionary(p=>p.Key,p=>p.Value);
public static string Category(string type) => type is "GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM" ? "METAL" : type;
public static string Material(DbRow item)
{
var type=item.Text("type",item.Text("itemType"));
if(type is "GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM")return type;
var material=item.Text("material");
if(material.Length==0 && item.Text("extraAttributes").Length>0)
try { using var d=JsonDocument.Parse(item.Text("extraAttributes"));if(d.RootElement.TryGetProperty("material",out var m))material=m.ToString(); } catch(JsonException) { }
return material switch {"黄金"=>"GOLD","白银"=>"SILVER","铂金"=>"PLATINUM","钯金"=>"PALLADIUM",_=>material.Length==0?"OTHER":material};
}
public static string MaterialName(string material) => material=="PALLADIUM"?"钯金":Materials.GetValueOrDefault(material,material);
public static string ItemName(DbRow item)
{
var type=item.Text("type",item.Text("itemType"));
return Category(type)=="METAL" ? "贵金属 · "+MaterialName(Material(item)) : Categories.GetValueOrDefault(type,Display.Item(type));
}
public static string NewCode() => "JD"+DateTime.Today.ToString("yyyyMMdd")+Guid.NewGuid().ToString("N")[..8].ToUpperInvariant();
public static bool StockMatches(DbRow item,string category) => category switch
{
"ALL"=>true,
"GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM"=>Category(item.Text("type"))=="METAL" && Material(item)==category,
"METAL_OTHER"=>Category(item.Text("type"))=="METAL" && Material(item)=="OTHER",
_=>Category(item.Text("type"))==category
};
public static string? QuoteKey(DbRow item) => Category(item.Text("type"))=="METAL" ? Material(item) switch
{ "GOLD"=>"gold", "SILVER"=>"silver", "PLATINUM"=>"platinum", _=>null } : null;
}
public sealed record MetalTotals(decimal Cost,decimal Weight,decimal? Average,decimal? Value)
{
public decimal? Gain => Value.HasValue ? Fees.Round(Value.Value-Cost) : null;
public decimal? Yield => Gain.HasValue && Cost>0 ? Gain.Value/Cost*100 : null;
}
public static class InventoryAnalytics
{
public static MetalTotals Metal(IEnumerable<DbRow> records,IReadOnlyDictionary<string,decimal> bids)
{
var items=records.ToList();var cost=items.Sum(i=>i.Money("amount"));var weight=items.Sum(i=>i.Money("weight"));
bool complete=items.Count>0 && items.All(i=>i.Money("weight")>0);
decimal? average=complete && weight>0 ? cost/weight : null;
decimal? value=complete && items.All(i=>ItemCatalog.QuoteKey(i) is string key && bids.GetValueOrDefault(key)>0)
? Fees.Round(items.Sum(i=>i.Money("weight")*bids[ItemCatalog.QuoteKey(i)!])) : null;
return new(cost,weight,average,value);
}
}
using System.Text.Json;
namespace JiDangJia.Core;
public static class ItemCatalog
{
public static readonly Dictionary<string,string> Categories = new()
{ ["METAL"]="贵金属", ["LUXURY"]="奢侈品", ["JEWELRY"]="珠宝/饰品", ["WATCH"]="名表", ["ELECTRONICS"]="电子产品", ["VEHICLE"]="车辆", ["PROPERTY"]="房产", ["OTHER"]="其他" };
public static readonly Dictionary<string,string> Materials = new()
{ ["GOLD"]="黄金", ["SILVER"]="白银", ["PLATINUM"]="铂金", ["OTHER"]="其他" };
public static readonly Dictionary<string,string> AttributeLabels = new()
{ ["model"]="型号", ["purity"]="成色", ["certificate"]="证书编号", ["storage"]="存储容量", ["condition"]="品相", ["plateNo"]="车牌号", ["vin"]="车架号", ["mileage"]="里程(公里)", ["address"]="房产地址", ["area"]="面积(平方米)", ["certNo"]="产权证号" };
public static Dictionary<string,string> Choices(string kind) => kind=="CONSIGN"
? new[]{"METAL","LUXURY","WATCH","JEWELRY","ELECTRONICS","VEHICLE","OTHER"}.ToDictionary(k=>k,k=>Categories[k])
: Categories.Where(p=>kind is not ("RECYCLE" or "PURCHASE") || p.Key is not ("VEHICLE" or "PROPERTY")).ToDictionary(p=>p.Key,p=>p.Value);
public static string Category(string type) => type is "GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM" ? "METAL" : type;
public static string Material(DbRow item)
{
var type=item.Text("type",item.Text("itemType"));
if(type is "GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM")return type;
var material=item.Text("material");
if(material.Length==0 && item.Text("extraAttributes").Length>0)
try { using var d=JsonDocument.Parse(item.Text("extraAttributes"));if(d.RootElement.TryGetProperty("material",out var m))material=m.ToString(); } catch(JsonException) { }
return material switch {"黄金"=>"GOLD","白银"=>"SILVER","铂金"=>"PLATINUM","钯金"=>"PALLADIUM",_=>material.Length==0?"OTHER":material};
}
public static string MaterialName(string material) => material=="PALLADIUM"?"钯金":Materials.GetValueOrDefault(material,material);
public static string ItemName(DbRow item)
{
var type=item.Text("type",item.Text("itemType"));
return Category(type)=="METAL" ? "贵金属 · "+MaterialName(Material(item)) : Categories.GetValueOrDefault(type,Display.Item(type));
}
public static string NewCode() => "JD"+DateTime.Today.ToString("yyyyMMdd")+Guid.NewGuid().ToString("N")[..8].ToUpperInvariant();
public static bool StockMatches(DbRow item,string category) => category switch
{
"ALL"=>true,
"GOLD" or "SILVER" or "PLATINUM" or "PALLADIUM"=>Category(item.Text("type"))=="METAL" && Material(item)==category,
"METAL_OTHER"=>Category(item.Text("type"))=="METAL" && Material(item)=="OTHER",
_=>Category(item.Text("type"))==category
};
public static string? QuoteKey(DbRow item) => Category(item.Text("type"))=="METAL" ? Material(item) switch
{ "GOLD"=>"gold", "SILVER"=>"silver", "PLATINUM"=>"platinum", _=>null } : null;
}
public sealed record MetalTotals(decimal Cost,decimal Weight,decimal? Average,decimal? Value)
{
public decimal? Gain => Value.HasValue ? Fees.Round(Value.Value-Cost) : null;
public decimal? Yield => Gain.HasValue && Cost>0 ? Gain.Value/Cost*100 : null;
}
public static class InventoryAnalytics
{
public static MetalTotals Metal(IEnumerable<DbRow> records,IReadOnlyDictionary<string,decimal> bids)
{
var items=records.ToList();var cost=items.Sum(i=>i.Money("amount"));var weight=items.Sum(i=>i.Money("weight"));
bool complete=items.Count>0 && items.All(i=>i.Money("weight")>0);
decimal? average=complete && weight>0 ? cost/weight : null;
decimal? value=complete && items.All(i=>ItemCatalog.QuoteKey(i) is string key && bids.GetValueOrDefault(key)>0)
? Fees.Round(items.Sum(i=>i.Money("weight")*bids[ItemCatalog.QuoteKey(i)!])) : null;
return new(cost,weight,average,value);
}
}