Slink/sos_inventory/models/sos_fir_brr.py

240 lines
11 KiB
Python
Executable File

from odoo import models, fields, api
from odoo.exceptions import UserError
from datetime import date,datetime
class FIR_BRR(models.Model):
_name = 'sos_fir_brr'
_description = 'Batch Release Report'
_rec_name='fir_no'
_order = 'id desc'
fir_no = fields.Char(string="BRR No",default=lambda self: self._generate_id(),readonly= True, required= True)
fir_date = fields.Date(string="BRR Date")
fg_name = fields.Many2one('sos_fg', string='FG Name')
product_name = fields.Char(related="fg_name.name", string='Product Name',readonly=True)
plan_ref_no = fields.Many2one('sos_fg_plan', string='Indent Ref No')
batch_size = fields.Integer(string="Batch Size / Received Quantity")
batch_No = fields.Char(string="Batch No")
mfg_date = fields.Char(string="Manufacturing Date")
sampling_size = fields.Char(string="Sampling Size")
serial_no_line_ids = fields.One2many('sos_brr_serial_no_lines', 'ref_id',copy=True)
calibration_line_ids = fields.One2many('sos_calibration_devices_fir', 'ref_id',copy=True)
testing_parameter_line_ids = fields.One2many('sos_fir_brr_line', 'ref_line_id',copy=True)
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')
qc_by_name = fields.Many2one('res.users', string='QC Tested&Provided by Sign')
qc_by_image = fields.Image(related="qc_by_name.signature_image",string='Prepared by Sign',readonly=True)
qc_tested_on = fields.Date(string="Approved On")
reworked_count = fields.Integer(string="Reworked Count",default=0)
qa_by_name = fields.Many2one('res.users', string='QA by Sign')
qa_by_image = fields.Image(related="qa_by_name.signature_image",string='Prepared by Sign',readonly=True)
qa_tested_on = fields.Datetime(string="Approved On")
ppm = fields.Integer(string="PPM",compute="_compute_ppm")
stores_received_by = fields.Many2one('res.users', string='Store Received by Sign')
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")
ncmr_ref = fields.Many2one('sos_ncmr',string="NCMR Reference (If any Rejected)")
def action_report_brr_btn(self):
try:
action = self.env.ref("sos_inventory.action_report_brr").report_action(self)
return action
except ValueError as e:
print(f"Failed to find report action: {e}")
@api.depends('batch_size', 'rejected_qty')
def _compute_ppm(self):
for record in self:
if record.rejected_qty != 0:
record.ppm = (record.rejected_qty / record.batch_size) * 10**6
else:
record.ppm = 0
@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('batch_size', 'rejected_qty')
def _compute_rejected_percentage(self):
for record in self:
if record.batch_size > 0:
record.rejection_percentage = (record.rejected_qty / record.batch_size) * 100
else:
record.rejection_percentage = 0
def action_qc_esign_btn(self):
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:
ncmr_record = self.env['sos_ncmr'].create({
'ncmr_no': ncmr_id,
'fg_option':True,
'material_option':False,
'sfg_option':False,
'batch_no':self.batch_No,
'rejected_qty':self.rejected_qty,
'fg_name': self.fg_name.id,
'fg_incoming_doc_ref':self.id,
'department':'Quality Control'
})
if ncmr_record:
self.ncmr_ref = ncmr_record.id
ncmr_body_html = f"""
<p>Below <b>NCMR</b> is waiting for your Inspection</p>
"""
sequence_util.send_group_email(self.env,'sos_ncmr',ncmr_id,"deenalaura.m@sosaley.in","NCMR Inspection Pending",ncmr_body_html,'sos_inventory.sos_qc_user')
# Email part
body_html = f"""
<p>Below <b>Batch Release Report</b> is waiting for your Approval</p>
"""
sequence_util.send_group_email(self.env,"sos_fir_brr",self.id,"deenalaura.m@sosaley.in","BRR Approval Request",body_html,'sos_inventory.sos_qa_user')
# Email part ends
return sequence_util.action_assign_signature(
self,
'qc_by_name',
'qc_tested_on'
)
def action_qa_esign_btn(self):
# Email part
body_html = f"""
<p>Below <b>FIR</b> is waiting for your Approval</p>
"""
send_email = self.env['sos_common_scripts']
send_email.send_group_email(self.env,"sos_fir_brr",self.id,"deenalaura.m@sosaley.in","BRR 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 action_stores_esign_btn(self):
if self.plan_ref_no:
# Production Status
sos_record = self.env['sos_production_plan'].search([
('fg_name', '=', self.fg_name.id),
('plan_ref_no', '=', self.plan_ref_no.plan_ref_no)
], limit=1)
sequence_util = self.env['sos_common_scripts']
week_number = sequence_util.calculate_week_number(
sos_record.indent_start_date ,
sos_record.target_date ,
date.today()
)
field_name = f'qc_week_{week_number}'
fgplan_field_name = f'planned_week_{week_number}'
# FG Plan update
fg_plan_record = self.env['sos_fg_plan_line'].search([
('fg_name', '=', self.fg_name.id)
], limit=1)
if fg_plan_record:
current_value = getattr(fg_plan_record, fgplan_field_name, 0)
fg_plan_record.write({fgplan_field_name: current_value + self.approved_qty})
if sos_record:
current_value = getattr(sos_record, field_name, 0)
sos_record.write({field_name: current_value + self.approved_qty})
# Production Status Ends
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'
)
approved_qty = self.approved_qty
if approved_qty > 0:
current_qty = self.fg_name.inhand_stock_qty
new_qty = current_qty + approved_qty
self.fg_name.inhand_stock_qty = new_qty
self.env['sos_fg_transaction_history'].create({
'ref_id': self.fg_name.id,
'fir_no': self.id,
'component_id': self.fg_name.id,
'quantity': approved_qty,
'action': 'in',
})
def _generate_id(self):
sequence_util = self.env['sos_common_scripts']
return sequence_util.generate_sequence('sos_fir_brr','BRR', 'fir_no')
@api.onchange('fg_name')
def _onchange_fg_name(self):
if self.fg_name:
self._load_testing_parameters()
@api.model
def create(self, vals):
record = super(FIR_BRR, self).create(vals)
if record.fg_name:
record._load_testing_parameters()
return record
def write(self, vals):
result = super(FIR_BRR, self).write(vals)
if 'fg_name' in vals:
self._load_testing_parameters()
return result
def _load_testing_parameters(self):
if self.fg_name:
testing_parameters = self.env['sos_testing_parameters'].search([('fg_name', '=', self.fg_name.id)])
if not testing_parameters:
raise UserError('No testing parameters found for this FG.')
# Clear any existing lines
lines = [(5, 0, 0)]
sorted_parameters = testing_parameters.parameter_ids.sorted(key=lambda param: param.sequence)
# Append the sorted parameters
for param in sorted_parameters:
lines.append((0, 0, {
'testing_parameter': param.id,
'sequence': param.sequence,
'specification': param.specification,
'results': param.results,
'inspection_decision':param.inspection_decision
}))
# Set the sorted lines to testing_parameter_line_ids
self.testing_parameter_line_ids = lines
class FIR_BRR_Line(models.Model):
_name = 'sos_fir_brr_line'
_description = 'Batch Release Report Line Items'
ref_line_id = fields.Many2one('sos_fir_brr', ondelete="cascade")
sequence = fields.Integer(string="sequence")
testing_parameter = fields.Many2one('sos_parameter', string='Testing Parameter')
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")
inspection_decision = fields.Selection([('PASS','PASS'),('FAIL','FAIL')],string="Inspection Decision")
specification = fields.Char(string="Specification")
results = fields.Text(string="Results")
class Calibration_devices(models.Model):
_name = 'sos_calibration_devices_fir'
_description = 'Calibartion Devices List'
ref_id = fields.Many2one('sos_fir_brr', ondelete="cascade")
calibration_device = fields.Many2one('sos_calibration_devices',string="Equipment Name", required=True)
identification_No = fields.Char(string="Identification No",related="calibration_device.identification_no")
certification_No = fields.Char(string="Certification No",related="calibration_device.certification_no")
calibrated_date = fields.Date(string="Calibrated Date",related="calibration_device.calibrated_on")
due_date = fields.Date(string="Due Date",related="calibration_device.calibrated_due")
class FIR_BRR_serial_no_Lines(models.Model):
_name = 'sos_brr_serial_no_lines'
_description = 'Serial No Line Items'
ref_id = fields.Many2one('sos_fir_brr', ondelete="cascade")
serial_no = fields.Char(string="Serial No")
inspection_decision = fields.Selection([('PASS','PASS'),('FAIL','FAIL')],string="Inspection Decision",default="PASS")