feat(fusion_accounting_assets): partial sale wizard

Made-with: Cursor
This commit is contained in:
gsinghpal
2026-04-19 20:05:17 -04:00
parent 892c37e2b0
commit 92f445eb8f
7 changed files with 158 additions and 1 deletions

View File

@@ -1,2 +1,3 @@
from . import create_asset_wizard
from . import disposal_wizard
from . import partial_sale_wizard

View File

@@ -0,0 +1,67 @@
"""Partial sale wizard (sell a portion of an asset).
Splits the asset into a child (the sold portion) and disposes the child;
parent retains remaining cost + salvage."""
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class FusionPartialSaleWizard(models.TransientModel):
_name = "fusion.partial.sale.wizard"
_description = "Asset Partial Sale Wizard"
asset_id = fields.Many2one(
'fusion.asset', required=True,
default=lambda self: self._default_asset(),
)
company_id = fields.Many2one(related='asset_id.company_id')
currency_id = fields.Many2one(related='asset_id.currency_id')
cost = fields.Monetary(related='asset_id.cost', readonly=True)
book_value = fields.Monetary(related='asset_id.book_value', readonly=True)
sold_pct = fields.Float(
string='% of cost being sold', default=30.0,
help="Percentage of original cost attributed to the sold portion.",
)
sold_amount = fields.Monetary(string='Sale Amount', required=True)
sale_date = fields.Date(required=True, default=fields.Date.today)
sale_partner_id = fields.Many2one('res.partner')
estimated_sold_cost = fields.Monetary(compute='_compute_sold_cost')
estimated_gain_loss = fields.Monetary(compute='_compute_sold_cost')
@api.model
def _default_asset(self):
ctx = self.env.context
if ctx.get('active_model') == 'fusion.asset':
return ctx.get('active_id')
return False
@api.depends('sold_pct', 'sold_amount', 'cost')
def _compute_sold_cost(self):
for w in self:
w.estimated_sold_cost = round(w.cost * (w.sold_pct or 0) / 100, 2)
w.estimated_gain_loss = w.sold_amount - w.estimated_sold_cost
def action_partial_sell(self):
self.ensure_one()
if not (0 < self.sold_pct < 100):
raise UserError(_("sold_pct must be strictly between 0 and 100."))
if self.asset_id.state == 'disposed':
raise UserError(_("Asset already disposed."))
result = self.env['fusion.asset.engine'].partial_sale(
self.asset_id,
sold_amount=self.sold_amount,
sold_qty=self.sold_pct / 100,
sale_date=self.sale_date,
sale_partner=self.sale_partner_id,
)
return {
'type': 'ir.actions.act_window',
'res_model': 'fusion.asset',
'res_id': result['parent_asset_id'],
'view_mode': 'form',
'target': 'current',
}

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_fusion_partial_sale_wizard_form" model="ir.ui.view">
<field name="name">fusion.partial.sale.wizard.form</field>
<field name="model">fusion.partial.sale.wizard</field>
<field name="arch" type="xml">
<form string="Partial Sale">
<group>
<field name="asset_id" readonly="1" options="{'no_create': True}"/>
<field name="cost" readonly="1"/>
<field name="book_value" readonly="1"/>
<field name="company_id" invisible="1"/>
<field name="currency_id" invisible="1"/>
</group>
<group>
<field name="sold_pct"/>
<field name="estimated_sold_cost" readonly="1"/>
<field name="sold_amount"/>
<field name="estimated_gain_loss" readonly="1"/>
<field name="sale_date"/>
<field name="sale_partner_id"/>
</group>
<footer>
<button name="action_partial_sell" type="object"
string="Confirm Partial Sale" class="btn-primary"/>
<button special="cancel" string="Cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_fusion_partial_sale_wizard" model="ir.actions.act_window">
<field name="name">Partial Sale</field>
<field name="res_model">fusion.partial.sale.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>