Details
Description
A service to renew currently occurs via Services::getAllPaidPending by checking that a service has a non-null last renew date, and an invoice that has been paid associated with the service since the last time the cron ran to renew services.
This is not enough criteria to distinguish whether the paid invoice for the service is indeed for a renewal. The invoice could be for a service option, a term/package change, or something else.
The proposed resolution is to specifically associate a renewal invoice with its service. Only when one of these invoices is paid would the service renew.
When a service renewal date is bumped, an invoice is created for it. This is the invoice that should be saved as the renewal invoice. Once this invoice has been paid, the service should be renewed, and the associated record of the renewal invoice should be removed.
New table:
`service_invoices`
`service_id`, `invoice_id`
When the cron runs to create a service renewal invoice, add it to `service_invoices`.
When the invoice is paid in full, the Services::getAllRenewablePaid method (or another method) called from the cron should check the `service_invoices` table to determine any of the invoices has been paid. For every paid invoice, renew the service, and remove the records from `service_invoices` table.
For backward compatibility, during upgrade, we may need to add all open invoices into `service_invoices` that contain a line item with a service ID. This would allow the current incorrect behavior to continue for existing invoices so that we do not miss renewing any services that should be renewed.