part_ratio.py
4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""
数据模型 - 库销比
"""
from dataclasses import dataclass
from decimal import Decimal
from datetime import datetime
from typing import Optional
@dataclass
class PartRatio:
"""配件库销比数据"""
id: int
group_id: int
brand_id: Optional[int] = None
brand_grouping_id: Optional[int] = None
supplier_id: Optional[int] = None
supplier_name: Optional[str] = None
area_id: Optional[int] = None
area_name: Optional[str] = None
shop_id: int = 0
shop_name: Optional[str] = None
part_id: Optional[int] = None
part_code: str = ""
part_name: Optional[str] = None
part_biz_type: Optional[str] = None
unit_price: Decimal = Decimal("0")
cost_price: Decimal = Decimal("0")
storage_total_cnt: Decimal = Decimal("0")
in_stock_unlocked_cnt: Decimal = Decimal("0")
has_plan_cnt: Decimal = Decimal("0")
on_the_way_cnt: Decimal = Decimal("0")
out_stock_cnt: Decimal = Decimal("0")
storage_locked_cnt: Decimal = Decimal("0")
out_stock_ongoing_cnt: Decimal = Decimal("0")
buy_cnt: int = 0
transfer_cnt: int = 0
gen_transfer_cnt: int = 0
part_tag: Optional[int] = None
stock_age: Optional[int] = None
unit: Optional[str] = None
out_times: Optional[int] = None
statistics_date: str = ""
@property
def valid_storage_cnt(self) -> Decimal:
"""有效库存数量 = 在库未锁 + 在途 + 计划数"""
return self.in_stock_unlocked_cnt + self.on_the_way_cnt + self.has_plan_cnt
@property
def valid_storage_amount(self) -> Decimal:
"""有效库存金额"""
return self.valid_storage_cnt * self.cost_price
@property
def avg_sales_cnt(self) -> Decimal:
"""平均销量 (90天出库数 + 未关单已锁 + 未关单出库 + 订件) / 3"""
total = (self.out_stock_cnt or Decimal("0")) + self.storage_locked_cnt + self.out_stock_ongoing_cnt + Decimal(str(self.buy_cnt))
return total / Decimal("3")
@property
def avg_sales_amount(self) -> Decimal:
"""平均销量金额"""
return self.avg_sales_cnt * self.cost_price
@property
def current_ratio(self) -> Decimal:
"""当前库销比"""
if self.avg_sales_cnt == 0:
return Decimal("999")
return self.valid_storage_cnt / self.avg_sales_cnt
@classmethod
def from_dict(cls, data: dict) -> "PartRatio":
"""从字典创建"""
return cls(
id=data.get("id", 0),
group_id=data.get("group_id", 0),
brand_id=data.get("brand_id"),
brand_grouping_id=data.get("brand_grouping_id"),
supplier_id=data.get("supplier_id"),
supplier_name=data.get("supplier_name"),
area_id=data.get("area_id"),
area_name=data.get("area_name"),
shop_id=data.get("shop_id", 0),
shop_name=data.get("shop_name"),
part_id=data.get("part_id"),
part_code=data.get("part_code", ""),
part_name=data.get("part_name"),
part_biz_type=data.get("part_biz_type"),
unit_price=Decimal(str(data.get("unit_price", 0))),
cost_price=Decimal(str(data.get("cost_price", 0))),
storage_total_cnt=Decimal(str(data.get("storage_total_cnt", 0))),
in_stock_unlocked_cnt=Decimal(str(data.get("in_stock_unlocked_cnt", 0))),
has_plan_cnt=Decimal(str(data.get("has_plan_cnt", 0))),
on_the_way_cnt=Decimal(str(data.get("on_the_way_cnt", 0))),
out_stock_cnt=Decimal(str(data.get("out_stock_cnt", 0))),
storage_locked_cnt=Decimal(str(data.get("storage_locked_cnt", 0))),
out_stock_ongoing_cnt=Decimal(str(data.get("out_stock_ongoing_cnt", 0))),
buy_cnt=int(data.get("buy_cnt", 0)),
transfer_cnt=int(data.get("transfer_cnt", 0)),
gen_transfer_cnt=int(data.get("gen_transfer_cnt", 0)),
part_tag=data.get("part_tag"),
stock_age=data.get("stock_age"),
unit=data.get("unit"),
out_times=data.get("out_times"),
statistics_date=data.get("statistics_date", ""),
)