108 lines
4.6 KiB
Python
108 lines
4.6 KiB
Python
from html import escape
|
|
|
|
|
|
def _text(value):
|
|
"""Escape user-entered text and keep its line breaks ("Maymar Office\\nOr\\nHead Office")."""
|
|
if value in (None, ""):
|
|
return ""
|
|
return "<br>".join(escape(line.strip()) for line in str(value).splitlines())
|
|
|
|
|
|
def _salary(value):
|
|
if value in (None, ""):
|
|
return ""
|
|
try:
|
|
amount = float(str(value).replace(",", ""))
|
|
return f"PKR {amount:,.0f}"
|
|
except (TypeError, ValueError):
|
|
return _text(value)
|
|
|
|
|
|
def _recruiter_names(recruiter_names):
|
|
names = [str(n).strip() for n in (recruiter_names or []) if n and str(n).strip()]
|
|
if not names:
|
|
return ""
|
|
if len(names) == 1:
|
|
return escape(names[0])
|
|
if len(names) == 2:
|
|
return f"{escape(names[0])} & {escape(names[1])}"
|
|
return ", ".join(escape(n) for n in names[:-1]) + f" & {escape(names[-1])}"
|
|
|
|
|
|
def _package_row(label, value, bold=False, widths=(174, 449), bold_label=False, valign="top"):
|
|
cell = f"border:1px solid #000000;padding:1px 4px;vertical-align:{valign};"
|
|
shown = f"<strong>{value}</strong>" if bold else value
|
|
label = f"<strong>{label}</strong>" if bold_label else label
|
|
return (
|
|
"<tr>"
|
|
f'<td width="{widths[0]}" style="width:{widths[0]}px;{cell}">{label}</td>'
|
|
f'<td width="{widths[1]}" style="width:{widths[1]}px;{cell}">{shown}</td>'
|
|
"</tr>"
|
|
)
|
|
|
|
|
|
def render_offer_email_subject(candidate_name, offered_position, company_name):
|
|
"""Offer Intent <Candidate Name> - <Designation> <Entity Name>"""
|
|
name = str(candidate_name or "").strip()
|
|
position = str(offered_position or "").strip()
|
|
company = str(company_name or "").strip()
|
|
return f"Offer Intent {name} - {position} {company}".strip()
|
|
|
|
|
|
def render_offer_email_body(
|
|
candidate_name,
|
|
offered_position,
|
|
cadre,
|
|
company_name,
|
|
monthly_gross_salary,
|
|
subsidized_services,
|
|
probation_period,
|
|
notice_period,
|
|
location,
|
|
timings,
|
|
recruiter_names,
|
|
):
|
|
"""Annexure J - Offer format to be sent to the candidate, as an Outlook-safe
|
|
HTML body: inline styles and a bordered table only, no <style> block or
|
|
classes (Outlook strips them). Arial in grey and the bold runs match the PDF;
|
|
the offer letter itself goes out as an attachment. recruiter_names is a list,
|
|
joined as "A", "A & B" or "A, B & C"."""
|
|
font = "font-family:Arial,Helvetica,sans-serif;font-size:11pt;color:#595959;"
|
|
table_font = "font-family:Arial,Helvetica,sans-serif;font-size:11pt;color:#7F7F7F;"
|
|
paragraph = "margin:0 0 11pt 0;"
|
|
first_name = (str(candidate_name or "").strip().split() or [""])[0]
|
|
|
|
rows = (
|
|
_package_row("Monthly Gross Salary", _salary(monthly_gross_salary), bold=True)
|
|
+ _package_row("Subsidized Services", _text(subsidized_services), valign="middle")
|
|
+ _package_row("Probation Period", _text(probation_period), valign="middle")
|
|
+ _package_row("Notice Period", _text(notice_period), valign="middle")
|
|
+ _package_row("Location", _text(location), valign="middle")
|
|
+ _package_row("Timings", _text(timings), valign="middle")
|
|
)
|
|
|
|
return (
|
|
f'<div style="{font}">'
|
|
f'<p style="{paragraph}">Dear {escape(first_name)},</p>'
|
|
f'<p style="{paragraph}">Hope this email finds you well.</p>'
|
|
f'<p style="{paragraph}">Subsequent to your interviews and pursuant to our discussion, '
|
|
f"we are pleased to offer you the role of <strong>{_text(offered_position)}</strong> "
|
|
f"in <strong>{_text(cadre)}</strong> Cadre with <strong>{_text(company_name)}</strong>, "
|
|
f"based at {_text(' '.join(str(location or '').split()))}.</p>"
|
|
f'<p style="{paragraph}">As discussed, the details of the remuneration package are as follows:</p>'
|
|
'<table cellpadding="0" cellspacing="0" border="1" width="623" '
|
|
f'style="width:623px;border-collapse:collapse;border:1px solid #000000;{table_font}margin:0 0 11pt 0;">'
|
|
f"{rows}"
|
|
"</table>"
|
|
f'<p style="{paragraph}">You will also be eligible for all the benefits at your grade '
|
|
"as per the Company’s policy.</p>"
|
|
f'<p style="{paragraph}">Also attached in the email is the offer letter. Please sign the attached '
|
|
"offer letter as your acceptance within 24 hours, mentioning your "
|
|
"<strong>suggested date for joining.</strong></p>"
|
|
f'<p style="{paragraph}text-align:justify;">We look forward to the opportunity to work with you '
|
|
"in an atmosphere that is mutually challenging and rewarding.</p>"
|
|
f'<p style="{paragraph}">Regards,</p>'
|
|
f'<p style="margin:0;">{_recruiter_names(recruiter_names)}</p>'
|
|
"</div>"
|
|
)
|