# models/yet_to_bill_wizard.py from odoo import models, fields, api from collections import defaultdict def _norm(s): return (s or '').strip().lower() class SosYetToBillWizard(models.TransientModel): _name = 'yet_to_bill_wizard' _description = 'Yet To Bill' line_ids = fields.One2many('yet_to_bill_line', 'wizard_id', string="Lines") @api.model def default_get(self, fields_list): res = super().default_get(fields_list) brief_ref_id = self.env.context.get('brief_ref_id') brief_domain = [('ref_id', '=', brief_ref_id)] if brief_ref_id else [] Brief = self.env['sos_sales_achievement_report_brief'] Billing = self.env['sos_billing_collection'] line_cmds = [] # Search all brief records brief_records = Brief.search(brief_domain) for br in brief_records: proposal = br.proposal_value or 0.0 customer = br.customer_name po_no = br.po_no if not customer or not po_no: continue # Get billed amount for same customer & po_no billed_lines = Billing.search([ ('customer_name', '=', customer.id), ('po_no', '=', po_no), ('action_status', '=', 'Billed') ]) billed_amount = sum(billed_lines.mapped('value')) remaining = proposal - billed_amount if remaining > 0: line_cmds.append((0, 0, { 'customer_id': customer.id, 'customer_name_display': customer.display_name, 'po_no': po_no, 'proposal_value': proposal, 'billed_value': billed_amount, 'remaining_value': remaining, })) res['line_ids'] = line_cmds return res def action_open(self): return { 'type': 'ir.actions.act_window', 'name': 'Yet To Bill', 'res_model': 'yet_to_bill_wizard', # FIXED 'view_mode': 'form', 'res_id': self.id, 'target': 'new', } class SosYetToBillLine(models.TransientModel): _name = 'yet_to_bill_line' _description = 'Yet To Bill Line' _order = 'remaining_value desc' wizard_id = fields.Many2one('yet_to_bill_wizard', required=True, ondelete='cascade') customer_id = fields.Many2one('sos_customers', string="Customer", readonly=True) customer_name_display = fields.Char(string="Customer Name", readonly=True) po_no = fields.Char(string="PO No", readonly=True) proposal_value = fields.Float(string="Proposal Value", readonly=True) billed_value = fields.Float(string="Billed Value", readonly=True) remaining_value = fields.Float(string="Yet to Bill", readonly=True)