How to assign Float type field to a Char type field in odoo 15? - odoo-15

Full Code:
from odoo import fields, models, api
class ExtraWeight(models.Model):
_name = 'courier.extra.weights'
_description = 'Charge setting for Extra Weight'
_rec_name = 'combination'
extra_weight = fields.Float(string='Next (KG)', required=True, translate=True)
extra_charge = fields.Float(string='Charge for next Weight (TK)', required=True, translate=True)
max_weight = fields.Float(string='Max Wight (KG)', required=True, translate=True)
combination = fields.Char('Combination', compute='_compute_fields_combination')
#api.depends('extra_weight', 'extra_charge')
def _compute_fields_combination(self):
for record in self:
record.combination = 'Extra Increment:' + str(record.extra_weight) + '(KG) Rate' + str(record.extra_charge) + '(TK) Max:'+str(record.max_weight)+'(KG)'
I want to set 'Extra Increment:' + str(record.extra_weight) + '(KG) Rate' + str(record.extra_charge) + '(TK) Max:'+str(record.max_weight)+'(KG)' to combination. But I am getting the following error:
COALESCE types text and double precision cannot be matched
LINE 1: ...CE("courier_extra_weights__extra_weight"."value", "courier_e..

Your code looks good to me. It seems Char is not suitable as per your output length. Replace field type from Char to Text

Related

I am trying to fetch the product line of custom module in product line of invoice module in odoo 15

I have inherited account.move model and added job_card_id field(many2one) in it, as shown as below :
Image
Below given is Image of Selected Job Card :
Image
Below given is code of my model and I also tried creating function below fields :
class JobCard(models.Model):
_name = "job.card"
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Job Card Master"
_rec_name = 'job_card_number'
job_card_number = fields.Char(string='Job Card No.', readonly=True)
customer_id = fields.Many2one('res.partner', string="Customer Name", tracking=True)
vehicle_id = fields.Many2one('res.partner.line', string="Vehicle", tracking=True,
domain="[('x_customer_id','=',customer_id)]")
date_time_of_invoice = fields.Datetime(string='Date & Time of Invoice', tracking=True, default=fields.Datetime.now)
start_date_time = fields.Datetime(string='Start Date & Time', tracking=True)
end_date_time = fields.Datetime(string='End Date & Time', tracking=True)
priority = fields.Selection([
('0', 'Normal'),
('1', 'Low'),
('2', 'High'),
('3', 'Very High')], string="Priority") # priority widget
state = fields.Selection([
('draft', 'Draft'),
('in_progress', 'In Progress'),
('done', 'Done'),
('cancel', 'Cancelled')], string="Status", default='draft', required=True) # status bar
active = fields.Boolean(string="Active", default=True, tracking=True)
x_product_ids = fields.Many2many('job.card.line', 'product_id', string="Job Card Details")
x_quantity_ids = fields.One2many('job.card.line', 'quantity', string="Job Card Details")
x_price_ids = fields.One2many('job.card.line', 'price', string="Job Card Details")
x_total_ids = fields.One2many('job.card.line', 'total', string="Job Card Details")
x_employee_ids = fields.One2many('job.card.line', 'employee_id', string="Job Card Details")
x_job_card_ids = fields.One2many('job.card.line', 'job_card_id', string="Job Card Details")
job_card_count = fields.Integer(compute='compute_job_card_count', string='Job Card Count')
def get_invoice_line_vals(self):
vals_list = []
for job_card_line in self.x_product_ids:
vals_list.append({
' price_unit': job_card_line.price_unit,
'quantity': job_card_line.quantity
})
return vals_list
Below given is code of inherited model and also added onchange function :
class CustomInvoice(models.Model):
_inherit = "account.move"
job_card_id = fields.Many2one('job.card', string="Job Card", domain="[('customer_id','=',partner_id)]",
tracking=True)
#api.onchange('job_card_id')
def _onchange_job_card_id(self):
# creates your invoice lines vals according to your values
invoice_lines_vals = self.job_card_id.get_invoice_line_vals()
self.update({'invoice_line_ids': [(5, 0)] + [(0, 0, vals) for vals in invoice_lines_vals]})
Below given is code of my job card line :
class JobCardLine(models.Model):
_name = "job.card.line"
job_card_id = fields.Many2one('job.card', string="Job Card Id", tracking=True)
product_id = fields.Many2one('product.template', string="Product", tracking=True)
quantity = fields.Integer(string="Quantity", tracking=True)
# price = fields.Char(string="Price")
price = fields.Float(string="Price")
total = fields.Integer(string='Total', compute='_compute_total', tracking=True,
help="This field will be calculated from quantity and price !")
employee_id = fields.Many2one('hr.employee', string="Employee", tracking=True)
x_job_card_id = fields.Many2one('res.partner', string="Vehicle Details")
#api.onchange('product_id')
def _on_change_product_id(self):
self.price = self.product_id.list_price
#api.depends('quantity', 'price')
def _compute_total(self):
print("self........", self)
for rec in self:
rec.total = rec.quantity * rec.price
Actually I wanted to add product line of selected job card into Invoice product line automatically when I select the job card.
But I am getting error as shown below :
Error
You got that error because you have no field named line_ids in job.card model. Maybe you need to change it to x_product_ids.
The TyprError (int object is not iterable) is caused by the first tuple passed to the write method :
(6, 0, 0)
Odoo expects the third parameter to be iterable. If you need to clear the list, use (5,0)
Avoid calling the write method inside an onchange function. You can read the following danger notice in the official onchange documentation:
DangerSince #onchange returns a recordset of pseudo-records, calling any one of the CRUD methods (create(), read(), write(), unlink()) on the aforementioned recordset is undefined behaviour, as they potentially do not exist in the database yet.Instead, simply set the record’s field like shown in the example above or call the update() method.
Edit:
You have two errors in get_invoice_line_vals function
1/ ValueError:
Invalid field ' price_unit' on model 'account.move.line'
You need to remove the space at the beginning.
2/ AttributeError:
'job.card.line' object has no attribute 'price_unit'.
Use the price field instead.

Get value from a Many2one related model in model create function

I have two models, TextMessage and Device, that are related many TextMessages to one Device.
from odoo import models, fields, api
class Device(models.Model):
_name = 'device'
_description = 'A model for storing all devices'
name = fields.Char()
iden = fields.Char()
model_name = fields.Char()
manufacturer = fields.Char()
push_token = fields.Char()
app_version = fields.Integer()
icon = fields.Char()
has_sms = fields.Char()
text_message_ids = fields.One2many("text_message", "device_id", string="Text Messages")
from odoo import models, fields, api
class TextMessage(models.Model):
_name = 'text_message'
_description = 'Text Messages'
name = fields.Char()
message_text = fields.Text()
pb_response = fields.Text()
target_number = fields.Char()
device_id = fields.Many2one('device', 'Device', required=True)
#api.model
#api.depends("device_id")
def create(self, values):
print("values['device_id']",values["device_id"])
print("self.device_id",self.device_id.iden)
for rec in self.device_id:
print("Device ID",rec.iden)
values['pb_response'] = rec.device_id.iden
return super().create(values)
In the create method of TextMessage, I want to retrieve the value of the iden attribute of the Device model.
The print statements in TextMessage.create print:
values['device_id'] 1
self.device_id False
The print statement in the loop prints nothing.
You can't access self before creating the record so it will be false.
You can write the create method in two ways:
Create the record first and then get the iden value:
#api.model
def create(self, values):
res = super().create(values)
res.pb_response = res.device_id.iden
return res
Or you can get the device_id record from values as below:
#api.model
def create(self, values):
if 'device_id' in values and values.get('device_id',False):
device = self.env['device'].browse(values.get('device_id'))
if device:
values['pb_response'] = device.iden
return super().create(values)
If the pb_response field is the same of the iden field then you can create it as related field to device_id.iden and you will get the iden value automatically once the device-id assigned as below:
pb_response = fields.Char(related="device_id.iden")

How can I convert the total price of an invoice to letters in odoo 11?

I have a created module called 'custom_report_module', where I make a personalized invoice ... The invoice works well but I want to add the total amount in letters .. for example .. if the purchase reached 500,000 that I printed in letters "are: five hundred thousand guaranies "or" are: five hundred thousand "
class account_invoice(models.Model):
_inherit = "account.invoice"
#api.multi
def amount_to_text(self, amount, currency='rupee'):
return amount_to_text(amount, currency)
my xml
<span t-esc="l.amount_to_text(l.price_unit, l.price_unit)"/>
Please have a look at the this code
#api.multi
def amount_to_text(self, amount):
self.ensure_one()
def _num2words(number, lang):
try:
return num2words(number, lang=lang).title()
except NotImplementedError:
return num2words(number, lang='en').title()
if num2words is None:
logging.getLogger(__name__).warning("The library 'num2words' is missing, cannot render textual amounts.")
return ""
formatted = "%.{0}f".format(self.decimal_places) % amount
parts = formatted.partition('.')
integer_value = int(parts[0])
fractional_value = int(parts[2] or 0)
lang_code = self.env.context.get('lang') or self.env.user.lang
lang = self.env['res.lang'].search([('code', '=', lang_code)])
amount_words = tools.ustr('{amt_value} {amt_word}').format(
amt_value=_num2words(integer_value, lang=lang.iso_code),
amt_word=self.currency_unit_label,
)
if not self.is_zero(amount - integer_value):
amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format(
amt_value=_num2words(fractional_value, lang=lang.iso_code),
amt_word=self.currency_subunit_label,
)
return amount_words

Use name_get in odoo 9

How to concatenate Many2one field, open drop down list all car is visible. I need [id] and [name].
For example:
[01] Audi,
[02] BMW
car_id = fields.Many2one('my.cars', 'Cars')
#api.multi
def name_get(self):
???
Try with following:
#api.multi
def name_get(self):
result = []
for record in self:
name = '[' + str(record.id) + ']' + ' ' + record.name
result.append((record.id, name))
return result
Note:
name_get() method must be set on my.cars object.

TypeError: generate_purchase_order() takes exactly 1 argument (5 given)

I am trying to convert openerp 7 code to odoo8. In V7 browse() method had several parameters like self,cr,uid,ids,context but in V8 I think none of these is needed.In my custom module I am trying to create a purchase order based on the information obtained from mrp.I have done a custom calculation for how many Kgs of paper needed for 10000 quantities of books to be manufactured.After calculation this info should go to purchase invoice.Products will be obtained from bill of materials,quantity from no of kgs of paper needed and unit price from product cost attribute.I am unable to solve this error "method takes exactly 1 argument (5 given)"
mrp.py,
from openerp import models
class mrp_production(models.Model):
_inherit = 'mrp.production'
def generate_purchase_order(self,supplier_id,warehouse_id):
purchase_obj = self.env['purchase.order']
purchase_line_obj = self.env['purchase.order.line']
warehouse_obj = self.env['stock.warehouse']
warehouse = warehouse_obj.browse(warehouse_id)
if not warehouse:
return False
if isinstance(warehouse, list):
warehouse = warehouse[0]
for order in self:
vals = {}
vals = purchase_obj.onchange_partner_id()
vals['origin'] = order.name
vals['partner_id'] = supplier_id
vals['warehouse_id'] = warehouse_id
vals['location_id'] = warehouse.lot_stock_id.id
vals['date_order'] = order.date_planned
purchase_id = purchase_obj.create(vals)
for line in self.bom_id.bom_line_ids:
if not line.product_id:
continue
line_vals = purchase_line_obj.onchange_product_id(line.product_id.id,
line.product_uom_qty, line.product_uom.id, supplier_id,
date_planned=line.date_planned)['value']
line_vals['name'] = line.name
line_vals['product_id'] = line.product_id.id
if not line_vals.get('price_unit', False):
line_vals['price_unit'] = line.product_id.list_price
line_vals['product_uom'] = line.product_uom.id
line_vals['product_uom_qty'] = 181.13
line_vals['order_id'] = purchase_id
purchase_line_obj.create(line_vals)
return True
generate_purchase_order.py,
from openerp import models,fields,api
class generate_purchase_order(models.Model):
_name = 'mrp_to_purchase_order.generate_purchase_order'
_description = 'Generate Purchase Order'
partner_id = fields.Many2one('res.partner', 'Supplier', required=True, domain="[('supplier','=',True)]")
warehouse_id = fields.Many2one('stock.warehouse', 'Warehouse', required=True)
#api.multi
def onchange_partner_id(self,partner_id):
return {}
def generate_purchase_order(self):
for wizard in self:
#mrp_order_ids = [context['active_id']]
mrp_obj = self.env['mrp.production']
mrp_obj.generate_purchase_order(wizard.partner_id.id, wizard.warehouse_id.id)
return { 'type': 'ir.actions.act_window_close'}
If you are calling the generate_purchase_order method from some other method in your model, then use the decorator #api.multi for that method.
Also in your generate_purchase_order method, replace
for order in self.browse():
by
for order in self:
EDIT
#api.multi
def generate_purchase_order(self):
for wizard in self:
#mrp_order_ids = [context['active_id']]
mrp_obj = self.env['mrp.production']
# Get the mrp record
mrp_rec = code to get mrp record
mrp_rec.generate_purchase_order(wizard.partner_id.id, wizard.warehouse_id.id)
return { 'type': 'ir.actions.act_window_close'}