{"id":19234571,"url":"https://github.com/smitelli/envoi","last_synced_at":"2026-06-13T06:33:40.321Z","repository":{"id":245471218,"uuid":"818332980","full_name":"smitelli/envoi","owner":"smitelli","description":"Converts YAML invoice data into reasonably well-formatted PDFs.","archived":false,"fork":false,"pushed_at":"2024-10-19T01:42:05.000Z","size":320,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-23T13:08:07.953Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smitelli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-21T15:59:55.000Z","updated_at":"2024-10-19T01:42:08.000Z","dependencies_parsed_at":"2025-01-05T01:12:11.577Z","dependency_job_id":"2d1080c4-aa7c-421e-9ee7-1860f3ada7da","html_url":"https://github.com/smitelli/envoi","commit_stats":null,"previous_names":["smitelli/envoi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smitelli/envoi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smitelli%2Fenvoi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smitelli%2Fenvoi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smitelli%2Fenvoi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smitelli%2Fenvoi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smitelli","download_url":"https://codeload.github.com/smitelli/envoi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smitelli%2Fenvoi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34275068,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T16:14:19.349Z","updated_at":"2026-06-13T06:33:40.305Z","avatar_url":"https://github.com/smitelli.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Envoi\n=====\n\nConverts YAML invoice data into reasonably well-formatted PDFs.\n\nby [Scott Smitelli](mailto:scott@smitelli.com)\n\nThe Quick Bits\n--------------\n\n```bash\npython -m venv .venv\n.venv/bin/pip install --upgrade pip\n.venv/bin/pip install --editable .[dev]\n\n.venv/bin/envoi\n```\n\n\"Source\" File Definition\n------------------------\n\nThe base name of the source file will be used to name the output file. As an\nexample, `sources/240601-01.yaml` will generate `output/240601-01.pdf` when\nit is processed. If the source file has its `paid` flag set, the output file\nis slightly modified to `output/240601-01.paid.pdf` Source files can be\norganized into any arbitrary subdirectory structure beneath the `sources/`\ndirectory and `output/` will mirror that organization.\n\n```yaml\n# String containing the base name (without `.yaml`) of the payer file in the\n# `payers/` directory to pull unchanging information from. The example payer\n# file will be in `payers/example.yaml`.\npayer: example\n\n# Mark this invoice as paid. Produces a PDF with a red \"PAID\" overlay and\n# adds a `paid` tag to the output filename (this prevents overwriting the\n# original PDF that was originally sent.) Defaults false.\npaid: false\n\n# Date this invoice was generated. Affects the invoice number, and the\n# invoice/due dates shown in the box.\ninvoice_date: 2024-06-01\n\n# Integer sequence number identifying this invoice within a single date. Only\n# incremented when more than one invoice is produced on a single\n# `invoice_date` -- usually this stays at 1.\ninvoice_seq: 1\n\n# Integer number of days. This is added to `invoice_date` to produce the due\n# date shown at the top of the PDF. If this date falls on a weekend, it is\n# adjusted ahead to the following Monday.\ndays_due_in: 30\n\n# Optional floating point adjustments value. Added if positive, subtracted if\n# negative. Changes the final total of the invoice without introducing a\n# specific ledger line to account for it. Explain it in `notes`! Defaults 0.\nadjustments: 0.00\n\n# Optional string of text to show in a notes box at the end of the PDF.\n# Defaults empty.\nnotes: Thank you for your business.\n\n# Optional floating point value. If this is set and any item in `ledger` does\n# not have a `rate`, this value will be used for that item's rate. Has no\n# default -- if this is not set and something in `ledger` needs it, the PDF\n# will not be built.\ndefault_rate: 100.00\n\n# List of maps, each element representing one line of ledger data to show on\n# the invoice. All of the ledger lines are printed in the order defined, and\n# their totals are summed together to produce the total amount due.\nledger:\n    - date: 2024-05-03  # The date when this item was incurred.\n      qty: 1            # The number of units purchased/utilized.\n      rate: 99.99       # The price for one unit.\n      description: One  # Freeform text to display in the description box.\n\n    - date: 2024-05-10  # Second item. This uses the global `default_rate`.\n      qty: 1.5\n      description: One and a half hours!\n```\n\n\"Payer\" File Definition\n-----------------------\n\nThe payer file is designed to hold default values that never change between\ninvoices. For example, the \"bill to\" address likely has the same content for\nthe duration of the business relationship, so it can be pulled in by\nreference via the payer file.\n\nAny top-level key supported in a source file can be given here, with the\nexception of `payer`.\n\n```yaml\n# List of strings to display as the address in the header on page one of the\n# PDF. Each list element is separated with a bullet and laid out on one line.\nheader_address:\n    - Element 1\n    - Element 2\n\n# List of strings to display as the footer on page one of the PDF. Formatted\n# similarly to `header_address`.\nfooter_address:\n    - Element 1\n    - Element 2\n\n# List of strings to use in the \"BILL TO\" box.\nbill_to_address:\n    - Line 1\n    - Line 2\n\n# Optional area. Any key:value allowed in a source file (except for `payer`)\n# can be given here, and will take effect in any instance where a source file\n# does not have that top-level key set.\ndays_due_in: 60  # In this example, the source file no longer needs this now.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmitelli%2Fenvoi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmitelli%2Fenvoi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmitelli%2Fenvoi/lists"}