import json
from doc_helpers import *
from build_workbook import CLIENTS,DATA,eligible,START,END

PROMO='Pour souligner également la première année d’activités de notre service de sexologie, nous vous remercions de votre confiance en vous offrant un rabais de 5 % sur vos consultations de sexologie du 2026-09-01 au 2027-08-31 inclusivement. Le rabais sera appliqué automatiquement à la facturation de ces consultations admissibles.'
def letter_body(d,c=None,merge=False):
    p(d,ORG,'Subtitle');p(d,'[Adresse de l’organisme]\n[Téléphone] • [Courriel]')
    p(d,'Le 14 septembre 2026')
    pa=p(d)
    if merge:
        field(pa,' MERGEFIELD Prenom ','Camille');pa.add_run(' ');field(pa,' MERGEFIELD Nom ','Exemple')
        pa=p(d);field(pa,' MERGEFIELD Adresse ','101, rue Démonstration')
        pa=p(d);field(pa,' MERGEFIELD Ville ','Ville Exemple');pa.add_run(' (');field(pa,' MERGEFIELD Province ','QC');pa.add_run(')  ');field(pa,' MERGEFIELD Code_postal ','H0H 0H0')
    else:
        i=CLIENTS.index(c)+1;pa.text=f'{c[1]} {c[2]}\n{100+i}, rue Démonstration\nVille Exemple (QC)  H0H 0H0'
    heading(d,'Objet : Cinq ans à vos côtés',2)
    p(d,'Bonjour,')
    p(d,'Notre organisme célèbre son cinquième anniversaire. Depuis cinq ans, notre équipe réunit des services professionnels en droit, en psychologie et en sexologie afin de répondre aux besoins de notre clientèle.')
    p(d,'Votre confiance contribue à notre développement et nous vous en remercions. Cet anniversaire est l’occasion de réaffirmer notre engagement à vous offrir un accueil attentif et des services de qualité.')
    if merge:
        pa=p(d)
        # Nested native IF and MERGEFIELD: offer is absent from the false branch.
        prefix='Pour souligner également la première année d’activités de notre service de sexologie, nous vous remercions de votre confiance en vous offrant un rabais de 5 % sur vos consultations de sexologie du '
        tail=' inclusivement. Le rabais sera appliqué automatiquement à la facturation de ces consultations admissibles.'
        field(pa,' IF ',PROMO,[('field',' MERGEFIELD Admissible '),('text',' = "Oui" "'+prefix),('field',' MERGEFIELD Debut_promotion '),('text',' au '),('field',' MERGEFIELD Fin_promotion '),('text',tail+'" "" ')])
    elif eligible(c[0]):p(d,PROMO)
    p(d,'Pour obtenir des renseignements sur nos services ou prendre rendez-vous, veuillez communiquer avec notre réception aux coordonnées indiquées en tête de lettre.')
    p(d,'Nous vous prions de recevoir nos salutations les meilleures.')
    p(d,'Henriette Bonmarché\nDirectrice générale')
    p(d,'Démonstration : coordonnées et date d’envoi à confirmer avant diffusion.','Caption')

def build():
    d=base('Correspondance — Anniversaire de l’organisme');letter_body(d,merge=True);merge_source(d);save(d,'04_Lettre_anniversaire_publipostage.docx')
    # Two complete, branded .dotx templates with personalized typeset signatures.
    for num,svc,name,titletext,accent in [('05','psychologie','Micheline Champagne','Psychologue',TEAL),('06','sexologie','Julie Grandmaison','Sexologue','7E5D87')]:
        d=base('Correspondance — Service de '+svc)
        p(d,ORG,'Subtitle');p(d,'[Adresse de l’organisme]\n[Téléphone de la réception] • [Courriel de la réception]')
        p(d,'[Lieu], le [date]');p(d,'[Prénom et nom du destinataire]\n[Adresse]\n[Ville] ([Province])  [Code postal]')
        heading(d,'Objet : [Objet précis de la lettre]',2)
        p(d,'[Madame, Monsieur ou formule d’appel convenue],')
        p(d,'[Présenter brièvement la raison de la correspondance.]')
        p(d,'[Expliquer les renseignements utiles et indiquer clairement la démarche attendue, la date ou les modalités du rendez-vous.]')
        p(d,'[Ajouter, au besoin, les coordonnées de la personne à joindre pour obtenir des précisions.]')
        p(d,'Veuillez recevoir mes salutations distinguées.')
        pa=p(d);rr=pa.add_run(name);rr.bold=True;rr.font.size=Pt(17);rr.font.color.rgb=RGBColor.from_string(accent)
        pa=p(d,titletext+'\nTéléphone : [numéro et poste]\nCourriel : [adresse professionnelle]\nAdresse : [adresse professionnelle]')
        borders=el('w:pBdr');borders.append(el('w:left',{'w:val':'single','w:sz':'18','w:space':'9','w:color':accent}));pa._p.get_or_add_pPr().append(borders)
        p(d,'[Initiales, pièces jointes ou copie conforme, si nécessaire]','Caption')
        tmp=ROOT/'_fabrication_00VB'/f'modele_{svc}.docx';d.save(tmp);as_template(tmp,OUT/f'{num}_Modele_lettre_{svc}.dotx')
    # Expected results are explicitly demonstrations, not a claimed Word merge execution.
    d=base('Exemples attendus — Deux variantes de la lettre')
    letter_body(d,CLIENTS[0]);d.add_page_break();letter_body(d,CLIENTS[2]);save(d,'08_Exemples_lettres_anniversaire.docx')
    # Annual report: native LINK fields and native calculation controls.
    d=base('Bilan annuel — Outil relié au classeur Excel')
    title(d,'Bilan annuel des activités','Exercice de démonstration 2026')
    p(d,ORG)
    pa=p(d);link(pa,'Portrait mensuel',anchor='PortraitMensuel');pa.add_run('  •  ');link(pa,'Contrôle des montants',anchor='ControleMontants')
    heading(d,'Synthèse administrative',1,'Synthese')
    p(d,'Le présent bilan regroupe les heures de services effectivement réalisées et les montants hors taxes correspondants. Les réservations futures sont suivies séparément dans Excel, afin de ne pas les confondre avec des services déjà rendus.')
    p(d,'Les données présentées sont fictives et servent à vérifier les outils. Les mois sans activité enregistrée apparaissent à zéro; cette absence de données ne permet pas de conclure à une absence réelle de services.')
    path=str(OUT/'03_Gestion_organisme.xlsx').replace('\\','\\\\')
    def xlink(para,cell,result):field(para,f' LINK Excel.Sheet.12 "{path}" "Portrait!{cell}" \\a \\t ',result)
    t=table(d,['Indicateur annuel','Valeur liée à Excel'],[['Heures réalisées',''],['Montants bruts hors taxes',''],['Rabais accordés',''],['Montants nets hors taxes','']],[9,7])
    for row,cell,value in [(1,'R18C5','21,25'),(2,'R18C6','2 545,00 $'),(3,'R18C7','23,75 $'),(4,'R18C8','2 521,25 $')]:xlink(t.cell(row,1).paragraphs[0],cell,value)
    heading(d,'Lecture des résultats',2)
    p(d,'Les montants comprennent les prestations réalisées dont la facture est encore en brouillon. La comparaison des heures réalisées et des heures déjà facturées dans le portrait sert à repérer les dossiers à traiter. L’écart d’heures du rendez-vous R023 doit être expliqué avant validation de sa facture.')
    heading(d,'Actualisation',2)
    p(d,'Enregistrer et recalculer le classeur, puis ouvrir ce bilan dans Word pour ordinateur. Actualiser les liaisons connues, sélectionner le document avec Ctrl+A et appuyer sur F9. Répéter F9 pour recalculer le contrôle après le chargement des valeurs. Vérifier le résultat avant de produire le PDF officiel.')
    p(d,'Après déplacement du dossier, rétablir les sources dans Fichier > Informations > Modifier les liaisons vers les fichiers. Les valeurs visibles avant actualisation constituent le dernier résultat mémorisé. Le mécanisme de liaison doit être essayé dans Word lors de la mise en service.','Caption')
    newpage(d,'Portrait mensuel','PortraitMensuel')
    p(d,'Source : 03_Gestion_organisme.xlsx, feuille Portrait, cellules A5:H18. Les cellules numériques du tableau ci-dessous sont des champs liés au classeur.')
    months=['Janv.','Févr.','Mars','Avr.','Mai','Juin','Juill.','Août','Sept.','Oct.','Nov.','Déc.']
    rows=[]
    for m in range(1,13):rows.append([months[m-1]]+['']*7)
    rows.append(['TOTAL']+['']*7)
    t=table(d,['Mois','Droit (h)','Psy. (h)','Sexo. (h)','Total (h)','Brut ($)','Rabais ($)','Net ($)'],rows,[2,1.7,1.7,1.7,1.7,2.5,2.2,2.5])
    for m in range(1,14):
        md=[r for r in DATA if r[1].year==2026 and (m==13 or r[1].month==m)]
        vals=[sum(r[17] for r in md if r[4]==svc) for svc in ['Juridique','Psychologie','Sexologie']]+[sum(r[17] for r in md)]+[sum(r[c] for r in md) for c in [12,13,14]]
        for j,v in enumerate(vals,1):xlink(t.cell(m,j).paragraphs[0],f'R{m+5 if m<=12 else 18}C{j+1}',f'{v:.2f}'.replace('.',','))
    p(d,'Les consultations annulées, les absences et les rendez-vous planifiés ne produisent pas de revenus dans cette simulation. Les capacités et les tarifs sont des hypothèses paramétrées dans le classeur.','Caption')
    pa=p(d);link(pa,'Retour à la synthèse',anchor='Synthese')
    newpage(d,'Contrôle des montants','ControleMontants')
    p(d,'Le rapprochement ci-dessous recalcule le montant net dans Word et le compare au montant provenant d’Excel. L’objectif est un écart de 0,00 $. Un écart exige de vérifier les sources, leur actualisation et les formules.')
    t=table(d,['Brut Excel ($)','Rabais Excel ($)','Net calculé Word ($)','Net Excel ($)','Écart ($)'],[['','','','','']],[3.2]*5)
    xlink(t.cell(1,0).paragraphs[0],'R18C6','2545,00');xlink(t.cell(1,1).paragraphs[0],'R18C7','23,75')
    field(t.cell(1,2).paragraphs[0],' = A2-B2 \\# "0,00" ','2521,25')
    xlink(t.cell(1,3).paragraphs[0],'R18C8','2521,25')
    field(t.cell(1,4).paragraphs[0],' = C2-D2 \\# "0,00" ','0,00')
    heading(d,'Validation de la période',2)
    table(d,['Vérification','Responsable','Trace attendue'],[['Concordance des heures réalisées et des dossiers','Pierre Tremblay','Liste des écarts corrigés'],['Rabais et factures émises','Anne-Marie Sauvageau','PDF des factures et contrôle des numéros'],['Portrait et communication publique','Henriette Bonmarché','Bilan validé et daté']],[6.2,4.5,5.3])
    p(d,'Validation de la période : [date]\nPréparation : [nom]\nValidation : [nom et fonction]\nCommentaires : [écarts résolus et décisions]')
    pa=p(d);link(pa,'Retour à la synthèse',anchor='Synthese')
    save(d,'07_Bilan_annuel_lie.docx')
    print('Outils Word créés.')

if __name__=='__main__':build()
