import openpyxl
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill, numbers
from openpyxl.utils import get_column_letter

wb = openpyxl.Workbook()

# ============================================================
# STYLES
# ============================================================
header_font = Font(name='Calibri', bold=True, size=12, color='FFFFFF')
title_font = Font(name='Calibri', bold=True, size=14, color='1F4E79')
subtitle_font = Font(name='Calibri', bold=True, size=11, color='1F4E79')
bold_font = Font(name='Calibri', bold=True, size=10)
normal_font = Font(name='Calibri', size=10)
net_font = Font(name='Calibri', bold=True, size=13, color='FFFFFF')
section_font = Font(name='Calibri', bold=True, size=11, color='FFFFFF')

dark_blue_fill = PatternFill(start_color='1F4E79', end_color='1F4E79', fill_type='solid')
light_blue_fill = PatternFill(start_color='D6E4F0', end_color='D6E4F0', fill_type='solid')
green_fill = PatternFill(start_color='2E7D32', end_color='2E7D32', fill_type='solid')
orange_fill = PatternFill(start_color='E65100', end_color='E65100', fill_type='solid')
light_gray_fill = PatternFill(start_color='F2F2F2', end_color='F2F2F2', fill_type='solid')
yellow_fill = PatternFill(start_color='FFF9C4', end_color='FFF9C4', fill_type='solid')
white_fill = PatternFill(start_color='FFFFFF', end_color='FFFFFF', fill_type='solid')

thin_border = Border(
    left=Side(style='thin'), right=Side(style='thin'),
    top=Side(style='thin'), bottom=Side(style='thin')
)
bottom_thick = Border(bottom=Side(style='medium'))
double_bottom = Border(bottom=Side(style='double'))

center_align = Alignment(horizontal='center', vertical='center', wrap_text=True)
left_align = Alignment(horizontal='left', vertical='center', wrap_text=True)
right_align = Alignment(horizontal='right', vertical='center')

fcfa_format = '#,##0'
pct_format = '0.00%'

def apply_border_range(ws, min_row, max_row, min_col, max_col):
    for r in range(min_row, max_row + 1):
        for c in range(min_col, max_col + 1):
            ws.cell(row=r, column=c).border = thin_border

# ============================================================
# ONGLET PARAMÈTRES
# ============================================================
ws_params = wb.active
ws_params.title = "Paramètres"
ws_params.sheet_properties.tabColor = "1F4E79"

# Largeurs colonnes
ws_params.column_dimensions['A'].width = 35
ws_params.column_dimensions['B'].width = 20
ws_params.column_dimensions['C'].width = 25
ws_params.column_dimensions['D'].width = 20

# Titre
ws_params.merge_cells('A1:D1')
c = ws_params['A1']
c.value = "⚙️ PARAMÈTRES LÉGAUX & TAUX - CAMEROUN"
c.font = Font(name='Calibri', bold=True, size=16, color='FFFFFF')
c.fill = dark_blue_fill
c.alignment = center_align
for col in range(1, 5):
    ws_params.cell(row=1, column=col).fill = dark_blue_fill

# --- Section CNPS ---
ws_params.merge_cells('A3:D3')
c = ws_params['A3']
c.value = "📋 COTISATIONS SOCIALES (CNPS)"
c.font = section_font
c.fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')
for col in range(1, 5):
    ws_params.cell(row=3, column=col).fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')

params_cnps = [
    ("Plafond mensuel CNPS", 750000, "B5", "Plafond_CNPS"),
    ("Taux salarial CNPS (Vieillesse + AF)", 0.042, "B6", "Taux_CNPS_sal"),
    ("Taux patronal CNPS (Prestations familiales)", 0.07, "B7", "Taux_CNPS_pf"),
    ("Taux patronal CNPS (Pensions)", 0.042, "B8", "Taux_CNPS_pen"),
    ("Taux patronal CNPS (Accident du travail)", 0.0175, "B9", "Taux_CNPS_at"),
    ("Taux patronal CNPS (total)", 0.1295, "B10", "Taux_CNPS_pat"),
]

for i, (label, val, cell_ref, name) in enumerate(params_cnps):
    row = 5 + i
    ws_params.cell(row=row, column=1, value=label).font = normal_font
    ws_params.cell(row=row, column=1).fill = light_gray_fill if i % 2 == 0 else white_fill
    cell = ws_params.cell(row=row, column=2, value=val)
    cell.font = bold_font
    cell.alignment = right_align
    cell.border = thin_border
    cell.fill = yellow_fill
    if isinstance(val, float) and val < 1:
        cell.number_format = pct_format
    else:
        cell.number_format = fcfa_format
    ws_params.cell(row=row, column=3, value=f"Nom: {name}").font = Font(name='Calibri', italic=True, size=9, color='888888')
    ws_params[cell_ref].name = name

# --- Section IRPP ---
ws_params.merge_cells('A12:D12')
c = ws_params['A12']
c.value = "📋 BARÈME IRPP (Impôt sur le Revenu des Personnes Physiques)"
c.font = section_font
c.fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')
for col in range(1, 5):
    ws_params.cell(row=12, column=col).fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')

# En-têtes barème
headers_irpp = ["Tranche", "Plancher mensuel", "Plafond mensuel", "Taux"]
for j, h in enumerate(headers_irpp, 1):
    c = ws_params.cell(row=13, column=j, value=h)
    c.font = bold_font
    c.fill = light_blue_fill
    c.alignment = center_align
    c.border = thin_border

bareme_irpp = [
    ("Tranche 1", 0, 166667, 0),
    ("Tranche 2", 166667, 250000, 0.11),
    ("Tranche 3", 250000, 416667, 0.165),
    ("Tranche 4", 416667, 833333, 0.23),
    ("Tranche 5", 833333, 999999999, 0.30),
]

for i, (tranche, bas, haut, taux) in enumerate(bareme_irpp):
    row = 14 + i
    ws_params.cell(row=row, column=1, value=tranche).font = normal_font
    ws_params.cell(row=row, column=1).fill = light_gray_fill if i % 2 == 0 else white_fill
    c2 = ws_params.cell(row=row, column=2, value=bas)
    c2.number_format = fcfa_format
    c2.alignment = right_align
    c2.border = thin_border
    c2.fill = yellow_fill
    c3 = ws_params.cell(row=row, column=3, value=haut if haut < 99999999 else "∞")
    c3.number_format = fcfa_format
    c3.alignment = right_align
    c3.border = thin_border
    c3.fill = yellow_fill
    c4 = ws_params.cell(row=row, column=4, value=taux)
    c4.number_format = pct_format
    c4.alignment = right_align
    c4.border = thin_border
    c4.fill = yellow_fill

# Noms pour le barème
ws_params['B14'].name = 'IRPP_T1_bas'
ws_params['C14'].name = 'IRPP_T1_haut'
ws_params['D14'].name = 'IRPP_T1_taux'
ws_params['B15'].name = 'IRPP_T2_bas'
ws_params['C15'].name = 'IRPP_T2_haut'
ws_params['D15'].name = 'IRPP_T2_taux'
ws_params['B16'].name = 'IRPP_T3_bas'
ws_params['C16'].name = 'IRPP_T3_haut'
ws_params['D16'].name = 'IRPP_T3_taux'
ws_params['B17'].name = 'IRPP_T4_bas'
ws_params['C17'].name = 'IRPP_T4_haut'
ws_params['D17'].name = 'IRPP_T4_taux'
ws_params['B18'].name = 'IRPP_T5_bas'
ws_params['D18'].name = 'IRPP_T5_taux'

# --- Section Abattements ---
ws_params.merge_cells('A20:D20')
c = ws_params['A20']
c.value = "📋 ABATTEMENTS & EXONÉRATIONS"
c.font = section_font
c.fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')
for col in range(1, 5):
    ws_params.cell(row=20, column=col).fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')

abattements = [
    ("Taux d'abattement forfaitaire IRPP", 0.20, "B22", "Taux_abattement", pct_format),
    ("Plafond annuel abattement", 500000, "B23", "Plafond_abat_annuel", fcfa_format),
    ("Plafond mensuel abattement (= annuel/12)", None, "B24", "Plafond_abat_mensuel", fcfa_format),
    ("Indemnité transport exonérée", 10000, "B25", "Transport_exo", fcfa_format),
]

for i, (label, val, cell_ref, name, fmt) in enumerate(abattements):
    row = 22 + i
    ws_params.cell(row=row, column=1, value=label).font = normal_font
    ws_params.cell(row=row, column=1).fill = light_gray_fill if i % 2 == 0 else white_fill
    cell = ws_params.cell(row=row, column=2)
    cell.font = bold_font
    cell.alignment = right_align
    cell.border = thin_border
    cell.fill = yellow_fill
    cell.number_format = fmt
    if val is not None:
        cell.value = val
    ws_params.cell(row=row, column=3, value=f"Nom: {name}").font = Font(name='Calibri', italic=True, size=9, color='888888')

# Formule pour plafond mensuel abattement
ws_params['B24'].value = '=B23/12'

ws_params['B22'].name = 'Taux_abattement'
ws_params['B23'].name = 'Plafond_abat_annuel'
ws_params['B24'].name = 'Plafond_abat_mensuel'
ws_params['B25'].name = 'Transport_exo'

# --- Section Taux supplémentaires ---
ws_params.merge_cells('A27:D27')
c = ws_params['A27']
c.value = "📋 AUTRES PARAMÈTRES"
c.font = section_font
c.fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')
for col in range(1, 5):
    ws_params.cell(row=27, column=col).fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')

autres = [
    ("Taux prime d'ancienneté", 0.02, "B29", "Taux_anciennete", pct_format),
    ("Majoration heures sup. (130%)", 1.30, "B30", "Majoration_HS", pct_format),
    ("Taux heures sup. nuit (150%)", 1.50, "B31", "Majoration_HS_nuit", pct_format),
    ("Taux heures sup. dimanche/jour férié (200%)", 2.00, "B32", "Majoration_HS_dim", pct_format),
]

for i, (label, val, cell_ref, name, fmt) in enumerate(autres):
    row = 29 + i
    ws_params.cell(row=row, column=1, value=label).font = normal_font
    ws_params.cell(row=row, column=1).fill = light_gray_fill if i % 2 == 0 else white_fill
    cell = ws_params.cell(row=row, column=2, value=val)
    cell.font = bold_font
    cell.alignment = right_align
    cell.border = thin_border
    cell.fill = yellow_fill
    cell.number_format = fmt
    ws_params.cell(row=row, column=3, value=f"Nom: {name}").font = Font(name='Calibri', italic=True, size=9, color='888888')
    ws_params[cell_ref].name = name

# ============================================================
# ONGLET PAIE
# ============================================================
ws = wb.create_sheet("Paie", 0)
ws.sheet_properties.tabColor = "2E7D32"

# Largeurs colonnes
ws.column_dimensions['A'].width = 5
ws.column_dimensions['B'].width = 35
ws.column_dimensions['C'].width = 15
ws.column_dimensions['D'].width = 15
ws.column_dimensions['E'].width = 18
ws.column_dimensions['F'].width = 18

# === EN-TÊTE ENTREPRISE ===
ws.merge_cells('A1:F1')
c = ws['A1']
c.value = "BULLETIN DE PAIE"
c.font = Font(name='Calibri', bold=True, size=18, color='FFFFFF')
c.fill = dark_blue_fill
c.alignment = center_align
for col in range(1, 7):
    ws.cell(row=1, column=col).fill = dark_blue_fill
ws.row_dimensions[1].height = 35

ws.merge_cells('A2:F2')
c = ws['A2']
c.value = "RÉPUBLIQUE DU CAMEROUN — Travail et Sécurité Sociale"
c.font = Font(name='Calibri', italic=True, size=10, color='FFFFFF')
c.fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')
c.alignment = center_align
for col in range(1, 7):
    ws.cell(row=2, column=col).fill = PatternFill(start_color='37474F', end_color='37474F', fill_type='solid')

# === INFORMATIONS ENTREPRISE ===
ws.merge_cells('A4:F4')
c = ws['A4']
c.value = "🏢 INFORMATIONS EMPLOYEUR"
c.font = section_font
c.fill = dark_blue_fill
for col in range(1, 7):
    ws.cell(row=4, column=col).fill = dark_blue_fill

info_entreprise = [
    ("Raison sociale :", "", "N° CNPS :", ""),
    ("Adresse :", "", "N° Employeur :", ""),
    ("Activité :", "Industrie / Manufacture", "Convention collective :", "Industrie au Cameroun"),
]

for i, (l1, v1, l2, v2) in enumerate(info_entreprise):
    row = 5 + i
    ws.cell(row=row, column=1, value=l1).font = bold_font
    ws.merge_cells(start_row=row, start_column=2, end_row=row, end_column=3)
    ws.cell(row=row, column=2, value=v1).font = normal_font
    ws.cell(row=row, column=2).border = Border(bottom=Side(style='dotted'))
    ws.cell(row=row, column=4, value=l2).font = bold_font
    ws.merge_cells(start_row=row, start_column=5, end_row=row, end_column=6)
    ws.cell(row=row, column=5, value=v2).font = normal_font
    ws.cell(row=row, column=5).border = Border(bottom=Side(style='dotted'))

# === INFORMATIONS SALARIÉ ===
ws.merge_cells('A9:F9')
c = ws['A9']
c.value = "👤 INFORMATIONS SALARIÉ"
c.font = section_font
c.fill = dark_blue_fill
for col in range(1, 7):
    ws.cell(row=9, column=col).fill = dark_blue_fill

info_salarie = [
    ("Nom & Prénom :", "", "Matricule :", ""),
    ("Date de naissance :", "", "N° CNPS :", ""),
    ("Poste / Emploi :", "", "Catégorie :", ""),
    ("Date d'embauche :", "", "Ancienneté (années) :", ""),
    ("Nbre personnes à charge :", "", "Période :", "Janvier 2025"),
]

for i, (l1, v1, l2, v2) in enumerate(info_salarie):
    row = 10 + i
    ws.cell(row=row, column=1, value=l1).font = bold_font
    ws.merge_cells(start_row=row, start_column=2, end_row=row, end_column=3)
    ws.cell(row=row, column=2, value=v1).font = normal_font
    ws.cell(row=row, column=2).border = Border(bottom=Side(style='dotted'))
    ws.cell(row=row, column=4, value=l2).font = bold_font
    ws.merge_cells(start_row=row, start_column=5, end_row=row, end_column=6)
    ws.cell(row=row, column=5, value=v2).font = normal_font
    ws.cell(row=row, column=5).border = Border(bottom=Side(style='dotted'))

# === SECTION GAINS ===
row_gains_header = 17
ws.merge_cells(f'A{row_gains_header}:F{row_gains_header}')
c = ws.cell(row=row_gains_header, column=1)
c.value = "💰 GAINS / RÉMUNÉRATION"
c.font = section_font
c.fill = green_fill
for col in range(1, 7):
    ws.cell(row=row_gains_header, column=col).fill = green_fill

row_gains_sub = row_gains_header + 1
gains_headers = ["N°", "Désignation", "Base / Quantité", "Taux / Unité", "Montant (FCFA)", "Soumis CNPS"]
for j, h in enumerate(gains_headers, 1):
    c = ws.cell(row=row_gains_sub, column=j, value=h)
    c.font = bold_font
    c.fill = light_blue_fill
    c.alignment = center_align
    c.border = thin_border

# Lignes de gains
gains = [
    (1, "Salaire de base mensuel", "=C19*D19", "SAISIR", True),
    (2, "Prime d'ancienneté", "=E18*Taux_anciennete", "Auto", True),
    (3, "Prime de rendement / performance", "", "SAISIR", True),
    (4, "Indemnité de logement", "", "SAISIR", True),
    (5, "Indemnité de risque / salissure", "", "SAISIR", True),
    (6, "Heures supplémentaires (130%)", "=C23*D23*Majoration_HS", "SAISIR", True),
    (7, "Heures sup. nuit (150%)", "", "SAISIR", True),
    (8, "Heures sup. dimanche/férié (200%)", "", "SAISIR", True),
    (9, "Indemnité de transport", "", "SAISIR", False),
    (10, "Prime de panier", "", "SAISIR", False),
    (11, "Autres primes / indemnités", "", "SAISIR", True),
]

start_gain_row = row_gains_sub + 1  # row 18
for i, (num, designation, formula, note, cnps) in enumerate(gains):
    row = start_gain_row + i
    ws.cell(row=row, column=1, value=num).font = normal_font
    ws.cell(row=row, column=1).alignment = center_align
    ws.cell(row=row, column=1).border = thin_border

    ws.cell(row=row, column=2, value=designation).font = normal_font
    ws.cell(row=row, column=2).border = thin_border

    ws.cell(row=row, column=3).font = normal_font
    ws.cell(row=row, column=3).alignment = right_align
    ws.cell(row=row, column=3).border = thin_border
    ws.cell(row=row, column=3).fill = yellow_fill
    ws.cell(row=row, column=3).number_format = fcfa_format

    ws.cell(row=row, column=4).font = normal_font
    ws.cell(row=row, column=4).alignment = right_align
    ws.cell(row=row, column=4).border = thin_border
    ws.cell(row=row, column=4).fill = yellow_fill
    ws.cell(row=row, column=4).number_format = fcfa_format

    ws.cell(row=row, column=5).font = normal_font
    ws.cell(row=row, column=5).alignment = right_align
    ws.cell(row=row, column=5).border = thin_border
    ws.cell(row=row, column=5).number_format = fcfa_format
    if formula and formula.startswith("="):
        ws.cell(row=row, column=5).value = formula
    else:
        ws.cell(row=row, column=5).fill = yellow_fill

    ws.cell(row=row, column=6, value="Oui" if cnps else "Non").font = normal_font
    ws.cell(row=row, column=6).alignment = center_align
    ws.cell(row=row, column=6).border = thin_border

    if i % 2 == 0:
        for col in range(1, 7):
            if ws.cell(row=row, column=col).fill == PatternFill():
                ws.cell(row=row, column=col).fill = light_gray_fill

# Correction: pour les lignes saisies, la colonne E doit être saisie manuellement
# Ligne 1 (salaire base): E = C * D
ws.cell(row=start_gain_row, column=5).value = f"=C{start_gain_row}*D{start_gain_row}"
ws.cell(row=start_gain_row, column=5).fill = white_fill

# Ligne 2 (ancienneté): E = E_salaire_base * taux
ws.cell(row=start_gain_row+1, column=5).value = f"=E{start_gain_row}*Taux_anciennete"
ws.cell(row=start_gain_row+1, column=5).fill = white_fill

# Lignes saisies manuellement (3,4,5) : E est jaune (saisie)
for r in [start_gain_row+2, start_gain_row+3, start_gain_row+4]:
    ws.cell(row=r, column=5).value = None

# Ligne 6 (HS 130%): E = C * D * Majoration_HS
ws.cell(row=start_gain_row+5, column=5).value = f"=C{start_gain_row+5}*D{start_gain_row+5}*Majoration_HS"
ws.cell(row=start_gain_row+5, column=5).fill = white_fill

# Lignes 7, 8 saisies
# Ligne 9 transport: saisie avec indication
# Lignes 10, 11 saisies

# Total brut
total_brut_row = start_gain_row + len(gains)  # row 29
ws.merge_cells(f'A{total_brut_row}:D{total_brut_row}')
c = ws.cell(row=total_brut_row, column=1)
c.value = "TOTAL BRUT"
c.font = Font(name='Calibri', bold=True, size=11, color='1F4E79')
c.alignment = Alignment(horizontal='right', vertical='center')
for col in range(1, 7):
    ws.cell(row=total_brut_row, column=col).fill = light_blue_fill
    ws.cell(row=total_brut_row, column=col).border = Border(top=Side(style='medium'), bottom=Side(style='medium'))
ws.cell(row=total_brut_row, column=5).value = f"=SOMME(E{start_gain_row}:E{total_brut_row-1})"
ws.cell(row=total_brut_row, column=5).font = Font(name='Calibri', bold=True, size=11)
ws.cell(row=total_brut_row, column=5).alignment = right_align
ws.cell(row=total_brut_row, column=5).number_format = fcfa_format

# === SECTION RETENUES ===
row_retenues_header = total_brut_row + 2
ws.merge_cells(f'A{row_retenues_header}:F{row_retenues_header}')
c = ws.cell(row=row_retenues_header, column=1)
c.value = "📉 COTISATIONS & RETENUES"
c.font = section_font
c.fill = orange_fill
for col in range(1, 7):
    ws.cell(row=row_retenues_header, column=col).fill = orange_fill

row_ret_sub = row_retenues_header + 1
ret_headers = ["N°", "Désignation", "Base imposable", "Taux", "Montant (FCFA)", "Part"]
for j, h in enumerate(ret_headers, 1):
    c = ws.cell(row=row_ret_sub, column=j, value=h)
    c.font = bold_font
    c.fill = light_blue_fill
    c.alignment = center_align
    c.border = thin_border

# Lignes de retenues
start_ret_row = row_ret_sub + 1
retenues = [
    (1, "CNPS - Part salariale (4,2%)", f"=MIN(E{total_brut_row}-Transport_exo;Plafond_CNPS)", "Taux_CNPS_sal", "Salariale"),
    (2, "IRPP (avant abattement)", f"=MAX(0;E{total_brut_row}-Transport_exo)", "", ""),
    (3, "Abattement forfaitaire 20%", "", "", ""),
    (4, "Revenu net imposable (RNI)", "", "", ""),
    (5, "IRPP dû", "", "", ""),
    (6, "Taxe communale (10% IRPP)", "", "", ""),
    (7, "Avance sur salaire", "", "", "Saisir"),
    (8, "Opposition / Saisie", "", "", "Saisir"),
    (9, "Prêt logement", "", "", "Saisir"),
    (10, "Autres retenues", "", "", "Saisir"),
]

for i, (num, designation, base_f, taux_f, note) in enumerate(retenues):
    row = start_ret_row + i
    ws.cell(row=row, column=1, value=num).font = normal_font
    ws.cell(row=row, column=1).alignment = center_align
    ws.cell(row=row, column=1).border = thin_border

    ws.cell(row=row, column=2, value=designation).font = normal_font
    ws.cell(row=row, column=2).border = thin_border

    ws.cell(row=row, column=3).font = normal_font
    ws.cell(row=row, column=3).alignment = right_align
    ws.cell(row=row, column=3).border = thin_border
    ws.cell(row=row, column=3).number_format = fcfa_format

    ws.cell(row=row, column=4).font = normal_font
    ws.cell(row=row, column=4).alignment = right_align
    ws.cell(row=row, column=4).border = thin_border
    ws.cell(row=row, column=4).number_format = pct_format

    ws.cell(row=row, column=5).font = normal_font
    ws.cell(row=row, column=5).alignment = right_align
    ws.cell(row=row, column=5).border = thin_border
    ws.cell(row=row, column=5).number_format = fcfa_format

    ws.cell(row=row, column=6, value=note if note else "").font = Font(name='Calibri', italic=True, size=9, color='888888')
    ws.cell(row=row, column=6).alignment = center_align
    ws.cell(row=row, column=6).border = thin_border

    if i % 2 == 0:
        for col in range(1, 7):
            if ws.cell(row=row, column=col).fill == PatternFill():
                ws.cell(row=row, column=col).fill = light_gray_fill

# Remplissage des formules de retenues
r1 = start_ret_row      # CNPS
r2 = start_ret_row + 1  # IRPP avant abattement (base)
r3 = start_ret_row + 2  # Abattement
r4 = start_ret_row + 3  # RNI
r5 = start_ret_row + 4  # IRPP dû
r6 = start_ret_row + 5  # Taxe communale
r7 = start_ret_row + 6  # Avance
r8 = start_ret_row + 7  # Opposition
r9 = start_ret_row + 8  # Prêt
r10 = start_ret_row + 9 # Autres

# Ligne 1 CNPS
ws.cell(row=r1, column=3).value = f"=MIN(E{total_brut_row}-Transport_exo;Plafond_CNPS)"
ws.cell(row=r1, column=3).fill = white_fill
ws.cell(row=r1, column=4).value = Taux_CNPS_sal if False else '=Taux_CNPS_sal'  
# Fix: need to use the named range
ws.cell(row=r1, column=4).value = '=Taux_CNPS_sal'
ws.cell(row=r1, column=4).fill = white_fill
ws.cell(row=r1, column=5).value = f"=C{r1}*D{r1}"

# Ligne 2 Base IRPP brute
ws.cell(row=r2, column=3).value = f"=MAX(0;E{total_brut_row}-Transport_exo)"
ws.cell(row=r2, column=3).fill = white_fill
ws.cell(row=r2, column=4).value = None
ws.cell(row=r2, column=5).value = f"=C{r2}"

# Ligne 3 Abattement
ws.cell(row=r3, column=3).value = None
ws.cell(row=r3, column=5).value = f"=MIN(C{r2}*Taux_abattement;Plafond_abat_mensuel)"
ws.cell(row=r3, column=4).value = '=Taux_abattement'
ws.cell(row=r3, column=4).fill = white_fill

# Ligne 4 RNI = Base IRPP - CNPS sal - Abattement
ws.cell(row=r4, column=5).value = f"=MAX(0;C{r2}-E{r1}-E{r3})"
ws.cell(row=r4, column=3).value = f"=E{r4}"
ws.cell(row=r4, column=3).fill = white_fill

# Ligne 5 IRPP dû - formule en escalier
ws.cell(row=r5, column=5).value = (
    f'=ARRONDI('
    f'SI(E{r4}<=IRPP_T1_haut;0;'
    f'SI(E{r4}<=IRPP_T2_haut;(E{r4}-IRPP_T2_bas)*IRPP_T2_taux;'
    f'SI(E{r4}<=IRPP_T3_haut;(IRPP_T3_bas-IRPP_T2_bas)*IRPP_T2_taux+(E{r4}-IRPP_T3_bas)*IRPP_T3_taux;'
    f'SI(E{r4}<=IRPP_T4_haut;(IRPP_T3_bas-IRPP_T2_bas)*IRPP_T2_taux+(IRPP_T4_bas-IRPP_T3_bas)*IRPP_T3_taux+(E{r4}-IRPP_T4_bas)*IRPP_T4_taux;'
    f'(IRPP_T3_bas-IRPP_T2_bas)*IRPP_T2_taux+(IRPP_T4_bas-IRPP_T3_bas)*IRPP_T3_taux+(IRPP_T5_bas-IRPP_T4_bas)*IRPP_T4_taux+(E{r4}-IRPP_T5_bas)*IRPP_T5_taux))));0)'
)

# Ligne 6 Taxe communale = 10% IRPP
ws.cell(row=r6, column=5).value = f"=ARRONDI(E{r5}*0.10;0)"
ws.cell(row=r6, column=4).value = 0.10

# Lignes 7-10 : saisie manuelle (jaune)
for r in [r7, r8, r9, r10]:
    ws.cell(row=r, column=5).fill = yellow_fill

# Total retenues
total_ret_row = start_ret_row + len(retenues)
ws.merge_cells(f'A{total_ret_row}:D{total_ret_row}')
c = ws.cell(row=total_ret_row, column=1)
c.value = "TOTAL RETENUES"
c.font = Font(name='Calibri', bold=True, size=11, color='C62828')
c.alignment = Alignment(horizontal='right', vertical='center')
for col in range(1, 7):
    ws.cell(row=total_ret_row, column=col).fill = PatternFill(start_color='FFCDD2', end_color='FFCDD2', fill_type='solid')
    ws.cell(row=total_ret_row, column=col).border = Border(top=Side(style='medium'), bottom=Side(style='medium'))
ws.cell(row=total_ret_row, column=5).value = f"=SOMME(E{start_ret_row}:E{total_ret_row-1})"
ws.cell(row=total_ret_row, column=5).font = Font(name='Calibri', bold=True, size=11, color='C62828')
ws.cell(row=total_ret_row, column=5).alignment = right_align
ws.cell(row=total_ret_row, column=5).number_format = fcfa_format

# === NET À PAYER ===
net_row = total_ret_row + 2
ws.merge_cells(f'A{net_row}:D{net_row}')
c = ws.cell(row=net_row, column=1)
c.value = "✅ NET À PAYER (FCFA)"
c.font = net_font
c.fill = green_fill
c.alignment = Alignment(horizontal='right', vertical='center')
for col in range(1, 7):
    ws.cell(row=net_row, column=col).fill = green_fill
ws.cell(row=net_row, column=5).value = f"=E{total_brut_row}-E{total_ret_row}"
ws.cell(row=net_row, column=5).font = Font(name='Calibri', bold=True, size=14, color='FFFFFF')
ws.cell(row=net_row, column=5).fill = green_fill
ws.cell(row=net_row, column=5).alignment = right_align
ws.cell(row=net_row, column=5).number_format = '#,##0 "FCFA"'
ws.cell(row=net_row, column=5).border = Border(top=Side(style='double'), bottom=Side(style='double'))
ws.row_dimensions[net_row].height = 30

# Ligne en toutes lettres
lettres_row = net_row + 1
ws.merge_cells(f'A{lettres_row}:F{lettres_row}')
ws.cell(row=lettres_row, column=1).value = f'Arrêté le présent bulletin à la somme de : NET À PAYER = {ws.cell(row=net_row, column=5).coordinate} FCFA'
ws.cell(row=lettres_row, column=1).value = f'=CONCATENATE("Arrêté le présent bulletin à la somme de : ",TEXTE(E{net_row};"# ##0")," FCFA")'
ws.cell(row=lettres_row, column=1).font = Font(name='Calibri', italic=True, size=10)

# === COTISATIONS PATRONALES (pour info) ===
patron_row = lettres_row + 2
ws.merge_cells(f'A{patron_row}:F{patron_row}')
c = ws.cell(row=patron_row, column=1)
c.value = "📋 COTISATIONS PATRONALES (à titre informatif)"
c.font = section_font
c.fill = PatternFill(start_color='5D4037', end_color='5D4037', fill_type='solid')
for col in range(1, 7):
    ws.cell(row=patron_row, column=col).fill = PatternFill(start_color='5D4037', end_color='5D4037', fill_type='solid')

pat_sub = patron_row + 1
pat_headers = ["N°", "Désignation", "Base", "Taux", "Montant (FCFA)", "Remarque"]
for j, h in enumerate(pat_headers, 1):
    c = ws.cell(row=pat_sub, column=j, value=h)
    c.font = bold_font
    c.fill = light_blue_fill
    c.alignment = center_align
    c.border = thin_border

cotis_patron = [
    (1, "Prestations familiales (7%)", f"=C{r1}", '=Taux_CNPS_pf'),
    (2, "Pensions (4,2%)", f"=C{r1}", '=Taux_CNPS_pen'),
    (3, "Accident du travail (1,75%)", f"=C{r1}", '=Taux_CNPS_at'),
    (4, "TOTAL COTISATIONS PATRONALES", "", ""),
]

start_pat_row = pat_sub + 1
for i, (num, des, base, taux) in enumerate(cotis_patron):
    row = start_pat_row + i
    ws.cell(row=row, column=1, value=num).font = normal_font
    ws.cell(row=row, column=1).alignment = center_align
    ws.cell(row=row, column=1).border = thin_border
    ws.cell(row=row, column=2, value=des).font = normal_font
    ws.cell(row=row, column=2).border = thin_border
    ws.cell(row=row, column=3).border = thin_border
    ws.cell(row=row, column=3).number_format = fcfa_format
    ws.cell(row=row, column=4).border = thin_border
    ws.cell(row=row, column=4).number_format = pct_format
    ws.cell(row=row, column=5).border = thin_border
    ws.cell(row=row, column=5).number_format = fcfa_format
    if i < 3:
        ws.cell(row=row, column=3).value = base
        ws.cell(row=row, column=3).fill = white_fill
        ws.cell(row=row, column=4).value = taux
        ws.cell(row=row, column=4).fill = white_fill
        ws.cell(row=row, column=5).value = f"=C{row}*D{row}"
        ws.cell(row=row, column=5).fill = white_fill
    if i % 2 == 0:
        for col in range(1, 7):
            if ws.cell(row=row, column=col).fill == PatternFill():
                ws.cell(row=row, column=col).fill = light_gray_fill

# Total patronal
total_pat_row = start_pat_row + 3
ws.cell(row=total_pat_row, column=2).value = "TOTAL COTISATIONS PATRONALES"
ws.cell(row=total_pat_row, column=2).font = Font(name='Calibri', bold=True, size=10, color='5D4037')
ws.cell(row=total_pat_row, column=5).value = f"=SOMME(E{start_pat_row}:E{total_pat_row-1})"
ws.cell(row=total_pat_row, column=5).font = Font(name='Calibri', bold=True, size=10, color='5D4037')
ws.cell(row=total_pat_row, column=5).number_format = fcfa_format
for col in range(1, 7):
    ws.cell(row=total_pat_row, column=col).fill = PatternFill(start_color='D7CCC8', end_color='D7CCC8', fill_type='solid')
    ws.cell(row=total_pat_row, column=col).border = Border(top=Side(style='medium'), bottom=Side(style='medium'))

# === COÛT TOTAL EMPLOYEUR ===
cout_row = total_pat_row + 2
ws.merge_cells(f'A{cout_row}:D{cout_row}')
c = ws.cell(row=cout_row, column=1)
c.value = "COÛT TOTAL EMPLOYEUR"
c.font = Font(name='Calibri', bold=True, size=11, color='FFFFFF')
c.fill = PatternFill(start_color='5D4037', end_color='5D4037', fill_type='solid')
c.alignment = Alignment(horizontal='right', vertical='center')
for col in range(1, 7):
    ws.cell(row=cout_row, column=col).fill = PatternFill(start_color='5D4037', end_color='5D4037', fill_type='solid')
ws.cell(row=cout_row, column=5).value = f"=E{total_brut_row}+E{total_pat_row}"
ws.cell(row=cout_row, column=5).font = Font(name='Calibri', bold=True, size=12, color='FFFFFF')
ws.cell(row=cout_row, column=5).alignment = right_align
ws.cell(row=cout_row, column=5).number_format = '#,##0 "FCFA"'
ws.cell(row=cout_row, column=5).border = Border(bottom=Side(style='double'))

# === SIGNATURES ===
sig_row = cout_row + 3
ws.merge_cells(f'A{sig_row}:C{sig_row}')
ws.cell(row=sig_row, column=1).value = "Signature de l'Employeur :"
ws.cell(row=sig_row, column=1).font = bold_font
ws.merge_cells(f'D{sig_row}:F{sig_row}')
ws.cell(row=sig_row, column=4).value = "Signature du Salarié (avec mention 'Bon pour accord') :"
ws.cell(row=sig_row, column=4).font = bold_font

ws.merge_cells(f'A{sig_row+2}:C{sig_row+2}')
ws.cell(row=sig_row+2, column=1).value = "Date : _____/_____/_________"
ws.cell(row=sig_row+2, column=1).font = normal_font
ws.merge_cells(f'D{sig_row+2}:F{sig_row+2}')
ws.cell(row=sig_row+2, column=4).value = "Date : _____/_____/_________"
ws.cell(row=sig_row+2, column=4).font = normal_font

# Mention légale
legal_row = sig_row + 4
ws.merge_cells(f'A{legal_row}:F{legal_row}')
ws.cell(row=legal_row, column=1).value = "Mention légale : Conformément à l'article 37 du Décret n°2019/482, ce bulletin de paie doit être conservé par le salarié pendant une durée minimale de 4 ans."
ws.cell(row=legal_row, column=1).font = Font(name='Calibri', italic=True, size=8, color='999999')
ws.cell(row=legal_row, column=1).alignment = Alignment(wrap_text=True)

# === IMPRESSION ===
ws.print_area = f'A1:F{legal_row}'
ws.page_setup.orientation = 'portrait'
ws.page_setup.paperSize = ws.PAPERSIZE_A4
ws.page_setup.fitToWidth = 1
ws.page_setup.fitToHeight = 1
ws.sheet_properties.pageSetUpPr = openpyxl.worksheet.properties.PageSetupProperties(fitToPage=True)

# Protection (optionnelle) — on laisse tout déverrouillé pour modification facile
# ws.protection.sheet = True

# ============================================================
# ONGLET EXEMPLE CHIFFRÉ (pour vérification)
# ============================================================
ws_ex = wb.create_sheet("Exemple chiffré")
ws_ex.sheet_properties.tabColor = "FF6F00"
ws_ex.column_dimensions['A'].width = 35
ws_ex.column_dimensions['B'].width = 20

ws_ex.merge_cells('A1:B1')
c = ws_ex['A1']
c.value = "📊 EXEMPLE CHIFFRÉ DE VÉRIFICATION"
c.font = Font(name='Calibri', bold=True, size=14, color='FFFFFF')
c.fill = PatternFill(start_color='FF6F00', end_color='FF6F00', fill_type='solid')
c.alignment = center_align
ws_ex['B1'].fill = PatternFill(start_color='FF6F00', end_color='FF6F00', fill_type='solid')

exemples = [
    ("", ""),
    ("Saisissez dans l'onglet 'Paie' :", ""),
    ("Cellule C18 (Base salaire)", "173.33 heures"),
    ("Cellule D18 (Taux horaire)", "1731 FCFA"),
    ("→ Salaire de base (E18)", "300 000 FCFA"),
    ("", ""),
    ("Cellule E19 (Ancienneté)", "Auto-calculé 2%"),
    ("Cellule E20 (Prime rendement)", "15 000"),
    ("Cellule E21 (Ind. logement)", "20 000"),
    ("Cellule E22 (Ind. risque)", "0"),
    ("Cellule C23 (Nb heures sup)", "10 heures"),
    ("Cellule D23 (Taux horaire sup)", "1731 FCFA"),
    ("Cellule E26 (Transport)", "10 000"),
    ("", ""),
    ("RÉSULTATS ATTENDUS :", ""),
    ("Total Brut", "≈ 364 316 FCFA"),
    ("CNPS salariale (4,2%)", "≈ 14 811 FCFA"),
    ("IRPP dû", "≈ 12 800 FCFA"),
    ("Taxe communale", "≈ 1 280 FCFA"),
    ("Net à payer", "≈ 335 425 FCFA"),
]

for i, (label, val) in enumerate(exemples):
    row = 2 + i
    ws_ex.cell(row=row, column=1, value=label).font = bold_font if ":" in label or "→" in label or "RÉSULTATS" in label else normal_font
    ws_ex.cell(row=row, column=2, value=val).font = normal_font
    if "→" in label or "RÉSULTATS" in label:
        ws_ex.cell(row=row, column=1).fill = light_blue_fill
        ws_ex.cell(row=row, column=2).fill = light_blue_fill

# Sauvegarde
filename = "Bulletin_Paie_Cameroun_Industrie.xlsx"
wb.save(filename)
print(f"✅ Fichier '{filename}' généré avec succès!")
print(f"   → Onglet 'Paie' : bulletin complet avec formules")
print(f"   → Onglet 'Paramètres' : taux et barèmes modifiables")
print(f"   → Onglet 'Exemple chiffré' : guide de saisie")('Hello world!')

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: