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

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

class sos_iqi(models.Model):
    _name = 'sos_iqi'
    _description = 'Incoming Quality Inspection'
    _rec_name = 'iqi_no'
    _order = 'id desc'

    iqi_no = fields.Char(string="IQI No", readonly= True, required= True, default=lambda self: self._generate_id())
    iqi_date = fields.Datetime(string="IQI Date",  default=fields.Datetime.now)
    ir_id_unique_id=fields.Many2one('sos_ir', string='Inward Ref No')
    test_report = fields.Selection([('yes','YES'),('no','NO')],string='Test Report Received',help="If No, action taken (Collect Material inspection report")
    in_tact = fields.Selection([('yes','YES'),('no','NO')],string='Boxes/Bag/Barrels/Rolls Sealing shall be in-tact',help="If No, Is opened Boxes / Bags / Barrels/Rolls are identified and stored separately, intimate to QC and Supplier/Service provider.")
    inspection_label = fields.Selection([('yes','YES'),('no','NO'),('na','NA')],string="Identification Label affixed post inspection")
    review_test_report = fields.Selection([('yes','YES'),('no','NO')],string="Reviewed the Material Test reports.Any changes in the material specification",help="If Yes, is it Adequate / Needs More Information / Updated Quality Plan")
    test_report_no = fields.Char(string="Material Test Report No")
    test_report_doc = fields.Binary(string="Test Report")
    test_report_filename=fields.Char(string="Test Report Name")
    batch_no = fields.Text(string="Batch No")
    serial_no = fields.Text(string="Serial No")
    fg_name = fields.Many2one('sos_fg', string='FG Name')
    iqi_type = fields.Selection([('new','New'),('rework','Reworked')],string='IQI Type',default='new')
    material_name = fields.Many2one('sos_material', string="Material Name")
    material_code = fields.Char(string="Material Code")
    supplier_name = fields.Many2one('sos_suppliers',string="Supplier Name")
    material_category = fields.Many2one('sos_material_configuration',string="Material Category")
    uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], string="UOM")
    wo_planned_at = fields.Selection([('inhouse', 'In-House'),('outsource', 'Out-Sourcing')],default="outsource",string="W.O Planned at")
    rca_required = fields.Selection([('yes', 'Yes'),('no', 'No')], string="RCA Required")
    rca_notes_text=fields.Text(string="Notes",default="The requirement for a Root Cause Analysis (RCA) is determined by defect severity, recurrence, or a defect rate below 10,000 parts per million (PPM).")
    sfg_name = fields.Many2one('sos_sfg', string="SFG Name")
    sfg_code = fields.Char(string="SFG Code",related="sfg_name.sfg_code")
    service_provider_name = fields.Many2one('sos_service_providers',string="Service Provider Name")
    sfg_category = fields.Many2one('sos_sfg_configuration',string="SFG Category")

    invoice_no = fields.Char(string="Invoice No")
    invoice_date = fields.Datetime(string="Invoice date")
    received_qty = fields.Integer(string="Received Quantity")
    approved_qty = fields.Integer(string="Approved Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    rejection_percentage = fields.Float(string="Rejected Percentage", compute="_compute_rejected_percentage", store=True)
    rejection_percentage_display = fields.Char('Rejection Percentage', compute='_compute_rejected_percentage_display')
    testing_line_ids = fields.One2many('sos_testing_parameters_line', 'ref_id', ondelete='cascade')
    calibration_line_ids = fields.One2many('sos_iqi_calibration_line','calibration_id', ondelete='cascade')
    material_option = fields.Boolean('Materials', default=True)
    sfg_option = fields.Boolean('Semi-Finished Goods')
    prepared_by_name = fields.Many2one('res.users', string='Stores Provided by')
    prepared_by_image = fields.Image(related="prepared_by_name.signature_image",string='Prepared by Sign',readonly=True)
    prepared_on = fields.Date(string="Prepared On")
    products = 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="Products",required=True)
    qc_by_name = fields.Many2one('res.users', string='QC Tested by')
    qc_by_image = fields.Image(related="qc_by_name.signature_image",string='QC Tested Sign',readonly=True)
    qc_tested_on = fields.Date(string="QC Tested On")

    stores_received_by = fields.Many2one('res.users', string='Stores Received by')
    stores_received_image = fields.Image(related="stores_received_by.signature_image",string='Stores Received by Sign',readonly=True)
    stores_received_on = fields.Date(string="Stores Received On")

    qa_by_name = fields.Many2one('res.users', string='QA Approved By')
    qa_by_image = fields.Image(related="qa_by_name.signature_image",string='QA Approved by Sign',readonly=True)
    qa_tested_on = fields.Date(string="QA Approved On")
    qa_comments = fields.Text(string="QA Comments")
    ppm = fields.Integer(string="PPM",compute="_compute_ppm")
    reworked_count = fields.Integer(string="Reworked Count",default=0)
    old_iqi_ref = fields.Many2one('sos_iqi',string="Rework References")
    status = fields.Selection([ ('open', 'Open'),('closed', 'Closed')], default='open' , string="Status")
    batch_allotmnet = fields.Boolean(string="Allot Batch") 
    batch_allotmnet_field = fields.Char(string="Other Field", compute='_compute_batch_allotmnet', store=True)
    ncmr_ref = fields.Many2one('sos_ncmr',string="NCMR Reference (If any Rejected)")
    from_origin = fields.Selection([('Vendor','Vendor'),('In-House','In-House')],string="Received From",default="Vendor")
    currency_id = fields.Many2one('res.currency', string='Currency')
    unit_price = fields.Monetary(string="Unit Price", currency_field='currency_id') 
    @api.onchange('received_qty', 'approved_qty')
    def _onchange_rejected_qty(self):
        if self.received_qty and self.approved_qty:
            self.rejected_qty = self.received_qty - self.approved_qty
    @api.depends('batch_allotmnet')
    def _compute_batch_allotmnet(self):
        for record in self:
            if record.batch_allotmnet:
                new_record = self.env['sos_batch_allotment_register'].create({
                                'sfg_name': record.sfg_name.id,
                                'alloted_date':record.iqi_date,
                                'batch_size':record.received_qty,
                                'iqi_ref_no':record.id
                            })



    @api.depends('received_qty', 'rejected_qty')
    def _compute_ppm(self):
        for record in self:
            if record.rejected_qty != 0 and record.received_qty != 0:
                record.ppm = (record.rejected_qty / record.received_qty) * 10**6
            else:
                record.ppm = 0  
    def action_report_iqi_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_iqi").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")
    def action_view_report(self):

        if not self.test_report_doc:
            raise UserError("No test report available for this record.")
        
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'test_report_doc'),
        'target': 'new',  # This opens the PDF in a new tab
        }
    @api.depends('rejection_percentage')
    def _compute_rejected_percentage_display(self):
        for record in self:
            record.rejection_percentage_display = "{:.2f}%".format(record.rejection_percentage)
    @api.depends('received_qty', 'rejected_qty')
    def _compute_rejected_percentage(self):
        for record in self:
            if record.received_qty > 0:
                record.rejection_percentage = (record.rejected_qty / record.received_qty) * 100
            else:
                record.rejection_percentage = 0
    @api.onchange('material_category')
    def _onchange_material_category(self):
        if self.material_category:
            self._load_testing_parameters('material')
    @api.onchange('sfg_category')
    def _onchange_sfg_category(self):
        if self.sfg_category:
            self._load_testing_parameters('sfg')
    def _load_testing_parameters(self,types):
        if types == 'material':
            if self.material_category:
                testing_parameters = self.env['sos_material_configuration'].search([('id', '=', self.material_category.id)])
                if not testing_parameters:
                    raise UserError('No testing parameters found for this Item.')
                lines = [(5, 0, 0)]
                sorted_parameters = testing_parameters.parameter_ids.sorted(key=lambda param: param.sequence)

                for param in sorted_parameters:
                    lines.append((0, 0, {
                        'testing_parameter': param.name,
                        'req_readings':param.observation,
                        'obtained_readings':param.obtained_observation
                        
                    }))
                self.testing_line_ids = lines
        else:
            if self.sfg_category:
                testing_parameters = self.env['sos_sfg_configuration'].search([('id', '=', self.sfg_category.id)])
                if not testing_parameters:
                    raise UserError('No testing parameters found for this Item.')
                lines = [(5, 0, 0)]
                sorted_parameters = testing_parameters.parameter_ids.sorted(key=lambda param: param.sequence)
                for param in sorted_parameters:
                    lines.append((0, 0, {
                        'testing_parameter': param.name,
                        'req_readings':param.observation,
                        'obtained_readings':param.obtained_observation
                    }))
                self.testing_line_ids = lines
    @api.onchange('material_option')
    def _onchange_material_option(self):
        if self.material_option:
            self.sfg_option = False

    @api.onchange('sfg_option')
    def _onchange_sfg_option(self):
        if self.sfg_option:
            self.material_option = False
    def _generate_id(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.generate_sequence('sos_iqi','IQI', 'iqi_no')

    def action_report_esign_btn(self):
        # Email part
        body_html = f"""
        <p>Below <b>IQI</b> is waiting for your Approval</p>
        """
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,'sos_iqi',self.id,"deenalaura.m@sosaley.in","IQI Approval Request",body_html,'sos_inventory.sos_qc_user')
        # Email part ends
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'prepared_by_name',
        'prepared_on'
    )
    def action_qc_esign_btn(self):
        if self.approved_qty == 0 and self.rejected_qty == 0:
            raise UserError("Please enter Approved Quantity or Rejected Quantity before proceeding.")
        ncmr_record = False
        sequence_util = self.env['sos_common_scripts']
        ncmr_id = sequence_util.generate_sequence('sos_ncmr', 'NCMR', 'ncmr_no')
        if self.rejected_qty > 0:
            
            if self.material_option:
                ncmr_record = self.env['sos_ncmr'].create({
                            'ncmr_no': ncmr_id,
                            'material_option':True,
                            'sfg_option':False,
                            'batch_no':self.batch_no,
                            'rejected_qty':self.rejected_qty,
                            'material_name': self.material_name.id,
                            'material_code': self.material_name.material_code,
                            'incoming_doc_ref':self.id,
                            'department':'Quality Control',
                            'rca_required':self.rca_required
                        })
            else:
                ncmr_record = self.env['sos_ncmr'].create({
                            'ncmr_no': ncmr_id,
                            'material_option':False,
                            'sfg_option':True,
                            'batch_no':self.batch_no,
                            'rejected_qty':self.rejected_qty,
                            'sfg_name': self.sfg_name.id,
                            'sfg_code': self.sfg_name.sfg_code,
                            'incoming_doc_ref':self.id,
                            'department':'Quality Control',
                            'rca_required':self.rca_required
                            
                        })
        # Email part
        body_html = f"""
        <p>Below <b>IQI</b> is waiting for your Approval</p>
        """
        ncmr_body_html = f"""
        <p>Below <b>NCMR</b> is waiting for your Inspection</p>
        """
        if ncmr_record:
            self.ncmr_ref = ncmr_record.id
            sequence_util.send_group_email(self.env,'sos_ncmr',ncmr_record.id,"deenalaura.m@sosaley.in","NCMR Inspection Pending",ncmr_body_html,'sos_inventory.sos_qc_user')

        sequence_util.send_group_email(self.env,'sos_iqi',self.id,"deenalaura.m@sosaley.in","IQI Approval Request",body_html,'sos_inventory.sos_scg_group_user')
        # Email part ends
        return sequence_util.action_assign_signature(
        self, 
        'qc_by_name',
        'qc_tested_on'
    )
    def action_qa_esign_btn(self):
        self.status = "closed"
        if self.ncmr_ref:
            self.ncmr_ref.rca_required = self.rca_required
            self.ncmr_ref.rca_notes_text = self.rca_notes_text
        # Email part
        body_html = f"""
        <p>Below <b>IQI</b> is waiting for your Approval</p>
        """
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,'sos_iqi',self.id,"deenalaura.m@sosaley.in","IQI Approval Request",body_html,'sos_inventory.sos_scg_group_user')
        # Email part ends
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'qa_by_name',
        'qa_tested_on'
    )
    def generate_grn(self):
        sequence_util = self.env['sos_common_scripts']
        grn_no = sequence_util.generate_sequence('sos_grn', 'GRN', 'grn_no')
        grn_record = None
        grn_line_values = []
        if self.material_option == True:
            grn_record = self.env['sos_grn'].with_context(from_script=True).create({
                'grn_no': grn_no,
                'iqi_no': self.id,
                'ir_no':self.ir_id_unique_id.id,
                'supplier_name': self.supplier_name.id,
                'received_goods_type': 'Materials',
                'supplier_invoice_no':self.invoice_no,
                'po_no':self.ir_id_unique_id.po_no.id
            })
            grn_line_values = self.env['sos_grn_line'].with_context(from_script=True).create({
                'grn_id': grn_record.id, 
                'component_id': self.material_name.id,
                'received_qty': self.received_qty,
                'approved_qty':self.approved_qty,
                'rejected_qty':self.rejected_qty,
                'invoice_qty': self.received_qty,
                'unit_price':self.unit_price

            })
        elif self.sfg_option == True:
            if self.from_origin == "Vendor":
                grn_record = self.env['sos_grn'].with_context(from_script=True).create({
                    'grn_no': grn_no,
                    'iqi_no': self.id,
                    'ir_no':self.ir_id_unique_id.id,
                    'service_provider_name': self.service_provider_name.id,
                    'received_goods_type': 'SFG',
                    'wo_no':self.ir_id_unique_id.wo_no.id,
                    'supplier_invoice_no':self.ir_id_unique_id.dc_no_char
                })
                grn_line_values = self.env['sos_grn_line_sfg'].with_context(from_script=True).create({
                    'grn_id': grn_record.id, 
                    'component_id': self.sfg_name.id,
                    'received_qty': self.received_qty,
                    'approved_qty':self.approved_qty,
                    'rejected_qty':self.rejected_qty
                })
            else:
                approved_qty = self.approved_qty
                current_qty = self.sfg_name.inhand_stock_qty
                current_value = self.sfg_name.unit_price
                new_qty = current_qty + approved_qty
                if new_qty > 0:  
                    new_unit_price = ((current_qty * current_value) + (approved_qty * self.sfg_name.unit_price)) / new_qty
                else:
                    new_unit_price = self.sfg_name.unit_price
                self.sfg_name.inhand_stock_qty = new_qty
                self.sfg_name.unit_price =  new_unit_price
                if approved_qty > 0:
                    self.env['sos_sfg_transaction_history'].create({
                        'ref_id': self.sfg_name.id,
                        'iqi_no': self.id,
                        'component_id': self.sfg_name.id,
                        'quantity': approved_qty,
                        'unit_price': self.sfg_name.unit_price,
                        'action': 'in',
                    })
        
    def action_stores_received_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'stores_received_by',
        'stores_received_on',
        'sos_inventory.sos_scg_group_user'
    )
        self.generate_grn()
        # Email part
        body_html = f"""
        <p>Below <b>IQI</b> is waiting for your Approval</p>
        """
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,'sos_iqi',self.id,"deenalaura.m@sosaley.in","IQI Approval Request",body_html,'sos_inventory.sos_qa_user')
        # Email part ends
        
class sos_testing_lines(models.Model):
    _name = 'sos_testing_parameters_line'
    _description = 'Testing Parameters Lines'

    ref_id = fields.Many2one('sos_iqi', string="Materials", ondelete="cascade")
    qp_no = fields.Char(string="QP No")
    testing_parameter = fields.Char(string="Testing Parameter")
    req_readings = fields.Char(string="Required Readings / Observation")
    obtained_readings = fields.Char(string="Obtained Readings / Observation")
    inspection_remark = fields.Selection([('PASS','PASS'),('FAIL','FAIL')],string="Inspection Decision")
    sampled_qty = fields.Integer(string="Sampled Quantity")
    accepted_qty = fields.Integer(string="Accepted Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    remarks = fields.Text(string="Remarks")
    aodr_qty = fields.Integer(string="Accepted on Deviation  (or) Reworked Qty (If any)")
    aodr_no = fields.Many2one('sos_aodr',string="AODR NO")


class SOS_iqi_calibration_line(models.Model):
    _name = 'sos_iqi_calibration_line'
    _description = 'Calibration Devices of IQI'

    calibration_id = fields.Many2one('sos_iqi', string="Materials", ondelete="cascade")
    name = fields.Many2one('sos_calibration_devices',string="Equipment Name", required=True)
    s_no = fields.Char(string="Equipment Serial No",related="name.s_no")
    identification_no= fields.Char(string="Identification No",related="name.identification_no")
    certification_no= fields.Char(string="Certification No",related="name.certification_no")
    calibrated_on = fields.Date(string="Calibrated On",related="name.calibrated_on")
    calibrated_due = fields.Date(string="Calibration Due",related="name.calibrated_due")