Odoo: Override Integer field in onchange not working whereas Float is changed - WHY? - odoo

I have extended the product.template with following fields:
length = fields.Integer("Length", default=0)
length_float = fields.Float("Float", default=0.0)
Additionally I have extended the product.packaging model with this fields and an onchange method:
product_id_ref = fields.Many2one('product.product', string="Product Reference")
length = fields.Integer('Length')
length_float = fields.Float('Length_Float')
#api.onchange("product_id_ref")
def _onchange_product(self):
if self.product_id_ref:
self.length_float = self.product_id_ref.length_float
self.length = self.product_id_ref.length
Interestingly the FLOAT field length_float is changed as expected and shown in the view. The INTEGER field is not changed.
Something more suprising is that if I change the order of the onchange method
#api.onchange("product_id_ref")
def _onchange_product(self):
if self.product_id_ref:
self.length = self.product_id_ref.length
self.length_float = self.product_id_ref.length_float
NO value is changed!
How could that be?? Does anyone have an idea?
Thanks!

It came out that the problem was the 'length' field itself. This name leads to problems on the javascript side. Renaming leads to the desired result.

Related

How to correct filter fields domain in a model?

I'm getting the following error trying to filter a field by another field value of the same model.
File
"/opt/..../tfutbol/models/partido.py",
line 29, in Partido
figura = fields.Many2one('tfutbol.jugador',domain=[('equipo_id','=',local.id)])
RuntimeError: maximum recursion depth exceeded while calling a Python
object
The line of code trying with the problem is:
figura = fields.Many2one('tfutbol.jugador',domain=[('equipo_id','=',local.id),('equipo_id','=',visitante.id)])
All the relevant code, is above:
class Partido(models.Model):
_name = 'tfutbol.partido'
local = fields.Many2one('tfutbol.equipo')
visitante = fields.Many2one('tfutbol.equipo')
figura = fields.Many2one('tfutbol.jugador',domain=[('equipo_id','=',local.id),('equipo_id','=',visitante.id)])
class Equipo(models.Model):
_name = 'tfutbol.equipo'
name = fields.Char('Nombre')
jugador_ids = fields.One2many('tfutbol.jugador', 'equipo_id', string="Jugadores")
class Jugador(models.Model):
_name = 'tfutbol.jugador'
name = fields.Char('Nombre')
equipo_id = fields.Many2one('tfutbol.equipo')
Thanks for reading!
If you read the docstring on /odoo/fields.py on the Many2one class definition you will see that:
:param domain: an optional domain to set on candidate values on the
client side (domain or string)
That means that you cannot use the dot notation (record.field) to pull in values because this has not been implemented on javascript.
So what you can do to dynamically create a domain like the one you want is:
Create an onchange method that will be invoked every time you set a value on the local and visitante fields and will change the domain on the figura field. For example:
#api.onchange('figura','visitante')
def onchange_method(self):
domain = {}
domain['figura'] = [('equipo_id','=',self.local.id),('equipo_id','=',self.visitante.id)]
return {'domain': domain}
Note: When you do not set an operator in a domain with multiple leafs (parameters) an explicit AND is added, so in your domain you are searching for the equipo_id filed to be equal to self.local.id AND self.visitante.id which will not work, you might want to add an OR like:
['|',('equipo_id','=',self.local.id),('equipo_id','=',self.visitante.id)]

Sales Order Confirmation Report - SalesConfirmDP

I am modifying the SalesConfirmDP class and trying to add the CustVendExternalItem.ExternalItemTxt field into a new field I have created.
I have tried a couple of things but I do not think my syntax was correct i.e I declare the CustVendExternalItem table in the class declaration. But then when I try to insert CustVendExternalItem.ExternalItemTxt into my new field, it does not populate, I guess there must be a method which I need to include?
If anyone has any suggestion it would be highly appreciated.
Thank you in advance.
private void setSalesConfirmDetailsTmp(NoYes _confirmTransOrTaxTrans)
{
DocuRefSearch docuRefSearch;
// Body
salesConfirmTmp.JournalRecId = custConfirmJour.RecId;
if(_confirmTransOrTaxTrans == NoYes::Yes)
{
if (printLineHeader)
{
salesConfirmTmp.LineHeader = custConfirmTrans.LineHeader;
}
else
{
salesConfirmTmp.LineHeader = '';
}
salesConfirmTmp.ItemId = this.itemId();
salesConfirmTmp.Name = custConfirmTrans.Name;
salesConfirmTmp.Qty = custConfirmTrans.Qty;
salesConfirmTmp.SalesUnitTxt = custConfirmTrans.salesUnitTxt();
salesConfirmTmp.SalesPrice = custConfirmTrans.SalesPrice;
salesConfirmTmp.DlvDate = custConfirmTrans.DlvDate;
salesConfirmTmp.DiscPercent = custConfirmTrans.DiscPercent;
salesConfirmTmp.DiscAmount = custConfirmTrans.DiscAmount;
salesConfirmTmp.LineAmount = custConfirmTrans.LineAmount;
salesConfirmTmp.CurrencyCode = custConfirmJour.CurrencyCode;
salesConfirmTmp.PrintCode = custConfirmTrans.TaxWriteCode;
if (pdsCWEnabled)
{
salesConfirmTmp.PdsCWUnitId = custConfirmTrans.pdsCWUnitId();
salesConfirmTmp.PdsCWQty = custConfirmTrans.PdsCWQty;
}
**salesConfirmTmp.ExternalItemText = CustVendExternalItem.ExternalItemTxt;**
if ((custFormletterDocument.DocuOnConfirm == DocuOnFormular::Line)
|| (custFormletterDocument.DocuOnConfirm == DocuOnFormular::All))
{
docuRefSearch = DocuRefSearch::newTypeIdAndRestriction(custConfirmTrans,
custFormletterDocument.DocuTypeConfirm,
DocuRestriction::External);
salesConfirmTmp.Notes = Docu::concatDocuRefNotes(docuRefSearch);
}
salesConfirmTmp.InventDimPrint = this.printDimHistory();
Well, AX cannot guess which record you need, there is a helper class CustVendExternalItemDescription to deal with it:
boolean found;
str externalItemId;
...
[found, externalItemId, salesConfirmTmp.ExternalItemText] = CustVendExternalItemDescription::findExternalItemDescription(
ModuleCustVend::Cust,
custConfirmTrans.ItemId,
custConfirmTrans.inventDim(),
custConfirmJour.OrderAccount,
CustTable::find(custConfirmJour.OrderAccount).CustItemGroupId);
The findExternalItemDescription method returns more information than you need here, but you have to define variables to store it anyway.
Well, the steps to solve this problem are fairly easy and i will try to give you a step by step approach how to solve this problem.
1) Are you initialising CustVendExternalItem properly? Make a record of the same and initialise it as Jan has shown above, then debug your code and see if the value is being initialised in your DP class.
2)If your value is being initialised correctly, but it is not showing up in the report design there can be multiple issues such as:
Overlapping of text boxes.
Insufficient space for the given field
Some report parameter/property not being set correctly which causes
your value not to show up on the report.
Check these one by one and you should end up arriving towards a solution

Odoo: Access field by it's name (given as string)

I have a model, where I want to access a field, given by a string. Example:
def test(self):
field = 'name'
name = getattr(self, field)
This works fine - name is set to self.name. But then I want to access a related field:
def test2(self):
field = 'partner_id.name'
name = getattr(self, field)
That doesn't work (because 'partner_id.name' does not exist on self). Any idea how to do it right?
getattr doesn't support the dot notation, only simple attribute names. You can however create a simple function that does:
def getfield(model, field_name):
value = model
for part in field_name.split('.'):
value = getattr(value, part)
return value
You would use it like this:
def test2(self):
field = 'partner_id.name'
name = getfield(self, field)
You need to use the object that contain partner_id.name
def test2(self):
field = 'name'
object = self.pool.get('res.partner').browse(cr, uid, self.partner_id.id)#v7
#object = self.env['res.partner'].browse(self.partner_id.id)#v8
name = getattr(object, field)
I also came across another solution, inspired by the mail template system:
from openerp.tools.safe_eval import safe_eval as eval
def test2(self):
field = 'partner_id.name'
field = 'object.' + field
name = eval(field, {'object': self})

How to not store an integer field in openerp

I have an integer field in which i just display a value calculated with an 'on_change' function.
Is there anyway to not store that value in my Database(another way than using a function field)?
I also tried to put store=False but i guess it doesn't work with an integer field
here's my integer field:
'quantite_op': fields.integer('Quantité produite par opération',store=False,readonly=True),
And the onchange function:
def onchange_num_of(self,cr,uid,ids,of_num,operation_nom,quantite,context=None):
res = {}
if of_num:
ordre_f = self.pool.get('ordres_fabrication').browse(cr, uid,of_num,context=context)
res['delai_of'] =ordre_f.delai
res['quantite_of'] =ordre_f.quantite
if operation_nom:
record =self.search(cr, uid, [('of_num','=',of_num),('operation_nom','=',operation_nom)])
qte=0
for item in record:
prod = self.browse(cr, uid,item,context=context)
qte += prod.quantite
res['quantite_op'] = qte+quantite
return {'value': res}
Thanks
you will always have that field in your db, except it's a non-stored functional field. but you can manipulate the create or write methods of the model. you can set your integer field on None resp. False in that methods, so no value will be stored in that db column.

Assigning value to DateTimePicker.Value affects other class properties (VB.NET)

I have a line that assigns a value to my form's Me.dateTimePickerAddStartDate.Value - the value gets assigned properly, but it also affects all of my Me.checkBoxAddXXXXXX.Checked values, assigning them to TRUE. I'm at a loss in understanding why this might happen - am I doing something wrong?
I just added the CType to ensure that it wasn't an explicit/implicit problem.
If I put the last three lines preceding the Me.checkBoxAddXXXXX.Checked assignments, everything works as expected, but I don't want to cover up a problem and find out it shows up some place else unexpectedly - I'd like to solve the root issue.
Me.checkBoxAddMonday.Checked = m_Archiving.Time.Monday
Me.checkBoxAddTuesday.Checked = m_Archiving.Time.Tuesday
Me.checkBoxAddWednesday.Checked = m_Archiving.Time.Wednesday
Me.checkBoxAddThursday.Checked = m_Archiving.Time.Thursday
Me.checkBoxAddFriday.Checked = m_Archiving.Time.Friday
Me.checkBoxAddSaturday.Checked = m_Archiving.Time.Saturday
Me.checkBoxAddSunday.Checked = m_Archiving.Time.Sunday
Me.numericUpDownAddOffset.Value = CType(m_Archiving.Time.OffSet, System.Decimal)
Me.dateTimePickerAddStartDate.Value = CType(m_Archiving.Time.StartDate, System.DateTime)
Me.dateTimePickerAddStartTime.Value = CType(m_Archiving.Time.StartTime, System.DateTime)