I creating an invoice from another model, and want to get validated not draft
But internal number and total are not generated with my code.
invoice_id = self.pool.get('account.invoice').create(cr, uid,{
'partner_id':self.supplier.id,
'name' : 'Faltante mercaderia',
'journal_id': journal_id,
'account_id':account_id,
'type': 'in_refund',
})
self.pool.get('account.invoice.line').create(cr, uid,{
'invoice_id' : invoice_id,
'name' : 'Faltante mercaderia %s: %s' %(self.type,self.number),
'quantity' : self.dif_final,
'price_unit':self.tarifa_dif / 1000,
})
a = self.env['account.invoice'].browse([invoice_id])
a.invoice_validate()
I also try adding a.action_number()
This code should work for you:
inv_obj = self.pool.get('account.invoice')
inv_obj.button_compute(cr, uid, [invoice_id], context=context, set_total=True)
inv_obj.action_date_assign(cr, uid, invoice_id, context=context)
inv_obj.action_move_create(cr, uid, invoice_id, context=context)
inv_obj.action_number(cr, uid, invoice_id, context=context)
inv_obj.invoice_validate(cr, uid, invoice_id, context=context)
You can check by calling all above methods and let me know.
validate button sends a signal to a workflow, you just need to send the same signal:
a.signal_workflow('invoice_open')
Related
I have inherited from purchase.order.line. I have added a bunch of related fields. They are all related to fields in product.product via product_id in order_line.
What I want to achieve is that when a user selects or changes a product in the purchase order line form, the related fields should get refreshed/updated/populated with values of the selected product.
I have written the onchange method for this but I'm not sure how to invoke it from the inherited view? The product_id field was already there in the (parent) order_line view and it already has an onchange defined. How do I get the system to use my onchange as well?
I don't want to disturb the onchange_productid method that is already there in purchase.order.line. So either before my onchange or after it, it should continue with its standard functioning.
Thanks
EDIT: latest version (getting errors when any of the related many2one or selection fields has a value).
class purchase_order_line_custom(osv.osv):
_name = 'purchase.order.line'
_inherit = 'purchase.order.line'
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'qualified_name':product.qualified_name,
'product_type' : product.product_type or None,
'product_subtype' : product.product_subtype,
'count_id':product.count_id or None
})
return values
_columns={
'product_type': fields.related('product_id','product_type',type='selection', string='Product Type', selection=[('X','X'),('Y','Y'),('Z','Z')]),
'product_subtype': fields.related('product_id','product_subtype',type='char', size=64, string='Sub-Type'),
'qualified_name': fields.related('product_id','qualified_name',type='char', size=64, string='Qualified Name'),
'count_id': fields.related('product_id','count_id',type='many2one',relation='product.mycount',string='Count')
}
purchase_order_line_custom()
you need to overide the onchange function(you can use super() ) for the field 'product_id' and update the result.
for example
def onchange_product(self,cr,uid,ids,product_id,context=None):
values = super(<your_class_name>,self).onchange_product(cr, uid,ids,product_id,context=context)
# values will be a dictionary containing 'value' as a key.
# You need to add all the newly added related fields and other fields to the values['value'].
# if 'aaa' is the newly added field, then values['value'].update({'aaa':<value for aaa>})
# then return values
return values
modify you onchange to the following
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'product_type' : product.product_type,
'product_subtype' : product.product_subtype,
'qualified_name' : product.qualified_name,
'count_id' : product.count_id
})
return values
First let's understand why fields.related is used?
fields.related field that points to some data inside another field of the current record.
That means, fields which are related will be filled automatically when you will select the value of other field.
Example:
_columns = {
'product_id': fields.many2one('product.product', 'Product'),
'product_name': fields.related('product_id', 'name', type='char', string='Product Name'),
}
In this example product_name will be filled automatically when you will select the product_id. You don't have to write onchange for that.
You can find many examples for fields.related.
Followup question from openerp override onchange behavior without affecting base
15244031
The following code does get fired but I get server error 500 when any of the related fields has a value.
When I look at the log, it says JSON serialization issue.
TypeError: browse_record(product.mycount, 1) is not JSON serializable
Please suggest a solution.
class purchase_order_line_custom(osv.osv):
_name = 'purchase.order.line'
_inherit = 'purchase.order.line'
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'qualified_name':product.qualified_name,
'product_type' : product.product_type or None,
'product_subtype' : product.product_subtype,
'count_id':product.count_id or None
})
return values
_columns={
'product_type': fields.related('product_id','product_type',type='selection', string='Product Type', selection=[('X','X'),('Y','Y'),('Z','Z')]),
'product_subtype': fields.related('product_id','product_subtype',type='char', size=64, string='Sub-Type'),
'qualified_name': fields.related('product_id','qualified_name',type='char', size=64, string='Qualified Name'),
'count_id': fields.related('product_id','count_id',type='many2one',relation='product.mycount',string='Count')
}
purchase_order_line_custom()
in the line 'count_id':product.count_id or None, I think count_id is a many2one field in product.you are trying to pass object to the count_id field in product.order.line, you need to pass product.count_id.id to get the id.
In my custom sale quotation report I want to show some products with a 0 quantity and therefore have created sale order lines for some products with their quantities set to 0. It works fine and shows in the sale quotation report.
But when I confirm that same sale quotation into a sale order OpenERP throws the following message:
"Data Insufficient !
Please check the quantity in procurement order(s), it should not be 0 or less!"
How can I confirm an order with some quantities set to 0?
First you have to inherit the Procurement and then override the action_confirm method in your custom module.
In procurement.py, find "def action_confirm()" on line: 320. Copy and past the whole method and remove those lines which raise the exception.
Hope this will solve your problem.
Thank You.
class procurement_order(osv.osv):
_inherit = 'procurement.order'
def action_confirm(self, cr, uid, ids, context=None):
move_obj = self.pool.get('stock.move')
for procurement in self.browse(cr, uid, ids, context=context):
#if procurement.product_qty <= 0.00:
#raise osv.except_osv(_('Data Insufficient !'),_('Please check the quantity in procurement order(s), it should not be 0 or less!'))
if procurement.product_id.type in ('product', 'consu'):
if not procurement.move_id:
source = procurement.location_id.id
if procurement.procure_method == 'make_to_order':
source = procurement.product_id.product_tmpl_id.property_stock_procurement.id
id = move_obj.create(cr, uid, {
'name': procurement.name,
'location_id': source,
'location_dest_id': procurement.location_id.id,
'product_id': procurement.product_id.id,
'product_qty': procurement.product_qty,
'product_uom': procurement.product_uom.id,
'date_expected': procurement.date_planned,
'state': 'draft',
'company_id': procurement.company_id.id,
'auto_validate': True,
})
move_obj.action_confirm(cr, uid, [id], context=context)
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move': 1})
self.write(cr, uid, ids, {'state': 'confirmed', 'message': ''})
return True
Can anyone share how I can change the "from" field value when sending a message because it always has the same email address?
--the address of the outgoing mail server I configure.
You can even send mail without making use of email template.
You can use mail.message & mail.mail objects.
def send_mail(cr, uid, ids, context=context):
mail_server_obj = self.pool.get('ir.mail_server')
mail_message_obj = self.pool.get('mail.message')
mail_mail_obj = self.pool.get('mail.mail')
for id in ids:
mail_message_id = mail_message_obj.create(cr, uid, {'email_from': 'from_add', 'model': 'model_name', 'res_id': id, 'subject': 'subject_name', 'body': 'your_html_body'}, context=context)
mail_server_ids = mail_server_obj.search(cr, uid, [], context=context)
mail_mail_id = mail_mail_obj.create(cr, uid, {'mail_message_id': mail_message_id, 'mail_server_id': mail_server_ids and mail_server_ids[0], 'state': 'outgoing', 'email_from': 'from_add', 'email_to': 'to_add', 'body_html': 'your_html_body'}, context=context)
if mail_mail_id:
mail_mail_obj.send(cr, uid, [mail_mail_id], context=context)
return True
There are many ways of sending mails. The good way is by creating a email template.
First create one email template.
def send_email(self, cr, uid, ids, context=None):
email_template_obj = self.pool.get('email.template')
template_ids = email_template_obj.search(cr, uid, [('model_id.model', '=', 'sale.order')])
if template_ids:
for id in ids:
values = email_template_obj.generate_email(cr, uid, template_ids[0], id, context=context)
print "values:: ", values
values['subject'] = your_subject
values['email_to'] = your_mail_to_address
values['email_cc'] = your_cc_address
values['body_html'] = your_body_html_part
values['body'] = your_body_html_part
mail_mail_obj = self.pool.get('mail.mail')
msg_id = mail_mail_obj.create(cr, uid, values, context=context)
if msg_id:
mail_mail_obj.send(cr, uid, [msg_id], context=context)
return True
Hope this will solve your problem.
Thank you.
Change your email preference from the top right menu showing your login.
I would like to use onchange to set account invoice price to a default price set in res.partner. Could anyone give me an example of this ?
Thanks,
Joe
There are lots of examples of onchange in addons.
For example, if you want to change the value of 'name' field and want to set product's name based on selected product:
def onchange_product_id(self, cr, uid, ids, product_id, context=None):
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
return {'value': {'name': prod.name}}
return {}
Write this in your_invoice_view.xml:
<field name="product_id" on_change="product_id_change(product_id, parent.partner_id, context)"/>
Write onchange in your_invoice.py under "invoice_line" model(class):
def onchange_product_id_change(self, cr, uid, ids, product_id, partner_id context=None):
if product_id and partner_id:
product_brw = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
partner_brw = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
/*write your logic */
return {'value': {'price_unit': your calculated value}}
return {}