"""Generate DOCX: Letter TO client from Jingtian & Gongcheng.""" from pathlib import Path from docx import Document from docx.shared import Pt, Inches, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH def generate( output_path: Path, firm: dict, client: dict, body: str, closing: str, ref_number: str, date: str, re_line: str, ): """Generate a formal letter from the firm to a client.""" doc = Document() style = doc.styles["Normal"] font = style.font font.name = "Times New Roman" font.size = Pt(11) # Firm letterhead header = doc.add_paragraph() header.alignment = WD_ALIGN_PARAGRAPH.CENTER run = header.add_run(firm["name"]) run.bold = True run.font.size = Pt(14) run.font.color.rgb = RGBColor(0, 51, 102) subheader = doc.add_paragraph() subheader.alignment = WD_ALIGN_PARAGRAPH.CENTER run = subheader.add_run(firm.get("chinese_name", "")) run.font.size = Pt(12) run.font.color.rgb = RGBColor(0, 51, 102) addr = doc.add_paragraph() addr.alignment = WD_ALIGN_PARAGRAPH.CENTER run = addr.add_run(firm["address"]) run.font.size = Pt(9) run.font.color.rgb = RGBColor(100, 100, 100) # Divider line doc.add_paragraph("_" * 72).runs[0].font.color.rgb = RGBColor(180, 180, 180) # Reference and date ref_para = doc.add_paragraph() ref_para.add_run(f"Our Ref: {ref_number}").font.size = Pt(10) date_para = doc.add_paragraph() date_para.add_run(f"Date: {date}").font.size = Pt(10) doc.add_paragraph() # spacer # Recipient recipient = doc.add_paragraph() recipient.add_run(f"{client['contact_person']}").font.size = Pt(11) recipient.add_run("\n") recipient.add_run(f"{client['name']}").font.size = Pt(11) recipient.add_run("\n") recipient.add_run(client["address"]).font.size = Pt(11) doc.add_paragraph() # RE line re_para = doc.add_paragraph() run = re_para.add_run(f"RE: {re_line}") run.bold = True run.underline = True doc.add_paragraph() # Body paragraphs — strip any closing already in body text body_clean = body for strip_phrase in [ "Yours sincerely,", "Yours faithfully,", "Kind regards,", "Best regards,", ]: if strip_phrase in body_clean: body_clean = body_clean[: body_clean.index(strip_phrase)].rstrip() for para_text in body_clean.split("\n\n"): if para_text.strip(): doc.add_paragraph(para_text.strip()) doc.add_paragraph() # Signature block doc.add_paragraph("Yours faithfully,") doc.add_paragraph() sig = doc.add_paragraph() run = sig.add_run(firm["attorney"]["name"]) run.bold = True doc.add_paragraph("Partner") doc.add_paragraph(firm["name"]) doc.save(str(output_path))