Skip to content

feat(billing): Add sales tax fields to contract and billing protos#286

Open
dashed wants to merge 2 commits into
mainfrom
aleal/feat/contract-sales-tax
Open

feat(billing): Add sales tax fields to contract and billing protos#286
dashed wants to merge 2 commits into
mainfrom
aleal/feat/contract-sales-tax

Conversation

@dashed
Copy link
Copy Markdown
Member

@dashed dashed commented Jun 4, 2026

Summary

Adds the proto delta needed to pass an already-computed sales tax from the
presentation (Invoicer) layer down into the Contract data service, and keeps the
customer's tax registration number on BillingDetails where it is read.

Changes

  • CreateContractRequest.sales_tax (InvoiceLineItem, tag 7) and
    RolloverContractRequest.sales_tax (InvoiceLineItem, tag 6): the
    pre-computed sales tax (amount in cents + a human-readable label) for the
    invoice. Contract folds it into the invoice amount before charge-forgiveness
    is applied, kept separate from the priced line_items. It is a message field,
    so presence is checked via HasField; unset means no sales tax applies.
  • BillingDetails.tax_number (string, tag 6): the customer's tax
    registration number (e.g. VAT ID) on file, used upstream when determining the
    customer's tax treatment.

Why

Sales tax is now computed in the Invoicer (presentation) layer, before the
Contract request is built. The computed result is passed down via sales_tax,
so Contract no longer computes tax and no longer needs a tax-id input of its own.

Relationship to #284

This supersedes the design in #284, which added customer_tax_id to the two
contract requests so Contract could compute tax itself. Those request fields are
dropped here — Contract no longer computes tax. tax_number still lands on
BillingDetails (it was also in #284) because the Invoicer reads it to compute
tax. #284 is left open for reference; it is not being merged.

Generated bindings

  • Rust bindings (committed) regenerated for contract.v1 and
    billing_details.v1.
  • Python bindings are gitignored and regenerated locally; not part of this diff.
  • VERSION/CHANGELOG/Cargo.lock version bumps are left to release
    automation.

Verification

  • buf lint, buf format, and buf breaking (against main) all pass — the
    fields are purely additive.
  • cargo check and cargo clippy -- -D warnings pass for the sentry_protos
    crate.
  • Confirmed at runtime that HasField("sales_tax") / HasField("tax_number")
    behave correctly on the generated Python messages.

Refs REVENG-15

Add a sales_tax field (InvoiceLineItem) to CreateContractRequest and
RolloverContractRequest. It carries the pre-computed sales tax (amount in
cents plus a label) for the invoice down to Contract, where it is folded
into the invoice amount before charge-forgiveness is applied and kept
separate from the priced line_items. As a message field, its presence is
checked via HasField; unset means no sales tax applies.

Add a tax_number field to BillingDetails for the customer's tax
registration number (e.g. VAT ID) on file, used upstream when determining
the customer's tax treatment.

Tax is now computed before the contract request is built and the result is
passed down, so Contract no longer needs a tax-id input to compute tax
itself.

Refs REVENG-15
Co-Authored-By: Claude <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 4, 2026

REVENG-15

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

The latest Buf updates on your PR. Results from workflow ci / buf-checks (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJun 4, 2026, 1:43 AM

@dashed dashed self-assigned this Jun 4, 2026
@dashed dashed marked this pull request as ready for review June 4, 2026 15:47
@dashed dashed requested a review from a team as a code owner June 4, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant