-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinventory.py
More file actions
172 lines (146 loc) · 5.74 KB
/
inventory.py
File metadata and controls
172 lines (146 loc) · 5.74 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import pandas as pd
import numpy as np
# TODO decide whether a flask app or CLI is better
# a flask app would include the ability to upload the csvs
# ? porque no los dos
# TODO the way files are managed will need to be updated
TCG_PRICE_FILE = "tcg-full-magic-inventory.csv"
TCG_INVENTORY_FILE = "tcg-inventory.csv"
INVENTORY_FILE = "sell_inventory.csv"
OUTPUT_FILE = "output.csv"
SHIPPING_COST = 1.33
def clean_inventory_condition(df: pd.DataFrame) -> pd.DataFrame:
"""The locally scanned inventory stores conditions differently than
the TCG Player seller inventory. This function corrects the local inventory
to match the TCG formatting
Args:
df (pd.DataFrame): The local inventory
Returns:
pd.DataFrame: Local inventory cleaned up
"""
df.loc[df["Printing"] == "Foil", "Condition"] += " Foil"
return df
def update_tcg_inventory(df_tcg: pd.DataFrame, df_inventory: pd.DataFrame):
"""Update TCG Player store inventory from local file
Args:
df_tcg (pd.DataFrame): Dataframe for current TCG player inventory
df_inventory (pd.DataFrame): Scanned inventory to be added
"""
# TODO this should probably output a dataframe
df_inventory_cleaned = clean_inventory_condition(df_inventory)
df_merged = pd.merge(
df_tcg,
df_inventory_cleaned,
left_on="TCGplayer Id",
right_on="SKU",
how="inner",
suffixes=("", "_inventory"),
)
process_purchase(df_merged)
df_merged["Add to Quantity"] = df_merged["Quantity"]
update_inventory_pricing(df_merged)
df_final = df_merged[df_tcg.columns]
update_tcg_pricing(df_final)
def determine_purchase_type(row: pd.DataFrame) -> str:
try:
x = float(row["TCG Low Price"])
except ValueError:
return "Purchase"
if x < 2:
return "Donation"
else:
return "Purchase"
def process_purchase(df: pd.DataFrame) -> None:
df_purchase = df[
["Product Name", "Set Name", "Condition", "TCG Low Price", "Add to Quantity"]
].copy()
# Apply the function to create a new column
df_purchase["Sale Type"] = df_purchase.apply(determine_purchase_type, axis=1)
# Reorder the columns as desired
df_purchase = df_purchase[
[
"Product Name",
"Set Name",
"Condition",
"Sale Type",
"TCG Low Price",
"Add to Quantity",
]
]
df_purchase.to_csv("purchase.csv", index=False)
def update_inventory_pricing(df: pd.DataFrame):
"""Take a dataframe in TCG player inventory settings, update the listed price to lowest price
This is used when adding a local scanned inventory to the larger store
Or as a fall back
Args:
df (pd.DataFrame): TCG player inventory
"""
# TODO this should ouput a dataframe
df["TCG Marketplace Price"] = df["TCG Low Price With Shipping"].fillna(
df["TCG Market Price"]
)
df.to_csv("output.csv", index=False)
def update_tcg_pricing(df: pd.DataFrame):
"""Take a dataframe for a TCG player store inventory and adjust prices
based on a specific strategy
Args:
df (pd.DataFrame): TCG Player store inventory
"""
# TODO this should return a dataframe
# TODO add a way to change the pricing strategy
try:
# Iterate over each row in the dataframe
for index, row in df.iterrows():
low_price_with_shipping = row["TCG Low Price With Shipping"]
market_price = row["TCG Market Price"]
# Check the condition and update the "TCG Marketplace Price" column accordingly
diff = market_price - low_price_with_shipping
# if the low price is greater than the market price
if diff < 0:
# set the price to be 125% of the way between the lowest listing and the market price
price = round(market_price + abs(diff) * 1.25, 2) - SHIPPING_COST
if price < 0.50:
# anything below 50 cents loses money
df.at[index, "TCG Marketplace Price"] = 0.50
else:
df.at[index, "TCG Marketplace Price"] = price
elif diff >= 0:
price = (
round(
low_price_with_shipping + (diff / 2),
2,
)
- SHIPPING_COST
)
if price < 0.50:
df.at[index, "TCG Marketplace Price"] = 0.50
else:
df.at[index, "TCG Marketplace Price"] = price
else:
# effectively a fail state cause what are the odds the lowest listed price is exactly market value
df.at[index, "TCG Marketplace Price"] = low_price_with_shipping
df.to_csv("output.csv", index=False)
except TypeError:
# this happens when for some reason and entry in the dataframe is NaN
update_inventory_pricing(df)
def update_staged_pricing(df: pd.DataFrame):
process_purchase(df)
update_tcg_pricing(df)
if __name__ == "__main__":
t = input(
"Are you updating inventory, updating pricing or updating staged inventory? "
)
if t.lower() == "inventory":
df_tcg = pd.read_csv(TCG_PRICE_FILE, keep_default_na=False, low_memory=False)
df_inventory = pd.read_csv(INVENTORY_FILE, keep_default_na=False)
update_tcg_inventory(df_tcg, df_inventory)
elif t.lower() == "pricing":
df = pd.read_csv(TCG_INVENTORY_FILE)
update_tcg_pricing(df)
elif t.lower() == "staged":
df = pd.read_csv(TCG_INVENTORY_FILE)
update_staged_pricing(df)
else:
print(
'The only valid responses are "inventory" or "pricing". Please try again.'
)