[19.0][ADD] subscription_oca: subscription renewals#1469
Conversation
4be868b to
a6fba40
Compare
Add a first-class renewal workflow so a subscription can spawn a child renewal quote, keep the link between both records, and automatically close the parent when the renewal is activated. * `parent_subscription_id` Many2one (self) — points at the contract this one was renewed from. * `origin_subscription_id` recursive computed Many2one (stored) — walks up the chain to the original contract. * `child_subscription_ids` One2many — renewals spawned from this one. * `renewal_count` — convenience compute for the stat button. * `is_renewed` Boolean (stored, partial index) — True when any child is not yet closed. Hides the Renew button while a quote is open. `action_prepare_renewal()` clones template, lines, pricelist, fiscal position, partner and journal into a new subscription in the configured `pre` stage, then chats a link on the parent. Activating that renewal calls `_handle_renewal_activation(child=self)` on the parent, which closes it via `close_subscription()`. UI: * Header button "Renew", visible only when the contract is in progress and there is no active child yet. * Stat buttons "Parent contract" and "Renewals" on the form. * Search filters "Renewals" / "Originals" and a groupby by parent contract. Migration: pure additive. `-u subscription_oca` runs the ORM recompute for `origin_subscription_id` and `is_renewed`; existing subscriptions end up with `False` for both (correct — no genealogy existed before). This does not touch `stage_id` semantics or any pre-existing field, so installations with custom stages keep working unchanged.
a6fba40 to
68372a9
Compare
|
I see the value of subscription_oca as a simpler subscription solution with a lower barrier to entry than contract. My concern is the long-term direction. As we continue adding features like renewals, aren't we gradually converging on the same feature set? Would it make sense to explore extending or integrating with contract for some advanced capabilities instead of implementing them independently? I'm not sure it will be sustainable for both modules to evolve in parallel if they end up covering the same use cases. |
|
This PR has the |
|
Hi @jelenapoblet, The Our experience with the In the same way that, in #1453, @pedrobaeza has one opinion ("With all of these changes, you are converting subscription_oca into contract in complexity terms") and you have another ("I don't think it will reach the same level of complexity as contract."), in this case I think exactly the same thing is happening. If the changes should be implemented in a different way—for example, splitting the functionality into more modules, or having a separate repository dedicated exclusively to keeping |
|
@alvaro-domatix I completely understand the history, and also why subscription_oca exists. We use it ourselves for exactly the same reason. We evaluated contract, and it didn't fit our needs either. |
|
@jelenapoblet I think for us this is structural, not really a feature-set question. We didn't pick subscription_oca because it was the lighter option or because it did less. We picked it because its model fits how we work, and because it's clearly laid out. Doing less was a side effect, not the reason. So adding functionality to it, carefully and additively, is what turns it into a genuinely powerful module that still fits us. That's the whole point. And that's why I have a hard time following the argument. If subscription_oca should stay limited on purpose to keep distance from contract, we just end up with a weaker module for no real gain. If the advanced features belong in contract instead, well, contract's base model doesn't fit us. And by your own words, it doesn't fit you either. I don't really see a third option that works. Open to the wider positioning conversation, wherever it makes sense. But for us, keeping subscription_oca frozen isn't really on the table. |
Adds subscription renewals while keeping the contractual genealogy: a renewal clones the template, lines, pricelist, fiscal position, partner and journal into a new subscription in the configured pre-stage, linked back to its parent.
The parent form gains:
Activating a renewal closes its parent via
close_subscription()(respecting the company), andis_renewed— a stored boolean with a partial index,Truewhile any non-closed child exists — hides the Renew button so a contract cannot be renewed twice in parallel.Purely additive: it does not touch
stage_idsemantics or any pre-existing field, so installations with custom stages keep working. Existing subscriptions simply end up with no parent/child lineage, which is correct.