Rendro.Recipes.Payslip (Rendro v1.3.4) (adapter)

Copy Markdown View Source

Data-driven payslip recipe. Net pay is the reader-first visual anchor (D-11): a tinted band directly under the identity header renders "NET PAY" at the largest text size on the page.

Uses the Tiered Composition pattern, mirroring Rendro.Recipes.Invoice:

  • document/2 — Batteries-included; returns a fully assembled
                    `%Rendro.Document{}` ready for `Rendro.render/2`.
  • page_template/1 — Layout only; returns the %Rendro.PageTemplate{}.
                    Geometry is derived from `Rendro.PageSize.resolve/2`
                    (A4 default, portrait)  zero hardcoded numerics, so
                    both A4 and US Letter render correctly (D-14).
  • sections/2 — Content only; returns a list of %Rendro.Section{}
                    structs mapped to named regions.

Required data keys

See validate_data!/1's contract (D-15):

  • :employer%{name (required), address}
  • :employee%{name (required), id, tax_code}
  • :period%{from, to} (required, Date.t())
  • :pay_date — required, Date.t()
  • :earnings — required, non-empty list of %{description, amount, ytd}
  • :deductions — required key, list (may be empty) of the same line shape
  • :net_pay — required Decimal.t(); must equal gross earnings minus
              total deductions (D-13)

Optional data keys

  • :totals%{gross, deductions, net, gross_ytd, deductions_ytd, net_ytd} — caller assertions checked against derived values via Decimal.equal?/2
  • :payment_method — masked identifier string (e.g. "···· 4321")

Jurisdiction / label / formatting overrides (D-16)

:palette, :labels, and :formatters are three orthogonal override maps merged over recipe-shipped defaults — the same convention as Rendro.Recipes.Invoice's palette(opts) seam. Statutory line content (e.g. "PAYE Income Tax" vs "Federal Income Tax") is caller :description data, never a library-enumerated jurisdiction type (D-17).

Summary

Functions

Assembles and returns a fully composed %Rendro.Document{}. Validates data (D-15/D-13 errors-as-product) before building the template.

Returns a %Rendro.PageTemplate{} with geometry derived from the page size option. Default is A4 portrait. Four named regions: :header (employer/ employee identity), :summary (the D-11 net-pay anchor band), :body (anchor: :flow — combined ledger + reconciliation), :footer (anchor: :bottom — masked payment method + page number).

Returns a list of %Rendro.Section{} structs mapping payslip content to the :header, :summary, :body, and :footer regions. Validates data and the :labels/:formatters opts shape (D-19) before building any section content.

Functions

document(data, opts \\ [])

@spec document(
  map(),
  keyword()
) :: Rendro.Document.t()

Assembles and returns a fully composed %Rendro.Document{}. Validates data (D-15/D-13 errors-as-product) before building the template.

Examples

iex> data = %{
...>   employer: %{name: "Aurora Textiles Co."},
...>   employee: %{name: "Jordan Rivera"},
...>   period: %{from: ~D[2026-06-01], to: ~D[2026-06-30]},
...>   pay_date: ~D[2026-07-05],
...>   earnings: [%{description: "Base Salary", amount: Decimal.new("1000.00")}],
...>   deductions: [],
...>   net_pay: Decimal.new("1000.00")
...> }
iex> doc = Rendro.Recipes.Payslip.document(data)
iex> doc.page_template
:payslip

page_template(opts \\ [])

@spec page_template(keyword()) :: Rendro.PageTemplate.t()

Returns a %Rendro.PageTemplate{} with geometry derived from the page size option. Default is A4 portrait. Four named regions: :header (employer/ employee identity), :summary (the D-11 net-pay anchor band), :body (anchor: :flow — combined ledger + reconciliation), :footer (anchor: :bottom — masked payment method + page number).

Options

  • :page_size:a4 (default), :us_letter, or {width, height} tuple
  • :margin_top / :margin_right / :margin_bottom / :margin_left — margin in pt (default 72)
  • :name — template name atom (default :payslip)

Examples

iex> template = Rendro.Recipes.Payslip.page_template()
iex> Enum.map(template.regions, & &1.name)
[:header, :summary, :body, :footer]

sections(data, opts \\ [])

@spec sections(
  map(),
  keyword()
) :: [Rendro.Section.t()]

Returns a list of %Rendro.Section{} structs mapping payslip content to the :header, :summary, :body, and :footer regions. Validates data and the :labels/:formatters opts shape (D-19) before building any section content.