Slink/sos_inventory/models/sos_dock_audit.py

803 lines
41 KiB
Python
Executable File

# -*- coding: utf-8 -*-
from odoo import models, fields, api
import time,logging
from odoo.exceptions import UserError
from collections import Counter
_logger = logging.getLogger(__name__)
class SOS_Dock_Audit(models.Model):
_name = 'sos_dock_audit'
_description = 'Dock Audit'
_rec_name = 'dock_audit_no'
_order = 'id desc'
dock_audit_no = fields.Char(string="Dock Audit No", readonly= True, required= True, default=lambda self: self._generate_id())
deliverables_boq_id = fields.Many2one('sos_deliverables_boq', string="Deliverables/BOQ Id")
fg_name = fields.Selection(
[
('BHMS 1.2V', 'BHMS 1.2V'),
('BHMS 2V', 'BHMS 2V'),
('BHMS 12V', 'BHMS 12V'),
('BHMS 48V', 'BHMS 48V'),
('BMS-HV', 'BMS-HV'),
('BMS-LV 100A', 'BMS-LV 100A'),
('BMS-LV 40A', 'BMS-LV 40A'),
('SBMS 55A', 'SBMS 55A'),
('MC 250W', 'MC 250W'),
('HeartTarang', 'HeartTarang')
],
string="Product Type",required=True)
quantity = fields.Integer(string="Quantity")
invoice_no = fields.Char(string="Invoice No")
customer_name = fields.Char(string="Customer Name")
lead_time = fields.Datetime(string="Lead Time")
customer_po_no = fields.Char(string="PO No")
customer_location = fields.Char(string="Customer Location")
customer_po_date = fields.Datetime(string="PO Date")
line_ids_miscellaneous = fields.One2many('sos_dock_audit_miscellaneous_items','ref_id', string="Miscellaneous")
line_ids_installation_kit = fields.One2many('sos_dock_audit_line_material_installation', 'ref_id', string="Installation Kit")
line_ids_fg = fields.One2many('sos_dock_audit_line_fg', 'ref_id', string="Finished Goods")
line_ids_sfg = fields.One2many('sos_dock_audit_line_sfg', 'ref_id', string="Semi-Finished Goods")
line_ids_material = fields.One2many('sos_dock_audit_line_material', 'ref_id', string="Finished Goods")
line_ids_transaction = fields.One2many('sos_dock_audit_transaction', 'ref_id', string="Finished Goods")
payment_status= fields.Selection([('credit_after_delivery', 'Payment After Delivery'),('received', 'Received'),('demo', 'Demo'),('warranty', 'Warranty'),('validation', 'Validation')],string="Payment Status")
billing_address = fields.Text(string="Billing Address")
shipping_address = fields.Text(string="Shipping Address")
purpose = fields.Char(string="Purpose")
gst_no = fields.Char(string="GST No")
design_verification_ids = fields.One2many('sos_design_verification', 'ref_id',copy=True, ondelete='cascade')
user_manual = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="User Manual")
installation_video = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Installation Video")
wiring_diagram = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Wiring Diagram")
warranty_card = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Warranty Card")
test_report = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Test Report")
sdcard_data = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="SD card Data")
cloud_data = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Cloud Data")
sim_provided_status = fields.Selection([('yes', 'Yes'),('no', 'No')], default='no',string="SIM Card Provided")
sim_number = fields.Char(string="SIM Number")
correct_product = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Product Correct?")
packaging_correct = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Packaging Correct?")
packing_received = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Packaging List Received?")
labeling_correct = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Labeling Correct?")
internal_rework = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Internal Rework (If Issued)")
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',readonly=True)
top_management_approved_on = fields.Datetime(string="Approved On")
audited_by_name = fields.Many2one('res.users', string='Audited by')
audited_by_image = fields.Image(related="audited_by_name.signature_image",string='Audited by Sign',readonly=True)
audited_on = fields.Datetime(string="Audited On")
ce_name = fields.Many2one('res.users', string='CE')
ce_image = fields.Image(related="ce_name.signature_image",string='CE Sign',readonly=True)
ce_approved_on = fields.Datetime(string="Approved On")
qa_by_name = fields.Many2one('res.users', string='QA Sign')
qa_by_image = fields.Image(related="qa_by_name.signature_image",string='QA by Sign',readonly=True)
accounts_approved_on = fields.Datetime(string="Accounts Approved On")
accounts_approved_name = fields.Many2one('res.users', string='Accounts Sign')
accounts_approved_by_image = fields.Image(related="accounts_approved_name.signature_image",string='Accounts Sign',readonly=True)
qa_tested_on = fields.Datetime(string="Tested On")
min_no = fields.Many2one('sos_min',string="Issue Note Ref No")
phase_version = fields.Integer(string="Phase",readonly=True)
report_phase = fields.Char(string="Report Phase")
status = fields.Selection([ ('open', 'Open'),('close', 'Closed')], default='open' , string="Status")
@api.model
def create(self, vals):
customer_po_no = vals.get('customer_po_no')
deliverables_boq_id = vals.get('deliverables_boq_id')
dock_audit_no = vals.get('dock_audit_no')
sequence_util = self.env['sos_common_scripts']
#print(f" {customer_po_no } : customer_po_no : {deliverables_boq_id}")
if customer_po_no and deliverables_boq_id:
existing = self.search([
('customer_po_no', '=', customer_po_no),
('deliverables_boq_id', '=', deliverables_boq_id)
], limit=1)
if existing:
db_dock_audit_no = existing.dock_audit_no
db_deliverables_boq_id = existing.deliverables_boq_id
db_customer_po_no = existing.customer_po_no
if db_dock_audit_no:
url =f"https://slink.sosaley.in//web#id={existing.id}&cids=1&menu_id=175&action=233&model=sos_dock_audit&view_type=form"
raise UserError(
f"Dock audit [{db_dock_audit_no}] already exists for this BOQ and PO number.\n\n"
f"{url}"
)
return existing
else:
return super().create(vals)
else:
return super().create(vals)
@api.onchange('min_no')
def _onchange_min_no(self):
for line in self.line_ids_fg:
if self.min_no and self.min_no.line_ids_fg:
matching_lines = self.min_no.line_ids_fg.filtered(lambda l: l.component_id == line.component_id) # Compare based on fields
line.matched_line = True if matching_lines else False # 10 (green), 1 (red)
else:
line.matched_line = False # Default to red
def _generate_id(self):
sequence_util = self.env['sos_common_scripts']
return sequence_util.generate_sequence('sos_dock_audit','DA','dock_audit_no')
def action_top_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'
)
for record in self:
record.write({
'phase_version': record.phase_version+1,
'status': 'close',
})
def action_acc_esign_btn(self):
sequence_util = self.env['sos_common_scripts']
sequence_util.action_assign_signature(
self,
'accounts_approved_name',
'accounts_approved_on',
'sos_inventory.sos_finance_user'
)
# Email part
body_html = f"""
<p>Below Dock Audit is waiting for your Approval</p>
"""
sequence_util.send_direct_email(self.env,"sos_dock_audit",self.id,"ramachandran.r@sosaley.in","Dock Audit Approval",body_html)
# Email part ends
def action_auditor_esign_btn(self):
sequence_util = self.env['sos_common_scripts']
sequence_util.action_assign_signature(
self,
'audited_by_name',
'audited_on'
)
# Email part
body_html = f"""
<p>Below Dock Audit is waiting for your Approval</p>
"""
sequence_util.send_group_email(self.env,'sos_dock_audit',self.id,"deenalaura.m@sosaley.in","Dock Audit Approval",body_html,'sos_inventory.sos_qa_user')
# Email part ends
def action_qa_esign_btn(self):
sequence_util = self.env['sos_common_scripts']
sequence_util.action_assign_signature(
self,
'qa_by_name',
'qa_tested_on'
)
# Email part
body_html = f"""
<p>Below Dock Audit is waiting for your Approval</p>
"""
sequence_util.send_group_email(self.env,'sos_dock_audit',self.id,"deenalaura.m@sosaley.in","Dock Audit Approval",body_html,'sos_inventory.sos_ce_user')
# Email part ends
def action_ce_esign_btn(self):
sequence_util = self.env['sos_common_scripts']
sequence_util.action_assign_signature(
self,
'ce_name',
'ce_approved_on'
)
# Email part
body_html = f"""
<p>Below Dock Audit is waiting for your Approval</p>
"""
sequence_util.send_direct_email(self.env,"sos_dock_audit",self.id,"anitha.a@sosaley.in","Dock Audit Approval",body_html)
# Email part ends
@api.onchange('deliverables_boq_id')
def _onchange_deliverables_boq_id(self):
if self.deliverables_boq_id:
self.user_manual = self.deliverables_boq_id.sales_id.user_manual
self.installation_video = self.deliverables_boq_id.sales_id.installation_video
self.wiring_diagram = self.deliverables_boq_id.sales_id.wiring_diagram
self.warranty_card = self.deliverables_boq_id.sales_id.warranty_card
self.test_report = self.deliverables_boq_id.sales_id.test_report
self.sdcard_data = self.deliverables_boq_id.sales_id.sdcard_data
self.cloud_data = self.deliverables_boq_id.sales_id.cloud_data
self.billing_address = self.deliverables_boq_id.sales_id.billing_address
self.shipping_address = self.deliverables_boq_id.sales_id.shipping_address
self.gst_no = self.deliverables_boq_id.sales_id.gst_no
self.payment_status = self.deliverables_boq_id.sales_id.payment_status
self.customer_name = self.deliverables_boq_id.sales_id.customer_name
self.fg_name = self.deliverables_boq_id.sales_id.fg_name
self.quantity = self.deliverables_boq_id.sales_id.qty
self.lead_time = self.deliverables_boq_id.sales_id.lead_time
self.customer_po_no = self.deliverables_boq_id.sales_id.customer_po_no
self.customer_po_date = self.deliverables_boq_id.sales_id.customer_po_date
self.line_ids_installation_kit = [(5, 0, 0)] # Clear existing records
self.line_ids_installation_kit = [
(0, 0, {
'component_id': line.component_id, # Replace 'field1' with the actual field names
'uom': line.uom,
'material_code': line.material_code,
'material_name': line.material_name,
'singet_set_qty': line.singet_set_qty,
'total_set': line.total_set,
'quantity': line.quantity,
'unit_price': line.unit_price,
'total_price': line.total_price,
'phase': self.phase_version+1
# Add other fields to copy here
}) for line in self.deliverables_boq_id.line_ids_installation_kit
]
self.line_ids_fg = [(5, 0, 0)] # Clear existing records
self.line_ids_fg = [
(0, 0, {
'component_id': line.component_id, # Replace 'field1' with the actual field names
'uom': line.uom,
'fg_code': line.fg_code,
'fg_name': line.fg_name,
'singet_set_qty': line.singet_set_qty,
'total_set': line.total_set,
'quantity': line.quantity,
'unit_price': line.unit_price,
'total_price': line.total_price,
'is_spare':line.is_spare,
'phase': self.phase_version+1
# Add other fields to copy here
}) for line in self.deliverables_boq_id.line_ids_fg
]
self.line_ids_sfg = [(5, 0, 0)] # Clear existing records
self.line_ids_sfg = [
(0, 0, {
'component_id': line.component_id, # Replace 'field1' with the actual field names
'uom': line.uom,
'sfg_code': line.sfg_code,
'sfg_name': line.sfg_name,
'singet_set_qty': line.singet_set_qty,
'total_set': line.total_set,
'quantity': line.quantity,
'unit_price': line.unit_price,
'total_price': line.total_price,
'is_spare':line.is_spare,
'phase': self.phase_version+1
# Add other fields to copy here
}) for line in self.deliverables_boq_id.line_ids_sfg
]
self.line_ids_material = [(5, 0, 0)] # Clear existing records
self.line_ids_material = [
(0, 0, {
'component_id': line.component_id, # Replace 'field1' with the actual field names
'uom': line.uom,
'material_code': line.material_code,
'material_name': line.material_name,
'singet_set_qty': line.singet_set_qty,
'total_set': line.total_set,
'quantity': line.quantity,
'unit_price': line.unit_price,
'total_price': line.total_price,
'is_spare':line.is_spare,
'phase': self.phase_version+1
# Add other fields to copy here
}) for line in self.deliverables_boq_id.line_ids_material
]
self.line_ids_miscellaneous = [(5, 0, 0)] # Clear existing records
self.line_ids_miscellaneous = [
(0, 0, {
'name': line.name, # Replace 'field1' with the actual field names
'cost': line.cost,
'quantity': line.quantity,
'total_price': line.total_price,
'phase': self.phase_version+1
# Add other fields to copy here
}) for line in self.deliverables_boq_id.line_ids_miscellaneous
]
def action_clear_approval(self):
for record in self:
related_task_model = self.env['sos_dock_audit_transaction']
related_task_model.create({
'ref_id': record.id,
'dock_audit_no': record.dock_audit_no,
'phase_version': record.phase_version,
'audited_by_image': record.audited_by_image,
'audited_on': record.audited_on,
'audited_by_name': record.audited_by_name.id if record.audited_by_name else False,
'qa_by_image': record.qa_by_image,
'qa_tested_on': record.qa_tested_on,
'qa_by_name': record.qa_by_name.id if record.qa_by_name else False,
'ce_image': record.ce_image,
'ce_approved_on': record.ce_approved_on,
'ce_name': record.ce_name.id if record.qa_by_name else False,
'accounts_approved_by_image': record.accounts_approved_by_image,
'accounts_approved_on': record.accounts_approved_on,
'accounts_approved_name': record.accounts_approved_name.id if record.qa_by_name else False,
'top_management_approval_image': record.top_management_approval_image,
'top_management_approved_on': record.top_management_approved_on,
'top_management_name': record.top_management_name.id if record.qa_by_name else False,
})
record.write({
#'phase_version': record.phase_version+1,
'audited_by_image': False,
'audited_on': False,
'audited_by_name': False,
'qa_by_image': False,
'qa_tested_on': False,
'qa_by_name': False,
'ce_image': False,
'ce_approved_on': False,
'ce_name': False,
'accounts_approved_by_image': False,
'accounts_approved_on': False,
'accounts_approved_name': False,
'top_management_approval_image': False,
'top_management_approved_on': False,
'top_management_name': False,
'status': 'open'
})
#task_id = 5 # Just an example, this ID would typically come from somewhere (a field or context)
def action_report_dock_audit_btn(self):
try:
# filtered_recordfg = self.env['sos_dock_audit_line_fg'].search([
# ('phase', 'ilike', '1'),
# ('ref_id', 'in', self.ids) # Restrict to current records, if needed
# ])
#for line in filtered_recordfg:
# print(f" Filtered_recordfg : {line.component_id.display_name} ")
# filtered_recordsfg = self.env['sos_dock_audit_line_sfg'].search([
# ('phase', 'ilike', '1,2'),
# ('ref_id', 'in', self.ids) # Restrict to current records, if needed
# ])
action = self.env.ref("sos_inventory.action_report_dock_audit").report_action(self)
return action
except ValueError as e:
print(f"Failed to find report action: {e}")
def action_open_audit_report_wizard(self):
self.ensure_one()
if self.phase_version <= 0:
raise UserError("Phase version is zero. Please complete one phase before going for report.")
#print(f" {self.phase_version} : LLLL : {self.dock_audit_no}")
return {
'name': 'Dock Audit Report',
'type': 'ir.actions.act_window',
'res_model': 'dock.audit.report',
'view_mode': 'form',
'target': 'new',
'context': {
'default_dock_audit_id': self.dock_audit_no,
#'default_phase': ','.join(map(str, int_array)),
'phase': self.phase_version,
}
}
class sos_dock_audit_Line_Material(models.Model):
_name = 'sos_dock_audit_line_material'
_description = 'Material Lines'
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
is_spare = fields.Boolean(string="Spare")
phase = fields.Char(string="Phase",readonly=True)
total_phase_count = fields.Char(string="Aggregate Phase")
@api.onchange('component_id')
def _onchange_component_id(self):
"""
Set the initial value of `unit_price` when `component_id` is changed.
"""
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = record.unit_price * record.quantity
@api.model
def create(self, vals):
#print(f" First line in create ")
#component_id = vals.get('component_id')
ref_id = vals.get('ref_id')
#sequence_util = self.env['sos_common_scripts']
# if component_id and ref_id:
# # Search for an existing line with the same component_id and ref_id
# existing = self.search([
# ('component_id', '=', component_id),
# ('ref_id', '=', ref_id)
# ], limit=1)
# if existing:
# # Merge logic: add quantities
# existing.singet_set_qty += vals.get('singet_set_qty', 1)
# #existing.total_set += vals.get('total_set', 1)
# previousval = 0
# if vals.get('ref_id'):
# parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
# existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1)
# previousval = sequence_util.extract_value(existing.total_phase_count)
# if existing.total_phase_count:
# #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set)
# existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval))
# else:
# existing.total_phase_count = str(existing.singet_set_qty * existing.total_set)
# # quantity and total_price are computed, so they'll auto update
# return existing
#print(f"Initial : singet {vals.get('singet_set_qty', 1)}")
#print(f"Initial : total {vals.get('total_set', 1)}")
singleset = vals.get('singet_set_qty', 1)
total_set = vals.get('total_set', 1)
#print(f" singleset : {singleset}")
#print(f" totalset : {total_set}")
# If no match found, continue with normal creation
if vals.get('ref_id'):
parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
vals['phase'] = (parent.phase_version + 1) or 0
#vals['total_phase_count'] = singleset * total_set
vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set)
return super(sos_dock_audit_Line_Material, self).create(vals)
class sos_dock_audit_Line_sfg(models.Model):
_name = 'sos_dock_audit_line_sfg'
_description = 'SFG Order Lines'
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
currency_id = fields.Many2one('res.currency', string='Currency')
component_id = fields.Many2one('sos_sfg', string="SFG Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
sfg_code = fields.Char(related="component_id.sfg_code",string="SFG Code")
sfg_name = fields.Char(related="component_id.name",string="SFG Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price")
assembling_charges = fields.Monetary(string="Assembling cost per unit")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
is_spare = fields.Boolean(string="Spare")
phase = fields.Char(string="Phase",readonly=True) # ,readonly=True
total_phase_count = fields.Char(string="Aggregate Phase")
@api.onchange('component_id')
def _onchange_component_id(self):
"""
Set the initial value of `unit_price` when `component_id` is changed.
"""
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
record.assembling_charges = record.component_id.assembling_charges
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = (record.unit_price + record.assembling_charges) * record.quantity
@api.model
def create(self, vals):
#print(f" First line in create ")
#component_id = vals.get('component_id')
ref_id = vals.get('ref_id')
#sequence_util = self.env['sos_common_scripts']
# if component_id and ref_id:
# # Search for an existing line with the same component_id and ref_id
# existing = self.search([
# ('component_id', '=', component_id),
# ('ref_id', '=', ref_id)
# ], limit=1)
# if existing:
# # Merge logic: add quantities
# existing.singet_set_qty += vals.get('singet_set_qty', 1)
# #existing.total_set += vals.get('total_set', 1)
# previousval = 0
# if vals.get('ref_id'):
# parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
# existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1)
# previousval = sequence_util.extract_value(existing.total_phase_count)
# if existing.total_phase_count:
# #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set)
# existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval))
# else:
# existing.total_phase_count = str(existing.singet_set_qty * existing.total_set)
# # quantity and total_price are computed, so they'll auto update
# return existing
singleset = vals.get('singet_set_qty', 1)
total_set = vals.get('total_set', 1)
# If no match found, continue with normal creation
if vals.get('ref_id'):
parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
vals['phase'] = (parent.phase_version + 1) or 0
#vals['total_phase_count'] = singleset * total_set
vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set)
return super(sos_dock_audit_Line_sfg, self).create(vals)
class sos_dock_audit_Line_fg(models.Model):
_name = 'sos_dock_audit_line_fg'
_description = 'FG Order Lines'
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
currency_id = fields.Many2one('res.currency', string='Currency')
component_id = fields.Many2one('sos_fg',string="FG Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
fg_code = fields.Char(related="component_id.fg_code",string="FG Code")
fg_name = fields.Char(related="component_id.name",string="FG Name")
fg_display_name = fields.Char(related="component_id.display_name",string="FG Display Name")
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise", store=True)
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
is_spare = fields.Boolean(string="Spare")
matched_line = fields.Boolean(default=False)
phase = fields.Char(string="Phase",readonly=True) # ,readonly=True default=lambda self: self._get_phase_version_default() ,compute="_compute_phase" ,default=lambda self: self._compute_phase()
total_phase_count = fields.Char(string="Phase Wise Quantity")
#current_phase_value = fields.Char(compute="_compute_current_phase_value")
# @api.depends('total_phase_count')
# def _compute_current_phase_value(self):
# current_phase = self.env.context.get('current_phase')
# for line in self:
# line.current_phase_value = ''
# if current_phase and line.total_phase_count:
# for entry in line.total_phase_count.split(','):
# if entry.startswith(f'P{current_phase}-'):
# line.current_phase_value = entry
# break
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = record.unit_price * record.quantity
@api.model
def create(self, vals):
#component_id = vals.get('component_id')
ref_id = vals.get('ref_id')
#sequence_util = self.env['sos_common_scripts']
# if component_id and ref_id:
# # Search for an existing line with the same component_id and ref_id
# existing = self.search([
# ('component_id', '=', component_id),
# ('ref_id', '=', ref_id)
# ], limit=1)
##if existing:
# # Merge logic: add quantities
# existing.singet_set_qty += vals.get('singet_set_qty', 1)
# #existing.total_set += vals.get('total_set', 1)
## previousval = 0
## if vals.get('ref_id'):
## parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
# existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1)
## previousval = sequence_util.extract_value(existing.total_phase_count)
## if existing.total_phase_count:
# #print(f" TT :: {existing.total_phase_count} ")
## existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval))
# else:
# existing.total_phase_count = "P"+str(existing.phase)+"-"+str(existing.singet_set_qty * existing.total_set)
# # quantity and total_price are computed, so they'll auto update
#return existing
singleset = vals.get('singet_set_qty', 1)
total_set = vals.get('total_set', 1)
# data = "P3-1,P4-4"
# # Step 1: Split by comma to get individual items
# items = data.split(',')
# # Step 2: Split each item by hyphen
# split_data = [item.split('-') for item in items]
# print(f" {split_data} : split_data : {items[len(items)-2]}")
# If no match found, continue with normal creation
if vals.get('ref_id'):
#print(f"if vals ")
parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
vals['phase'] = (parent.phase_version + 1) or 0
vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set)
return super(sos_dock_audit_Line_fg, self).create(vals)
class sos_dock_audit_MiscellaneousCost(models.Model):
_name = 'sos_dock_audit_miscellaneous_items'
_description = 'Miscellaneous Items'
ref_id = fields.Many2one('sos_dock_audit', string="Miscellaneous", ondelete="cascade")
name = fields.Char(string='Name')
cost = fields.Float(string='Cost')
quantity = fields.Integer(string="Quantity")
currency_id = fields.Many2one('res.currency', string='Currency')
total_price = fields.Monetary(string="Total", currency_field='currency_id',compute="_compute_total_price")
phase = fields.Char(string="Phase", readonly=True) # , default=lambda self: self._phase_value()
#total_phase_count = fields.Char(string="Aggregate Phase")
@api.model
def create(self, vals):
ref_id = vals.get('ref_id')
if ref_id:
parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
vals['phase'] = (parent.phase_version+1) or 0
return super().create(vals)
@api.depends('cost','quantity')
def _compute_total_price(self):
#self.phase_version = (self.ref_id.phase_version+1)
for record in self:
record.total_price = record.cost * record.quantity
class sos_dock_audit_Material_installationkit(models.Model):
_name = 'sos_dock_audit_line_material_installation'
_description = 'Installation Kit Lines'
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",readonly=False)
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
phase = fields.Char(string="Phase",readonly=True)
total_phase_count = fields.Char(string="Aggregate Phase")
@api.onchange('component_id')
def _onchange_component_id(self):
"""
Set the initial value of `unit_price` when `component_id` is changed.
"""
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = record.unit_price * record.quantity
@api.model
def create(self, vals):
#component_id = vals.get('component_id')
ref_id = vals.get('ref_id')
#sequence_util = self.env['sos_common_scripts']
# if component_id and ref_id:
# # Search for an existing line with the same component_id and ref_id
# existing = self.search([
# ('component_id', '=', component_id),
# ('ref_id', '=', ref_id)
# ], limit=1)
# if existing:
# # Merge logic: add quantities
# existing.singet_set_qty += vals.get('singet_set_qty', 1)
# #existing.total_set += vals.get('total_set', 1)
# previousval = 0
# if vals.get('ref_id'):
# parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
# existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1)
# #print(f" Total_phase_count :{existing.total_phase_count}")
# #print(f" Extract Value :{self.extract_value(existing.total_phase_count)}")
# previousval = sequence_util.extract_value(existing.total_phase_count)
# #print(f" : previousval : {previousval}")
# if existing.total_phase_count:
# #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set)
# #print(f" Total Count : {existing.singet_set_qty * existing.total_set}")
# existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval))
# else:
# existing.total_phase_count = str(existing.singet_set_qty * existing.total_set)
# # quantity and total_price are computed, so they'll auto update
# return existing
singleset = vals.get('singet_set_qty', 1)
total_set = vals.get('total_set', 1)
# If no match found, continue with normal creation
if vals.get('ref_id'):
parent = self.env['sos_dock_audit'].browse(vals['ref_id'])
vals['phase'] = (parent.phase_version + 1) or 0
#vals['total_phase_count'] = singleset * total_set
vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set)
return super(sos_dock_audit_Material_installationkit, self).create(vals)
class SOS_Design_Verification(models.Model):
_name = 'sos_design_verification'
_description = 'Design Verification'
ref_id = fields.Many2one('sos_dock_audit')
name = fields.Char(string="Name")
remarks = fields.Text(string="Remarks")
class SOS_Dock_Audit_Transaction(models.Model):
_name = 'sos_dock_audit_transaction'
_description = 'Dock Audit Transaction'
ref_id = fields.Many2one('sos_dock_audit')
dock_audit_no = fields.Char(string="Dock Audit No")
phase_version = fields.Integer(string="Phase")
audited_by_image = fields.Image(related="audited_by_name.signature_image",string='Audited by Sign',readonly=True)
audited_on = fields.Datetime(string="Audited On")
audited_by_name = fields.Many2one('res.users', string='Audited by')
qa_by_image = fields.Image(related="qa_by_name.signature_image",string='QA by Sign',readonly=True)
qa_tested_on = fields.Datetime(string="Tested On")
qa_by_name = fields.Many2one('res.users', string='QA Sign')
ce_image = fields.Image(related="ce_name.signature_image",string='CE Sign',readonly=True)
ce_approved_on = fields.Datetime(string="Approved On")
ce_name = fields.Many2one('res.users', string='CE')
accounts_approved_by_image = fields.Image(related="accounts_approved_name.signature_image",string='Accounts Sign',readonly=True)
accounts_approved_on = fields.Datetime(string="Accounts Approved On")
accounts_approved_name = fields.Many2one('res.users', string='Accounts Sign')
top_management_approval_image = fields.Image(related="top_management_name.signature_image",string='Top Management Approval',readonly=True)
top_management_approved_on = fields.Datetime(string="Approved On")
top_management_name = fields.Many2one('res.users', string='Top Management Approver')