# -*- coding: utf-8 -*-

from odoo import models, fields, api
import time
from odoo.exceptions import UserError

class sos_deliverables_boq(models.Model):
    _name = 'sos_deliverables_boq'
    _description = 'Deliverables/BOQ'
    _rec_name = 'sales_id'
    _order = 'id desc'
     
    sales_id = fields.Many2one('sos_sales_order',string="Sales Order Id")
    fg_name = fields.Selection(
            [
             ('BHMS 1.2V', 'BHMS 1.2V'), 
                ('BHMS 2V', 'BHMS 2V'), 
                ('BHMS 12V', 'BHMS 12V'),  
                ('BHMS 48V', 'BHMS 48V'),
                ('BMS-HV', 'BMS-HV'),
                ('BMS-LV 100A', 'BMS-LV 100A'), 
                ('BMS-LV 40A', 'BMS-LV 40A'), 
                ('SBMS 55A', 'SBMS 55A'),              
                ('MC 250W', 'MC 250W'),                                
                ('HeartTarang', 'HeartTarang')                  
            ],
            string="Product Name",required=True)
    quantity = fields.Integer(string="Quantity")
    master_quantity = fields.Integer(string="Master Quantity")
    slave_quantity = fields.Integer(string="Slave Quantity")
    show_ev_fields = fields.Boolean(string="Show BMS Fields", compute="_compute_show_bms_fields", store=True)
    customer_name = fields.Char(string="Customer Name")
    customer_location = fields.Char(string="Customer Location")
    lead_time = fields.Datetime(string="Lead Time")
    scg_comments = fields.Text(string="Comments")
    rd_comments = fields.Text(string="Comments")
    production_comments = fields.Text(string="Comments")
    qc_comments = fields.Text(string="Comments")
    qa_comments = fields.Text(string="Comments")
    customer_po_no = fields.Char(string="PO No")
    customer_po_date = fields.Datetime(string="PO Date")
    line_ids_material = fields.One2many('sos_deliverables_line_material', 'ref_id', string="Materials",copy=True)
    line_ids_sfg = fields.One2many('sos_deliverables_line_sfg', 'ref_id', string="Semi-Finished Goods",copy=True)
    line_ids_fg = fields.One2many('sos_deliverables_line_fg', 'ref_id', string="Finished Goods",copy=True)
    line_ids_miscellaneous = fields.One2many('sos_deliverables_miscellaneous_items', 'ref_id',string="")
    line_ids_installation_kit = fields.One2many('sos_deliverables_line_material_installation', 'ref_id',string="")
    scg_reviewed_by = fields.Many2one('res.users', string='Prepared by')
    scg_reviewed_by_image = fields.Image(related="scg_reviewed_by.signature_image",string='Reviewed by Sign',readonly=True)
    scg_reviewed_on = fields.Datetime(string="Approved On")
    rd_reviewed_by = fields.Many2one('res.users', string='Prepared by')
    rd_reviewed_by_image = fields.Image(related="rd_reviewed_by.signature_image",string='Reviewed by Sign',readonly=True)
    rd_reviewed_on = fields.Datetime(string="Approved On")
    production_reviewed_by = fields.Many2one('res.users', string='Prepared by')
    production_reviewed_by_image = fields.Image(related="production_reviewed_by.signature_image",string='Reviewed by Sign',readonly=True)
    production_reviewed_on = fields.Datetime(string="Approved On")
    qc_reviewed_by = fields.Many2one('res.users', string='Prepared by')
    qc_reviewed_by_image = fields.Image(related="qc_reviewed_by.signature_image",string='Reviewed by Sign',readonly=True)
    qc_reviewed_on = fields.Datetime(string="Approved On")
    qa_reviewed_by = fields.Many2one('res.users', string='Prepared by')
    qa_reviewed_by_image = fields.Image(related="qa_reviewed_by.signature_image",string='Reviewed by Sign',readonly=True)
    qa_reviewed_on = fields.Datetime(string="Approved On")
    prepared_by = fields.Many2one('res.users', string='Prepared by')
    prepared_by_image = fields.Image(related="prepared_by.signature_image",string='Prepared by Sign',readonly=True)
    prepared_on = fields.Datetime(string="Prepared On")
    verified_by = fields.Many2one('res.users', string='Prepared by')
    verified_by_image = fields.Image(related="verified_by.signature_image",string='Prepared by Sign',readonly=True)
    verified_on = fields.Datetime(string="Prepared On")
    ce_verified_by = fields.Many2one('res.users', string='CE Verified by')
    ce_verified_by_image = fields.Image(related="ce_verified_by.signature_image",string='CE Verified by Sign',readonly=True)
    ce_verified_on = fields.Datetime(string="CE Head Verified On")
    scg_head_verified_by = fields.Many2one('res.users', string='SCG Verified by')
    scg_head_verified_by_image = fields.Image(related="scg_head_verified_by.signature_image",string='SCG Verified by Sign',readonly=True)
    scg_head_verified_on = fields.Datetime(string="SCG Head Verified On")
    batter_or_cells=fields.Integer(string="Battery/Cells")
    def action_report_boq(self):
        try:
            action = self.env.ref("sos_inventory.action_sos_deliverables_boq").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")
    def action_print_labels_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_labels").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")
    @api.depends('fg_name')
    def _compute_show_bms_fields(self):
        for record in self:
            record.show_ev_fields = record.fg_name.startswith('BHMS') if record.fg_name else False

    @api.onchange('fg_name')
    def _onchange_fg_name(self):
        if self.fg_name:
            self.line_ids_fg = [(5, 0, 0)]
            self.line_ids_sfg = [(5, 0, 0)]
            self.line_ids_material = [(5, 0, 0)]
            self.line_ids_installation_kit = [(5, 0, 0)]
            self.line_ids_miscellaneous = [(5, 0, 0)]
            record = self.env['sos_deliverables_config'].search([('fg_name', '=', self.fg_name)], limit=1)
            if record:
                for field_name, source_field in [
                    ('line_ids_fg', record.fg_ids),
                    ('line_ids_sfg', record.sfg_ids),
                    ('line_ids_material', record.material_ids),
                    ('line_ids_installation_kit', record.installation_kit_ids),
                    ('line_ids_miscellaneous', record.miscellaneous_ids)
                ]:
                    lines = []
                    if field_name != 'line_ids_miscellaneous':
                        for line_id in source_field:
                            line_vals = {
                                'ref_id': self.id,
                                'component_id': line_id.component_id.id,
                                'unit_price': line_id.component_id.unit_price,
                                'uom': line_id.uom,
                                'singet_set_qty': line_id.quantity,
                            }
                            if field_name == 'line_ids_sfg':
                                line_vals['assembling_charges'] = line_id.component_id.assembling_charges
                            lines.append((0, 0, line_vals))
                    else:
                        for line_id in source_field:
                            line_vals = {
                                'ref_id': self.id,
                                'name': line_id.name,
                                'quantity': line_id.quantity,
                            }
                        lines.append((0, 0, line_vals))
                    setattr(self, field_name, lines)



    def action_verified_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'verified_by',
        'verified_on'
    )
    def action_prepared_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        # Email part
        body_html = f"""
        <p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
        """ 
        sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_ce_head')
        # Email part ends
        return sequence_util.action_assign_signature(
        self, 
        'prepared_by',
        'prepared_on'
    )
    def action_ce_verified_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        # Email part
        body_html = f"""
        <p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
        """ 
        sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_scg_group_manager')
        # Email part ends
        return sequence_util.action_assign_signature(
        self, 
        'ce_verified_by',
        'ce_verified_on'
    )
    def action_scg_head_verified_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        # Email part
        body_html = f"""
        <p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
        """ 
        sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_qa_user')
        # Email part ends
        return sequence_util.action_assign_signature(
        self, 
        'scg_head_verified_by',
        'scg_head_verified_on'
    )
    
    def action_scg_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'scg_reviewed_by',
        'scg_reviewed_on'
    )
    def action_rd_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'rd_reviewed_by',
        'rd_reviewed_on'
    )
    def action_production_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'production_reviewed_by',
        'production_reviewed_on'
    )
    def action_qc_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'qc_reviewed_by',
        'qc_reviewed_on'
    )
    def action_qa_esign_btn(self):
        sos_order_delivery_plan_line = self.env['sos_order_delivery_plan'].create({
            'sales_id':self.sales_id.id,
            'fg_name':self.fg_name,
            'quantity':self.quantity,
            'customer_name':self.customer_name,
            'lead_time':self.lead_time,
            'deliverables_boq_id':self.id,
            'customer_po_no':self.customer_po_no,
            'customer_po_date':self.customer_po_date

        })
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'qa_reviewed_by',
        'qa_reviewed_on'
    )

class sos_deliverables_boq_Line_Material(models.Model):
    _name = 'sos_deliverables_line_material'
    _description = 'Material Lines'

    ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
    component_id = fields.Many2one('sos_material', string="Material Name", required=True)
    display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
    uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
    currency_id = fields.Many2one('res.currency', string='Currency')
    material_code = fields.Char(related="component_id.material_code",string="Material Code")
    material_name = fields.Char(related="component_id.part_no",string="Material Name")
    singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
    total_set =  fields.Integer(string="Total Set",default=1)
    quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
    unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
    total_price = fields.Monetary(string="Total",compute="_compute_total_price")
    is_spare = fields.Boolean(string="Spare")
    add_production_cost = fields.Boolean(string="Include in Costing",default=True)
    @api.onchange('component_id')
    def _onchange_component_id(self):
        """
        Set the initial value of `unit_price` when `component_id` is changed.
        """
        for record in self:
            if record.component_id:
                record.unit_price = record.component_id.unit_price
    @api.depends('singet_set_qty','total_set')
    def _compute_set_wise(self):
        for record in self:
            record.quantity = record.singet_set_qty * record.total_set
    @api.depends('unit_price','quantity')
    def _compute_total_price(self):
        for record in self:
            record.total_price = record.unit_price * record.quantity

class sos_deliverables_boq_Line_sfg(models.Model):
    _name = 'sos_deliverables_line_sfg'
    _description = 'SFG Order Lines'

    ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
    currency_id = fields.Many2one('res.currency', string='Currency')
    component_id = fields.Many2one('sos_sfg', string="SFG Name", required=True)
    uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
    sfg_code = fields.Char(related="component_id.sfg_code",string="SFG Code")
    sfg_name = fields.Char(related="component_id.name",string="SFG Name")
    singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
    total_set =  fields.Integer(string="Total Set",default=1)
    quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
    unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
    assembling_charges = fields.Monetary(string="Assembling cost per unit",related="component_id.assembling_charges")
    total_price = fields.Monetary(string="Total",compute="_compute_total_price")
    is_spare = fields.Boolean(string="Spare")
    add_production_cost = fields.Boolean(string="Include in Costing",default=True)
    @api.onchange('component_id')
    def _onchange_component_id(self):
        """
        Set the initial value of `unit_price` when `component_id` is changed.
        """
        for record in self:
            if record.component_id:
                record.unit_price = record.component_id.unit_price
                record.assembling_charges = record.component_id.assembling_charges
    @api.depends('singet_set_qty','total_set')
    def _compute_set_wise(self):
        for record in self:
            record.quantity = record.singet_set_qty * record.total_set
    @api.depends('unit_price','quantity')
    def _compute_total_price(self):
        for record in self:
            record.total_price = (record.unit_price + record.assembling_charges) * record.quantity

  
class sos_deliverables_boq_Line_fg(models.Model):
    _name = 'sos_deliverables_line_fg'
    _description = 'FG Order Lines'

    ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
    currency_id = fields.Many2one('res.currency', string='Currency')
    component_id = fields.Many2one('sos_fg',string="FG Name", required=True)
    uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
    fg_code = fields.Char(related="component_id.fg_code",string="FG Code")
    fg_name = fields.Char(related="component_id.name",string="FG Name")
    quantity = fields.Integer(string="Quantity",compute="_compute_set_wise", store=True)
    singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
    total_set =  fields.Integer(string="Total Set",default=1)
    unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
    total_price = fields.Monetary(string="Total",compute="_compute_total_price")
    is_spare = fields.Boolean(string="Spare")
    add_production_cost = fields.Boolean(string="Include in Costing",default=True)
    @api.onchange('component_id')
    def _onchange_component_id(self):
        for record in self:
            if record.component_id:
                record.unit_price = record.component_id.unit_price
    
                
    @api.depends('singet_set_qty','total_set')
    def _compute_set_wise(self):
        for record in self:
            record.quantity = record.singet_set_qty * record.total_set
    @api.depends('unit_price','quantity')
    def _compute_total_price(self):
        for record in self:
            record.total_price = record.unit_price * record.quantity

class sos_deliverables_MiscellaneousCost(models.Model):
    _name = 'sos_deliverables_miscellaneous_items'
    _description = 'Miscellaneous Items'

    ref_id = fields.Many2one('sos_deliverables_boq', string="Miscellaneous", ondelete="cascade")
    name = fields.Char(string='Name')
    cost = fields.Float(string='Cost')
    quantity = fields.Integer(string="Quantity")
    currency_id = fields.Many2one('res.currency', string='Currency')
    total_price = fields.Monetary(string="Total", currency_field='currency_id',compute="_compute_total_price")

    @api.depends('cost','quantity')
    def _compute_total_price(self):
        for record in self:
            record.total_price = record.cost * record.quantity


class sos_deliverables_Material_installationkit(models.Model):
    _name = 'sos_deliverables_line_material_installation'
    _description = 'Installation Kit Lines'

    ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
    component_id = fields.Many2one('sos_material', string="Material Name", required=True)
    display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
    uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
    currency_id = fields.Many2one('res.currency', string='Currency')
    material_code = fields.Char(related="component_id.material_code",string="Material Code")
    material_name = fields.Char(related="component_id.part_no",string="Material Name")
    singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
    total_set =  fields.Integer(string="Total Set",default=1)
    quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
    unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
    total_price = fields.Monetary(string="Total",compute="_compute_total_price")
    @api.onchange('component_id')
    def _onchange_component_id(self):
        """
        Set the initial value of `unit_price` when `component_id` is changed.
        """
        for record in self:
            if record.component_id:
                record.unit_price = record.component_id.unit_price
    @api.depends('singet_set_qty','total_set')
    def _compute_set_wise(self):
        for record in self:
            record.quantity = record.singet_set_qty * record.total_set
    @api.depends('unit_price','quantity')
    def _compute_total_price(self):
        for record in self:
            record.total_price = record.unit_price * record.quantity


