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

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

class SOS_IR(models.Model):
    _name = 'sos_ir'
    _description = 'Inward Register'
    _rec_name = 'ir_no'
    _order = 'received_date desc, id desc' 
    
    ir_no=fields.Char(string="Inward Reference No",default=lambda self: self._generate_id())
    supplier_name = fields.Many2one('sos_suppliers', string="Supplier Name")
    supplier_address = fields.Text(related='supplier_name.address', string="Supplier Address")
    service_provider_name = fields.Many2one('sos_service_providers', string="Service Provider Name")
    service_provider_address = fields.Char(related='service_provider_name.address', string="Service Provider Address")
    po_no = fields.Many2one(
    'sos_po',
    string="P.O No",
    domain="[('po_status', '=', 'open'), ('supplier_name', '=', supplier_name)]"
    )
    wo_no = fields.Many2one(
    'sos_wo',
    string="W.O No",
    domain="[('wo_status', '=', 'open'), ('supplier_name', '=', service_provider_name)]"
    )
    wo_no_inhouse = fields.Many2one(
    'sos_wo',
    string="W.O No",
    domain="[('wo_status', '=', 'open'), ('wo_planned_at', '=', 'inhouse')]"
    )
    dc_no = fields.Many2one('sos_dc',string="DC No/Invoice No")
    dc_date = fields.Datetime(string="DC Date/Invoice Date")
    dc_no_char = fields.Char(string="DC No/Invoice No")
    received_date = fields.Date(string="Received Date",default=fields.Date.today)
    receiving_dept = fields.Many2one('sos_departments',string="Receiving Department")
    receiving_by = fields.Many2one('res.users', string='Received By')
    parcel_count = fields.Char(string="No of Bags/Barrels/Rolls/Boxes")
    received_goods_type = fields.Selection([
        ('Materials', 'Materials'),
        ('SFG', 'SFG'),
        ('FG', 'FG')
    ], string='Goods Type',default="Materials",copy=True)
    line_ids_material = fields.One2many('sos_ir_line_material', 'ir_id', string="Materials Lines",copy=True)
    vehicle_type = fields.Selection([
        ('yes', 'Yes'),
        ('no', 'No'),
    ],string="Material Received in Top Closed Vehicle")
    boxes_sealing = fields.Selection([
        ('yes', 'Yes'),
        ('no', 'No'),
    ], string="Boxes/Bag/Barrels/Rolls Sealing shall be in-tact")
    line_ids_sfg = fields.One2many('sos_ir_line_sfg', 'ir_id', string="Components for SFG",copy=True)
    line_ids_fg = fields.One2many('sos_ir_line_fg', 'ir_id', string="Components for FG",copy=True)
    stores_approval_name = fields.Many2one('res.users', string='Stores Received By')
    stores_approval_image = fields.Image(related="stores_approval_name.signature_image",string='Stores-RM/PM In Charge')
    stores_approved_on = fields.Datetime(string="Approved On")
    indent_no = fields.Many2one('sos_fg_plan',string="Indent No")
    top_management_name = fields.Many2one('res.users', string='Top Management Approver')
    top_management_approval_image = fields.Image(related="top_management_name.signature_image",string='Top Management Approval')
    top_management_approved_on = fields.Datetime(string="Approved On")
    wo_planned_at = fields.Selection([('inhouse', 'In-House'),('outsource', 'Out-Sourcing')],default="outsource",string="W.O Planned at")
    dept_in_charge_name = fields.Many2one('res.users', string='Department In-Charge')
    dept_in_charge_image = fields.Image(related="dept_in_charge_name.signature_image",string='Department In-Charge Sign',readonly=True)
    dept_in_charge_approved_on = fields.Datetime(string="Approved On")
    test_report = fields.Binary(string="DC/Invoice Document")
    test_report_filename=fields.Char(string="DC DocumentFile Name")
    #Rework
    orr_no = fields.Many2one('sos_sfg_outsourcing_return_register',string="Ref No")
    iqi_no = fields.Many2one('sos_iqi',string="IQI No",related="orr_no.iqi_no")
    currency_id = fields.Many2one('res.currency', string='Currency')
    service_charge = fields.Monetary(string="Service Charge",currency_field='currency_id')
    _sql_constraints = [
        ('ir_no_unique', 'UNIQUE(ir_no)', 'The IR No must be unique!')
    ]

    @api.onchange('orr_no')
    def _onchange_orr_no(self):
        if self.orr_no:
            ir_ref_no = self.orr_no.iqi_no.ir_id_unique_id
            matching_ir_records = self.env['sos_ir'].search([('ir_no', 'like', f"{ir_ref_no.ir_no}%")], limit=1)
            variable = matching_ir_records.ir_no
            if variable[-1].isdigit():
                next_char = "(a)"
                self.ir_no = variable + next_char
            else:
                last_char = variable[-2]
                if 'a' <= last_char <= 'z':
                    next_char = f"({chr(ord(last_char) + 1)})" if last_char != 'z' else "(a)"
                    new_variable = variable[:-3]
                    self.ir_no = new_variable + next_char

            
            self.received_goods_type = self.orr_no.goods_type
            if self.orr_no.goods_type == "SFG":
                self.service_provider_name = ir_ref_no.service_provider_name
                self.wo_no = ir_ref_no.wo_no
                sfg_lines = [(5, 0, 0)]       
                sfg_lines.append((0, 0, {
                    'component_id': self.iqi_no.sfg_name,  
                    'qty': self.iqi_no.rejected_qty,
                    'order_qty': self.iqi_no.rejected_qty
                }))
                self.line_ids_sfg = sfg_lines
            else:
                self.supplier_name = ir_ref_no.supplier_name
                #self.po_no = ir_ref_no.po_no
                material_lines = [(5, 0, 0)] 
                material_lines.append((0, 0, {
                    'component_id': self.iqi_no.material_name,  
                    'qty': self.iqi_no.rejected_qty,
                    'order_qty': self.iqi_no.rejected_qty
                }))
                self.line_ids_material = material_lines
            self.parcel_count = ir_ref_no.parcel_count
            self.vehicle_type = ir_ref_no.vehicle_type
            self.boxes_sealing = ir_ref_no.boxes_sealing
            self.test_report = ir_ref_no.test_report
            self.test_report_filename = ir_ref_no.test_report_filename
            

    def action_view_invoice(self):
        """Action to view the PDF of the test report."""
        # Check if there is a test report
        if not self.test_report:
            raise UserError("No test report available for this record.")
        
        # Use `ir.actions.act_url` to open the binary file as a PDF
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'test_report'),
        'target': 'new',  # This opens the PDF in a new tab
        }
    @api.onchange('po_no')
    def _onchange_po_no(self):
        if self.po_no:
            try:
                lines = [(5, 0, 0)]
                
                for param in self.po_no.line_ids:
                    if param.status in [0, 1]:
                        if param.prev_received_qty < param.quantity:
                            qty = param.quantity  - param.prev_received_qty
                        else:
                            qty = param.quantity
                        lines.append((0, 0, {
                            'component_id': param.component_id.id,  
                            'qty': qty,
                            'order_qty': param.quantity,
                            'unit_price': param.unit_price
                        }))
                self.line_ids_material = lines
            
            except Exception as e:
                print("Error processing po_no: %s", str(e))
    @api.onchange('wo_no')
    def _onchange_wo_no(self):
        if self.wo_no:
            try:
                lines = [(5, 0, 0)]
                
                for param in self.wo_no.line_ids:
                    lines.append((0, 0, {
                        'component_id': param.component_id.id,  
                        'qty': param.quantity,
                        'order_qty': param.quantity
                    }))
                self.line_ids_sfg = lines
            
            except Exception as e:
                print("Error processing po_no: %s", str(e))
    @api.onchange('wo_no_inhouse')
    def _onchange_wo_no_inhouse(self):
        if self.wo_no_inhouse:
            try:
                lines = [(5, 0, 0)]
                
                for param in self.wo_no_inhouse.line_ids:
                    lines.append((0, 0, {
                        'component_id': param.component_id.id,  
                        'qty': param.quantity,
                        'order_qty': param.quantity
                    }))
                self.line_ids_sfg = lines
            
            except Exception as e:
                print("Error processing po_no: %s", str(e))


    def action_report_ir_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_ir").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")
    def _generate_id(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.generate_sequence('sos_ir','IR', 'ir_no')
    
    def action_report_esign_btn(self):

        iqi_model = self.env['sos_iqi']
        grn_model = self.env['sos_grn']
        grn_line_model = self.env['sos_grn_line']
        sequence_util = self.env['sos_common_scripts']
        material_model = self.env['sos_material']
        iqi_no = sequence_util.generate_sequence('sos_iqi', 'iqi', 'iqi_no')
        grn_no = sequence_util.generate_sequence('sos_grn', 'GRN', 'grn_no')
        if self.received_goods_type == "Materials":
            iqi_record = None
            grn_record = None
            iqi_lines_to_create = []
            grn_line_values = []
            
            for item in self.line_ids_material:
                # Fetch the component related to the current item
                component = self.env['sos_material'].browse(item.component_id.id)
                if self.supplier_name and self.supplier_name.id not in component.suppliers.ids:
                    component.write({
                        'suppliers': [(4, self.supplier_name.id)]
                    })

                if component.shelf_life == "yes":
                    shelflife_line_values = {
                            'ir_ref_no':self.id,
                            'name': item.component_id.id,  # Reference the created GRN
                            'quantity': item.qty,
                            'expiry_date':item.expiry_date
                        }
                    shellife_record = self.env['sos_shelflife_register'].create(shelflife_line_values)
                #raise UserError("The PO Number already exists. Validation failed.")
                if self.po_no:                
                    for pos in self.po_no.line_ids:
                        if component.id == pos.component_id.id:
                            if item.qty >= pos.quantity:  
                                pos.status = 2
                                pos.prev_received_qty = item.qty
                                self.po_no.received_qty += 1  
                            elif item.qty > 0:
                                pos.prev_received_qty = pos.prev_received_qty + item.qty
                                pos.status = 1
                                if pos.prev_received_qty >= pos.quantity:
                                    pos.status = 2
                                    self.po_no.received_qty += 1
                                
                            else:
                                pos.status = 0


                if component.inspection_method == 10:
                    if not grn_record:
                        grn_record_values = {
                            'grn_no': grn_no,
                            'ir_no':self.id,
                            'supplier_name': self.supplier_name.id,
                            'received_goods_type': 'Materials',
                            'supplier_invoice_no':self.dc_no_char,
                            'po_no':self.po_no.id
                        }
                        if iqi_record:
                            grn_record_values['iqi_no'] = iqi_record.id
                        grn_record = grn_model.with_context(from_script=True).create(grn_record_values)

                    if item.qty > 0:
                        grn_line_values = {
                            'grn_id': grn_record.id,  # Reference the created GRN
                            'component_id': item.component_id.id,
                            'received_qty': item.qty,
                            'approved_qty':item.qty,
                            'invoice_qty':item.order_qty,
                            'unit_price':item.unit_price
                        }
                        grn_line_model.with_context(from_script=True).create(grn_line_values)

                
                else:
                    iqi_record = self.env['sos_iqi'].create({
                    'iqi_no': sequence_util.generate_sequence('sos_iqi', 'IQI', 'iqi_no'),
                    'material_option':True,
                    'sfg_option':False,
                    'supplier_name': self.supplier_name.id,
                    'batch_no':item.batch_no,
                    'received_qty':item.qty,
                    'uom': item.component_id.uom,
                    'material_name': item.component_id.id,
                    'material_code': item.component_id.material_code,
                    'in_tact':self.boxes_sealing,
                    'invoice_no':self.dc_no_char,
                    'invoice_date':self.dc_date,
                    'ir_id_unique_id':self.id,
                    'from_origin':"Vendor",
                    'unit_price':item.unit_price
                    

                })
                    # 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',iqi_record.id,"deenalaura.m@sosaley.in","IQI Approval Request",body_html,'sos_inventory.sos_qc_user')
                    # Email part ends
        elif self.received_goods_type == "SFG":    
            for item in self.line_ids_sfg:
                # PO update part
                sfg_component = self.env['sos_sfg'].browse(item.component_id.id)
                if self.service_provider_name and self.service_provider_name.id not in sfg_component.service_providers.ids:
                    sfg_component.write({
                        'service_providers': [(4, self.service_provider_name.id)]
                    })
                if self.wo_planned_at == "outsource":
                    if self.wo_no: 
                        if not self.orr_no:               
                            for pos in self.wo_no.line_ids:
                                if sfg_component.id == pos.component_id.id:
                                    pos.last_received_quantity += item.qty
                else:
                    if self.wo_no_inhouse: 
                        if not self.orr_no:                
                            for pos in self.wo_no_inhouse.line_ids:
                                if sfg_component.id == pos.component_id.id:
                                    pos.last_received_quantity = pos.last_received_quantity + item.qty

                iqi_data = {
                    'iqi_no': sequence_util.generate_sequence('sos_iqi', 'IQI', 'iqi_no'),
                    'material_option':False,
                    'sfg_option':True,
                    'service_provider_name': self.service_provider_name.id,
                    'batch_no':item.batch_no,
                    'received_qty':item.qty,
                    'sfg_name': item.component_id.id,
                    'sfg_code': item.component_id.sfg_code,
                    'in_tact':self.boxes_sealing,
                    'invoice_no':self.dc_no_char,
                    'invoice_date':self.dc_date,
                    'ir_id_unique_id':self.id,
                    'from_origin':"Vendor"

                }
                if self.iqi_no.id:
                    iqi_data['iqi_no'] = sequence_util.generate_sequence('sos_iqi', 'R-IQI', 'iqi_no')
                    iqi_data['old_iqi_ref'] = self.iqi_no.id
                    iqi_data['iqi_type'] = 'rework'
                    # Rework Iteration starts
                    sos_record = self.env['sos_iqi'].search([('id', '=', self.iqi_no.id)], limit=1)
                    if sos_record:
                        rework_iteration = sos_record.reworked_count + 1
                        
                        sos_record.write({
                            'reworked_count':rework_iteration
                        })
                    # Rework Iteration ends
                iqi_record = self.env['sos_iqi'].create(iqi_data)
                body_html = f"""
                <p>Below <b>IQI</b> is waiting for your response</p>
                """
                
                send_email = self.env['sos_common_scripts']
                send_email.send_group_email(self.env,"sos_iqi",iqi_record.id,"deenalaura.m@sosaley.in","IQI Request",body_html,'sos_inventory.sos_qc_user')

        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'stores_approval_name',
        'stores_approved_on',
        'sos_inventory.sos_scg_group_user'
    )
        # Email part
        body_html = f"""
        <p>Below <b>Inward</b> is waiting for your Approval</p>
        """
        
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,"sos_ir",self.id,"deenalaura.m@sosaley.in","Incoming Material Received",body_html,'sos_inventory.sos_scg_group_manager')
        # Email part ends
        
    def action_deptincharge_esign_btn(self):
        # Email part
        body_html = f"""
        <p>Below <b>Inward</b> is waiting for your Approval</p>
        """
        subject = f"Inward Approval Request - {self.ir_no}"
        send_email = self.env['sos_common_scripts']
        send_email.send_direct_email(self.env,"sos_ir",self.id,"ramachandran.r@sosaley.in",subject,body_html)
        # Email part ends
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'dept_in_charge_name',
        'dept_in_charge_approved_on'
    )
    def action_topmanagement_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self,
        'top_management_name',
        'top_management_approved_on',
        'sos_inventory.sos_management_user'
        )
        body_html = f"""
                 <p>Below <b>Inward</b> was received</p>
                 """
                
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,"sos_ir",self.id,"deenalaura.m@sosaley.in","Material Received",body_html,'sos_inventory.sos_finance_user')
        

class SOS_IR_Line_Material(models.Model):
    _name = 'sos_ir_line_material'
    _description = 'Inward Register Material Lines'

    ir_id = fields.Many2one('sos_ir', string="IR", ondelete="cascade")
    component_id = fields.Many2one('sos_material', string="Part No", required=True)
    name = fields.Char(related="component_id.name")
    uom = fields.Selection(related="component_id.uom")
    inspection_method = fields.Integer(related="component_id.inspection_method")
    material_code = fields.Char(related="component_id.material_code")
    batch_no = fields.Char(string="Batch No / Lot No")
    order_qty = fields.Integer(string="Order Quantity")
    invoice_qty = fields.Integer(string="Invoice Quantity")
    qty = fields.Integer(string="Received Quantity")
    currency_id = fields.Many2one('res.currency', string='Currency')
    unit_price = fields.Monetary(string="Unit Price", currency_field='currency_id')
    test_report = fields.Binary(string="Test Report")
    test_report_filename=fields.Char(string="Test Report File Name")
    expiry_date = fields.Date(string="Expiry Date")
    shelf_life = fields.Selection([('yes', 'Yes'), ('no', 'No')],related="component_id.shelf_life", string="Shelf Life")

    @api.onchange('component_id')
    def _onchange_component_id(self):
        if self.component_id:
            self.unit_price = self.component_id.unit_price
            

    def action_view_pdf(self):
        """Action to view the PDF of the test report."""
        # Check if there is a test report
        if not self.test_report:
            raise UserError("No test report available for this record.")
        
        # Use `ir.actions.act_url` to open the binary file as a PDF
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'test_report'),
        'target': 'new',  # This opens the PDF in a new tab
    }
class SOS_IR_Line_SFG(models.Model):
    _name = 'sos_ir_line_sfg'
    _description = 'Inward Register SFG Lines'

    ir_id = fields.Many2one('sos_ir', string="IR", ondelete="cascade")
    component_id = fields.Many2one('sos_sfg', string="Part No", required=True)
    sfg_code = fields.Char(related="component_id.sfg_code")
    batch_no = fields.Char(string="Batch No / Lot No")
    invoice_qty = fields.Integer(string="Invoice Quantity")
    order_qty = fields.Integer(string="Order Quantity")
    qty = fields.Integer(string="Received Quantity")
    test_report = fields.Binary(string="Test Report")
    test_report_filename=fields.Char(string="Test Report File Name")
    def action_view_pdf(self):
        """Action to view the PDF of the test report."""
        # Check if there is a test report
        if not self.test_report:
            raise UserError("No test report available for this record.")
        
        # Use `ir.actions.act_url` to open the binary file as a PDF
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'test_report'),
        'target': 'new',  # This opens the PDF in a new tab
    }
class SOS_IR_Line_FG(models.Model):
    _name = 'sos_ir_line_fg'
    _description = 'Inward Register FG Lines'

    ir_id = fields.Many2one('sos_ir', string="IR", ondelete="cascade")
    component_id = fields.Many2one('sos_fg', string="Part No", required=True)
    fg_code = fields.Char(related="component_id.fg_code")
    batch_no = fields.Char(string="Batch No / Lot No")
    invoice_qty = fields.Integer(string="Invoice Quantity")
    order_qty = fields.Integer(string="Order Quantity")
    qty = fields.Integer(string="Received Quantity")
    test_report = fields.Binary(string="Test Report")
    test_report_filename=fields.Char(string="Test Report File Name")
    def action_view_pdf(self):
        """Action to view the PDF of the test report."""
        # Check if there is a test report
        if not self.test_report:
            raise UserError("No test report available for this record.")
        
        # Use `ir.actions.act_url` to open the binary file as a PDF
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'test_report'),
        'target': 'new',  # This opens the PDF in a new tab
    }