from odoo import api, fields, models, _
import logging
_logger = logging.getLogger(__name__)
from odoo.exceptions import ValidationError
from datetime import datetime,date,timedelta
from odoo.exceptions import UserError
import io
import xlsxwriter
from odoo.tools.misc import xlsxwriter
import base64

class SOS_FG_Plan(models.Model):
    _name = 'sos_fg_plan'
    _description = 'FG Plan'
    _rec_name = 'plan_ref_no'
    

    plan_ref_no = fields.Char(
        readonly=True, required=True, string='Plan ID', 
        default=lambda self: self._generate_id()
    )
    line_ids = fields.One2many('sos_fg_plan_line', 'plan_id', string='Lines', ondelete='cascade')
    sfg_line_ids = fields.One2many('sos_sfg_plan_line', 'plan_id', string='SFG Lines', ondelete='cascade')
    material_line_ids = fields.One2many('sos_material_plan_line', 'plan_id', string='Lines', ondelete='cascade')
    
    approved_by  = fields.Many2one('res.users', string='Approved By')
    approval_image = fields.Image(related="approved_by.signature_image",string='Top Management Approval Sign',readonly=True)
    approved_on = fields.Datetime(string="Approved On")

    prepared_by  = fields.Many2one('res.users', string='Planned By')
    prepared_image = fields.Image(related="prepared_by.signature_image",string='Prepared By Sign',readonly=True)
    prepared_on = fields.Datetime(string="Planned On")
    blowup = fields.Boolean(string="Blowup Done",default=False)
    target_date = fields.Date(string="Target Date",required=True)
    indent_start_date = fields.Date(string="Indent Start Date", default=lambda self: fields.Date.context_today(self))
    indent_status = fields.Selection([('open', 'Open'), ('cancel', 'Cancel'), ('hold', 'Hold'), ('close', 'Closed')], string='Indent Status', default="open")
    hold_cancel_reason = fields.Text(string='Hold/Cancel Reason')
    hold_cancel_by  = fields.Many2one('res.users', string='Hold & Cancelled By')
    company_id = fields.Many2one('res.company', store=True, copy=False,
                                string="Company",
                                default=lambda self: self.env.user.company_id.id)
    currency_id = fields.Many2one('res.currency', string="Currency",
                                 related='company_id.currency_id',
                                 default=lambda
                                 self: self.env.user.company_id.currency_id.id)
    estimated_assembling_charges = fields.Monetary(compute='_compute_assembling_charges', string="SFG Assembling Charges", currency_field='currency_id', readonly=True)
    estimated_material_cost = fields.Monetary(compute='_compute_material_charges', string="Material Procurement Cost", currency_field='currency_id', readonly=True)
    other_charges = fields.Monetary(string="Transport & Other Charges",currency_field='currency_id')
    overall_total = fields.Monetary(compute='_compute_overall_total',string ="Overall Estimated Cost",currency_field='currency_id')
    tax_value = fields.Monetary(string="Tax(18%)")
    @api.depends('estimated_assembling_charges', 'estimated_material_cost', 'other_charges')
    def _compute_overall_total(self):
        for record in self:
            overall_total = (
                (record.estimated_assembling_charges or 0) + 
                (record.estimated_material_cost or 0) + 
                (record.other_charges or 0)
            )
            
            with_tax = overall_total * (1.18)
            record.tax_value =  with_tax - overall_total
            record.overall_total = with_tax
    @api.depends('sfg_line_ids.total_assembling_cost')
    def _compute_assembling_charges(self):
        for record in self:
            record.estimated_assembling_charges = round(sum(line.total_assembling_cost for line in record.sfg_line_ids), 2)
    @api.depends('material_line_ids.total_approx_price')
    def _compute_material_charges(self):
        for record in self:
            record.estimated_material_cost = round(sum(line.total_approx_price for line in record.material_line_ids), 2)
    
    def open_reason_wizard(self):
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'hold_cancel_reason_wizard',
            'name':'Indent Status Change',
            'view_mode': 'form',
            'target': 'new',
            'context': {
                'default_model_id': self.id,
            }
        }


    @api.onchange('target_date', 'indent_start_date')
    def _onchange_dates(self):
        for record in self:
            if record.target_date:
                max_target_date = date.today() + timedelta(days=90)
                if record.target_date > max_target_date:
                    raise UserError("Target Date cannot exceed 90 days from the Indent Start Date(Today)")

    @api.model
    def default_get(self, fields_list):
        res = super(SOS_FG_Plan, self).default_get(fields_list)
        if 'line_ids' in fields_list and 'line_ids' not in res:
            default_lines = self._get_default_lines('sos_fg','fg_name')
            res['line_ids'] = [(0, 0, line) for line in default_lines]
        if 'sfg_line_ids' in fields_list and 'sfg_line_ids' not in res:
            default_lines = self._get_default_lines('sos_sfg','sfg_name')
            res['sfg_line_ids'] = [(0, 0, line) for line in default_lines]
        if 'material_line_ids' in fields_list and 'material_line_ids' not in res:
            default_lines = self._get_default_lines('sos_material','material_name')
            res['material_line_ids'] = [(0, 0, line) for line in default_lines]
        return res

    def _generate_id(self):
        model_name = 'sos_fg_plan'
        form_name = 'INDENT'
        field_name = 'plan_ref_no'
        today = fields.Date.today()
        year_start = today.year if today.month > 3 else today.year - 1
        year_end = year_start + 1
        fy = f"{year_start % 100}-{year_end % 100}"

        month = today.strftime('%m')
        base_sequence_prefix = f"SOS/{form_name}/{fy}/{month}/"

        records = self.env[model_name].sudo().search(
            [(field_name, 'like', f"{base_sequence_prefix}%")],
            order=f"{field_name} desc",
            limit=1
        )

        if records:
            last_sequence = records[0][field_name]
            last_suffix = last_sequence.split('/')[-1]
            if last_suffix.isdigit():
                new_suffix = f"{last_suffix}a"
            else:
                base_num = last_suffix[:-1]  
                last_alpha = last_suffix[-1]  
                next_alpha = chr(ord(last_alpha) + 1) if last_alpha < 'z' else 'a'
                new_suffix = f"{base_num}{next_alpha}"
        else:
            new_suffix = '016'

        return f"{base_sequence_prefix}{new_suffix}"



    
    def _get_default_lines(self,model,column):
        products = self.env[model].search([])
        default_lines = []
        for product in products:
            if (product.order_qty + product.minimum_stock_qty) > product.inhand_stock_qty:
                to_be_produce = (product.order_qty + product.minimum_stock_qty) - (product.inhand_stock_qty + product.in_transit_stock_qty)
                if to_be_produce > product.minimum_order_qty:
                    final_qty = to_be_produce
                else:
                    final_qty = product.minimum_order_qty
                default_line = {
                    column: product.id,
                    'inhand_qty': product.inhand_stock_qty,
                    'in_transit_stock_qty': product.in_transit_stock_qty,
                    'minimum_stock_qty': product.minimum_stock_qty,
                    'required_qty': product.order_qty,
                    'minimum_order_qty':product.minimum_order_qty,
                    'approved_cnt':final_qty,
                    'actual_required_qty':to_be_produce
                }
                if column == "material_name":
                    default_line['approx_price'] = product.unit_price
                elif column == "sfg_name":
                    default_line['assembling_cost'] = product.assembling_charges
                default_lines.append(default_line)
        return default_lines
    

  
    def send_indent_plan_email(self, email_ids):
        template = self.env.ref('sos_inventory.send_indent_plan_email_template') 
        if template:
            template.email_to = ','.join(email_ids)
            template.send_mail(self.id, force_send=True)
    def get_unique_emails(self):
        group_refs = [
            'sos_inventory.sos_scg_group_user',
            'sos_inventory.sos_scg_group_manager',
            'sos_inventory.sos_finance_user',
            'sos_inventory.sos_management_user',
            'sos_inventory.sos_qc_user',
            'sos_inventory.sos_qa_user',
            'sos_inventory.sos_production_user'
        ]
        group_ids = [self.env.ref(group_ref).id for group_ref in group_refs]
        users = self.env['res.users'].search([('groups_id', 'in', group_ids)])
        emails = list(set(users.mapped('email'))) 
        return emails
    def action_export_final(self):
        output = io.BytesIO()
        workbook = xlsxwriter.Workbook(output, {'in_memory': True})

        # Define custom headers for each sheet
        line_headers = {
            'fg_name': 'FG Name',
            'approved_cnt': 'Planned Qty'
        } 
        
        sfg_headers = {
            'sfg_name': 'SFG Name',
            'actual_required_qty': 'Actual Req Qty ',
            'minimum_order_qty': 'Minimum Order Qty',
            'assembling_cost':'Assembling Cost per unit',
            'total_assembling_cost':'Total Assembling Cost',
            'approved_cnt':'Planned Qty'
        }  
        
        material_headers = {
            'material_name': 'Material Name',
            'approx_price': 'Unit Price',
            'actual_required_qty': 'Field Z Header',
            'minimum_order_qty':'Minimum Order Qty',
            'total_approx_price':'Approx Price',
            'approved_cnt':'Planned Qty'
        }  
        
        custom_headers = {
            'estimated_assembling_charges': 'SFG Assembling Charges',
            'estimated_material_cost': 'Material Procurement Cost',
            'other_charges': 'Transport & Other Charges',
            'tax_value':'Tax (18%)',
            'overall_total':'Overall Estimated Cost'
        }  

        self._write_sheet(workbook, 'FG Plan', self.line_ids, line_headers)
        self._write_sheet(workbook, 'SFG Plan', self.sfg_line_ids, sfg_headers)
        self._write_sheet(workbook, 'Material Plan', self.material_line_ids, material_headers)

        # Write the custom sheet with fields from the main model (self) and custom headers
        self._write_custom_sheet(workbook, 'Budget', custom_headers)

        workbook.close()
        output.seek(0)

        # Create attachment and initiate download
        attachment = self.env['ir.attachment'].create({
            'name': f'{self.plan_ref_no}_Export.xlsx',
            'type': 'binary',
            'datas': base64.b64encode(output.read()),
            'res_model': self._name,
            'res_id': self.id,
            'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        })

        return {
            'type': 'ir.actions.act_url',
            'url': f'/web/content/{attachment.id}?download=true',
            'target': 'self',
        }

    def _write_sheet(self, workbook, sheet_name, line_records, headers):
        """Write data to each sheet based on specified fields and custom headers."""
        worksheet = workbook.add_worksheet(sheet_name)

        # Write custom headers
        for col, header in enumerate(headers.values()):
            worksheet.write(0, col, header)

        # Write data rows
        for row, record in enumerate(line_records, start=1):
            for col, field in enumerate(headers.keys()):
                value = getattr(record, field, '')
                # Convert value if necessary (Many2one, Date, etc.)
                if isinstance(value, models.Model):
                    worksheet.write(row, col, value.display_name if value else '')
                elif isinstance(value, (fields.Date, fields.Datetime)):
                    worksheet.write(row, col, value.strftime('%Y-%m-%d') if value else '')
                else:
                    worksheet.write(row, col, value)

    def _write_custom_sheet(self, workbook, sheet_name, headers):
        """Write a custom sheet with fields from the main model, row by row with custom headers."""
        worksheet = workbook.add_worksheet(sheet_name)

        # Write each field as a separate row with its custom header and value
        for row, (field, header) in enumerate(headers.items()):
            # Write the header in the first column
            worksheet.write(row, 0, header)

            # Retrieve the value for the field and write it in the second column
            value = getattr(self, field, '')
            
            # Convert value if necessary (Many2one, Date, etc.)
            if isinstance(value, models.Model):
                worksheet.write(row, 1, value.display_name if value else '')
            elif isinstance(value, (fields.Date, fields.Datetime)):
                worksheet.write(row, 1, value.strftime('%Y-%m-%d') if value else '')
            else:
                worksheet.write(row, 1, value)

     
    def action_top_approver_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        result = sequence_util.action_assign_signature(
            self, 
            'approved_by',
            'approved_on',
            'sos_inventory.sos_management_user'
        )
      
        email_addresses = self.get_unique_emails()
        self.send_indent_plan_email(email_addresses)
        self.env['sos_audit_log'].create_log('Approval', f'Indent <b>{self.plan_ref_no}</b> approved by {self.env.user.name}')
        self.update_store_qty(self.line_ids,self.sfg_line_ids,self.material_line_ids)
        self.create_production_plan(self.line_ids)
        self.create_procurement_plan(self.material_line_ids)
        self.create_fptc(self.line_ids)
        self.create_sfg_quotation(self.sfg_line_ids)

    def action_report_esign_btn(self):
        if self.blowup == False:
            self.blowup = True
            missing_boms = []
            for item in self.line_ids:
                if item.approved_cnt != 0:
                    fg_name = item.fg_name.id 
                    product_bom = self.env['sos_fg_bom'].search([
                        ('fg_name', '=', fg_name),
                        ('is_primary', '=', True)
                    ], limit=1)
                    if not product_bom:
                        missing_boms.append(item.fg_name.name)

            if missing_boms:
                raise UserError(f"BOM for following product(s) are Missing, Delete those for this Indent or add BOM(s) : {', '.join(missing_boms)}")
            else:
                self.create_sfg_plan(self.line_ids)
                self.create_material_plan(self.sfg_line_ids)
        else:
            raise UserError("Already Blowed up")
    def action_approve_esign_btn(self):
        body_html = f"""
        <p>Below <b>Indent Budget</b> is waiting for your Approval</p>
        """
        
        send_email = self.env['sos_common_scripts']
        send_email.send_direct_email(self.env,"sos_fg_plan",self.id,"ramachandran.r@sosaley.in","Indent Budget Approval",body_html)
        sequence_util = self.env['sos_common_scripts']
        result = sequence_util.action_assign_signature(
            self, 
            'prepared_by',
            'prepared_on'
        )

  
   
    def update_store_qty(self,line_ids,sfg_line_ids,material_line_ids):
        model_names = ['sos_fg', 'sos_sfg', 'sos_material']

        for model_name in model_names:
            if model_name == 'sos_fg':
                column_name = 'fg_name'
                line_ids_final = line_ids
            elif model_name == 'sos_sfg':
                column_name = 'sfg_name'
                line_ids_final = sfg_line_ids
            else:
                column_name = 'material_name'
                line_ids_final = material_line_ids
            for item in line_ids_final:
                f_id = getattr(item, column_name).id
                
                sos_record = self.env[model_name].search([('id', '=', f_id)], limit=1)
                if sos_record:
                    new_in_transit_qty = sos_record.in_transit_stock_qty + item.approved_cnt
                    
                    sos_record.write({
                        'order_qty': 0,
                        'in_transit_stock_qty': new_in_transit_qty,
                    })
                    if model_name != "sos_fg":
                        sos_record.write({
                        'blocked_qty': sos_record.blocked_qty + item.approved_cnt
                    })



  
    def create_sfg_quotation(self, line_ids):
        quotation_model = self.env['sos_sfg_quote_generation']
        quotation_line_model = self.env['sos_sfg_quote_generation_line']
        quotation_record = quotation_model.search([('plan_ref_no', '=', self.plan_ref_no)], limit=1)
        if not quotation_record:
            quotation_record = quotation_model.create({'plan_ref_no': self.plan_ref_no})
        for item in line_ids:
            if item.approved_cnt != 0:
                if item.blowup_action == "yes":
                    blowup_action_result = "with_materials"
                else:
                    blowup_action_result = "without_materials"
                quotation_line_model.create({
                            'material_name': item.sfg_name.id,
                            'required_qty': item.approved_cnt,
                            'inprogress_qty': item.approved_cnt,
                            'plan_id': quotation_record.id,
                            'purchase_type':blowup_action_result,
                            'supplier_name':item.sfg_name.service_providers
                        })
        
    def create_procurement_plan(self, line_ids):
        quotation_model = self.env['sos_quote_generation']
        quotation_line_model = self.env['sos_quote_generation_line']
        quotation_record = quotation_model.search([('plan_ref_no', '=', self.plan_ref_no)], limit=1)
        if not quotation_record:
            quotation_record = quotation_model.create({'plan_ref_no': self.plan_ref_no})
        for item in line_ids:
            if item.approved_cnt != 0:
                quotation_line_model.create({
                            'material_name': item.material_name.id,
                            'required_qty': item.approved_cnt,
                            'plan_id': quotation_record.id,
                            'supplier_name':item.material_name.suppliers
                        })
    def create_material_plan(self, line_ids):
        material_stores_model = self.env['sos_material']
        material_line_model = self.env['sos_material_plan_line']

        # Dictionary to store component quantities
        part_no_quantities = {}

        # Process each line to populate the quantities
        for item in line_ids:
            if item.approved_cnt != 0 and item.blowup_action != 'no':
                # Fetch the SFG BOM for the current item
                sfg_bom = self.env['sos_sfg_bom'].search([
                    ('name', '=', item.sfg_name.id)
                ], limit=1)
                if sfg_bom:
                    # Fetch SFG BOM lines
                    sfg_lines = self.env['sos_sfg_bom_line'].search([('bom_id', '=', sfg_bom.id)])
                    for sfg_line in sfg_lines:
                        component = sfg_line.primary_component_id
                        if component:
                            req_qty = sfg_line.quantity * item.approved_cnt
                            
                            # Aggregate quantities for the component
                            if component.part_no in part_no_quantities:
                                part_no_quantities[component.part_no]['req_qty'] += req_qty
                            else:
                                part_no_quantities[component.part_no] = {
                                    'inhand_stock_qty': max(0, component.inhand_stock_qty - component.blocked_qty),
                                    'in_transit_stock_qty': component.in_transit_stock_qty,
                                    'minimum_stock_qty': component.minimum_stock_qty,
                                    'minimum_order_qty': component.minimum_order_qty,
                                    'req_qty': req_qty,
                                    'part_no_id': component.id
                                }

        # Process the aggregated quantities to update or create material plan lines
        for part_no, data in part_no_quantities.items():
            inhand_stock_qty = data['inhand_stock_qty']
            minimum_stock_qty = data['minimum_stock_qty']
            req_qty = data['req_qty']
            minimum_order_qty = data['minimum_order_qty']
            in_transit_stock_qty = data['in_transit_stock_qty']

            # Check if the material line already exists
            pick_line = material_line_model.search([
                ('plan_id', '=', self.id),
                ('material_name', '=', data['part_no_id'])
            ], limit=1)

            if pick_line:
                # Update existing material line
                pick_line.write({
                    'actual_required_qty': pick_line.actual_required_qty + req_qty,
                    'required_qty': pick_line.required_qty + req_qty,
                    'approved_cnt': pick_line.approved_cnt + (req_qty if pick_line.approved_cnt else 0)
                })
            else:
                # Calculate the approved count if creating a new line
                if minimum_stock_qty > (inhand_stock_qty + in_transit_stock_qty) - req_qty:
                    approved_cnt = max(req_qty + minimum_stock_qty - (inhand_stock_qty + in_transit_stock_qty), minimum_order_qty)
                else:
                    approved_cnt = 0

                # Create a new material plan line
                material_line_model.create({
                    'material_name': data['part_no_id'],
                    'inhand_qty': inhand_stock_qty,
                    'minimum_stock_qty': minimum_stock_qty,
                    'plan_id': self.id,
                    'required_qty': req_qty,
                    'actual_required_qty': req_qty,  # Set correctly for new records
                    'approved_cnt': approved_cnt,
                    'minimum_order_qty': minimum_order_qty
                })


    def create_sfg_plan(self, line_ids):
        sfg_stores_model = self.env['sos_sfg']
        sfg_line_model = self.env['sos_sfg_plan_line']

        # Loop through the lines to process each item
        for item in line_ids:
            if item.approved_cnt != 0:
                fg_name = item.fg_name.id  # Use the ID for Many2one relationship
                fg_qty_to_produce = int(item.approved_cnt)
                
                # Fetch the primary BOM for the FG
                product_bom = self.env['sos_fg_bom'].search([
                    ('fg_name', '=', fg_name),
                    ('is_primary', '=', True)
                ], limit=1)
                
                if product_bom:
                    lines = self.env['sos_fg_bom_line'].search([('bom_id', '=', product_bom.id)])
                    
                    # Fetch existing SFG plan lines for the current plan
                    old_lines = sfg_line_model.search([('plan_id', '=', self.id)])
                    already_created_sfg = {line.sfg_name.id: line for line in old_lines}

                    for sfg_line in lines:
                        sfg_name = sfg_line.sfg_bom_id.name.id  # Use the ID for Many2one relationship
                        req_sfg_qty = sfg_line.quantity * fg_qty_to_produce
                        
                        sfg_inhand_qty = max(0, sfg_line.sfg_bom_id.name.inhand_stock_qty - sfg_line.sfg_bom_id.name.blocked_qty)
                        sfg_minimum_stock_qty = sfg_line.sfg_bom_id.name.minimum_stock_qty
                        sfg_intransit_stock_qty = sfg_line.sfg_bom_id.name.in_transit_stock_qty
                        
                        # Calculate approved quantity
                        if sfg_minimum_stock_qty <= (sfg_inhand_qty + sfg_intransit_stock_qty) - req_sfg_qty:
                            approved_cnt = 0
                        else:
                            #approved_cnt = req_sfg_qty + sfg_minimum_stock_qty - (sfg_inhand_qty + sfg_intransit_stock_qty)

                            approved_cnt = req_sfg_qty - (sfg_inhand_qty + sfg_intransit_stock_qty)

                        # If the SFG already exists in the plan, update its values
                        if sfg_name in already_created_sfg:
                            existing_line = already_created_sfg[sfg_name]
                            
                            # Determine the new approved count
                            if existing_line.actual_required_qty + req_sfg_qty > sfg_line.sfg_bom_id.name.minimum_order_qty:
                                order_to_be = existing_line.actual_required_qty + req_sfg_qty
                            else:
                                order_to_be = sfg_line.sfg_bom_id.name.minimum_order_qty
                            
                            # Update the existing line
                            existing_line.write({
                                'required_qty': existing_line.required_qty + req_sfg_qty,
                                'actual_required_qty': existing_line.actual_required_qty + req_sfg_qty,
                                'approved_cnt': order_to_be,
                                'blowup_action': 'yes'
                            })
                        else:
                            # Create a new SFG plan line
                            sfg_line_model.create({
                                'fg_name': fg_name,
                                'sfg_name': sfg_name,
                                'inhand_qty': sfg_inhand_qty,
                                'minimum_stock_qty': sfg_minimum_stock_qty,
                                'plan_id': self.id,
                                'actual_required_qty': approved_cnt,
                                'required_qty': req_sfg_qty,
                                'approved_cnt': approved_cnt,
                                'blowup_action': 'yes',
                                'assembling_cost': sfg_line.sfg_bom_id.name.assembling_charges
                            })

                    
                    material_lines = self.env['sos_sfg_bom_line'].search([('fg_bom_id', '=', product_bom.id)])
                    material_stores_model = self.env['sos_material']
                    material_line_model = self.env['sos_material_plan_line']

                    # Fetch existing material plan lines for the current plan
                    old_lines_material = material_line_model.search([('plan_id', '=', self.id)])
                    already_created_material = {line_material.material_name.id: line_material for line_material in old_lines_material}

                    for material_line in material_lines:
                        inhand_stock_qty = material_line.primary_component_id.inhand_stock_qty
                        minimum_stock_qty = material_line.primary_component_id.minimum_stock_qty
                        req_qty = material_line.quantity * fg_qty_to_produce
                        minimum_order_qty = material_line.primary_component_id.minimum_order_qty
                        intransit_qty_material = material_line.primary_component_id.in_transit_stock_qty

                        # Calculate the approved count for the material
                        if minimum_stock_qty > (inhand_stock_qty + intransit_qty_material) - req_qty:
                            #approved_cnt_material = max(req_qty + minimum_stock_qty - (inhand_stock_qty + intransit_qty_material), minimum_order_qty)
                            approved_cnt_material = max(req_qty - (inhand_stock_qty + intransit_qty_material), 0, minimum_order_qty)

                        else:
                            approved_cnt_material = 0

                        # Check if the material already exists in the current plan
                        if material_line.primary_component_id.id in already_created_material:
                            existing_line = already_created_material[material_line.primary_component_id.id]
                            # Accumulate approved_cnt
                            new_approved_cnt = existing_line.approved_cnt + approved_cnt_material
                            existing_line.write({
                                'actual_required_qty': existing_line.actual_required_qty + req_qty,
                                'required_qty': existing_line.required_qty + req_qty,
                                'approved_cnt': new_approved_cnt
                            })
                        else:
                            # Create a new material line
                            material_line_model.create({
                                'material_name': material_line.primary_component_id.id,
                                'inhand_qty': inhand_stock_qty,
                                'minimum_stock_qty': minimum_stock_qty,
                                'plan_id': self.id,
                                'minimum_order_qty': minimum_order_qty,
                                'actual_required_qty': req_qty,
                                'required_qty': req_qty,
                                'approved_cnt': approved_cnt_material
                            })


    def create_production_plan(self,line_ids):
        indent_model = self.env['sos_production_plan']
        indent_record = indent_model.search([('plan_ref_no', '=', self.plan_ref_no)], limit=1)
        
        if not indent_record:        
            for item in line_ids:
                fg_name = item.fg_name.id  
                qp_no = item.fg_name.qp_no
                fg_qty_to_produce = int(item.approved_cnt)
                indent_model.create({
                            'plan_ref_no': self.plan_ref_no,
                            'fg_name': fg_name,
                            'qp_no': qp_no,
                            'required_qty': fg_qty_to_produce,
                            'target_date': self.target_date,
                            'indent_start_date' : self.indent_start_date
                        })
    def create_fptc(self,line_ids):
        tc_model = self.env['sos_transfer_challan']
        tc_record = tc_model.search([('plan_ref_no', '=', self.plan_ref_no)], limit=1)
        
        if not tc_record:        
            for item in line_ids:
                fg_name = item.fg_name.id  
                tc_record_new = tc_model.create({
                            'plan_ref_no': self.plan_ref_no,
                            'planned_qty': item.approved_cnt,
                            'fg_name': fg_name,
                            'indent_start_date':self.indent_start_date,
                            'indent_target_date':self.target_date

                        })
                if tc_record_new:
                    try:
                        specifications = self.env['sos_testing_parameters'].search([('fg_name', '=', fg_name)], limit=1)
                        
                        if not specifications:
                            continue
                        
                        lines = [(5, 0, 0)] 
                        for param in specifications.specification_ids:
                            lines.append((0, 0, {
                                'specification': param.name,
                                'specification_value': ''
                            }))
                        tc_record_new.specification_line_ids = lines

                    except Exception as e:
                        _logger.error("Error processing specifications for FG %s: %s", fg_name, str(e))
                        continue

class SOS_FG_Plan_Line(models.Model):
    _name = 'sos_fg_plan_line'
    _description = 'FG Plan Lines'
    _order = 'approved_cnt desc'

    fg_name = fields.Many2one('sos_fg',string="FG Name")
    inhand_qty = fields.Integer(string="FG Stocks")
    minimum_stock_qty = fields.Integer(string="Minimum Stock Qty")
    in_transit_stock_qty = fields.Integer(string="In-transit Stock Qty")
    plan_id = fields.Many2one('sos_fg_plan', string='FG Plan', ondelete='cascade')
    required_qty = fields.Integer(string='Required Qty')
    actual_required_qty = fields.Integer(string='Actual Req Qty')
    minimum_order_qty = fields.Integer(string='Minimum Order Qty')
    approved_cnt = fields.Integer(string='Planned Qty', store=True)
    planned_week_1 = fields.Integer(string='Week 1')
    planned_week_2 = fields.Integer(string='Week 2')
    planned_week_3 = fields.Integer(string='Week 3')
    planned_week_4 = fields.Integer(string='Week 4')
    planned_week_5 = fields.Integer(string='Week 5')
    planned_week_6 = fields.Integer(string='Week 6')
    planned_week_7 = fields.Integer(string='Week 7')
    planned_week_8 = fields.Integer(string='Week 8')
    completed_qty = fields.Integer(string='Completed Qty', compute='_compute_completed',  store=True)
    
    @api.depends('planned_week_1', 'planned_week_2', 'planned_week_3', 'planned_week_4', 'planned_week_5', 'planned_week_6', 'planned_week_7', 'planned_week_8')
    def _compute_completed(self):
        for record in self:
            total_completed = (
                record.planned_week_1 +
                record.planned_week_2 +
                record.planned_week_3 +
                record.planned_week_4 +
                record.planned_week_5 +
                record.planned_week_6 +
                record.planned_week_7 +
                record.planned_week_8
            )
        record.completed_qty = total_completed



class SOS_SFG_Plan_Line(models.Model):
    _name = 'sos_sfg_plan_line'
    _description = 'SFG Plan Lines'
    _order = 'approved_cnt desc'
    fg_name = fields.Many2one('sos_fg',string="FG Name")
    company_id = fields.Many2one('res.company', store=True, copy=False,
                                string="Company",
                                default=lambda self: self.env.user.company_id.id)
    currency_id = fields.Many2one('res.currency', string="Currency",
                                 related='company_id.currency_id',
                                 default=lambda
                                 self: self.env.user.company_id.currency_id.id)
    sfg_name = fields.Many2one('sos_sfg',string="SFG Name")
    assembling_cost = fields.Monetary(currency_field='currency_id',string="Assembling Cost per unit")
    blowup_action = fields.Selection(
        [('yes', 'Yes'), ('no', 'No')],
        string='Blowup',default="yes"
    )
    inhand_qty = fields.Integer(string="SFG Stocks")
    minimum_stock_qty = fields.Integer(string="Minimum Stock Qty")
    in_transit_stock_qty = fields.Integer(string="In-transit Stock Qty")
    minimum_order_qty = fields.Integer(string="Minimum Order Qty")
    plan_id = fields.Many2one('sos_fg_plan', string='SFG Plan', ondelete='cascade')
    required_qty = fields.Integer(string='Required Qty')
    approved_cnt = fields.Integer(string='Planned Qty',default='1')
    actual_required_qty = fields.Integer(string='Actual Req Qty')
    total_assembling_cost = fields.Float(compute='_compute_total_assembling_cost', string='Total Assembling Cost')
    @api.onchange('sfg_name')
    def _onchange_sfg_name(self):
        for record in self:
            if record.sfg_name:
                record.assembling_cost = record.sfg_name.assembling_charges
    @api.depends('assembling_cost', 'approved_cnt')
    def _compute_total_assembling_cost(self):
        for record in self:
            if record.assembling_cost is not None and record.approved_cnt is not None:
                record.total_assembling_cost = record.assembling_cost * record.approved_cnt
            else:
                record.total_assembling_cost = 0


class SOS_Material_Plan_Line(models.Model):
    _name = 'sos_material_plan_line'
    _description = 'Material Plan Lines'
    _order = 'approved_cnt desc'

    material_name = fields.Many2one('sos_material',string="Material Name")
    company_id = fields.Many2one('res.company', store=True, copy=False,
                                string="Company",
                                default=lambda self: self.env.user.company_id.id)
    currency_id = fields.Many2one('res.currency', string="Currency",
                                 related='company_id.currency_id',
                                 default=lambda
                                 self: self.env.user.company_id.currency_id.id)
    inhand_qty = fields.Integer(string="Material Stocks")
    in_transit_stock_qty = fields.Integer(string="In-transit Stock Qty")
    minimum_stock_qty = fields.Integer(string="Minimum Stock Qty")
    plan_id = fields.Many2one('sos_fg_plan', string='Material Plan', ondelete='cascade')
    required_qty = fields.Integer(string='Required Qty')
    actual_required_qty = fields.Integer(string='Actual Req Qty')
    minimum_order_qty = fields.Integer(string='Minimum Order Qty')
    approved_cnt = fields.Integer(string='Planned Qty')
    approx_price = fields.Monetary(related="material_name.unit_price",currency_field='currency_id', string='Unit Price',store=True)
    total_approx_price = fields.Float(compute='_compute_total_approx_price', string='Approx Price',store=True)
    @api.onchange('material_name')
    def _onchange_material_name(self):
        for record in self:
            if record.material_name:
                record.approx_price = record.material_name.unit_price
    @api.depends('approx_price', 'approved_cnt')
    def _compute_total_approx_price(self):
        for record in self:
            if record.approx_price is not None and record.approved_cnt is not None:
                record.total_approx_price = record.approx_price * record.approved_cnt
            else:
                record.total_approx_price = 0


  
    