invoices: let the admin set the payment date
All checks were successful
Build and Deploy to Production / test (push) Successful in 1m40s
Build and Deploy to Production / build (push) Successful in 1m19s
Build and Deploy to Production / deploy (push) Successful in 56s

Payments often arrive before they are recorded, so stamping paid_at
with the click time skews received-per-month and days-to-pay stats.
Mark paid now takes an optional date, and a paid invoice gets a form
to correct it. Past days are stored at 12:00 UTC so the date holds in
any timezone; future and malformed dates are refused. The PDF does not
print the date, so nothing is re-rendered.

Assisted-by: Claude:opus-5-5
Claude-Session: https://claude.ai/code/session_01TCc5TvWnAs5xPvGMQXTJw3
This commit is contained in:
Sergei Poljanski 2026-11-03 01:47:03 +04:00
commit 9d88b8af8f
Signed by: asxpi
GPG key ID: 4F8851660FA4121B
5 changed files with 68 additions and 4 deletions

View file

@ -43,8 +43,19 @@
<% if can?('invoices', 'write') %>
<div class="invoice-actions">
<% unless @invoice.cancelled? %>
<form method="post" action="/admin/invoices/<%= @invoice.uuid %>/paid">
<% today = Time.now.utc.to_date.iso8601 %>
<% if @invoice.paid? %>
<form method="post" action="/admin/invoices/<%= @invoice.uuid %>/paid-date" class="invoice-form paid-form">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<input type="date" name="paid_on" required max="<%= today %>" value="<%= @invoice.paid_at.utc.to_date.iso8601 %>" aria-label="Payment date" />
<button type="submit" class="link-button">Change paid date</button>
</form>
<% end %>
<form method="post" action="/admin/invoices/<%= @invoice.uuid %>/paid" class="invoice-form paid-form">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<% unless @invoice.paid? %>
<input type="date" name="paid_on" max="<%= today %>" value="<%= today %>" aria-label="Payment date" />
<% end %>
<button type="submit" class="link-button"><%= @invoice.paid? ? 'Mark unpaid' : 'Mark paid' %></button>
</form>
<% end %>