Version 2 of Employee_contract
Version 2 of Employee_contract
import pandas as pd
from docxtpl import DocxTemplate
import re
from datetime import datetime
import subprocess
import glob
def get_safe_employee_name(full_name):
"""Convert employee name to a safe folder name"""
return re.sub(r'[^\w\s-]', '', full_name).strip().replace(' ', '_')
def clean_employee_folder(folder_path):
"""Remove old DOCX and PDF files from the employee folder"""
for ext in ['*.docx', '*.pdf']:
for file in glob.glob(os.path.join(folder_path, ext)):
try:
os.remove(file)
print(f"Removed old file: {os.path.basename(file)}")
except Exception as e:
print(f"Error removing old file {file}: {str(e)}")
def setup_employee_folder(employee_name):
"""Create or clean employee-specific folder and return its path"""
safe_name = get_safe_employee_name(employee_name)
employee_dir = os.path.join(BASE_OUTPUT_DIR, safe_name)
if os.path.exists(employee_dir):
print(f"\nExisting folder found for {employee_name}")
print("Cleaning old files...")
clean_employee_folder(employee_dir)
else:
print(f"\nCreating new folder for {employee_name}")
os.makedirs(employee_dir)
return employee_dir
def check_files_exist():
"""Check if required files exist"""
if not os.path.exists(EXCEL_PATH):
raise FileNotFoundError(f"Excel file not found at {EXCEL_PATH}")
if not os.path.exists(TEMPLATE_PATH):
raise FileNotFoundError(f"Template file not found at {TEMPLATE_PATH}")
def clean_currency(value):
"""Clean currency values and convert to string"""
if pd.isna(value):
return ""
if isinstance(value, (int, float)):
return f"{int(value):,}"
if isinstance(value, str):
numeric_value = float(re.sub(r'[^\d.]', '', value))
return f"{int(numeric_value):,}"
return str(value).strip()
def clean_numeric(value):
"""Clean numeric values to ensure they're integers"""
if pd.isna(value):
return ""
if isinstance(value, (int, float)):
return str(int(value))
return str(value).strip()
def get_fully_populated_rows(df):
"""Return indices of rows that have all required columns populated"""
required_columns = list(COLUMN_TO_PLACEHOLDER.keys())
fully_populated = df.dropna(subset=required_columns)
return [idx + 2 for idx in fully_populated.index.tolist()]
def get_user_row_selection(populated_rows):
"""Get user input for row selection"""
while True:
print(f"\nAvailable Excel row numbers with complete data:
{populated_rows}")
print("Enter Excel row numbers to process. You can:")
print("1. Enter a single row number")
print("2. Enter a range (e.g., '2-5')")
print("3. Enter multiple rows separated by commas (e.g., '2,3,5')")
try:
selected_indices = set()
for part in user_input.split(','):
part = part.strip()
if '-' in part:
start, end = map(int, part.split('-'))
if start not in populated_rows or end not in populated_rows:
raise ValueError(f"Row {start} or {end} is not available")
selected_indices.update([i for i in range(start, end + 1) if i
in populated_rows])
else:
row_num = int(part)
if row_num not in populated_rows:
raise ValueError(f"Row {row_num} is not available")
selected_indices.add(row_num)
except ValueError as e:
print(f"Invalid input: {e}. Please try again.")
def create_context(employee_data):
"""Create template context from employee data"""
context = {}
currency_columns = [
'Annual Pay (No.)', 'Basic (Monthly)', 'Basic (Annual)',
'HRA (Monthly)', 'HRA (Annual)', 'Bonus (Monthly)', 'Bonus (Annual)',
'Special Allowance (Monthly)', 'Special Allowance (Annual)',
'PF (Monthly)', 'PF (Annual)', 'CTC (Monthly)', 'CTC (Annual)'
]
numeric_columns = ['Date', 'Effective Date', 'Year', 'Effective Year']
def generate_filename(timestamp):
"""Generate a filename with timestamp"""
return f"Employment_Agreement_{timestamp}"
# Convert to PDF
try:
docx_to_pdf(docx_path, pdf_path)
generated_files.append((employee_name, docx_path, pdf_path))
print(f"Created new PDF for {employee_name}")
except Exception as pdf_error:
print(f"Error converting to PDF for {employee_name}:
{str(pdf_error)}")
generated_files.append((employee_name, docx_path, None))
print(f"Only DOCX was saved for {employee_name}")
except Exception as e:
print(f"Error processing Excel row {index + 2}: {str(e)}")
return generated_files
except Exception as e:
print(f"Error in process_employees: {str(e)}")
return []
def main():
try:
# Create base output directory
os.makedirs(BASE_OUTPUT_DIR, exist_ok=True)
if generated_files:
print("\nGenerated files summary:")
for employee_name, docx_path, pdf_path in generated_files:
print(f"\nEmployee: {employee_name}")
print(f"Location: {os.path.dirname(docx_path)}")
print(f"Files generated:")
print(f"- {os.path.basename(docx_path)}")
if pdf_path:
print(f"- {os.path.basename(pdf_path)}")
else:
print("- PDF conversion failed")
print("\nProcess completed!")
except Exception as e:
print(f"An error occurred: {str(e)}")
if __name__ == "__main__":
main()