Odoo xml rpc pass self - odoo

I need to call method (action_invoice_create) for sale order record. I cant find out how to pass self parameter. So task is to call method for order with id = 12. Here is some code:
import xmlrpclib
url = "https://myodoo.com"
db = "mydb"
username = '123'
password = '123'
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
new_id = 12 # id of existing sale order
model_name = 'sale.order'
models.execute_kw(db, uid, password, model_name, 'action_invoice_create', [new_id])

You do not need to pass self, you have to pass ids.
action_invoice_create expects ids as a list.
common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password, model_name, 'action_invoice_create', [[new_id]])

Related

How to rename partner ledger report in odoo8?

Partner ledger report name is 'account.report_partnerledger.pdf' by default. I want to change it to customer name (eg: john.pdf if customer name is john). How to do this?
Install report_custom_filename.
Go to Settings > Actions > Reports and search for Partner Ledger.
Fill in the Download filename field. This field is evaluated as jinja2 template with objects being a list of browse records of the records to print, and o the first record. If your model contains a name field, you might write something like ${o.name}_report.pdf as filename.
Possible through complex coding but thanks to odoo community we have one module named
report_custom_filename
which will let you do this by little configuration
Install 'report_custom_filename' module and make the following changes in report_routes method
def report_routes(self, reportname, docids=None, converter=None, **data):
cr, uid, context,registry = request.cr, request.uid, request.context,request.registry
response = super(ReportController, self).report_routes(
reportname, docids=docids, converter=converter, **data)
if docids:
docids = [int(i) for i in docids.split(',')]
report_xml = http.request.session.model('ir.actions.report.xml')
report_ids = report_xml.search(
[('report_name', '=', reportname)])
options_data = simplejson.loads(data['options'])
partner_id = options_data.get('ids')
for report in report_xml.browse(report_ids):
if not report.download_filename:
continue
#objects = http.request.session.model(report.model).browse(docids or [])
objects = request.registry[report.model].browse(cr, uid, partner_id, context=context)
customer_name = str(objects.name)
generated_filename = email_template.mako_template_env\
.from_string(report.download_filename)\
.render({
'objects': objects,
'o': customer_name,
'object': objects[:1],
'ext': report.report_type.replace('qweb-', ''),
})
response.headers['Content-Disposition'] = content_disposition(
generated_filename)
return response

Custom field default value - populate with other entries from same field

I have created a custom module with extra fields on the product screen. I am trying to have the default value be a drop down with all of the entries already submitted to that field or the option to create a new entry (same as the default value when adding a product to a BOM).
class product_part_detail(osv.osv):
_inherit = 'product.template'
_columns = {
'x_mfrname1': fields.char('P/N'),
}
_defaults ={
'x_mfrname1': get_default_name,
}
def get_default_name(self):
return "test"
I tried creating a many2one field that refers to a field in a different table but I keep getting an error when trying to install the module. Below is the updated code that I am having issues with. Thanks in advance!
class product_part_detail(osv.osv):
_inherit = 'product.template'
_name = 'product.part.detail'
_columns = {
'x_mfrname1': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
'x_mfrname2': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
}
class product_part_detail_fill(osv.osv):
_name = 'product.part.detail.fill'
def _sel_func(self, cr, uid, context=None):
obj = self.pool.get('product.part.detail')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['x_mfrname1', 'x_mfrname2'], context)
res = [(r['x_mfrname1'], r['x_mfrname2']) for r in res]
return res
_columns = {
'x_mfrname1id': fields.one2many('product.part.detail', 'x_mfrname1', 'x_mfrname2', selection=_sel_func),
}
A couple of things. The idea of a drop down of the values they have previously entered requires a many2one field. You would create another model and then make x_mfrname1 a many2one to that table. As long as the user has create access on that table they will get a create option on the drop down to key new values.
One other item, as you are using the pre-8 API, the method signature of your default method should be:
def get_default_name(self, cr, uid, context=None):

Odoo how to create or update record using XML

I have read Odoo documentation for creating new record. It uses XML RPC.
final Integer id = (Integer)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "create",
asList(new HashMap() {{ put("name", "New Partner"); }})
));
So is it possible to create new record only using XML message.
Thanks.
yes it is possible. here is the documenttation
and here is an example to create customer record using just a python file.
import xmlrpclib
username = 'admin' #the user
pwd = 'admin' #the password of the user
dbname = 'odoo' #the database
# Get the uid
sock_common = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/common')
uid = sock_common.login(dbname, username, pwd)
#replace localhost with the address of the server
sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/object')
partner = {
'name': 'atul arvind',
'phone': '8000111234'
}
partner_id = sock.execute(dbname, uid, pwd, 'res.partner', 'create', partner)
It will return newly created record's id.
hope it helps.

Django auth.models.User query by full name but Chinese name

In Chinese, the name format is 'LastnameFirstname' (number of characters for both Lastname and Firstname are varied), while in English, it is 'Firstname LastName'. We can see that in Chinese, the first name last name is swapped (which is not a problem in query here), and the first name last name is NOT separated by whitespace (which caused me this problem).
In SQL, we can do this:
SELECT *
FROM USER
WHERE Concat(last_name, first_name) = 'LastnameFirstName';
But how can I do this in Django? Given a FULLNAME string as 'LastnameFirstname', how can I do:
User.objects.filter(last_name+firstname=FULLNAME)
Another solution is to create a custom User model and create a new field called "full name", but this solution disables me to use other django built-in functions:
class User( models.Model ):
first_name = models.CharField( max_length=64 )
last_name = models.CharField( max_length=64 )
full_name = models.CharField( max_length=128 )
def save( self, *args, **kw ):
self.full_name = '{0}{1}'.format( first_name, last_name )
super( User, self ).save( *args, **kw )
I guess there would be a better solution.
Thanks. :)
You can either link to the User model and create your own class:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
def full_name(self):
return self.user.last_name + self.user.first_name
....
or you could subclass the AbstractUser model to define your own custom user attributes there:
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def full_name(self):
return self.last_name + self.first_name
Then in your settings set the default user model to your new class:
AUTH_USER_MODEL = 'myapp.MyUser'
The AbstractUser model only has 3 attributes: password,last_login and is_active. You can define the rest yourself.

Run a report from a wizard

I have a wizard with a button. On button action I want to run a report and leave the PDF on the server. I have the above code fragment that creates a report with web service. But in a wizard context I have normally only the uid (I think).
What will be the equivalent way to get the report to disk in a wizard ?
def reportToDisk(self, cr, uid, ids, context=None):
dbname = 'db'
username = 'user'
pwd = 'pass'
model = 'sale.order'
report_name = 'doc.sale'
sock_common = xmlrpclib.ServerProxy ('http://localhost:8069/xmlrpc/common')
uid = sock_common.login(dbname, username, pwd)
sock = xmlrpclib.ServerProxy ('http://localhost:8069/xmlrpc/object')
ids = sock.execute(dbname, uid, pwd, model, 'search',[])[0:1]
sock_report = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/report')
id_report = sock_report.report(
dbname, uid, pwd, report_name, ids,{'model': model, 'id': ids[0], 'report_type':'pdf'}
)
cont = True
while cont:
report = sock_report.report_get(dbname, uid, pwd, id_report)
cont = not report['state']
string_pdf = base64.decodestring(report['result'])
file_pdf = open('/home/arch-in/file.pdf','w')
file_pdf.write(string_pdf)
file_pdf.close()
Return the report action on your button click(It can be wizard button or view button, it just works with button click return) like following:
def btn_clik_action(self, cr, uid, ids, context=None):
if context == None:
context = {}
value = {
'type': 'ir.actions.report.xml',
'report_name':'report.name.(servicename)',
'datas': {
'model':'model.name',
'id': ids and ids[0] or False,
'ids': ids and ids or [],
'report_type': 'pdf'
},
'nodestroy': True
}
Just returning the report action will give you file of the report which basically you don't need to write or anything.
Thank YOu