from odoo import api, fields, models, _ import logging from datetime import date,datetime _logger = logging.getLogger(__name__) class SOS_SFG_Quote_Generation(models.Model): _name = 'sos_sfg_quote_generation' _description = 'SFG Quote Generation' _rec_name = 'plan_ref_no' plan_ref_no = fields.Char( readonly=True, required=True, string='Plan ID' ) line_ids = fields.One2many('sos_sfg_quote_generation_line', 'plan_id', string='Lines', ondelete='cascade') def action_generate_wo(self): wo_model = self.env['sos_wo'] wo_line_model = self.env['sos_wo_line'] supplier_dict = {} for record in self.line_ids: if record.final_supplier1_name: supplier = record.final_supplier1_name if supplier not in supplier_dict: supplier_dict[supplier] = [] supplier_dict[supplier].append({ 'name': record.material_name, 'product_qty': record.final_supplier1_qty, 'price_unit': record.final_supplier1_quoted_price }) # if record.final_supplier2_name: # supplier = record.final_supplier2_name # if supplier not in supplier_dict: # supplier_dict[supplier] = [] # supplier_dict[supplier].append({ # 'name': record.material_name, # 'product_qty': record.final_supplier2_qty, # 'price_unit': record.final_supplier2_quoted_price # }) # if record.supplier3_name: # supplier = record.supplier3_name # if supplier not in supplier_dict: # supplier_dict[supplier] = [] # supplier_dict[supplier].append({ # 'name': record.material_name, # 'product_qty': record.supplier3_qty, # 'price_unit': record.supplier3_quoted_price # }) for x, y in supplier_dict.items(): sequence_util = self.env['sos_common_scripts'] wo_no = sequence_util.generate_sequence('sos_wo','WO', 'wo_no') wo_record = wo_model.create({ 'wo_no': wo_no, 'wo_date': date.today(),'supplier_name': x.id, 'supplier_gst_no': x.gst_no, 'sarf_no':x.service_provider_code, 'supplier_address': x.address }) for components in y: wo_line_model.create({ 'wo_id': wo_record.id, 'component_id': components['name'].id,'qp':components['name'].qp_no,'hsn_code':components['name'].hsn_code, 'quantity': components['product_qty'],'unit_price': components['price_unit'], 'total_price': components['product_qty'] * components['price_unit'] }) message = 'Work Order(s) successfully generated.' return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': message, 'type': 'success', 'sticky': False } } def action_generate_quotation(self): supplier_materials = {} for item in self.line_ids: for supplier in item.supplier_name: if supplier not in supplier_materials: supplier_materials[supplier] = [] supplier_materials[supplier].append({ 'material_name': item.material_name.id, 'required_qty': item.required_qty }) wizards = [] for supplier, materials in supplier_materials.items(): wizard_lines = [(0, 0, { 'material_name': material['material_name'], 'required_qty': material['required_qty'] }) for material in materials] wizard = self.env['supplier_sfg_quotation_wizard'].create({ 'supplier_id': supplier.id, 'plan_id': self.id, 'line_ids': wizard_lines }) wizards.append(wizard.id) return { 'type': 'ir.actions.act_window', 'name': 'Generate Quotation', 'view_mode': 'tree,form', 'res_model': 'supplier_sfg_quotation_wizard', 'domain': [('id', 'in', wizards)], 'target': 'new', } class SOS_SFG_Quote_Generation_Line(models.Model): _name = 'sos_sfg_quote_generation_line' _description = 'SFG Quote Generation Lines' plan_id = fields.Many2one('sos_sfg_quote_generation', string='Quote Generation', ondelete='cascade') required_qty = fields.Integer(string='Planned Qty') inprogress_qty = fields.Integer(string='In-Progress Qty') purchase_type = fields.Selection([ ('with_materials', 'Materials Provided'), ('without_materials', 'No Materials Provided'), ], string='Purchase Type', required=True, default='without_materials') supplier_name = fields.Many2many('sos_service_providers', string='Supplier', domain="[('id', 'in', suppliers_ids)]") suppliers_ids = fields.Many2many('sos_service_providers', compute='_compute_suppliers_ids', store=False) status = fields.Selection( [ ('open', 'Open'), ('close', 'Closed') ], default='open', string="Status", compute="_compute_from_ir", inverse="_set_status", store=True ) material_name = fields.Many2one('sos_sfg',string="SFG Name") supplier1_name = fields.Many2one('sos_service_providers',string="Service Provider 1") supplier1_quoted_price = fields.Integer(string='Price') supplier1_qty = fields.Integer(string='Qty') supplier2_name = fields.Many2one('sos_service_providers',string="Service Provider 2") supplier2_quoted_price = fields.Integer(string='Price') supplier2_qty = fields.Integer(string='Qty') supplier3_name = fields.Many2one('sos_service_providers',string="Service Provider 3") supplier3_quoted_price = fields.Integer(string='Price') supplier3_qty = fields.Integer(string='Qty') # Supplier Selection final_supplier1_name = fields.Many2one('sos_service_providers',string="Service Provider 1") final_supplier1_quoted_price = fields.Integer(string='Price') final_supplier1_qty = fields.Integer(string='Qty') # final_supplier2_name = fields.Many2one('sos_service_providers',string="Service Provider 2") # final_supplier2_quoted_price = fields.Integer(string='Price') # final_supplier2_qty = fields.Integer(string='Qty') # final_supplier3_name = fields.Many2one('sos_service_providers',string="Service Provider 3") # final_supplier3_quoted_price = fields.Integer(string='Price') # final_supplier3_qty = fields.Integer(string='Qty') best_supplier = fields.Many2one('sos_service_providers', string="Best Deal", compute='_compute_best_supplier', store=True) available_suppliers = fields.Many2many('sos_service_providers', compute='_compute_available_suppliers') remarks = fields.Char(string="Remarks") @api.onchange('required_qty', 'inprogress_qty', 'status') def _onchange_check_inprogress_qty(self): for rec in self: if (rec.inprogress_qty >= rec.required_qty and rec.required_qty != 0) or rec.status == 'close': rec.inprogress_qty = 0 @api.depends('required_qty', 'inprogress_qty') def _compute_from_ir(self): for record in self: if record.inprogress_qty <= 0: record.status = "close" else: record.status = "open" def _set_status(self): for record in self: # Custom logic based on user changes if record.status == 'close': # Perform actions for 'close' pass elif record.status == 'open': # Perform actions for 'open' pass @api.depends('supplier1_name', 'supplier2_name', 'supplier3_name') def _compute_available_suppliers(self): for record in self: suppliers = [] if record.supplier1_name: suppliers.append(record.supplier1_name.id) if record.supplier2_name: suppliers.append(record.supplier2_name.id) if record.supplier3_name: suppliers.append(record.supplier3_name.id) record.available_suppliers = [(6, 0, suppliers)] @api.onchange('final_supplier1_name') def _onchange_final_supplier1_name(self): if self.final_supplier1_name: # Check which supplier is selected and update price and quantity accordingly if self.final_supplier1_name == self.supplier1_name: self.final_supplier1_quoted_price = self.supplier1_quoted_price self.final_supplier1_qty = self.supplier1_qty # elif self.final_supplier1_name == self.supplier2_name: # self.final_supplier1_quoted_price = self.supplier2_quoted_price # self.final_supplier1_qty = self.supplier2_qty # elif self.final_supplier1_name == self.supplier3_name: # self.final_supplier1_quoted_price = self.supplier3_quoted_price # self.final_supplier1_qty = self.supplier3_qty @api.depends('supplier1_quoted_price', 'supplier1_qty', 'supplier2_quoted_price', 'supplier2_qty', 'supplier3_quoted_price', 'supplier3_qty') def _compute_best_supplier(self): for record in self: best_supplier = None best_score = float('inf') suppliers = [ (record.supplier1_name, record.supplier1_quoted_price, record.supplier1_qty), (record.supplier2_name, record.supplier2_quoted_price, record.supplier2_qty), (record.supplier3_name, record.supplier3_quoted_price, record.supplier3_qty) ] final_supplier_qty = 0 final_supplier_price = 0 for supplier, price, qty in suppliers: if supplier: score = price / qty if qty else float('inf') if score < best_score: best_score = score best_supplier = supplier final_supplier_qty = qty final_supplier_price = price record.best_supplier = best_supplier record.final_supplier1_name = best_supplier if best_supplier: record.final_supplier1_qty = final_supplier_qty record.final_supplier1_quoted_price = final_supplier_price @api.onchange('material_name') def _onchange_material_name(self): if self.material_name: supplier_ids = self.material_name.suppliers.ids if supplier_ids: self.suppliers_ids = supplier_ids else: self.suppliers_ids = self.env['sos_service_providers'].search([]).ids else: self.suppliers_ids = self.env['sos_service_providers'].search([]).ids @api.depends('material_name') def _compute_suppliers_ids(self): for record in self: if record.material_name: supplier_ids = record.material_name.service_providers.ids if supplier_ids: record.suppliers_ids = supplier_ids else: record.suppliers_ids = self.env['sos_service_providers'].search([]).ids else: record.suppliers_ids = self.env['sos_service_providers'].search([]).ids