320 lines
15 KiB
Python
Executable File
320 lines
15 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, fields, api
|
|
import re
|
|
|
|
class sos__dc(models.Model):
|
|
_name = 'sos_dc'
|
|
_description = 'Delivery Challan'
|
|
_rec_name = 'dc_no'
|
|
_order = 'id desc'
|
|
|
|
def _default_invoicing_address(self):
|
|
html_content = self.env.company.company_details
|
|
if not isinstance(html_content, str):
|
|
html_content = str(html_content)
|
|
clean_text = re.sub(r'</p>', '\n', html_content)
|
|
clean_text = re.sub(r'<[^>]+>', '', clean_text)
|
|
lines = clean_text.split('\n')
|
|
for line in lines:
|
|
if line.strip():
|
|
line.strip()
|
|
return clean_text
|
|
|
|
|
|
|
|
dc_no = fields.Char(string="D.C No", readonly= True, required= True, default=lambda self: self._generate_id())
|
|
dock_audit_no = fields.Many2one('sos_dock_audit',string="Fill Challan against Dock Audit")
|
|
dc_date = fields.Datetime(string="D.C Date",required=True)
|
|
dispatch_mode=fields.Selection([('By Courier', 'By Courier'),('By Hand', 'By Hand'),('By Direct Delivery', 'By Direct Delivery')],string="Mode of Dispatch")
|
|
from_station = fields.Char(string="From Station",default="Sosaley Technologies Private Limited,Chennai")
|
|
to_station = fields.Char(string="To Station")
|
|
sosaley_gst_no = fields.Char(string="Sosaley GST No",default="33AACCJ0045R1ZI")
|
|
customer_gst_no = fields.Char(string="Customer GST No")
|
|
purpose = fields.Char(string="Remarks")
|
|
purpose_remarks=fields.Selection([('Outsourcing', 'Outsourcing'),('Sales', 'Sales'),('I&C / Service', 'I&C / Service'),('Demo', 'Demo'),('Validation', 'Validation'),('Warranty', 'Warranty')],string="Purpose")
|
|
indent_no = fields.Many2one('sos_fg_plan', string='Ref No')
|
|
po_no = fields.Char(string="PO No")
|
|
invoice_no = fields.Char(string="Invoice No")
|
|
carried_by = fields.Many2one('res.users', string='Carried By')
|
|
billing_address = fields.Text(string="Billing Address")
|
|
to_address = fields.Text(string="Shipping Address")
|
|
approval_name = fields.Many2one('res.users', string='Prepared By')
|
|
approval_image = fields.Image(related="approval_name.signature_image",string='Authorised Signatory',readonly=True)
|
|
approved_on = fields.Datetime(string="Approved On")
|
|
line_ids = fields.One2many('sos_dc_line', 'dc_id')
|
|
line_ids_miscellaneous = fields.One2many('sos_dc_line_miscellaneous', 'dc_id')
|
|
line_ids_materials = fields.One2many('sos_dc_line_material', 'dc_id')
|
|
line_ids_sfg = fields.One2many('sos_dc_line_sfg', 'dc_id')
|
|
line_ids_fg = fields.One2many('sos_dc_line_fg', 'dc_id')
|
|
dc_type = fields.Selection([ ('others', 'Others'),('out_souce_return', 'Outsourcing / Returnable'),('out_souce_noreturn', 'Outsourcing / Non-Returnable'),('customer_return', 'Customer / Returnable'),('customer_noreturn', 'Customer / Non-Returnable')], default='customer_return' , string="Type")
|
|
wo_no = fields.Many2one('sos_wo', string="W.O No", domain="[('wo_status', '=', 'open')]")
|
|
auto_load_sfg_items = fields.Many2many('sos_sfg', string='SFG Name')
|
|
auto_load_sfg_items_domain = fields.Char(compute='_compute_auto_load_sfg_items_domain')
|
|
order_qty = fields.Integer(string="Order Quantity",default=1)
|
|
service_provider_name = fields.Many2one('sos_service_providers',string="Service Provider Name")
|
|
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")
|
|
dept_in_charge_name = fields.Many2one('res.users', string='Department In-Charge')
|
|
dept_in_charge_image = fields.Image(related="dept_in_charge_name.signature_image",string='Department In-Charge Sign',readonly=True)
|
|
dept_in_charge_approved_on = fields.Datetime(string="Approved On")
|
|
remarks = fields.Text(string="Remarks")
|
|
courier = fields.Char(string="Courier Name")
|
|
lr_no = fields.Char(string="LR No")
|
|
@api.onchange('dock_audit_no')
|
|
def _onchange_dock_audit_no(self):
|
|
if self.dock_audit_no:
|
|
self.billing_address = self.dock_audit_no.billing_address
|
|
self.to_address = self.dock_audit_no.shipping_address
|
|
self.po_no = self.dock_audit_no.customer_po_no
|
|
self.purpose = self.dock_audit_no.purpose
|
|
self.invoice_no = self.dock_audit_no.invoice_no
|
|
self.customer_gst_no = self.dock_audit_no.gst_no
|
|
self.line_ids_materials = [(5, 0, 0)]
|
|
self.line_ids_materials = [
|
|
(0, 0, {
|
|
'component_id': line.component_id,
|
|
'uom': line.uom,
|
|
'qty': line.quantity
|
|
}) for line in self.dock_audit_no.line_ids_material
|
|
]
|
|
self.line_ids_materials = [
|
|
(0, 0, {
|
|
'component_id': line.component_id,
|
|
'uom': line.uom,
|
|
'qty': line.quantity
|
|
}) for line in self.dock_audit_no.line_ids_installation_kit
|
|
]
|
|
self.line_ids_sfg = [(5, 0, 0)]
|
|
self.line_ids_sfg = [
|
|
(0, 0, {
|
|
'component_id': line.component_id,
|
|
'uom': line.uom,
|
|
'qty': line.quantity
|
|
}) for line in self.dock_audit_no.line_ids_sfg
|
|
]
|
|
self.line_ids_fg = [(5, 0, 0)]
|
|
self.line_ids_fg = [
|
|
(0, 0, {
|
|
'component_id': line.component_id,
|
|
'uom': line.uom,
|
|
'qty': line.quantity
|
|
}) for line in self.dock_audit_no.line_ids_fg
|
|
]
|
|
self.line_ids_miscellaneous = [(5, 0, 0)]
|
|
self.line_ids_miscellaneous = [
|
|
(0, 0, {
|
|
'description': line.name,
|
|
'qty': line.quantity
|
|
}) for line in self.dock_audit_no.line_ids_miscellaneous
|
|
]
|
|
|
|
@api.onchange('service_provider_name')
|
|
def _onchange_service_provider_name(self):
|
|
if self.service_provider_name and (self.dc_type == 'out_souce_return' or self.dc_type == 'out_souce_noreturn'):
|
|
if self.service_provider_name.address:
|
|
self.to_address = self.service_provider_name.address
|
|
self.to_station = self.service_provider_name.service_provider_name
|
|
else:
|
|
self.to_address = False
|
|
self.to_station = False
|
|
else:
|
|
self.to_address = False
|
|
self.to_station = False
|
|
@api.onchange('order_qty')
|
|
def _onchange_order_qty(self):
|
|
if self.auto_load_sfg_items:
|
|
self.line_ids = [(5, 0, 0)]
|
|
|
|
for sfg_item in self.auto_load_sfg_items:
|
|
sfg_record = self.env['sos_sfg_bom'].search([('name', '=', sfg_item.name)], limit=1)
|
|
|
|
if sfg_record:
|
|
sfg_materials = self.env['sos_sfg_bom_line'].search([('bom_id', '=', sfg_record.id)])
|
|
|
|
material_lines = []
|
|
for material in sfg_materials:
|
|
line_vals = {
|
|
'component_id': material.primary_component_id.id,
|
|
'uom': material.primary_component_id.uom,
|
|
'req_qty': material.quantity * self.order_qty,
|
|
'given_qty': material.quantity * self.order_qty,
|
|
'uom': 'Nos'
|
|
}
|
|
material_lines.append((0, 0, line_vals))
|
|
|
|
self.line_ids = material_lines
|
|
else:
|
|
print(f"No matching BOM found for the selected SFG item: {sfg_item.name}")
|
|
|
|
@api.depends('wo_no')
|
|
def _compute_auto_load_sfg_items_domain(self):
|
|
for record in self:
|
|
if record.wo_no:
|
|
component_ids = record.wo_no.line_ids.mapped('component_id.id')
|
|
record.auto_load_sfg_items_domain = [('id', 'in', component_ids)]
|
|
else:
|
|
record.auto_load_sfg_items_domain = []
|
|
|
|
@api.onchange('auto_load_sfg_items')
|
|
def _onchange_auto_load_sfg_items(self):
|
|
if self.auto_load_sfg_items:
|
|
# Clear existing lines first
|
|
self.line_ids = [(5, 0, 0)] # This clears the existing lines
|
|
|
|
# Loop through each selected item in the Many2many field
|
|
for sfg_item in self.auto_load_sfg_items:
|
|
# Search for the SFG record
|
|
sfg_record = self.env['sos_sfg_bom'].search([('name', '=', sfg_item.name)], limit=1)
|
|
|
|
if sfg_record:
|
|
# Get all materials related to the selected SFG
|
|
sfg_materials = self.env['sos_sfg_bom_line'].search([('bom_id', '=', sfg_record.id)])
|
|
|
|
# Loop through the materials and prepare the data
|
|
material_lines = []
|
|
for material in sfg_materials:
|
|
line_vals = {
|
|
'component_id': material.primary_component_id.id,
|
|
'uom': material.primary_component_id.uom, # Ensure the UOM field is correctly referenced
|
|
'req_qty': material.quantity,
|
|
'given_qty': material.quantity,
|
|
'uom': 'Nos' # Update UOM if needed
|
|
}
|
|
# Append the material lines as a tuple (0, 0, line_vals)
|
|
material_lines.append((0, 0, line_vals))
|
|
|
|
# Assign the new lines to the line_ids field
|
|
self.line_ids = material_lines
|
|
else:
|
|
print(f"No matching BOM found for the selected SFG item: {sfg_item.name}")
|
|
|
|
def _generate_id(self):
|
|
sequence_util = self.env['sos_common_scripts']
|
|
return sequence_util.generate_sequence('sos_dc','DC', 'dc_no')
|
|
|
|
def action_report_dc_btn(self):
|
|
try:
|
|
action = self.env.ref("sos_inventory.action_report_dc").report_action(self)
|
|
return action
|
|
except ValueError as e:
|
|
print(f"Failed to find report action: {e}")
|
|
|
|
def approved_by_sign_btn(self):
|
|
# Email part
|
|
body_html = f"""
|
|
<p>Below <b>DC</b> is waiting for your Approval</p>
|
|
"""
|
|
subject = f"Delivery Challan Approval Request - {self.dc_no}"
|
|
sequence_util = self.env['sos_common_scripts']
|
|
sequence_util.send_mon_min_email(self.env,"sos_dc",self.id,"deenalaura.m@sosaley.in",subject,body_html,"user")
|
|
sequence_util.action_assign_signature(
|
|
self,
|
|
'approval_name',
|
|
'approved_on'
|
|
)
|
|
def deptincharge_sign_btn(self):
|
|
# Email part
|
|
body_html = f"""
|
|
<p>Below <b>DC</b> is waiting for your Approval</p>
|
|
"""
|
|
subject = f"Delivery Challan Approval Request - {self.dc_no}"
|
|
send_email = self.env['sos_common_scripts']
|
|
send_email.send_direct_email(self.env,"sos_dc",self.id,"ramachandran.r@sosaley.com",subject,body_html)
|
|
# Email part ends
|
|
sequence_util = self.env['sos_common_scripts']
|
|
sequence_util.action_assign_signature(
|
|
self,
|
|
'dept_in_charge_name',
|
|
'dept_in_charge_approved_on'
|
|
)
|
|
|
|
def action_top_esign(self):
|
|
if self.wo_no:
|
|
sos_dc_record = self.env['sos_wo'].search([('id', '=', self.wo_no.id)], limit=1)
|
|
if sos_dc_record:
|
|
sos_dc_record.write({'dc_no': self.id})
|
|
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'
|
|
)
|
|
# Email part
|
|
body_html = f"""
|
|
<p>Below <b>DC</b> was Approved</p>
|
|
"""
|
|
|
|
send_email = self.env['sos_common_scripts']
|
|
send_email.send_direct_email(self.env,"sos_dc",self.id,self.approval_name.login,"Delivery Challan Approved",body_html)
|
|
# Email part ends
|
|
class DC_Line(models.Model):
|
|
_name = 'sos_dc_line'
|
|
_description = 'DC Lines'
|
|
|
|
dc_id = fields.Many2one('sos_dc', ondelete="cascade")
|
|
description = fields.Char(string="Description")
|
|
qty = fields.Integer(string="Quantity")
|
|
uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips'), ('Packs', 'Packs')], string="Uom", default='Nos')
|
|
component_id = fields.Many2one('sos_material', string="Material Part No")
|
|
req_qty = fields.Integer(string="Required Quantity")
|
|
given_qty = fields.Integer(string="Given Quantity")
|
|
display_name = fields.Char(string="Material Name", compute="_compute_display_name", store=True)
|
|
|
|
@api.depends('component_id')
|
|
def _compute_display_name(self):
|
|
for record in self:
|
|
if record.component_id:
|
|
record.display_name = record.component_id.name or record.component_id.part_no
|
|
else:
|
|
record.display_name = False # or an empty string ''
|
|
|
|
class DC_Line_miscellaneous(models.Model):
|
|
_name = 'sos_dc_line_miscellaneous'
|
|
_description = 'DC Lines Miscellaneous'
|
|
|
|
dc_id = fields.Many2one('sos_dc', ondelete="cascade")
|
|
description = fields.Char(string="Description")
|
|
qty = fields.Integer(string="Quantity")
|
|
uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips')], string="Uom", default='Nos')
|
|
|
|
class DC_Line_Materials(models.Model):
|
|
_name = 'sos_dc_line_material'
|
|
_description = 'DC Lines Material'
|
|
|
|
dc_id = fields.Many2one('sos_dc', ondelete="cascade")
|
|
qty = fields.Integer(string="Quantity")
|
|
uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips')], string="Uom", default='Nos')
|
|
component_id = fields.Many2one('sos_material', string="Material Part No")
|
|
display_name = fields.Char(string="Material Name", compute="_compute_display_name", store=True)
|
|
|
|
|
|
@api.depends('component_id')
|
|
def _compute_display_name(self):
|
|
for record in self:
|
|
if record.component_id:
|
|
record.display_name = record.component_id.name or record.component_id.part_no
|
|
else:
|
|
record.display_name = False # or an empty string ''
|
|
|
|
class DC_Line_SFG(models.Model):
|
|
_name = 'sos_dc_line_sfg'
|
|
_description = 'DC Lines SFG'
|
|
|
|
dc_id = fields.Many2one('sos_dc', ondelete="cascade")
|
|
qty = fields.Integer(string="Quantity")
|
|
uom = fields.Selection([('Nos', 'Nos'),('set', 'Set')], string="Uom", default='Nos')
|
|
component_id = fields.Many2one('sos_sfg', string="SFG Name")
|
|
|
|
class DC_Line_FG(models.Model):
|
|
_name = 'sos_dc_line_fg'
|
|
_description = 'DC Lines FG'
|
|
|
|
dc_id = fields.Many2one('sos_dc', ondelete="cascade")
|
|
qty = fields.Integer(string="Quantity")
|
|
uom = fields.Selection([('Nos', 'Nos'),('set', 'Set')], string="Uom", default='Nos')
|
|
component_id = fields.Many2one('sos_fg', string="FG Name")
|
|
serial_no = fields.Char(string="Serial No")
|