I am trying to create a sequence in odoo here is my xml file
<record model="ir.sequence" id="connection_sequence_id">
<field name="name">New Connections Sequence</field>
<field name="code">ftth.connection</field>
<field name="prefix">FTTH</field>
<field name="padding">6</field>
<field name="company_id" eval="False" />
</record>
I have created a field for it in my .py file
my_seq = fields.Char(string="sequence", default=lambda self: _('New'))
and overiddeen the create function by using the following code
#api.model
def create(self, vals):
if vals:
vals['my_seq'] = self.env['ir.sequence'].next_by_code('ftth.connection') or _('New')
result = super(NewConnections, self).create(vals)
return result
but my code is not generating a sequence instead it gives ftth.connection.(sequence number).what might be wrong with my code.please assist
use super to customize your create function, this an example:
#api.model
def create(self, vals):
if vals:
seq = self.env['ir.sequence']
vals['my_seq'] = seq.next_by_code('ftth.connection') or _('New')
return super(ObjectName, self).create(values)
I need to filter products in purchase order line based on value in parent table (purchase.order).
Purchase_order.py
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
product_variety_type = fields.Selection([('raw_material','Raw Material'),('stationary','Stationary')],string='Product Variety')
I already defined a domain filter in purchase.order.line.py, need to add one more condition ('variety','=',self._context.get('variety')
class PurchaseOrderLines(models.Model):
_inherit = 'purchase.order.line'
#api.onchange('product_id')
#api.depends('order_id')
def onchange_product_id2(self):
product_variety_type = self._context.get('variety') // Value is None
result = super(PurchaseOrderLines,self).onchange_product_id()
supplier_infos = self.env['product.supplierinfo'].search([('name', '=', self.partner_id.id)])
product_ids = self.env['product.product']
if not supplier_infos:
product_ids = product_ids.search([])
for supplier_info in supplier_infos:
product_ids += supplier_info.product_tmpl_id.product_variant_ids
result.update({'domain': {'product_id': [('id', 'in', product_ids.ids)]}})
return result
I tried to pass a context value from parent view,but no luck.
*.xml
<field name="partner_id" position="after">
<field name="product_variety_type" required="1" context="
{'variety':product_variety_type}"/>
</field>
How can i do this?
You don't have to use the context. Just use self.order_id to get the value.
#api.onchange('product_id')
def onchange_product_id2(self):
product_variety_type = self.order_id.product_variety_type
# and so on
i have override product_id_change() of sale.order.line its working fine.
Now my requirement is to get sale.order fields in my onchange so how can i get field value of sale.order from sale.order.line product_id_change()
here is my code odoov8
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0, uom=False, qty_uos=0, uos=False, name='', partner_id=False, lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None):
#how to access self.order_id
print "order id===", order_id
res = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty=qty,uom=uom, qty_uos=qty_uos, uos=uos, name=name, partner_id=partner_id,lang=lang, update_tax=update_tax, date_order= date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag, context=context)
return res
You can do it using following steps.
1.In On change method you can pass one argument parent.
<record model="ir.ui.view" id="sale_margin_sale_order_line">
<field name="name">sale.order.line.margin_and_quantities.view.form</field>
<field name="type">form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='order_line']/form[#string='Sales Order Lines']/group/group[1]/field[#name='product_id']"
position="attributes"> position="attributes">
<attribute name="on_change">
product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,
product_uos,name,parent.partner_id, False, False, parent.date_order, False, parent.fiscal_position, True, context,parent)
</attribute>
</xpath>
</field>
</record>
In above view we have used position attributes option to replace on_change method.
In on_change method just add one parameter at last parent, parent means sale.order object.
product_id field is available in sale.order.line, you can access order_id using parent keyword in the view.
2.Inherit product_id_change method in py file.
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None,order_id=False):
res=super(sale_order,self).product_id_change(cr,uid,ids,pricelist,product,qty,uom,qty_uos,uos,name,partner_id,lang,update_tax,date_order,packaging,fiscal_position,flag,context)
return res
In above method order_id is available in method argument, so you
can directly access it.
If you have installed sale_stock module then you should inherit
product_id_change_with_wh method in py file & change position attributes in product_id_change_with_wh on_change in view, also
must give dependency of sale_stock in openerp.py file.
After that you will get order_id field in
product_id_change_with_wh on_change method & pass this parameter in on_change product_id method.
Ex :
def product_id_change_with_wh(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, warehouse_id=False, context=None,order_id=False):
context = context or {}
product_uom_obj = self.pool.get('product.uom')
product_obj = self.pool.get('product.product')
warning = {}
#UoM False due to hack which makes sure uom changes price, ... in product_id_change
res = self.product_id_change(cr, uid, ids, pricelist, product, qty=qty,
uom=False, qty_uos=qty_uos, uos=uos, name=name, partner_id=partner_id,
lang=lang, update_tax=update_tax, date_order=date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag, context=context,order_id=order_id)
This method is written in the old API so you have to browse the sale.order.line record, which is changed.
def product_id_change(
self, cr, uid, ids, pricelist, product, qty=0, uom=False,
qty_uos=0, uos=False, name='', partner_id=False, lang=False,
update_tax=True, date_order=False, packaging=False,
fiscal_position=False, flag=False, context=None):
line = self.browse(cr, uid, ids[0], context)
# print line.order_id.name
res = super(sale_order_line, self).product_id_change(
cr, uid, ids, pricelist, product, qty=qty,uom=uom,
qty_uos=qty_uos, uos=uos, name=name, partner_id=partner_id
lang=lang, update_tax=update_tax, date_order= date_order,
packaging=packaging, fiscal_position=fiscal_position,
flag=flag, context=context)
return res
I usually create a new Database Structure Field by using the Debugging Mode, then Edit FormView and writing e.g. <field name="x_delivery_date"/>. Also I can show it later on the printed report like this:
<div name="x_delivery_date" t-if="doc.x_delivery_date">
<strong>Delivery Date:</strong>
<p t-field="doc.x_delivery_date"/>
</div>
But how do I display a field (commitment_date), which is available in the model (sale.order) in another models formview (account.invoice)? I guess that I have to use object relations or related field, but I don't know how. I hope somebody can help me. Many thanks in advance.
You can use related fields for that. You have to add two fields to account.invoice to do it.
class AccountInvoice(models.Model):
_inherit = "account.invoice"
order_id = fields.Many2one('sale.order', 'Related_order')
commitment_date = fields.Date(related='order_id.commitment_date')
Then you can use the commitment_date fields in account.invoice forms. The value of the field in sale.order will be reflected on the form right away. But be aware that changing the value of that field will change the value of that field on the sale.order as well.
EDIT
For reports just use the field like it is a regular field of account.invoice (so doc.commitment_date)
First you need to add a many2one field in account.invoice
class account_invoice(osv.osv):
_inherit = "account.invoice"
_columns = {
'source_id':fields.many2one('sale.order','Source')
}
Then inherit the _prepare_invoice function in sale_order. In this function you are going to pass the sale order id as source id to the account.invoice
class sale_order(osv.osv):
_inherit = "sale.order"
def _prepare_invoice(self, cr, uid, order, lines, context=None):
if context is None:
context = {}
journal_id = self.pool['account.invoice'].default_get(cr, uid, ['journal_id'], context=context)['journal_id']
if not journal_id:
raise osv.except_osv(_('Error!'),
_('Please define sales journal for this company: "%s" (id:%d).') % (order.company_id.name, order.company_id.id))
invoice_vals = {
'name': order.client_order_ref or '',
'origin': order.name,
'type': 'out_invoice',
#Sale order id as source_id
'source_id':order.id,
'reference': order.client_order_ref or order.name,
'account_id': order.partner_invoice_id.property_account_receivable.id,
'partner_id': order.partner_invoice_id.id,
'journal_id': journal_id,
'invoice_line': [(6, 0, lines)],
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': order.payment_term and order.payment_term.id or False,
'fiscal_position': order.fiscal_position.id or order.partner_invoice_id.property_account_position.id,
'date_invoice': context.get('date_invoice', False),
'company_id': order.company_id.id,
'user_id': order.user_id and order.user_id.id or False,
'section_id' : order.section_id.id
}
invoice_vals.update(self._inv_get(cr, uid, order, context=context))
return invoice_vals
Add this in View file
<record id="invoice_form" model="ir.ui.view">
<field name="name">account.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='date_invoice']" position="after">
<field name="source_id"/>
</xpath>
</field>
</record>
Now add this in your report file
<div name="x_delivery_date" t-if="doc.x_delivery_date">
<strong>Delivery Date:</strong>
<p t-field="doc.x_delivery_date"/>
<p t-field="doc.source_id.commitment_date"/>
</div>
I am trying to achieve that all the users that are Hr managers should be allowed to see the records.
I have created a Functional Field:
def list_HRM(self, cr, uid, ids, field_name, arg, context):
attribute = {}
hr_managers = self.pool.get('hr.employee').search(cr, uid, ['&', ('department_id.name', '=', 'Human Resources'), ('manager', '=', True)], context=context)
hr_managers_uid = []
for record in hr_managers:
hr_managers_uid.append(self.pool.get('hr.employee').browse(cr, uid, record, context=context).user_id.id)
record = self.browse(cr, uid, ids)[0]
attribute[record.id] = str(uid in hr_managers_uid or uid==1)
return attribute
_columns={
'hr_managers_func' : fields.function(list_HRM, type='char', method=True, string='List of HR Managers'),
'always_true':fields.boolean()
}
_defaults={
'always_true':True
}
In .xml file:
<field name="always_true" invisible="1"/>
<field name="hr_managers_func" invisible="1"/>
In Record Rule:
['&','|',('state','=','hod_depart'),('state','=','hr_review'),('always_true','=',eval(hr_managers_func))]
I used field 'always_true' because of the record rule condition format i.e.
[('field_name','operator',values)].
I thought that rule will evaluate the functional field using eval
but unfortunately eval is not working on the record rule ,
I am getting this error:
NameError: name 'eval' is not defined
I could not think of more than this.
I saw few forum somewhat similar to my problem, they were using the related field to avoid the functional field in the record, but here I have to check whether the current user belong to hr managers or not .
I have tried explaining this in the best possible way, Looking forward for some reply.
To restrict on a function field, you need to define a fnct_search. The functional field per se becomes a dummy.
In your model:
def _my_functional_field_search(self, cr, uid, obj, name, args, context=None):
list_of_ids = [...]
return [('id', 'in', list_of_ids)]
_columns = {
'my_functional_field': fields.function(
lambda **x: True,
fnct_search=_my_functional_field_search,
type='boolean',
method=True,
),
}
And then in your security XML file:
<record id="your_rule_id" model="ir.rule">
<field name="name">Your Rule Name</field>
<field name="model_id" ref="model_the_model" />
<field name="groups" eval="[(4, ref('group_affected_group'))]" />
<field name="domain_force">[('my_functional_field', '=', True)]</field>
</record>