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

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


class sos__grn(models.Model):
    _name = 'sos_grn'
    _description = 'Goods Receipt Note'
    _rec_name = 'grn_no'
    _order = 'id desc'

    supplier_invoice_no = fields.Char(string="Supplier Invoice/DC No")
    iqi_no = fields.Many2one('sos_iqi', string='IQI No')
    ir_no = fields.Many2one('sos_ir', string='Inward Ref No')
    grn_no = fields.Char(string="GRN No", required= True, readonly= True, default=lambda self: self._compute_sequence())
    grn_date = fields.Datetime(string="GRN Date")
    supplier_name = fields.Many2one('sos_suppliers',string="Supplier Name")
    service_provider_name = fields.Many2one('sos_service_providers', string="Service Provider Name")
    company_id = fields.Many2one('res.company', string='Company', 
        default=lambda self: self.env.company.id, index=True)
    no_of_parcel=fields.Integer(string="No. of Bags / Boxes/ Barrels/Rolls Received")
    no_of_parcel_per_invoice=fields.Integer(string="No. of Bags/ Boxes/ Barrels/Rolls as per Invoice")
    identification_label = fields.Selection([ ('Yes', 'Yes'),('No', 'No'),('NA', 'NA')],'Identification Label affixed post inspection', default='Yes')
    po_no = fields.Many2one('sos_po', string='Our PO No')
    wo_no = fields.Many2one('sos_wo', string='Our WO No')
    approved_selector = fields.Selection([ ('Yes', 'Yes'),('No', 'No')],'Material Received from Approved Supplier', default='Yes')
    test_report_no = fields.Char(string="Material Final Inspection Test Report No. & Date")
    reworked_process = fields.Char(string="Reworked Process (If any)")
    approved_storage_location = fields.Char(string="Approved Material Stored in",default="Stores")
    rejected_storage_location = fields.Char(string="Rejected Material Stored in",default="Stores")
    inspection_remarks = fields.Selection([ ('Approved', 'Approved'),('Re work', 'Re work'),('Rejected', 'Rejected')],'Inspection Remarks:  Approved / Re work / Rejected', default='Approved')
    stores_approval_name = fields.Many2one('res.users', string='Approved By')
    stores_approval_image = fields.Image(related="stores_approval_name.signature_image",string='Stores-RM/PM In Charge',readonly=True)
    stores_approval_on = fields.Date(string="Stores Received On")
    line_ids = fields.One2many('sos_grn_line', 'grn_id', string="Components")
    line_ids_sfg = fields.One2many('sos_grn_line_sfg', 'grn_id', string="SFG")
    line_ids_fg  = fields.One2many('sos_grn_line_fg', 'grn_id', string="FG")
    received_goods_type = fields.Selection([
        ('Materials', 'Materials'),
        ('SFG', 'SFG'),
        ('FG', 'FG')
    ], string='Received Goods Type',default="Materials",copy=True)
    
    responsiveness = fields.Selection([
        ('10', '10'),
        ('5', '5')
    ], string='Responsiveness',copy=True)
    
    reports = fields.Selection([
        ('30', '30'),
        ('25', '25'),
        ('10', '10')
    ], string='Report',copy=True)

    delivery = fields.Selection([
        ('30', '30'),
        ('25', '25'),
        ('10', '10')
    ], string='Delivery',copy=True) 
    
    _sql_constraints = [
        ('grn_no_unique', 'UNIQUE(grn_no)', 'The GRN No must be unique!')
    ]
    @api.model
    def create(self, vals):
        record = super(sos__grn, self).create(vals)
        if not self.env.context.get('from_script', False):
            record.action_report_esign_btn()
        return record
        
    def action_report_grn_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_grn").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")

    def action_report_esign_btn(self):
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'stores_approval_name',
        'stores_approval_on',
        'sos_inventory.sos_scg_group_user'
    )
        if self.received_goods_type == "Materials":
            for item in self.line_ids:  
                component = self.env['sos_material'].browse(item.component_id.id)
                if component:
                    current_qty = getattr(component, 'inhand_stock_qty', 0)
                    current_value = getattr(component, 'unit_price', 0)
                    current_intransit_qty = getattr(component, 'in_transit_stock_qty', 0)
                    if item.approved_qty < current_intransit_qty:
                        new_intransit_qty = current_intransit_qty - item.approved_qty
                    else:
                        new_intransit_qty = 0
                    new_qty = current_qty + item.approved_qty
                    new_unit_price = ((current_qty * current_value) + (item.approved_qty * item.unit_price))/new_qty
                    component.write({'inhand_stock_qty': new_qty, 'in_transit_stock_qty': new_intransit_qty,
                     'unit_price': new_unit_price})
                    if item.approved_qty > 0:
                        component.line_ids_in.create({'ref_id': component.id,'component_id': item.component_id.id,
                        'quantity' : item.approved_qty,'unit_price':item.unit_price,'ir_no':self.ir_no.id,
                        'action' : 'in'})
                    if item.rejected_qty > 0:
                        if self.po_no:
                            self.po_no.po_status = 'open'

        elif self.received_goods_type == "SFG":
            for item in self.line_ids_sfg: 
                if self.ir_no.indent_no:
                    procurement_record = self.env['sos_sfg_quote_generation'].search([('plan_ref_no', '=', self.ir_no.indent_no.plan_ref_no)], limit=1)
                    for every in procurement_record.line_ids:
                        
                        if str(every.material_name.name).strip().lower() == str(item.component_id.name).strip().lower():
                            if (every.inprogress_qty - item.approved_qty) < 0:
                                inprogress = 0
                            else: 
                                inprogress = every.inprogress_qty - item.approved_qty
                            every.write({
                                'inprogress_qty':inprogress
                            })
                component = self.env['sos_sfg'].browse(item.component_id.id)
                current_intransit_qty = getattr(component, 'in_transit_stock_qty', 0)
                if item.approved_qty < current_intransit_qty:
                    new_intransit_qty = current_intransit_qty - item.approved_qty
                else:
                    new_intransit_qty = 0
                if component:
                    current_value = getattr(component, 'inhand_stock_qty', 0)
                    component.write({'inhand_stock_qty': current_value + item.approved_qty ,'in_transit_stock_qty': new_intransit_qty,})
                    if item.approved_qty > 0:
                        component.line_ids_in.create({'ref_id': component.id,'component_id': item.component_id.id,
                        'quantity' : item.approved_qty,'ir_no':self.ir_no.id,
                        'action' : 'in'})
                    if item.rejected_qty > 0:
                        if self.wo_no:
                            self.wo_no.wo_status = 'open'
        else:
            for item in self.line_ids_fg:  
                component = self.env['sos_fg'].browse(item.component_id.id)
                if component:
                    current_value = getattr(component, 'inhand_stock_qty', 0)
                    component.write({'inhand_stock_qty': current_value + item.approved_qty})
        

    def _compute_sequence(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.generate_sequence('sos_grn','GRN', 'grn_no')

class sos_grn_line(models.Model):
    _name = 'sos_grn_line'
    _description = 'GRN Material Lines'

    grn_id = fields.Many2one('sos_grn', string="Materials", ondelete="cascade")
    component_id = fields.Many2one('sos_material', string="Material Name", required=True)
    ordered_qty = fields.Integer(string="Ordered Quantity")
    received_qty = fields.Integer(string="Actual Received Quantity")
    invoice_qty = fields.Integer(string="Quantity as Per Invoice")
    approved_qty = fields.Integer(string="Approved Quantity")
    currency_id = fields.Many2one('res.currency', string='Currency')
    unit_price = fields.Monetary(string="Unit Price", currency_field='currency_id')
    rejected_qty = fields.Integer(string="Rejected Quantity")
    reworked_qty = fields.Integer(string="Reworked Quantity (If any)")
    
    quality_marks = fields.Integer(string="Quality",compute="_compute_quality")
    
    @api.depends('received_qty', 'rejected_qty')
    def _compute_quality(self):
        for record in self:
            if record.rejected_qty != 0:
                record.quality_marks = (100 - ((record.rejected_qty / record.received_qty) * 100))
                if record.quality_marks >= 80 and record.quality_marks <=99:
                    record.quality_marks = 25
                else:
                    record.quality_marks = 10
            else:
                record.quality_marks = 100
    
    @api.model
    def write(self, vals):
        for record in self:
            if 'approved_qty' in vals:
                component_id = vals.get('component_id', record.component_id.id)
                approved_qty = vals.get('approved_qty', record.approved_qty) 
                unit_price = vals.get('unit_price', record.unit_price)
                component = self.env['sos_material'].browse(component_id)

                if component:
                    current_qty = component.inhand_stock_qty or 0
                    current_value = component.unit_price or 0
                    current_intransit_qty = getattr(component, 'in_transit_stock_qty', 0)
                    if approved_qty < current_intransit_qty:
                        new_intransit_qty = current_intransit_qty - approved_qty
                    else:
                        new_intransit_qty = 0
                    new_qty = current_qty + approved_qty
                    if new_qty > 0:  
                        new_unit_price = ((current_qty * current_value) + (approved_qty * unit_price)) / new_qty
                    else:
                        new_unit_price = unit_price

                    component.write({
                        'inhand_stock_qty': new_qty,
                        'unit_price': new_unit_price,
                        'in_transit_stock_qty': new_intransit_qty
                    })
                    if approved_qty > 0:
                        self.env['sos_material_transaction_history'].create({
                            'ref_id': component.id,
                            'component_id': component_id,
                            'quantity': approved_qty,
                            'unit_price': unit_price,
                            'action': 'in',
                        })

        # Call the super method to apply the actual write
        return super(sos_grn_line, self).write(vals)

    @api.model
    def create(self, vals):
        if not self.env.context.get('from_script', False):
            component_id = vals.get('component_id')
            approved_qty = vals.get('approved_qty', 0)  
            unit_price = vals.get('unit_price', 0) 
            
            if component_id:
                component = self.env['sos_material'].browse(component_id)
                if component:
                    current_qty = getattr(component, 'inhand_stock_qty', 0) 
                    current_value = getattr(component, 'unit_price', 0) 
                    current_intransit_qty = getattr(component, 'in_transit_stock_qty', 0)
                    if approved_qty < current_intransit_qty:
                        new_intransit_qty = current_intransit_qty - approved_qty
                    else:
                        new_intransit_qty = 0
                    new_qty = current_qty + approved_qty
                    if new_qty > 0:  
                        new_unit_price = ((current_qty * current_value) + (approved_qty * unit_price)) / new_qty
                    else:
                        new_unit_price = unit_price

                    component.write({
                        'inhand_stock_qty': new_qty,
                        'unit_price': new_unit_price,
                        'in_transit_stock_qty': new_intransit_qty
                    })
                    if approved_qty > 0:
                        self.env['sos_material_transaction_history'].create({
                            'ref_id': component.id,
                            'component_id': component_id,
                            'quantity': approved_qty,
                            'unit_price': unit_price,
                            'action': 'in',
                        })

        record = super(sos_grn_line, self).create(vals)

        return record


class sos_grn_line_sfg(models.Model):
    _name = 'sos_grn_line_sfg'
    _description = 'GRN SFG Lines'

    grn_id = fields.Many2one('sos_grn', string="Materials", ondelete="cascade")
    component_id = fields.Many2one('sos_sfg', string="Material Name", required=True)
    ordered_qty = fields.Integer(string="Ordered Quantity")
    received_qty = fields.Integer(string="Actual Received Quantity")
    invoice_qty = fields.Integer(string="Quantity as Per Invoice")
    approved_qty = fields.Integer(string="Approved Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    reworked_qty = fields.Integer(string="Reworked Quantity (If any)")

    quality_marks = fields.Integer(string="Quality",compute="_compute_sfgquality")
    
    responsiveness = fields.Selection([
        ('10', '10'),
        ('5', '5')
    ], string='Responsiveness',copy=True,default="10") 

    reports = fields.Selection([
        ('30', '30'),
        ('25', '25'),
        ('10', '10')
    ], string='Report',copy=True,default="30")

    delivery = fields.Selection([
        ('30', '30'),
        ('25', '25'),
        ('10', '10')
    ], string='Delivery',copy=True,default="30") 
    
    @api.depends('received_qty', 'rejected_qty')
    def _compute_sfgquality(self):
        for record in self:
            if record.rejected_qty != 0:
                record.quality_marks = (100 - ((record.rejected_qty / record.received_qty) * 100))
                if record.quality_marks >= 80 and record.quality_marks <=99:
                    record.quality_marks = 25
                else:
                    record.quality_marks = 10
            else:
                record.quality_marks = 100
    
class sos_grn_line_fg(models.Model):
    _name = 'sos_grn_line_fg'
    _description = 'GRN FG Lines'

    grn_id = fields.Many2one('sos_grn', string="Materials", ondelete="cascade")
    component_id = fields.Many2one('sos_fg', string="Material Name", required=True)
    ordered_qty = fields.Integer(string="Ordered Quantity")
    received_qty = fields.Integer(string="Actual Received Quantity")
    invoice_qty = fields.Integer(string="Quantity as Per Invoice")
    approved_qty = fields.Integer(string="Approved Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    reworked_qty = fields.Integer(string="Reworked Quantity (If any)")

