Spaces:
Sleeping
Sleeping
File size: 8,519 Bytes
c8070f0 2e71512 30ec96f e31db5b 998189d 71c9c71 e31db5b fd49148 e31db5b 998189d b410d5b 998189d 94781fc b410d5b 998189d 94781fc 998189d c8070f0 2e71512 6f80885 fa9147a 2e71512 e31db5b fa9147a 30ec96f fa9147a 2e71512 30ec96f fa9147a 2241ab1 2e71512 2241ab1 2e71512 998189d 2e71512 dc19751 6f80885 a5eabd0 dc19751 bb6d835 71c9c71 bb6d835 998189d 67ef6b6 998189d 67ef6b6 998189d bb6d835 998189d bb6d835 998189d 67ef6b6 998189d 67ef6b6 998189d bba3ce6 4d33aa0 502f088 bba3ce6 4d33aa0 998189d 4d33aa0 b410d5b 998189d b410d5b 998189d fa9147a 998189d a97dcd6 998189d 94781fc 998189d bb6d835 998189d 13663b1 94781fc 13663b1 94781fc fd49148 998189d b410d5b fd49148 998189d 13663b1 e31db5b 13663b1 998189d e31db5b 998189d 550fc9d 998189d 94781fc 998189d |
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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
import streamlit as st
import pandas as pd
import requests
from datetime import datetime
from dotenv import load_dotenv
import os
import time
from datetime import datetime, date, timedelta
import re
load_dotenv()
base_url = os.getenv("BASE_URL")
#setup base config for streamlit
st.set_page_config(layout="wide")
# Cache to store requests
# cache = {}
later_time = (datetime.now() + timedelta(hours=7))
# Init variable
if "cache" not in st.session_state:
print('cache not in session...')
st.session_state.cache = {}
if "last_data" not in st.session_state:
st.session_state.last_data = {}
if "param" not in st.session_state:
st.session_state.param = {}
# Set the page to full width
print('>>>> start over <<<<<')
# Streamlit app
# st.title("Stock Movement Data")
# Function to make API request
# @st.cache_data
def make_api_request():
# Replace the following URL with your actual API endpoint
api_url = base_url + "/v1/simulation/fifo"
start_datetime = datetime.combine(start_date, start_time)
start_date_millis = (int(start_datetime.timestamp()) - (7 * 60 * 60)) * 1000
# start_date_str = start_date.strftime("%Y-%m-%d")
# print('--- timestamp', start_date_str)
# start_date_millis = int(datetime.strptime(start_date_str, "%Y-%m-%d").timestamp()) * 1000 - (7 * 60 * 60 )
# print(start_date_millis)
# Make the API request with query parameters
params = {"product": product_name, "outlet": outlet_name, "start_date": start_date_millis}
print(f'---> make a request: {params}')
response = requests.get(api_url, params=params)
if response.status_code == 200:
# print('response ', response.json())
return response.json()
else:
st.error(f"Error: {response.status_code}")
print('request err: ', response)
return None
# Function to format date
def format_date(date_str):
if date_str == 0 or pd.isna(date_str) or date_str is None:
return 0
# Convert date to datetime, add 7 hours, and format it
formatted_date = pd.to_datetime(date_str, unit='ms') + pd.to_timedelta("7 hours")
return formatted_date.strftime("%d/%m/%Y %H:%M")
def remove_trailing_zeros(num):
# return "{:.1f}".format(num).rstrip('0').rstrip('.')
num = f"{num:.3f}"
return re.sub(r'\.?0+$', '', str(num))
def format_df(data):
tables = []
if data == '' : return tables
df = pd.json_normalize(data)
# Check if column exists (number)
for col in ["price", "created_at"]:
if col not in df.columns:
# If not, add the column and fill with NaN or other default
df[col] = 0
# Check if column exists (sting)
for col in ["stock_out_source", "stock_out_id"]:
if col not in df.columns:
# If not, add the column and fill with NaN or other default
df[col] = ""
df['stock_out_origin'] = df['stock_out'].astype(float)
df["stock in"] = df["stock_in_source"] + " #" + df["stock_in_id"].astype(str)
df["stock out"] = df["stock_out_source"] + " #" + df["stock_out_id"].astype(str)
df["date_in"] = df["created_at_in"].apply(format_date)
df["date_out"] = df["created_at"].apply(format_date)
df['stock_out'] = df['stock_out'].apply(remove_trailing_zeros)
df['stock_out_total'] = df['stock_out_total'].apply(remove_trailing_zeros)
fill_values = {'price': 0, 'created_at': 0}
df = df.fillna(value=fill_values)
# Group by stock_price_id and aggregate details
grouped_data = df.groupby("stock_price_id").agg(
{"product_name": "first", "outlet_name": "first", "price": "first",
"stock_in": "first", "stock_out_total": "first", "stock_in_source": "first",
"stock_in_id": "first", "stock in": "first", "date_in":"first", "created_at_in": "first"}
).reset_index()
grouped_data = grouped_data.sort_values(by="created_at_in")
# Iterate through groups and display main and detail tables
for index, row in grouped_data.iterrows():
main_table = pd.DataFrame([row], columns=["stock in", "price", "stock_in"])
main_table['price'] = main_table['price'].apply(remove_trailing_zeros)
main_table['stock_out'] = row['stock_out_total']
main_table['date_in'] = row['date_in']
detail_data = df[df["stock_price_id"] == row["stock_price_id"]]
detail_table = detail_data[["stock out", "stock_out", "date_out"]]
# detail_table['stock_out_origin'] = detail_data['stock_out'].astype(float)
tables.append({'main': main_table,
'detail': detail_table})
return tables
def show_table():
st.write("### Fifo Table")
st.write(f'Product: **{product_name}**, Outlet: **{outlet_name}**, Start Date: **{start_date}** **{start_time}**')
# Make the API request
api_data = make_api_request()
if api_data and api_data['data'] is None:
st.write("No data found. Make sure to stock opname the product!")
if api_data and api_data["data"]:
# st.json(api_data)
timestamp = later_time.strftime("%H:%M:%S") #time.strftime("%H:%M:%S")
st.session_state.cache[timestamp] = api_data['data']
st.session_state.last_data = api_data['data']
# Convert API response to DataFrame
tables = format_df(api_data["data"])
for table in tables:
# Create two columns for the layout
col1, col2 = st.columns(2)
# Display main table
col1.table(table['main'])
# Display detail table with specific columns if the checkbox is checked
if show_detail:
col2.table(table['detail'])
# col2.markdown(f'**Total: {table["detail"]["stock_out_origin"].sum()}**')
st.write("------")
with st.sidebar.form("filter"):
# Input fields
outlet_suggestios = ['Toko Oke', 'Drawing Franco Studio', 'Dr Franco']
product_name = st.text_input("Product Name")
outlet_name = st.text_input("Outlet Name", autocomplete='Toko Oke')
with st.expander("Show More"):
start_date = st.date_input("Start Date (stock in)", value = date.today().replace(day = 1))
start_time = st.time_input("Start Time (stock in)", value = datetime.min )
show_detail = st.checkbox("Show Detail Table", value=True)# Checkbox to show/hide detail table
print('product-name: ', product_name)
submitted = st.form_submit_button("Apply")# on_click=show_table
if submitted:
print('submit....', product_name)
show_table()
with st.sidebar.form("edit_form"):
st.write("## Edit the data")
stock_key = st.text_input("Table Key (e.g. stock_opname #802)")
stock_in = st.number_input("Updated Qty Stock In", min_value=0)
update = st.form_submit_button("Update")
if update:
# Extract stock_in_source and stock_in_id from stock_key
stock_in_source, stock_in_id = stock_key.split("#")
# Prepare data for the API request
data = {
"qty": stock_in,
"stock_in_source": stock_in_source.strip(),
"stock_in_id": stock_in_id.strip()
}
print('--- update: ', data)
# API endpoint
api_url = base_url + "/v1/simulation/fifo"
# Make the PUT request
response = requests.put(api_url, data=data)
if response.status_code == 200:
st.success("Update successful!")
show_table()
else:
st.error(f"Update failed. Status code: {response.status_code}")
st.write("### History")
cache = st.session_state.cache
#if cache empty, set default
print('size:: ', len(cache.keys()))
if cache is None or len(cache.keys()) == 0:
cache = {'None': ''}
tabs_title = list(cache.keys())
tabs = st.tabs(tabs_title)
for tab, key in zip(tabs, list(cache.keys())):
with tab:
if st.button('Show', key=key):
data = cache[key]
tables = format_df(data)
st.write(f'History of **{data[0]["product_name"]}**, at **{data[0]["outlet_name"]}**')
for table in tables:
col1, col2 = st.columns(2)
col1.write(table['main'])
col2.write(table['detail'])
st.write("---")
# show_table()
with st.sidebar.form('form_cache'):
if st.form_submit_button("Clear Cache"):
if "cache" in st.session_state:
del st.session_state["cache"]
st.session_state.cache = {}
|