Spaces:
Sleeping
Sleeping
poemsforaphrodite
commited on
Commit
•
293baf4
1
Parent(s):
5f30d96
Update app.py
Browse files
app.py
CHANGED
@@ -8,6 +8,9 @@ from openai import OpenAI
|
|
8 |
import uuid
|
9 |
import re
|
10 |
import time
|
|
|
|
|
|
|
11 |
|
12 |
# Load environment variables from .env file
|
13 |
load_dotenv()
|
@@ -157,13 +160,18 @@ def generate_answer(query, context):
|
|
157 |
print(f"Error generating answer: {str(e)}")
|
158 |
return f"Error generating answer: {str(e)}"
|
159 |
|
160 |
-
def generate_hr_document(
|
161 |
-
print(f"Generating HR document
|
162 |
try:
|
|
|
|
|
|
|
|
|
|
|
163 |
response = client.chat.completions.create(
|
164 |
-
model="gpt-4o-mini",
|
165 |
messages=[
|
166 |
-
{"role": "system", "content": "You are an HR assistant. Generate a professional HR document based on the given
|
167 |
{"role": "user", "content": prompt}
|
168 |
]
|
169 |
)
|
@@ -172,11 +180,38 @@ def generate_hr_document(prompt):
|
|
172 |
print(f"Error generating HR document: {str(e)}")
|
173 |
return f"Error generating HR document: {str(e)}"
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
def main():
|
176 |
st.set_page_config(page_title="HR Document Assistant", layout="wide")
|
177 |
st.title("HR Document Assistant")
|
178 |
|
179 |
-
tab1, tab2, tab3, tab4 = st.tabs(["📤 Upload PDF", "🔍 Query Database", "📝 Generate HR Document", "🗑️ Clear Database"])
|
180 |
|
181 |
with tab1:
|
182 |
st.header("Upload PDF")
|
@@ -201,13 +236,91 @@ def main():
|
|
201 |
|
202 |
with tab3:
|
203 |
st.header("Generate HR Document")
|
204 |
-
st.write("
|
205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
if st.button("✍️ Generate Document"):
|
207 |
-
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
|
210 |
with tab4:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
st.header("Clear Database")
|
212 |
st.write("Use this option carefully. It will remove all data from the Pinecone index.")
|
213 |
if st.button("🗑️ Clear Database"):
|
|
|
8 |
import uuid
|
9 |
import re
|
10 |
import time
|
11 |
+
import pandas as pd
|
12 |
+
import matplotlib.pyplot as plt
|
13 |
+
import seaborn as sns
|
14 |
|
15 |
# Load environment variables from .env file
|
16 |
load_dotenv()
|
|
|
160 |
print(f"Error generating answer: {str(e)}")
|
161 |
return f"Error generating answer: {str(e)}"
|
162 |
|
163 |
+
def generate_hr_document(document_type, additional_info):
|
164 |
+
print(f"Generating HR document: {document_type}")
|
165 |
try:
|
166 |
+
prompt = f"""Generate a professional {document_type} for an HR department.
|
167 |
+
Additional information: {additional_info}
|
168 |
+
|
169 |
+
Important: Format the response as plain text, not markdown. Use appropriate line breaks and spacing for readability."""
|
170 |
+
|
171 |
response = client.chat.completions.create(
|
172 |
+
model="gpt-4o-mini",
|
173 |
messages=[
|
174 |
+
{"role": "system", "content": "You are an expert HR assistant. Generate a professional HR document based on the given type and additional information. Format the response as plain text, not markdown."},
|
175 |
{"role": "user", "content": prompt}
|
176 |
]
|
177 |
)
|
|
|
180 |
print(f"Error generating HR document: {str(e)}")
|
181 |
return f"Error generating HR document: {str(e)}"
|
182 |
|
183 |
+
def calculate_paye(annual_income):
|
184 |
+
tax_bands = [
|
185 |
+
(5880, 0),
|
186 |
+
(1320, 0.05),
|
187 |
+
(1560, 0.10),
|
188 |
+
(38000, 0.175),
|
189 |
+
(192000, 0.25),
|
190 |
+
(366240, 0.30),
|
191 |
+
(float('inf'), 0.35)
|
192 |
+
]
|
193 |
+
|
194 |
+
remaining_income = annual_income
|
195 |
+
total_tax = 0
|
196 |
+
|
197 |
+
for band, rate in tax_bands:
|
198 |
+
if remaining_income <= 0:
|
199 |
+
break
|
200 |
+
taxable_amount = min(band, remaining_income)
|
201 |
+
tax = taxable_amount * rate
|
202 |
+
total_tax += tax
|
203 |
+
remaining_income -= taxable_amount
|
204 |
+
|
205 |
+
return total_tax
|
206 |
+
|
207 |
+
def calculate_ssnit(basic_salary):
|
208 |
+
return basic_salary * 0.055
|
209 |
+
|
210 |
def main():
|
211 |
st.set_page_config(page_title="HR Document Assistant", layout="wide")
|
212 |
st.title("HR Document Assistant")
|
213 |
|
214 |
+
tab1, tab2, tab3, tab4, tab5 = st.tabs(["📤 Upload PDF", "🔍 Query Database", "📝 Generate HR Document", "🧮 Tax Calculator", "🗑️ Clear Database"])
|
215 |
|
216 |
with tab1:
|
217 |
st.header("Upload PDF")
|
|
|
236 |
|
237 |
with tab3:
|
238 |
st.header("Generate HR Document")
|
239 |
+
st.write("Select an HR document type and provide additional information to generate the document.")
|
240 |
+
|
241 |
+
document_types = [
|
242 |
+
"Employment Contract", "Offer Letter", "Job Description", "Employee Handbook",
|
243 |
+
"Performance Review Form", "Disciplinary Action Form", "Leave Request Form",
|
244 |
+
"Onboarding Checklist", "Termination Letter", "Non-Disclosure Agreement (NDA)",
|
245 |
+
"Code of Conduct", "Workplace Policy", "Benefits Summary", "Compensation Plan",
|
246 |
+
"Training and Development Plan", "Resignation Letter", "Exit Interview Form",
|
247 |
+
"Employee Grievance Form", "Time-off Request Form", "Workplace Safety Guidelines"
|
248 |
+
]
|
249 |
+
|
250 |
+
selected_document = st.selectbox("Select HR Document Type", document_types)
|
251 |
+
additional_info = st.text_area("Additional Information",
|
252 |
+
placeholder="Enter any specific details or requirements for the document...")
|
253 |
+
|
254 |
if st.button("✍️ Generate Document"):
|
255 |
+
with st.spinner("Generating document..."):
|
256 |
+
document = generate_hr_document(selected_document, additional_info)
|
257 |
+
st.subheader(f"Generated {selected_document}")
|
258 |
+
st.text_area("Document Content", value=document, height=400)
|
259 |
+
st.download_button(
|
260 |
+
label="Download Document",
|
261 |
+
data=document,
|
262 |
+
file_name=f"{selected_document.lower().replace(' ', '_')}.txt",
|
263 |
+
mime="text/plain"
|
264 |
+
)
|
265 |
|
266 |
with tab4:
|
267 |
+
st.header("Tax Calculator")
|
268 |
+
st.write("Calculate PAYE and SSNIT contributions based on annual income and basic salary.")
|
269 |
+
|
270 |
+
salary_examples = {
|
271 |
+
"Entry Level": (36000, 30000),
|
272 |
+
"Mid Level": (72000, 60000),
|
273 |
+
"Senior Level": (120000, 90000),
|
274 |
+
"Executive": (240000, 180000)
|
275 |
+
}
|
276 |
+
|
277 |
+
selected_example = st.selectbox("Select a salary example or enter custom values:",
|
278 |
+
["Custom"] + list(salary_examples.keys()))
|
279 |
+
|
280 |
+
if selected_example == "Custom":
|
281 |
+
annual_income = st.number_input("Annual Income (GH₵)", min_value=0.0, value=0.0, step=1000.0)
|
282 |
+
basic_salary = st.number_input("Basic Salary (GH₵)", min_value=0.0, value=0.0, step=1000.0)
|
283 |
+
else:
|
284 |
+
annual_income, basic_salary = salary_examples[selected_example]
|
285 |
+
st.write(f"Annual Income: GH₵ {annual_income:.2f}")
|
286 |
+
st.write(f"Basic Salary: GH₵ {basic_salary:.2f}")
|
287 |
+
|
288 |
+
if st.button("Calculate Taxes"):
|
289 |
+
ssnit_contribution = calculate_ssnit(basic_salary)
|
290 |
+
taxable_income = annual_income - ssnit_contribution
|
291 |
+
paye = calculate_paye(taxable_income)
|
292 |
+
net_income = annual_income - ssnit_contribution - paye
|
293 |
+
|
294 |
+
col1, col2 = st.columns(2)
|
295 |
+
|
296 |
+
with col1:
|
297 |
+
st.subheader("Tax Breakdown")
|
298 |
+
st.write(f"SSNIT Contribution: GH₵ {ssnit_contribution:.2f}")
|
299 |
+
st.write(f"PAYE: GH₵ {paye:.2f}")
|
300 |
+
st.write(f"Total Deductions: GH₵ {(ssnit_contribution + paye):.2f}")
|
301 |
+
st.write(f"Net Income: GH₵ {net_income:.2f}")
|
302 |
+
|
303 |
+
with col2:
|
304 |
+
# Pie chart for income breakdown
|
305 |
+
fig, ax = plt.subplots(figsize=(3, 2))
|
306 |
+
sizes = [ssnit_contribution, paye, net_income]
|
307 |
+
labels = ['SSNIT', 'PAYE', 'Net']
|
308 |
+
colors = ['#ff9999', '#66b3ff', '#99ff99']
|
309 |
+
ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90, textprops={'fontsize': 6})
|
310 |
+
ax.axis('equal')
|
311 |
+
plt.title("Income Breakdown", fontsize=8)
|
312 |
+
st.pyplot(fig)
|
313 |
+
|
314 |
+
# Display tax rates by income bracket as a table
|
315 |
+
st.subheader("Tax Rates by Income Bracket")
|
316 |
+
tax_data = {
|
317 |
+
"Income Range (GH₵)": ["0 - 5,880", "5,881 - 7,200", "7,201 - 8,760", "8,761 - 46,760", "46,761 - 238,760", "238,761 - 605,000", "Above 605,000"],
|
318 |
+
"Rate (%)": [0, 5, 10, 17.5, 25, 30, 35]
|
319 |
+
}
|
320 |
+
df = pd.DataFrame(tax_data)
|
321 |
+
st.table(df)
|
322 |
+
|
323 |
+
with tab5:
|
324 |
st.header("Clear Database")
|
325 |
st.write("Use this option carefully. It will remove all data from the Pinecone index.")
|
326 |
if st.button("🗑️ Clear Database"):
|