Alasil commited on
Commit
ea19f65
·
verified ·
1 Parent(s): 0f6b17b

Upload 3 files

Browse files
Files changed (3) hide show
  1. order_&_profit_tracker.py +199 -0
  2. requirements.txt +3 -3
  3. secrets.toml +15 -0
order_&_profit_tracker.py ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Order & Profit Tracker
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1fHxAYay8sQTVp2vNAkLi-v7B67e37eu4
8
+ """
9
+
10
+ import streamlit as st
11
+ import pandas as pd
12
+ import json
13
+ import firebase_admin
14
+ from firebase_admin import credentials, firestore
15
+
16
+ # --- Firebase Initialization and Authentication ---
17
+
18
+ # Check if Firebase app is already initialized
19
+ if not firebase_admin._apps:
20
+ # Use Streamlit secrets to securely store Firebase credentials
21
+ try:
22
+ cred_dict = json.loads(st.secrets["firebase"]["service_account_key"])
23
+ cred = credentials.Certificate(cred_dict)
24
+ firebase_admin.initialize_app(cred)
25
+ except Exception as e:
26
+ st.error("❌ Firebase credentials are not configured correctly. Please check your Streamlit secrets.")
27
+ st.stop()
28
+
29
+ db = firestore.client()
30
+
31
+ # A simple password-based authentication for the team
32
+ def check_password():
33
+ """Returns `True` if the user is authenticated, `False` otherwise."""
34
+ st.markdown("---")
35
+ st.subheader("تسجيل الدخول")
36
+
37
+ password = st.secrets["app_password"]
38
+ if "password_correct" not in st.session_state:
39
+ st.session_state["password_correct"] = False
40
+
41
+ if not st.session_state["password_correct"]:
42
+ st.text_input("أدخل كلمة مرور التطبيق", type="password", key="auth_password")
43
+ if st.button("تسجيل الدخول"):
44
+ if st.session_state.auth_password == password:
45
+ st.session_state["password_correct"] = True
46
+ st.experimental_rerun()
47
+ else:
48
+ st.warning("كلمة المرور خاطئة. حاول مرة أخرى.")
49
+ return False
50
+ else:
51
+ return True
52
+
53
+ # --- Product Data ---
54
+ # Product data from the user's table (COGS, price, and price with print)
55
+ product_data = {
56
+ 'استيكر': {'cogs': 1, 'price': 5, 'price_with_print': None},
57
+ 'بالطو اوكسفورد': {'cogs': 330, 'price': 430, 'price_with_print': 450},
58
+ 'بالطو جبردين': {'cogs': 210, 'price': 320, 'price_with_print': 340},
59
+ 'قلم عادي': {'cogs': 10, 'price': 20, 'price_with_print': None},
60
+ 'قلم مضيئ': {'cogs': 40, 'price': 60, 'price_with_print': None},
61
+ 'ميدالية': {'cogs': 15, 'price': 35, 'price_with_print': None},
62
+ }
63
+
64
+ # --- Streamlit App UI and Logic ---
65
+
66
+ if not check_password():
67
+ st.stop()
68
+
69
+ # Get a dummy user ID for the sake of the app since we're not using email auth
70
+ # In a real app, you would use a proper user management system
71
+ user_id = "team_member_1"
72
+
73
+ # App title and user info
74
+ st.title("Order & Profit Tracker")
75
+ st.markdown("---")
76
+ st.info(f"مرحباً بك! أنت مسجل الدخول الآن. سيتم حفظ جميع الطلبات الخاصة بك ومشاركتها مع فريقك.")
77
+
78
+ # Order form
79
+ st.subheader("إدخال طلب جديد")
80
+ with st.form("order_form"):
81
+ st.markdown("---")
82
+ col1, col2, col3 = st.columns(3)
83
+ with col1:
84
+ order_id = st.text_input("رقم الطلب", help="مثال: ORD-12345")
85
+ with col2:
86
+ customer_name = st.text_input("اسم العميل", help="مثال: أحمد محمد")
87
+ with col3:
88
+ phone_number = st.text_input("رقم التليفون", help="مثال: 01001234567")
89
+
90
+ col4, col5 = st.columns(2)
91
+ with col4:
92
+ address = st.text_input("العنوان", help="مثال: 10 ش النصر، القاهرة")
93
+ with col5:
94
+ product_status = st.selectbox(
95
+ "حالة المنتج",
96
+ ["قيد التجهيز", "استلم العميل", "تم الإلغاء"]
97
+ )
98
+
99
+ col6, col7 = st.columns(2)
100
+ with col6:
101
+ item_name = st.selectbox("اسم المنتج", list(product_data.keys()))
102
+ with col7:
103
+ with_printing = st.checkbox("مع طباعة/تطريز/لوجو")
104
+
105
+ col8, col9 = st.columns(2)
106
+ with col8:
107
+ quantity = st.number_input("الكمية", min_value=1, value=1)
108
+ with col9:
109
+ packaging_cost = st.number_input("تكلفة التغليف ($)", min_value=0.0, value=0.0, step=0.01)
110
+
111
+ shipping_cost = st.number_input("تكلفة الشحن ($)", min_value=0.0, value=0.0, step=0.01)
112
+
113
+ # Calculate unit price and COGS dynamically
114
+ selected_product_info = product_data.get(item_name)
115
+ if selected_product_info:
116
+ cogs = selected_product_info['cogs']
117
+ unit_price = selected_product_info['price']
118
+ if with_printing and selected_product_info['price_with_print'] is not None:
119
+ unit_price = selected_product_info['price_with_print']
120
+ else:
121
+ cogs = 0
122
+ unit_price = 0
123
+
124
+ st.markdown(f"**سعر الوحدة**: ${unit_price:,.2f}")
125
+ st.markdown(f"**تكلفة البضاعة المباعة (COGS)**: ${cogs:,.2f}")
126
+
127
+ submitted = st.form_submit_button("حساب وحفظ الطلب")
128
+
129
+ if submitted:
130
+ # Perform calculations
131
+ subtotal = quantity * unit_price
132
+ total_costs = (quantity * cogs) + packaging_cost + shipping_cost
133
+ profit = subtotal - total_costs
134
+
135
+ # Display results
136
+ st.subheader("نتائج الطلب")
137
+ results_df = pd.DataFrame({
138
+ 'المبلغ الإجمالي': [f"${subtotal:,.2f}"],
139
+ 'إجمالي التكاليف': [f"${total_costs:,.2f}"],
140
+ 'الربح': [f"${profit:,.2f}"]
141
+ }).T.rename(columns={0: 'القيمة'})
142
+ st.table(results_df)
143
+
144
+ # Save to Firestore
145
+ order_data = {
146
+ 'order_id': order_id,
147
+ 'customer_name': customer_name,
148
+ 'phone_number': phone_number,
149
+ 'address': address,
150
+ 'item_name': item_name,
151
+ 'product_status': product_status,
152
+ 'quantity': quantity,
153
+ 'unit_price': unit_price,
154
+ 'cogs': cogs,
155
+ 'packaging_cost': packaging_cost,
156
+ 'shipping_cost': shipping_cost,
157
+ 'subtotal': subtotal,
158
+ 'total_costs': total_costs,
159
+ 'profit': profit,
160
+ 'user_id': user_id,
161
+ 'timestamp': firestore.SERVER_TIMESTAMP
162
+ }
163
+
164
+ try:
165
+ db.collection("orders").add(order_data)
166
+ st.success("✅ تم حفظ الطلب بنجاح!")
167
+ except Exception as e:
168
+ st.error(f"❌ حدث خطأ أثناء حفظ الطلب: {e}")
169
+
170
+ # Display recent orders
171
+ st.subheader("الطلبات الأخيرة")
172
+ try:
173
+ orders_ref = db.collection("orders")
174
+ orders_query = orders_ref.order_by("timestamp", direction=firestore.Query.DESCENDING).limit(20)
175
+ orders_docs = orders_query.stream()
176
+
177
+ orders = []
178
+ for doc in orders_docs:
179
+ orders.append(doc.to_dict())
180
+
181
+ if orders:
182
+ orders_df = pd.DataFrame(orders)
183
+ orders_df = orders_df.rename(columns={
184
+ 'order_id': 'رقم الطلب',
185
+ 'customer_name': 'العميل',
186
+ 'item_name': 'المنتج',
187
+ 'quantity': 'الكمية',
188
+ 'profit': 'الربح',
189
+ 'product_status': 'الحالة',
190
+ 'timestamp': 'التاريخ',
191
+ 'user_id': 'المستخدم'
192
+ })
193
+ orders_df['التاريخ'] = orders_df['التاريخ'].apply(lambda x: x.strftime("%Y-%m-%d %H:%M:%S") if x else "")
194
+ st.dataframe(orders_df[['رقم الطلب', 'العميل', 'المنتج', 'الكمية', 'الربح', 'الحالة', 'التاريخ', 'المستخدم']])
195
+ else:
196
+ st.info("لا توجد طلبات حتى الآن.")
197
+
198
+ except Exception as e:
199
+ st.error(f"❌ فشل تحميل الطلبات: {e}")
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- altair
2
- pandas
3
- streamlit
 
1
+ streamlit
2
+ pandas
3
+ firebase-admin
secrets.toml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ app_password = "Alasil1"
2
+
3
+ {
4
+ "type": "service_account",
5
+ "project_id": "tracking-ddbab",
6
+ "private_key_id": "3519b60c0bccd2f90423863a9aa3471ed58cade6",
7
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6nYilNASpfD59\n0/1wA8/VgYu/EY5HHBV5eFp4S+PLxH8Eamqx1tA/gVu1qz6kY/f3y+2vkUCmMhZr\nBPMezfCf+yjinUqN/VSS677wfLYnpHoOLmTmwmF7qXNiZcHFiLXzcDMd4FuzE2xV\nabT+Ran1uq2p12+0Bt+W0P/4ySpEWtQP9kakxI2XfDfTVjI4r3X2kiYETTUHeX2e\n6ryzmFhRm5ZpKl93Tzcg+E5tEYNjY41k5omksXpm9tkAhRO+7YsH5xydbOsiPr5e\nTbGNWc1fLdxRGKQdt7P5aThvWD0yJeB3ZgieslWW+TRJevoHTOvLMJnBpc79gmbV\n0xwuSFKzAgMBAAECggEALZ9RxsGe2iiLxotLDFWCO/o9xepu1CejgFzSEVLMUAar\n3tJ9XxjbNItVdmZ1HA9skeIDK8bg/UCFhohhP4itaQ8oAa7eiTQDtx93QKfciHiH\ndmwVMu0Wk/rrQIUMCFTR1r/5XzZ4dKEs/PyoyPkTAgYvarRGlMaRZveVfKcBdFAs\nF6pmz5PxYhr4FAR06VhjgcdkKFsrtjYLbWBsBoO4xnG6ZMliN63NvZ8pYBOSGOdR\nuW//mCeQx5w8AIQxdynVqdhJqD5HEGGpBQSEFWWHlWWfmyXqMOROL0bIFhsow3aD\nIlW4vXAxRKdctcVCL6JOJcphQCLjSYpuA6BfLZuq0QKBgQD/dCInvkfeRrwlSo4T\n0SeljQco0p2/LkhBeS59mkAFzHgEL6blYjG60YQwjNt53cshQhzpTQsf/4uecrqH\n5BYvS3sRb8yKrCNrxDwAQh9t57ib9DCxNXZe5j/1gTjAzYP2Zzj+Infl5igOB4OJ\nBF3vYmWgLVokaigcwCcCLQPytQKBgQC7A7W5DoQVUYL4L864BTaBGDt7vn6ZM6HC\nDXN9+TuzeNwaowk6mcvhC4hUNprrcZF6WCBvOTWIh51HMkxBmWgKy+O6IRGbsoYp\nTcP1M669wRDD+kPt0DdgdTgJCyaxr5S9JsFU9NDHPJ1b3KJoNZN3oWDtlmcHqCDv\ndNTM/b0IxwKBgFKqakMiOG+dxFTtA302OfZA5Qg44AN2HrvRU1IiEIXP3Sa9pOym\nEiG6m2R6sKuHMqzYkDKPVAJO2Ae2aNaA4Qz9CB5kZ3SYr/23yxLqUvFmAz+0je1K\nt7uOFzSDVLJPz1x1muPik5o6GMwxckdsulk1Jl3nTzxpfgGPzQ/PMW/hAoGALh3X\nFSBYP+2Oz2byofxfGWyBVp1+GIdb7z9j6H+qUjKOjF8B6pp8ZS1z29hvUXn69uF+\ndg70fYt7pE/p8A9FUcw/humarvtSDCNqHDA3egF/AeTYFW/QCBA/1jMSwqRamF5T\nNID+bvMqlrmMrwfvKoP4I/5/v6qdHI+B3l7/24cCgYArmz5/Qnd3jrBE7yz+X/un\nc+HTafmdKmij5lFI0i3Q79LzatzDCjC48dN4wvUShaRX8lZy4YU/GmVMiGv3/+i+\nNHnuoOvtyS++mfth+d+Lze73FTetf3ouBAxAvwHeWz2D0GcUSWMFT/C8uEOEVcBe\nUxERWeqlO1EpR+QV2SYIFQ==\n-----END PRIVATE KEY-----\n",
8
+ "client_email": "firebase-adminsdk-fbsvc@tracking-ddbab.iam.gserviceaccount.com",
9
+ "client_id": "112411434751837644720",
10
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
11
+ "token_uri": "https://oauth2.googleapis.com/token",
12
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
13
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40tracking-ddbab.iam.gserviceaccount.com",
14
+ "universe_domain": "googleapis.com"
15
+ }