241 lines
11 KiB
Python
Executable File
241 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()
|
|
)
|
|
week_number = min(week_number, 8)
|
|
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") |