python script to download multiple reports from odoo
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
We have an odoo server running (http://www.odoo.com/documentation/9.0/api_integration.html), which allows us to programmatically query and download invoice reports as PDF's
We're running this on python 2.7.3. I'm looking for tips on DRYness, future maintainability and help on blind spots in the code where something might go wrong, and the ability to output helpful data to the person running the script.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import xmlrpclib
import os
class UniReportPrinter():
def __init__(self, mode):
self.mode = mode
from apiv9connector import s51OpenERPConnector_apiv9
# during dev only get vals from prod that are needed
self.odooconnection1 = s51OpenERPConnector_apiv9()
self.odooconnection1.login()
print "logged in"
odooconnection1 = ''
self.partners =
@property
def partners(self):
return self.partners
@partners.setter
def partners(self, value):
self.partners = value
def get_reports(self):
nextmonth = self.__get_next_month()
print('searching for invoices, filtered by:')
print('state: open')
print('date: ' + nextmonth.strftime("%Y-%m-%d"))
print('reference: like SB%')
invoice_ids = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search',
[[('state', '=', 'open'), ('date_invoice', '=', nextmonth.strftime("%Y-%m-%d")),('reference', 'like', 'SB%')]])
self.__get_partner_details(invoice_ids)
self.__download_report(invoice_ids)
def __get_next_month(self):
from datetime import date
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
def __get_partner_details(self, invoice_ids):
partners = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search_read',
[[['id', 'in', invoice_ids]]],
'fields': ['reference', 'id', 'partner_id'])
self.partners = partners
def __download_report(self, invoice_ids):
for invoice_id in invoice_ids:
report = xmlrpclib.ServerProxy('/xmlrpc/2/report'.format('https://odoo.example.com'))
result = report.render_report(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.report_invoice', [invoice_id])
filename = self.__get_file_name(invoice_id)
sys.stdout.write("r[%s]" % filename )
sys.stdout.flush()
self.__save_report(result, filename)
def __get_file_name(self, invoice_id):
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
def __save_report(self, report_data, filename):
nextmonth = self.__get_next_month()
year = nextmonth.year
month = nextmonth.month
path = str(year) + '/' + str(month) + '/'
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
fileNamePath = os.path.join(path, filename)
my_file = open(fileNamePath, 'w')
my_file.write(report_data['result'].decode('base64'))
my_file.close()
###############main#############
if __name__ == "__main__":
unireportprinter = UniReportPrinter(mode='live')
unireportprinter.get_reports()
python python-2.7 odoo
add a comment |Â
up vote
2
down vote
favorite
We have an odoo server running (http://www.odoo.com/documentation/9.0/api_integration.html), which allows us to programmatically query and download invoice reports as PDF's
We're running this on python 2.7.3. I'm looking for tips on DRYness, future maintainability and help on blind spots in the code where something might go wrong, and the ability to output helpful data to the person running the script.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import xmlrpclib
import os
class UniReportPrinter():
def __init__(self, mode):
self.mode = mode
from apiv9connector import s51OpenERPConnector_apiv9
# during dev only get vals from prod that are needed
self.odooconnection1 = s51OpenERPConnector_apiv9()
self.odooconnection1.login()
print "logged in"
odooconnection1 = ''
self.partners =
@property
def partners(self):
return self.partners
@partners.setter
def partners(self, value):
self.partners = value
def get_reports(self):
nextmonth = self.__get_next_month()
print('searching for invoices, filtered by:')
print('state: open')
print('date: ' + nextmonth.strftime("%Y-%m-%d"))
print('reference: like SB%')
invoice_ids = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search',
[[('state', '=', 'open'), ('date_invoice', '=', nextmonth.strftime("%Y-%m-%d")),('reference', 'like', 'SB%')]])
self.__get_partner_details(invoice_ids)
self.__download_report(invoice_ids)
def __get_next_month(self):
from datetime import date
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
def __get_partner_details(self, invoice_ids):
partners = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search_read',
[[['id', 'in', invoice_ids]]],
'fields': ['reference', 'id', 'partner_id'])
self.partners = partners
def __download_report(self, invoice_ids):
for invoice_id in invoice_ids:
report = xmlrpclib.ServerProxy('/xmlrpc/2/report'.format('https://odoo.example.com'))
result = report.render_report(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.report_invoice', [invoice_id])
filename = self.__get_file_name(invoice_id)
sys.stdout.write("r[%s]" % filename )
sys.stdout.flush()
self.__save_report(result, filename)
def __get_file_name(self, invoice_id):
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
def __save_report(self, report_data, filename):
nextmonth = self.__get_next_month()
year = nextmonth.year
month = nextmonth.month
path = str(year) + '/' + str(month) + '/'
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
fileNamePath = os.path.join(path, filename)
my_file = open(fileNamePath, 'w')
my_file.write(report_data['result'].decode('base64'))
my_file.close()
###############main#############
if __name__ == "__main__":
unireportprinter = UniReportPrinter(mode='live')
unireportprinter.get_reports()
python python-2.7 odoo
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
We have an odoo server running (http://www.odoo.com/documentation/9.0/api_integration.html), which allows us to programmatically query and download invoice reports as PDF's
We're running this on python 2.7.3. I'm looking for tips on DRYness, future maintainability and help on blind spots in the code where something might go wrong, and the ability to output helpful data to the person running the script.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import xmlrpclib
import os
class UniReportPrinter():
def __init__(self, mode):
self.mode = mode
from apiv9connector import s51OpenERPConnector_apiv9
# during dev only get vals from prod that are needed
self.odooconnection1 = s51OpenERPConnector_apiv9()
self.odooconnection1.login()
print "logged in"
odooconnection1 = ''
self.partners =
@property
def partners(self):
return self.partners
@partners.setter
def partners(self, value):
self.partners = value
def get_reports(self):
nextmonth = self.__get_next_month()
print('searching for invoices, filtered by:')
print('state: open')
print('date: ' + nextmonth.strftime("%Y-%m-%d"))
print('reference: like SB%')
invoice_ids = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search',
[[('state', '=', 'open'), ('date_invoice', '=', nextmonth.strftime("%Y-%m-%d")),('reference', 'like', 'SB%')]])
self.__get_partner_details(invoice_ids)
self.__download_report(invoice_ids)
def __get_next_month(self):
from datetime import date
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
def __get_partner_details(self, invoice_ids):
partners = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search_read',
[[['id', 'in', invoice_ids]]],
'fields': ['reference', 'id', 'partner_id'])
self.partners = partners
def __download_report(self, invoice_ids):
for invoice_id in invoice_ids:
report = xmlrpclib.ServerProxy('/xmlrpc/2/report'.format('https://odoo.example.com'))
result = report.render_report(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.report_invoice', [invoice_id])
filename = self.__get_file_name(invoice_id)
sys.stdout.write("r[%s]" % filename )
sys.stdout.flush()
self.__save_report(result, filename)
def __get_file_name(self, invoice_id):
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
def __save_report(self, report_data, filename):
nextmonth = self.__get_next_month()
year = nextmonth.year
month = nextmonth.month
path = str(year) + '/' + str(month) + '/'
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
fileNamePath = os.path.join(path, filename)
my_file = open(fileNamePath, 'w')
my_file.write(report_data['result'].decode('base64'))
my_file.close()
###############main#############
if __name__ == "__main__":
unireportprinter = UniReportPrinter(mode='live')
unireportprinter.get_reports()
python python-2.7 odoo
We have an odoo server running (http://www.odoo.com/documentation/9.0/api_integration.html), which allows us to programmatically query and download invoice reports as PDF's
We're running this on python 2.7.3. I'm looking for tips on DRYness, future maintainability and help on blind spots in the code where something might go wrong, and the ability to output helpful data to the person running the script.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import xmlrpclib
import os
class UniReportPrinter():
def __init__(self, mode):
self.mode = mode
from apiv9connector import s51OpenERPConnector_apiv9
# during dev only get vals from prod that are needed
self.odooconnection1 = s51OpenERPConnector_apiv9()
self.odooconnection1.login()
print "logged in"
odooconnection1 = ''
self.partners =
@property
def partners(self):
return self.partners
@partners.setter
def partners(self, value):
self.partners = value
def get_reports(self):
nextmonth = self.__get_next_month()
print('searching for invoices, filtered by:')
print('state: open')
print('date: ' + nextmonth.strftime("%Y-%m-%d"))
print('reference: like SB%')
invoice_ids = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search',
[[('state', '=', 'open'), ('date_invoice', '=', nextmonth.strftime("%Y-%m-%d")),('reference', 'like', 'SB%')]])
self.__get_partner_details(invoice_ids)
self.__download_report(invoice_ids)
def __get_next_month(self):
from datetime import date
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
def __get_partner_details(self, invoice_ids):
partners = self.odooconnection1.models.execute_kw(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.invoice', 'search_read',
[[['id', 'in', invoice_ids]]],
'fields': ['reference', 'id', 'partner_id'])
self.partners = partners
def __download_report(self, invoice_ids):
for invoice_id in invoice_ids:
report = xmlrpclib.ServerProxy('/xmlrpc/2/report'.format('https://odoo.example.com'))
result = report.render_report(
self.odooconnection1.db, self.odooconnection1.uid, self.odooconnection1.password, 'account.report_invoice', [invoice_id])
filename = self.__get_file_name(invoice_id)
sys.stdout.write("r[%s]" % filename )
sys.stdout.flush()
self.__save_report(result, filename)
def __get_file_name(self, invoice_id):
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
def __save_report(self, report_data, filename):
nextmonth = self.__get_next_month()
year = nextmonth.year
month = nextmonth.month
path = str(year) + '/' + str(month) + '/'
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
fileNamePath = os.path.join(path, filename)
my_file = open(fileNamePath, 'w')
my_file.write(report_data['result'].decode('base64'))
my_file.close()
###############main#############
if __name__ == "__main__":
unireportprinter = UniReportPrinter(mode='live')
unireportprinter.get_reports()
python python-2.7 odoo
asked Apr 30 at 17:16
Jarede
199116
199116
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
Wasted looping
Let's do a pop quiz on this code:
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
If self.partner
contains a million values,
and the first value has id
equal to invoice_id
,
how many values will be visited?
All of them :(
That's unfortunate.
It would be better to spell out a loop:
for p in self.partners:
if p["id"] == invoice_id:
partner = p
break
else:
partner = None
Sure, this is longer, but it avoids a performance issue waiting to happen,
and it also handles the case gracefully when there is no matching value.
A compact alternative is possible using generator expressions, which are very cool:
partner = next(p for p in self.partners if p["id"] == invoice_id)
However, in this case, you would still need to handle the case when there is no matching value.
You would do that by expecting StopIteration
to be raised.
Avoid wildcard imports
It's good to avoid wildcard imports.
It makes it easier to understand where symbols come from.
When you import *
,
it can easily become confusing to tell where some names come from.
In this code the wildcard import seems pointless:
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
It seems the only thing it imports is the relativedelta
,
so you could write just that instead of using a *
.
Also, I think that the last 3 statements are actually easier to read inlined:
return today + relativedelta(months=1) + relativedelta(day=1)
Import at the top of the file
It's recommended to import packages at the top of the file, not inside functions.
The above link is part of PEP8, a collection of recommended guidelines that should help you achieve the goals such as maintainability outlined in your question.
Drop pointless statement
In the constructor of UniReportPrinter
there is this line:
odooconnection1 = ''
I'm wondering if you might be confusing odooconnection1
with self.odooconnection1
.
They are different variables.
The first is a local variable,
the second is a field of the object being created.
If you want to unset self.odooconnection1
, assign None
to it instead of an empty string.
Getters should return something
I would expect functions with "get" in the name to return something.
The __get_partner_details
function doesn't return anything.
I suggest to rename the method. Perhaps replace "get" with "fetch".
Be consistent
In some places I see print("string")
, in others print "string"
.
In some places I see '/foo'.format(bar)
, in others '%s/foo' % bar
, or bar + '/foo'
.
It's good to be consistent.
And to consistently use the right techniques.
In each of these examples the right technique is the first.
Use '...'.format(...)
Especially when formatting complex strings like here,
definitely use '...'.format(...)
instead:
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
Wasted looping
Let's do a pop quiz on this code:
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
If self.partner
contains a million values,
and the first value has id
equal to invoice_id
,
how many values will be visited?
All of them :(
That's unfortunate.
It would be better to spell out a loop:
for p in self.partners:
if p["id"] == invoice_id:
partner = p
break
else:
partner = None
Sure, this is longer, but it avoids a performance issue waiting to happen,
and it also handles the case gracefully when there is no matching value.
A compact alternative is possible using generator expressions, which are very cool:
partner = next(p for p in self.partners if p["id"] == invoice_id)
However, in this case, you would still need to handle the case when there is no matching value.
You would do that by expecting StopIteration
to be raised.
Avoid wildcard imports
It's good to avoid wildcard imports.
It makes it easier to understand where symbols come from.
When you import *
,
it can easily become confusing to tell where some names come from.
In this code the wildcard import seems pointless:
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
It seems the only thing it imports is the relativedelta
,
so you could write just that instead of using a *
.
Also, I think that the last 3 statements are actually easier to read inlined:
return today + relativedelta(months=1) + relativedelta(day=1)
Import at the top of the file
It's recommended to import packages at the top of the file, not inside functions.
The above link is part of PEP8, a collection of recommended guidelines that should help you achieve the goals such as maintainability outlined in your question.
Drop pointless statement
In the constructor of UniReportPrinter
there is this line:
odooconnection1 = ''
I'm wondering if you might be confusing odooconnection1
with self.odooconnection1
.
They are different variables.
The first is a local variable,
the second is a field of the object being created.
If you want to unset self.odooconnection1
, assign None
to it instead of an empty string.
Getters should return something
I would expect functions with "get" in the name to return something.
The __get_partner_details
function doesn't return anything.
I suggest to rename the method. Perhaps replace "get" with "fetch".
Be consistent
In some places I see print("string")
, in others print "string"
.
In some places I see '/foo'.format(bar)
, in others '%s/foo' % bar
, or bar + '/foo'
.
It's good to be consistent.
And to consistently use the right techniques.
In each of these examples the right technique is the first.
Use '...'.format(...)
Especially when formatting complex strings like here,
definitely use '...'.format(...)
instead:
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
add a comment |Â
up vote
3
down vote
accepted
Wasted looping
Let's do a pop quiz on this code:
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
If self.partner
contains a million values,
and the first value has id
equal to invoice_id
,
how many values will be visited?
All of them :(
That's unfortunate.
It would be better to spell out a loop:
for p in self.partners:
if p["id"] == invoice_id:
partner = p
break
else:
partner = None
Sure, this is longer, but it avoids a performance issue waiting to happen,
and it also handles the case gracefully when there is no matching value.
A compact alternative is possible using generator expressions, which are very cool:
partner = next(p for p in self.partners if p["id"] == invoice_id)
However, in this case, you would still need to handle the case when there is no matching value.
You would do that by expecting StopIteration
to be raised.
Avoid wildcard imports
It's good to avoid wildcard imports.
It makes it easier to understand where symbols come from.
When you import *
,
it can easily become confusing to tell where some names come from.
In this code the wildcard import seems pointless:
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
It seems the only thing it imports is the relativedelta
,
so you could write just that instead of using a *
.
Also, I think that the last 3 statements are actually easier to read inlined:
return today + relativedelta(months=1) + relativedelta(day=1)
Import at the top of the file
It's recommended to import packages at the top of the file, not inside functions.
The above link is part of PEP8, a collection of recommended guidelines that should help you achieve the goals such as maintainability outlined in your question.
Drop pointless statement
In the constructor of UniReportPrinter
there is this line:
odooconnection1 = ''
I'm wondering if you might be confusing odooconnection1
with self.odooconnection1
.
They are different variables.
The first is a local variable,
the second is a field of the object being created.
If you want to unset self.odooconnection1
, assign None
to it instead of an empty string.
Getters should return something
I would expect functions with "get" in the name to return something.
The __get_partner_details
function doesn't return anything.
I suggest to rename the method. Perhaps replace "get" with "fetch".
Be consistent
In some places I see print("string")
, in others print "string"
.
In some places I see '/foo'.format(bar)
, in others '%s/foo' % bar
, or bar + '/foo'
.
It's good to be consistent.
And to consistently use the right techniques.
In each of these examples the right technique is the first.
Use '...'.format(...)
Especially when formatting complex strings like here,
definitely use '...'.format(...)
instead:
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
Wasted looping
Let's do a pop quiz on this code:
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
If self.partner
contains a million values,
and the first value has id
equal to invoice_id
,
how many values will be visited?
All of them :(
That's unfortunate.
It would be better to spell out a loop:
for p in self.partners:
if p["id"] == invoice_id:
partner = p
break
else:
partner = None
Sure, this is longer, but it avoids a performance issue waiting to happen,
and it also handles the case gracefully when there is no matching value.
A compact alternative is possible using generator expressions, which are very cool:
partner = next(p for p in self.partners if p["id"] == invoice_id)
However, in this case, you would still need to handle the case when there is no matching value.
You would do that by expecting StopIteration
to be raised.
Avoid wildcard imports
It's good to avoid wildcard imports.
It makes it easier to understand where symbols come from.
When you import *
,
it can easily become confusing to tell where some names come from.
In this code the wildcard import seems pointless:
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
It seems the only thing it imports is the relativedelta
,
so you could write just that instead of using a *
.
Also, I think that the last 3 statements are actually easier to read inlined:
return today + relativedelta(months=1) + relativedelta(day=1)
Import at the top of the file
It's recommended to import packages at the top of the file, not inside functions.
The above link is part of PEP8, a collection of recommended guidelines that should help you achieve the goals such as maintainability outlined in your question.
Drop pointless statement
In the constructor of UniReportPrinter
there is this line:
odooconnection1 = ''
I'm wondering if you might be confusing odooconnection1
with self.odooconnection1
.
They are different variables.
The first is a local variable,
the second is a field of the object being created.
If you want to unset self.odooconnection1
, assign None
to it instead of an empty string.
Getters should return something
I would expect functions with "get" in the name to return something.
The __get_partner_details
function doesn't return anything.
I suggest to rename the method. Perhaps replace "get" with "fetch".
Be consistent
In some places I see print("string")
, in others print "string"
.
In some places I see '/foo'.format(bar)
, in others '%s/foo' % bar
, or bar + '/foo'
.
It's good to be consistent.
And to consistently use the right techniques.
In each of these examples the right technique is the first.
Use '...'.format(...)
Especially when formatting complex strings like here,
definitely use '...'.format(...)
instead:
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
Wasted looping
Let's do a pop quiz on this code:
partner = ([p for p in self.partners if p["id"] == invoice_id])[0]
If self.partner
contains a million values,
and the first value has id
equal to invoice_id
,
how many values will be visited?
All of them :(
That's unfortunate.
It would be better to spell out a loop:
for p in self.partners:
if p["id"] == invoice_id:
partner = p
break
else:
partner = None
Sure, this is longer, but it avoids a performance issue waiting to happen,
and it also handles the case gracefully when there is no matching value.
A compact alternative is possible using generator expressions, which are very cool:
partner = next(p for p in self.partners if p["id"] == invoice_id)
However, in this case, you would still need to handle the case when there is no matching value.
You would do that by expecting StopIteration
to be raised.
Avoid wildcard imports
It's good to avoid wildcard imports.
It makes it easier to understand where symbols come from.
When you import *
,
it can easily become confusing to tell where some names come from.
In this code the wildcard import seems pointless:
from dateutil.relativedelta import *
today = date.today()
nextmonth = today+relativedelta(months=+1)
nextmonth = nextmonth+relativedelta(day=1)
return nextmonth
It seems the only thing it imports is the relativedelta
,
so you could write just that instead of using a *
.
Also, I think that the last 3 statements are actually easier to read inlined:
return today + relativedelta(months=1) + relativedelta(day=1)
Import at the top of the file
It's recommended to import packages at the top of the file, not inside functions.
The above link is part of PEP8, a collection of recommended guidelines that should help you achieve the goals such as maintainability outlined in your question.
Drop pointless statement
In the constructor of UniReportPrinter
there is this line:
odooconnection1 = ''
I'm wondering if you might be confusing odooconnection1
with self.odooconnection1
.
They are different variables.
The first is a local variable,
the second is a field of the object being created.
If you want to unset self.odooconnection1
, assign None
to it instead of an empty string.
Getters should return something
I would expect functions with "get" in the name to return something.
The __get_partner_details
function doesn't return anything.
I suggest to rename the method. Perhaps replace "get" with "fetch".
Be consistent
In some places I see print("string")
, in others print "string"
.
In some places I see '/foo'.format(bar)
, in others '%s/foo' % bar
, or bar + '/foo'
.
It's good to be consistent.
And to consistently use the right techniques.
In each of these examples the right technique is the first.
Use '...'.format(...)
Especially when formatting complex strings like here,
definitely use '...'.format(...)
instead:
return str(partner['partner_id'][0])+'-'+partner['reference'] + '.pdf'
answered Apr 30 at 18:46
janos
95.5k12120343
95.5k12120343
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193281%2fpython-script-to-download-multiple-reports-from-odoo%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password