# -*- coding: utf-8 -*- from odoo import models, fields, api import time from odoo.exceptions import UserError class sos__mrn(models.Model): _name = 'sos_mrn' _description = 'Return Note' _rec_name = 'mrn_no' _order = 'id desc' mrn_no = fields.Char(string="MRN/SRN/FRN No", readonly= True, required= True, default=lambda self: self._generate_id(),copy=False) mrn_date = fields.Datetime(string="MRN/SRN/FRN Date", required=True, default=fields.Datetime.now,copy=False) min_no = fields.Many2one('sos_min',string="MIN/SIN/FIN No",copy=False) min_date = fields.Date(related="min_no.min_date",string="MIN/SIN/FIN Date",copy=False) filled_by = fields.Many2one('res.users', string='Filled By', readonly=True,required=True,default=lambda self: self.env.user) prepared_by_name = fields.Many2one('res.users', string='Prepared by',copy=False) prepared_by_image = fields.Image(related="prepared_by_name.signature_image",string='Prepared by Sign',readonly=True,copy=False) prepared_on = fields.Datetime(string="Approved On",copy=False) reporting_to = fields.Many2one('res.users',related="prepared_by_name.reporting_to", string='Prepared by') dept_in_charge_name = fields.Many2one('res.users', string='Department In-Charge',copy=False) dept_in_charge_image = fields.Image(related="dept_in_charge_name.signature_image",string='Department In-Charge Sign',readonly=True,copy=False) dept_in_charge_approved_on = fields.Datetime(string="Approved On",copy=False) stores_approved_by = fields.Many2one('res.users', string='Stores Approved By',copy=False) stores_approved_image = fields.Image(related="stores_approved_by.signature_image",string='Stores Approval Sign',readonly=True,copy=False) stores_approved_on = fields.Datetime(string="Approved On",copy=False) qa_approved_by = fields.Many2one('res.users', string='QA Approved By',copy=False) qa_approved_image = fields.Image(related="qa_approved_by.signature_image",string='QA Approval Sign',readonly=True,copy=False) qa_approved_on = fields.Datetime(string="Approved On",copy=False) material_option = fields.Boolean('Materials', default=True) sfg_option = fields.Boolean('Semi-Finished Goods') fg_option = fields.Boolean('Finished Goods') return_type = fields.Selection([('excess_qty', 'SFG Assembling, Excess Qty'),('customer', 'Customer Complaint'), ('spare', 'Spare'), ('service', 'Service'), ('expo', 'Expo'), ('demo', 'Demo'), ('others', 'Others')], string="Return Type") customer_name=fields.Char(string="Customer Name") order_type = fields.Char(string='order_type',copy=True) line_ids_material = fields.One2many('sos_mrn_line_material', 'mrn_id', string="Materials",copy=True) line_ids_sfg = fields.One2many('sos_mrn_line_sfg', 'mrn_id', string="Semi-Finished Goods",copy=True) line_ids_fg = fields.One2many('sos_mrn_line_fg', 'mrn_id', string="Finished Goods",copy=True) show_customer = fields.Boolean(compute="_compute_show_customer", store=False) 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) approx_value = fields.Monetary(compute='_compute_approx_value', string="Approximate Value", currency_field='currency_id', readonly=True) is_ce_user_created = fields.Boolean( compute='_compute_is_ce_user_created', store=True, string='Created by CE User' ) @api.depends('create_uid') def _compute_is_ce_user_created(self): ce_groups = [ self.env.ref('sos_inventory.sos_ce_user').id ] for record in self: record.is_ce_user_created = any( gid in record.create_uid.groups_id.ids for gid in ce_groups ) @api.onchange('min_no') def _onchange_min_no(self): if self.min_no: self.material_option = self.min_no.material_option self.sfg_option = self.min_no.sfg_option self.fg_option = self.min_no.fg_option #materials self.line_ids_material = [(5, 0, 0)] material_lines = [] for material in self.min_no.line_ids_material: line_vals = { 'mrn_id': self.id, 'component_id': material.component_id, 'qp_no': material.qp_no, 'uom': material.uom, 'quantity': material.quantity } material_lines.append((0, 0, line_vals)) self.line_ids_material = material_lines #sfg self.line_ids_sfg = [(5, 0, 0)] sfg_lines = [] for sfg in self.min_no.line_ids_sfg: line_vals_sfg = { 'mrn_id': self.id, 'component_id': sfg.component_id, 'qp_no': sfg.qp_no, 'quantity': sfg.quantity } sfg_lines.append((0, 0, line_vals_sfg)) self.line_ids_sfg = sfg_lines #sfg self.line_ids_fg = [(5, 0, 0)] fg_lines = [] for fg in self.min_no.line_ids_fg: line_vals_fg = { 'mrn_id': self.id, 'component_id': fg.component_id, 'quantity': fg.quantity } fg_lines.append((0, 0, line_vals_fg)) self.line_ids_fg = fg_lines @api.depends('line_ids_material.total_cost') def _compute_approx_value(self): for record in self: record.approx_value = sum(line.total_cost for line in record.line_ids_material) @api.depends('return_type') def _compute_show_customer(self): for rec in self: rec.show_customer = rec.return_type in ['spare', 'service', 'customer'] # @api.model # def create(self, vals): # record = super(sos__mrn, self).create(vals) # record.action_report_esign_btn() # return record @api.onchange('material_option', 'sfg_option', 'fg_option') def _onchange_material_option(self): options = [] if self.material_option: options.append("Material") if self.sfg_option: options.append("SFG") if self.fg_option: options.append("FG") self.order_type = ",".join(options) def _generate_id(self): sequence_util = self.env['sos_common_scripts'] return sequence_util.generate_sequence('sos_mrn','MRN', 'mrn_no') def action_report_mrn_btn(self): try: action = self.env.ref("sos_inventory.action_report_mrn").report_action(self) return action except ValueError as e: print(f"Failed to find report action: {e}") def action_report_esign_incharge(self): # Email part body_html = f"""
Below Return Note is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_group_email(self.env,'sos_mrn',self.id,"deenalaura.m@sosaley.in","Return Note Approval Request",body_html,'sos_inventory.sos_qa_user') # Email part ends send_email.action_assign_signature( self, 'dept_in_charge_name', 'dept_in_charge_approved_on' ) def action_qa_esign(self): # Email part body_html = f"""Below Return Note is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_group_email(self.env,'sos_mrn',self.id,"deenalaura.m@sosaley.in","Return Note Approval Request",body_html,'sos_inventory.sos_scg_group_user') # Email part ends send_email.action_assign_signature( self, 'qa_approved_by', 'qa_approved_on', 'sos_inventory.sos_qa_user' ) def action_report_esign_btn1(self): sequence_util = self.env['sos_common_scripts'] splitted=self.order_type.split(",") customer_return_record = False if self.return_type == "customer": sequence_util = self.env['sos_common_scripts'] tc_no = sequence_util.generate_sequence('sos_transfer_challan_return_from_customer','TC', 'tc_no') customer_return_record = self.env['sos_transfer_challan_return_from_customer'].create({ 'tc_no': tc_no, 'mrn_ref_no':self.id }) for eachone in splitted: if eachone == "Material": for item in self.line_ids_material: component = self.env['sos_material'].browse(item.component_id.id) if item.qa_decision == "to_stores": current_qty = getattr(component, 'inhand_stock_qty', 0) new_qty = current_qty + item.quantity component.write({'inhand_stock_qty': new_qty}) component.line_ids_in.create({'ref_id': component.id,'component_id': item.component_id.id, 'quantity' : item.quantity,'mrn_no':self.id, 'action' : 'in'}) else: iqi_record = self.env['sos_return_iqi'].create({ 'iqi_no': sequence_util.generate_sequence('sos_return_iqi', 'Return-IQI', 'iqi_no'), 'material_option':True, 'sfg_option':False, 'received_qty':item.quantity, 'material_name': item.component_id.id, 'material_code': item.component_id.material_code, 'mrn_id':self.id }) if customer_return_record and self.return_type == "customer" and item.qa_decision != "to_stores": create_vals = { 'tc_id': customer_return_record.id, 'item_name': component.name, 'item_type': 'Material', 'return_incoming_doc_ref':iqi_record.id if iqi_record else None } new_line = self.env['sos_transfer_challan_return_from_customer_lines'].create(create_vals) # Email part body_html = f"""Below Return-IQI is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_group_email(self.env,'sos_return_iqi',iqi_record.id,"deenalaura.m@sosaley.in","Return-IQI Inspection Request",body_html,'sos_inventory.sos_qc_user') # Email part ends elif eachone == "SFG": for item in self.line_ids_sfg: component = self.env['sos_sfg'].browse(item.component_id.id) if item.qa_decision == "to_stores": current_qty = getattr(component, 'inhand_stock_qty', 0) new_qty = current_qty + item.quantity component.write({'inhand_stock_qty': new_qty}) component.line_ids_in.create({'ref_id': component.id,'component_id': item.component_id.id, 'quantity' : item.quantity,'mrn_no':self.id, 'action' : 'in'}) else: if component: iqi_record = self.env['sos_return_iqi'].create({ 'iqi_no': sequence_util.generate_sequence('sos_return_iqi', 'Return-IQI', 'iqi_no'), 'material_option':False, 'sfg_option':True, 'received_qty':item.quantity, 'sfg_name': item.component_id.id, 'sfg_code': item.component_id.sfg_code, 'mrn_id':self.id, 'iqi_date':item.mrn_id.mrn_date }) # Email part body_html = f"""Below Return-IQI is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_group_email(self.env,'sos_return_iqi',iqi_record.id,"deenalaura.m@sosaley.in","Return-IQI Inspection Request",body_html,'sos_inventory.sos_qc_user') # Email part ends if customer_return_record and self.return_type == "customer" and item.qa_decision != "to_stores": create_vals = { 'tc_id': customer_return_record.id, 'item_name': component.name, 'item_type': 'SFG', 'return_incoming_doc_ref':iqi_record.id if iqi_record else None } new_line = self.env['sos_transfer_challan_return_from_customer_lines'].create(create_vals) else: for item in self.line_ids_fg: component = self.env['sos_fg'].browse(item.component_id.id) if item.qa_decision == "to_stores": current_qty = getattr(component, 'inhand_stock_qty', 0) new_qty = current_qty + item.quantity component.write({'inhand_stock_qty': new_qty}) component.line_ids_in.create({'ref_id': component.id,'component_id': item.component_id.id, 'quantity' : item.quantity,'mrn_no':self.id, 'action' : 'in'}) else: if self.return_type == "customer": return_fg_record = self.env['sos_return_fg_register'].create({ 'mrn_no': self.id, 'customer_name': self.customer_name, 'date':item.mrn_id.mrn_date, 'fg_name':item.component_id.id, 'lot_no':item.serial_no, 'reason_for_return':item.reject_reason, 'returned_quantity':item.quantity }) if component: return_fir_record = self.env['sos_return_fir'].create({ 'fir_no': sequence_util.generate_sequence('sos_return_fir', 'Return-BRR', 'fir_no'), 'fg_name': item.component_id.id, 'batch_No': item.batch_No, 'serial_no':item.serial_no, 'fir_date':item.mrn_id.mrn_date, 'batch_size':item.quantity }) # Email part body_html = f"""Below Return-BRR is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_group_email(self.env,'sos_return_fir',return_fir_record.id,"deenalaura.m@sosaley.in","Return-BRR Inspection Request",body_html,'sos_inventory.sos_qc_user') # Email part ends if customer_return_record and self.return_type == "customer" and item.qa_decision != "to_stores": create_vals = { 'tc_id': customer_return_record.id, 'item_name': component.name, 'item_type': 'FG', 'return_fg_incoming_doc_ref':return_fir_record.id if return_fir_record else None } new_line = self.env['sos_transfer_challan_return_from_customer_lines'].create(create_vals) return sequence_util.action_assign_signature( self, 'stores_approved_by', 'stores_approved_on', 'sos_inventory.sos_scg_group_user' ) def action_report_esign_btn(self): # Email part body_html = f"""Below Return Note is waiting for your Approval
""" send_email = self.env['sos_common_scripts'] send_email.send_mon_min_email(self.env,'sos_mrn',self.id,"deenalaura.m@sosaley.in","Return Note Approval Request",body_html,"user") # Email part ends sequence_util = self.env['sos_common_scripts'] return sequence_util.action_assign_signature( self, 'prepared_by_name', 'prepared_on' ) class Mrn_Line_Material(models.Model): _name = 'sos_mrn_line_material' _description = 'Material Order Lines' mrn_id = fields.Many2one('sos_mrn', string="Materials", ondelete="cascade") component_id = fields.Many2one('sos_material', string="Part No", required=True) qp_no = fields.Char(string="QP No") uom = fields.Selection([('meters', 'Meters'), ('Packs', 'Packs'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], string="Uom",readonly="1") reject_reason = fields.Text(string="Reason for return") quantity = fields.Integer(string="Quantity",default=1) condition = fields.Selection([ ('work', 'Working'),('nowork', 'Not Working')], default='work' , string="Condition") image = fields.Binary(string='Image', attachment=True) qa_decision = fields.Selection([('to_stores', 'Move to Stores'),('to_qc', 'Move to QC')], default="to_qc",string="QA Decision") 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) approx_price = fields.Monetary(string="Unit Price", compute='_compute_unit_price', store=True, readonly=False) total_cost = fields.Monetary(compute="_compute_total_cost", currency_field='currency_id') @api.depends('approx_price', 'quantity') def _compute_total_cost(self): for record in self: record.total_cost = record.approx_price * record.quantity @api.depends('component_id.unit_price') def _compute_unit_price(self): for record in self: record.approx_price = record.component_id.unit_price @api.onchange('component_id') def _onchange_component_id(self): if self.component_id: self.qp_no = self.component_id.qp_no self.uom = self.component_id.uom else: self.qp_no = False self.uom = False class Mrn_Line_SFG(models.Model): _name = 'sos_mrn_line_sfg' _description = 'SFG Order Lines' mrn_id = fields.Many2one('sos_mrn', string="Materials", ondelete="cascade") component_id = fields.Many2one('sos_sfg', string="SFG Name", required=True) qp_no = fields.Char(string="QP No") uom = fields.Selection([('set', 'Set'),('Nos', 'Nos'), ('Packs', 'Packs')], string="Uom",default="Nos") reject_reason = fields.Char(string="Reason for return") quantity = fields.Integer(string="Quantity",default=1) condition = fields.Selection([ ('work', 'Working'),('nowork', 'Not Working')], default='work' , string="Condition") image = fields.Binary(string='Image', attachment=True) qa_decision = fields.Selection([('to_stores', 'Move to Stores'),('to_qc', 'Move to QC')], default="to_qc",string="QA Decision") @api.onchange('component_id') def _onchange_component_id(self): if self.component_id: self.qp_no = self.component_id.qp_no self.uom = self.component_id.uom else: self.qp_no = False self.uom = False class Mrn_Line_FG(models.Model): _name = 'sos_mrn_line_fg' _description = 'FG Order Lines' mrn_id = fields.Many2one('sos_mrn', string="Materials", ondelete="cascade") component_id = fields.Many2one('sos_fg',string="FG Name", required=True) batch_No = fields.Char(string="Batch No") serial_no = fields.Char(string="Serial No") uom = fields.Selection([('set', 'Set'),('Nos', 'Nos'), ('Packs', 'Packs')], string="Uom",default="Nos") reject_reason = fields.Char(string="Reason for return") quantity = fields.Integer(string="Quantity",default=1) condition = fields.Selection([ ('work', 'Working'),('nowork', 'Not Working')], default='work' , string="Condition") image = fields.Binary(string='Image', attachment=True) qa_decision = fields.Selection([('to_stores', 'Move to Stores'),('to_qc', 'Move to QC')], default="to_qc",string="QA Decision") @api.onchange('component_id') def _onchange_component_id(self): if self.component_id: self.uom = self.component_id.uom else: self.uom = False