From ba68f9bdb1d97620107ead4d0700a5743b35a636 Mon Sep 17 00:00:00 2001 From: "Apa (Open ERP)" Date: Fri, 26 Dec 2008 15:31:51 +0530 Subject: [PATCH 01/15] please make these changes on the report technical guide: some informations need to be added: 1. menus disposition, 2. reports and modified views, 3. and also, dependencies bzr revid: apa@tinyerp.com-20081226100151-us7t500nk9xuaua5 --- .../module/report/ir_module_reference.rml | 80 ++++++++++++------ .../module/report/ir_module_reference.sxw | Bin 11183 -> 13836 bytes 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/bin/addons/base/module/report/ir_module_reference.rml b/bin/addons/base/module/report/ir_module_reference.rml index 14d549e815c..7aa3a80a3d1 100644 --- a/bin/addons/base/module/report/ir_module_reference.rml +++ b/bin/addons/base/module/report/ir_module_reference.rml @@ -3,18 +3,6 @@ @@ -66,6 +54,10 @@ + + + + @@ -104,44 +96,45 @@ - + - + - + - - - - + + - - Introspection report on objects + + Introspection report on objects + - - - - + + + + + +
- [[ repeatIn(objects, 'module') ]] + [[ repeatIn(objects,'module') ]] @@ -180,10 +173,41 @@ - + - [[ module.description ]] + Reports : + [[ format(module.reports_by_module) ]] + + + + Menu : + [[ format(module.menus_by_module) ]] + + + + View : + [[ format(module.views_by_module) ]] + + + + + + + Dependencies : + + + + + [[ repeatIn(module.dependencies_id,'dependencies_id') ]] + [[ dependencies_id.name ]] - [[ dependencies_id.state ]] + + + + + + + [[ module.description ]]
diff --git a/bin/addons/base/module/report/ir_module_reference.sxw b/bin/addons/base/module/report/ir_module_reference.sxw index f2344339a2a9e98d548cbb9bcea9299ab65de74b..ad3ecff7717c499938b6757e294d63deac3dcc1c 100644 GIT binary patch literal 13836 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 literal 11183 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 lSLB}`<6nvOx4n}7Lz Date: Fri, 26 Dec 2008 11:14:34 +0100 Subject: [PATCH 02/15] [FIX] modules: no version specify mean version '0' bzr revid: christophe@taupe-20081226101434-9qnhitt14kkxeu4i --- bin/addons/base/module/module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index f2541a17791..01917e9ab7e 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -346,7 +346,7 @@ class module(osv.osv): mod_sort = {} for m in modules: name, version, extension = m[0], m[1], m[-1] - if version == 'x': # 'x' version was a mistake + if not version or version == 'x': # 'x' version was a mistake version = '0' if name in mod_sort: if parse_version(version) <= parse_version(mod_sort[name][0]): @@ -367,7 +367,7 @@ class module(osv.osv): else: id = ids[0] installed_version = self.read(cr, uid, id, ['latest_version'])['latest_version'] - if installed_version == 'x': # 'x' version was a mistake + if not installed_version or installed_version == 'x': # 'x' version was a mistake installed_version = '0' if parse_version(version) > parse_version(installed_version): self.write(cr, uid, id, { 'url': url }) From 3c16899b996130ec35697597ebdcb79fc13a18f8 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 11:17:41 +0100 Subject: [PATCH 03/15] [IMP] PoolManager: use class methods instead of static methods bzr revid: christophe@taupe-20081226101741-noqnp5agvi0nxsu1 --- bin/sql_db.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/bin/sql_db.py b/bin/sql_db.py index 041f855b32b..4d4a5f8efb3 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -192,36 +192,36 @@ class PoolManager(object): _dsn = None maxconn = int(tools.config['db_maxconn']) or 64 - def dsn(db_name): - if PoolManager._dsn is None: - PoolManager._dsn = '' + @classmethod + def dsn(cls, db_name): + if cls._dsn is None: + cls._dsn = '' for p in ('host', 'port', 'user', 'password'): cfg = tools.config['db_' + p] if cfg: - PoolManager._dsn += '%s=%s ' % (p, cfg) - return '%s dbname=%s' % (PoolManager._dsn, db_name) - dsn = staticmethod(dsn) + cls._dsn += '%s=%s ' % (p, cfg) + return '%s dbname=%s' % (cls._dsn, db_name) - def get(db_name): - if db_name not in PoolManager._pools: + @classmethod + def get(cls, db_name): + if db_name not in cls._pools: logger = netsvc.Logger() try: logger.notifyChannel('dbpool', netsvc.LOG_INFO, 'Connecting to %s' % (db_name,)) - PoolManager._pools[db_name] = ConnectionPool(ThreadedConnectionPool(1, PoolManager.maxconn, PoolManager.dsn(db_name)), db_name) + cls._pools[db_name] = ConnectionPool(ThreadedConnectionPool(1, cls.maxconn, cls.dsn(db_name)), db_name) except Exception, e: logger.notifyChannel('dbpool', netsvc.LOG_ERROR, 'Unable to connect to %s: %s' % (db_name, str(e))) raise - return PoolManager._pools[db_name] - get = staticmethod(get) + return cls._pools[db_name] - def close(db_name): - if db_name in PoolManager._pools: + @classmethod + def close(cls, db_name): + if db_name in cls._pools: logger = netsvc.Logger() logger.notifyChannel('dbpool', netsvc.LOG_INFO, 'Closing all connections to %s' % (db_name,)) - PoolManager._pools[db_name].closeall() - del PoolManager._pools[db_name] - close = staticmethod(close) + cls._pools[db_name].closeall() + del cls._pools[db_name] def db_connect(db_name, serialize=0): return PoolManager.get(db_name) From 8cd39a445e71c9f105d75d5ea6a94f9492a1ee20 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 11:18:58 +0100 Subject: [PATCH 04/15] [IMP] allow methods 'all' and 'any' to be available with python 2.4 bzr revid: christophe@taupe-20081226101858-vfzy8x6blf2vmf6h --- bin/tools/misc.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/bin/tools/misc.py b/bin/tools/misc.py index ac5f8695149..933274ddf0c 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -664,6 +664,29 @@ def ustr(value): return unicode(value, 'utf-8') +# to be compatible with python 2.4 +import __builtin__ +if not hasattr(__builtin__, 'all'): + def all(iterable): + for element in iterable: + if not element: + return False + return True + + __builtin__.all = all + del all + +if not hasattr(__builtin__, 'any'): + def any(iterable): + for element in iterable: + if element: + return True + return False + + __builtin__.any = any + del any + + def get_languages(): languages={ From 1be0861d4a7f0a4f93059a432142cd56fe0daebf Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 12:12:02 +0100 Subject: [PATCH 05/15] [FIX] encoding bug in tree printscreen lp bug: https://launchpad.net/bugs/311159 fixed bzr revid: christophe@taupe-20081226111202-pz23wa09u5kezfam --- bin/report/printscreen/ps_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/report/printscreen/ps_list.py b/bin/report/printscreen/ps_list.py index 379f11361df..834e459e355 100644 --- a/bin/report/printscreen/ps_list.py +++ b/bin/report/printscreen/ps_list.py @@ -157,7 +157,7 @@ class report_printscreen_list(report_int): line[f]= line[f][1] if fields[f]['type'] in ('one2many','many2many') and line[f]: - line[f] = '( '+str(len(line[f])) + ' )' + line[f] = '( '+tools.ustr(len(line[f])) + ' )' if fields[f]['type'] == 'float': precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2 line[f]='%.2f'%(line[f]) @@ -166,7 +166,7 @@ class report_printscreen_list(report_int): col.setAttribute('para','yes') col.setAttribute('tree','no') if line[f] != None: - txt = new_doc.createTextNode(str(line[f] or '')) + txt = new_doc.createTextNode(tools.ustr(line[f] or '')) if temp[count] == 1: tsum[count] = float(tsum[count]) + float(line[f]); From 5c0aaf07e04999a451faaf7e59bd8d950ab59398 Mon Sep 17 00:00:00 2001 From: "Sofia (Open ERP)" Date: Fri, 26 Dec 2008 17:21:41 +0530 Subject: [PATCH 06/15] security rules added for objects bzr revid: sso@tinyerp.com-20081226115141-a3ar7e7agyvboawc --- addons/account_voucher/__terp__.py | 1 + addons/account_voucher/security/ir.model.access.csv | 6 ++++++ addons/mrp_subproduct/__terp__.py | 1 + addons/mrp_subproduct/security/ir.model.access.csv | 3 +++ addons/wiki/security/ir.model.access.csv | 2 ++ 5 files changed, 13 insertions(+) create mode 100644 addons/account_voucher/security/ir.model.access.csv create mode 100644 addons/mrp_subproduct/security/ir.model.access.csv diff --git a/addons/account_voucher/__terp__.py b/addons/account_voucher/__terp__.py index 867711e5fe4..dacd296cb85 100755 --- a/addons/account_voucher/__terp__.py +++ b/addons/account_voucher/__terp__.py @@ -43,6 +43,7 @@ Basic Accounting, plus new things which available are: ], "update_xml" : [ + "security/ir.model.access.csv", "account_voucher_sequence.xml", "account_view.xml", "account_report.xml", diff --git a/addons/account_voucher/security/ir.model.access.csv b/addons/account_voucher/security/ir.model.access.csv new file mode 100644 index 00000000000..b4203be5416 --- /dev/null +++ b/addons/account_voucher/security/ir.model.access.csv @@ -0,0 +1,6 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_account_voucher_user","account.voucher","model_account_voucher","account.group_account_user",1,0,0,0 +"access_account_voucher_line_user","account.voucher.line","model_account_voucher_line","account.group_account_user",1,0,0,0 +"access_account_voucher_manager","account.voucher","model_account_voucher","account.group_account_manager",1,1,1,1 +"access_account_voucher_line_manager","account.voucher.line","model_account_voucher_line","account.group_account_manager",1,1,1,1 + diff --git a/addons/mrp_subproduct/__terp__.py b/addons/mrp_subproduct/__terp__.py index 14b0152d532..b24501839bd 100644 --- a/addons/mrp_subproduct/__terp__.py +++ b/addons/mrp_subproduct/__terp__.py @@ -37,6 +37,7 @@ With this module: """, "demo_xml" : [], "update_xml" : [ + "security/ir.model.access.csv", "mrp_subproduct_view.xml", ], "active": False, diff --git a/addons/mrp_subproduct/security/ir.model.access.csv b/addons/mrp_subproduct/security/ir.model.access.csv new file mode 100644 index 00000000000..3c6547410d4 --- /dev/null +++ b/addons/mrp_subproduct/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_mrp_subproduct_user","mrp.subproduct","model_mrp_subproduct","mrp.group_mrp_user",1,0,0,0 +"access_mrp_subproduct_manager","mrp.subproduct","model_mrp_subproduct","mrp.group_mrp_manager",1,1,1,1 diff --git a/addons/wiki/security/ir.model.access.csv b/addons/wiki/security/ir.model.access.csv index a54122e0231..acb871141ff 100644 --- a/addons/wiki/security/ir.model.access.csv +++ b/addons/wiki/security/ir.model.access.csv @@ -3,4 +3,6 @@ "wiki_groups_all","wiki.groups","model_wiki_groups",,1,0,0,0 "wiki_wiki","wiki.wiki","model_wiki_wiki","base.group_user",1,1,1,1 "wiki_groups","wiki.groups","model_wiki_groups","base.group_system",1,1,1,1 +"wiki_groups_link","wiki.groups.link","model_wiki_groups_link","base.group_system",1,1,1,1 "wiki_wiki_history","wiki.wiki.history","model_wiki_wiki_history","base.group_user",1,0,1,0 +"wiki_wizard_wiki_history_show_diff","wizard.wiki.history.show_diff","model_wizard_wiki_history_show_diff","base.group_user",1,1,1,1 From d67eab9c0738265a32d9a3a3c97bf483bec06581 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 14:27:39 +0100 Subject: [PATCH 07/15] [FIX] encoding errors lp bug: https://launchpad.net/bugs/31159 fixed bzr revid: christophe@taupe-20081226132739-ty8u9qe32dcu4iyi --- addons/auction/report/huissier.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/addons/auction/report/huissier.py b/addons/auction/report/huissier.py index e01063ba9c0..9afe67834c1 100644 --- a/addons/auction/report/huissier.py +++ b/addons/auction/report/huissier.py @@ -25,9 +25,8 @@ from osv.osv import osv, orm from report.interface import report_rml #FIXME: use the one from tools and delete the one from report from report.int_to_text import int_to_text - -def toxml(val): - return val.replace('&', '&').replace('<','<').replace('>','>').decode('utf-8').encode('latin1', 'replace') +from tools import to_xml as toxml +from tools import ustr class report_custom(report_rml): def __init__(self, name, table, tmpl, xsl): @@ -38,7 +37,7 @@ class report_custom(report_rml): lots = pool.get('auction.lots').browse(cr, uid, ids) auction = lots[0].auction_id - xml = ''' + xml = ''' %s @@ -49,7 +48,7 @@ class report_custom(report_rml): for l in lots: # l['id_cont'] = str(i) if l['obj_price']==0: - price_french = 'retiré' + price_french = u'retiré' else: price_french = int_to_text(int(l['obj_price'] or 0.0))+' eur' i+=1 @@ -59,10 +58,9 @@ class report_custom(report_rml): %s %s %s - ''' % (i, l['obj_num'], toxml(l['name']), price_french, str(l['obj_price'] or '/')) + ''' % (i, l['obj_num'], ustr(toxml(l['name'])), ustr(price_french), ustr(l['obj_price'] or '/')) xml += '' -# file('/tmp/terp.xml','wb+').write(xml) return xml report_custom('report.flagey.huissier', 'auction.lots', '', 'addons/auction/report/huissier.xsl') From bfecad04b59ee60afe9127a838e5dda7cc6d8eb0 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 14:29:45 +0100 Subject: [PATCH 08/15] [FIX] encoding problems lp bug: https://launchpad.net/bugs/311159 fixed bzr revid: christophe@taupe-20081226132945-z366jn2es0mms9ul --- bin/report/interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/report/interface.py b/bin/report/interface.py index da94535498e..99b5860c3e0 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -86,6 +86,7 @@ class report_rml(report_int): def create(self, cr, uid, ids, datas, context): xml = self.create_xml(cr, uid, ids, datas, context) + xml = tools.ustr(xml).encode('utf8') if datas.get('report_type', 'pdf') == 'raw': return xml rml = self.create_rml(cr, xml, uid, context) From 2bc319d919ca7c2de535017d13c5635f761dbdf4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 16:05:51 +0100 Subject: [PATCH 09/15] [FIX] encoding problems with the logger lp bug: https://launchpad.net/bugs/311528 fixed bzr revid: christophe@taupe-20081226150551-bk3rfyzba2lq2emu --- bin/netsvc.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/bin/netsvc.py b/bin/netsvc.py index 5a718f0c7a6..bc0d5362468 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -115,7 +115,6 @@ class Service(object): self._response = s(self._response_process_id) def abortResponse(self, error, description, origin, details): - import tools if not tools.config['debug_mode']: raise Exception("%s -- %s\n\n%s"%(origin, description, details)) else: @@ -152,12 +151,11 @@ LOG_CRITICAL = 'critical' logging.DEBUG_RPC = logging.DEBUG - 1 def init_logger(): - from tools import config import os logger = logging.getLogger() - if config['syslog']: + if tools.config['syslog']: # SysLog Handler if os.name == 'nt': sysloghandler = logging.handlers.NTEventLogHandler("%s %s" % @@ -171,9 +169,9 @@ def init_logger(): # create a format for log messages and dates formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %Y %H:%M:%S') - if config['logfile']: + if tools.config['logfile']: # LogFile Handler - logf = config['logfile'] + logf = tools.config['logfile'] try: dirname = os.path.dirname(logf) if dirname and not os.path.isdir(dirname): @@ -192,7 +190,7 @@ def init_logger(): # add the handler to the root logger logger.addHandler(handler) - logger.setLevel(config['log_level'] or '0') + logger.setLevel(tools.config['log_level'] or '0') if isinstance(handler, logging.StreamHandler) and os.name != 'nt': # change color of level names @@ -240,13 +238,14 @@ class Logger(object): level_method = getattr(log, level) - result = str(msg).strip().split('\n') + result = tools.ustr(msg).strip().split('\n') if len(result)>1: for idx, s in enumerate(result): level_method('[%02d]: %s' % (idx+1, s,), extra=extra) elif result: level_method(result[0], extra=extra) +import tools init_logger() class Agent(object): @@ -303,7 +302,6 @@ class GenericXMLRPCRequestHandler: self.log('exception', e) tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) s = str(e) - import tools if tools.config['debug_mode']: import pdb tb = sys.exc_info()[2] @@ -314,7 +312,6 @@ class SSLSocket(object): def __init__(self, socket): if not hasattr(socket, 'sock_shutdown'): from OpenSSL import SSL - import tools ctx = SSL.Context(SSL.SSLv23_METHOD) ctx.use_privatekey_file(tools.config['secure_pkey_file']) ctx.use_certificate_file(tools.config['secure_cert_file']) @@ -441,7 +438,6 @@ class TinySocketClientThread(threading.Thread): except Exception, e: print repr(e) tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - import tools if tools.config['debug_mode']: import pdb tb = sys.exc_info()[2] From 6de8fb60593372dba23186207c2c7cc81fc3eb77 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 17:34:58 +0100 Subject: [PATCH 10/15] [FIX] project_gtd: format exception correctly lp bug: https://launchpad.net/bugs/311548 fixed bzr revid: christophe@taupe-20081226163458-btibjzmn0wu9jx3o --- addons/project_gtd/wizard/project_gtd_daily.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/project_gtd/wizard/project_gtd_daily.py b/addons/project_gtd/wizard/project_gtd_daily.py index ad62ee39a4f..3a87f1bd3ed 100644 --- a/addons/project_gtd/wizard/project_gtd_daily.py +++ b/addons/project_gtd/wizard/project_gtd_daily.py @@ -33,7 +33,7 @@ class wiz_timebox_open(wizard.interface): pool = pooler.get_pool(cr.dbname) ids = pool.get('project.gtd.timebox').search(cr, uid, [('user_id','=',uid),('type','=',tbtype)]) if not len(ids): - raise wizard.except_wizard('Error !', 'No timebox of the type "%s" defined !') + raise wizard.except_wizard('Error !', 'No timebox of the type "%s" defined !' % (tbtype,)) view_type = 'form,tree' if len(ids) >= 1: domain = "[('id','in',["+','.join(map(str,ids))+"])]" From 16195435ed780fa945d17c8b3ecb65edbb34fec6 Mon Sep 17 00:00:00 2001 From: qdp Date: Fri, 26 Dec 2008 19:11:02 +0100 Subject: [PATCH 11/15] *added option on account_journal to group the account_move_line generated by an invoice if the columns tax_code_id, product_id, analityc_account_id and account_id are the same *bugfix: error when no analytic journal was defined on the account_journal and we tried to add an analytic account on an invoice line *improved translatability bzr revid: qdp@tinyerp.com-20081226181102-7daak46z0wyut9eu --- addons/account/account.py | 3 ++- addons/account/account_move_line.py | 2 ++ addons/account/account_view.xml | 2 ++ addons/account/invoice.py | 26 +++++++++++++++++++++++--- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/addons/account/account.py b/addons/account/account.py index 86d7ac16c68..f218e5b5bd7 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -451,8 +451,9 @@ class account_journal(osv.osv): 'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tell Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."), 'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account'), 'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account'), - 'centralisation': fields.boolean('Centralised counterpart', help="Check this box if you want that each entry doesn't create a counterpart but share the same counterpart for each entry of this journal."), + 'centralisation': fields.boolean('Centralised counterpart', help="Check this box if you want that each entry doesn't create a counterpart but share the same counterpart for each entry of this journal. This is used in fiscal year closing."), 'update_posted': fields.boolean('Allow Cancelling Entries'), + 'group_invoice_lines': fields.boolean('Group invoice lines', help="If this box is cheked, the system will try to group the accouting lines when generating them from invoices."), 'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="The sequence gives the display order for a list of journals", required=True), 'user_id': fields.many2one('res.users', 'User', help="The responsible user of this journal"), 'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'), diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index f32d150906d..4dbc8819893 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -61,6 +61,8 @@ class account_move_line(osv.osv): def create_analytic_lines(self, cr, uid, ids, context={}): for obj_line in self.browse(cr, uid, ids, context): if obj_line.analytic_account_id: + if not obj_line.journal_id.analytic_journal_id: + raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name,)) amt = (obj_line.credit or 0.0) - (obj_line.debit or 0.0) vals_lines={ 'name': obj_line.name, diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 02ad8648b95..b471343863b 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -267,6 +267,8 @@ + + diff --git a/addons/account/invoice.py b/addons/account/invoice.py index 39e03c710ad..606b8b00f50 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -68,7 +68,7 @@ class account_invoice(osv.osv): tt = type2journal.get(type_inv, 'sale') result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context) if not result: - raise osv.except_osv(_('No Analytic Journal !'),("You have to define an analytic journal of type '%s' !") % (tt,)) + raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal of type '%s' !") % (tt,)) return result[0] def _get_type(self, cr, uid, context={}): @@ -448,7 +448,7 @@ class account_invoice(osv.osv): ait_obj = self.pool.get('account.invoice.tax') cur_obj = self.pool.get('res.currency') acc_obj = self.pool.get('account.account') - self.button_compute(cr, uid, ids, context={}, set_total=True) + self.button_compute(cr, uid, ids, context={}, set_total=False) for inv in self.browse(cr, uid, ids): if inv.move_id: continue @@ -598,14 +598,34 @@ class account_invoice(osv.osv): date = inv.date_invoice or time.strftime('%Y-%m-%d') part = inv.partner_id.id + line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, part, date, context={})) ,iml) + if inv.journal_id.group_invoice_lines: + line2 = {} + for x, y, l in line: + tmp = str(l['account_id']) + tmp += '-'+str('tax_code_id' in l and l['tax_code_id'] or "False") + tmp += '-'+str('product_id' in l and l['product_id'] or "False") + tmp += '-'+str('analytic_account_id' in l and l['analytic_account_id'] or "False") + + if tmp in line2: + am = line2[tmp]['debit'] - line2[tmp]['credit'] + (l['debit'] - l['credit']) + line2[tmp]['debit'] = (am > 0) and am or 0.0 + line2[tmp]['credit'] = (am < 0) and -am or 0.0 + line2[tmp]['tax_amount'] += l['tax_amount'] + line2[tmp]['analytic_lines'] += l['analytic_lines'] + else: + line2[tmp] = l + line = [] + for key, val in line2.items(): + line.append((0,0,val)) + journal_id = inv.journal_id.id #self._get_journal(cr, uid, {'type': inv['type']}) journal = self.pool.get('account.journal').browse(cr, uid, journal_id) if journal.centralisation: raise osv.except_osv(_('UserError'), _('Can not create invoice move on centralized journal')) - move = {'ref': inv.number, 'line_id': line, 'journal_id': journal_id, 'date': date} period_id=inv.period_id and inv.period_id.id or False if not period_id: From e5f9fa5eb2bf27b545abecfe4e9c13fce9092ebf Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 26 Dec 2008 19:45:38 +0100 Subject: [PATCH 12/15] [FIX] tools.ustr, like str, must always return a string lp bug: https://launchpad.net/bugs/311595 fixed bzr revid: christophe@taupe-20081226184538-lkf5lepssmgctbsz --- bin/tools/misc.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bin/tools/misc.py b/bin/tools/misc.py index 933274ddf0c..a9157541a99 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -649,10 +649,6 @@ def ustr(value): @return: unicode string """ - if (value is None) or (value is False): - return value - if not value: - return u'' if isinstance(value, unicode): return value From 68d226b36399a2de9ccaf1ae6e7b838c02e08240 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Fri, 26 Dec 2008 20:21:44 +0100 Subject: [PATCH 13/15] improve bzr revid: fp@tinyerp.com-20081226192144-xta0redr3e13vgja --- addons/base_contact/base_contact.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py index 289b0b48dc7..943949cff31 100644 --- a/addons/base_contact/base_contact.py +++ b/addons/base_contact/base_contact.py @@ -111,13 +111,13 @@ class res_partner_job(osv.osv): return super(res_partner_job,self).search(cr, user, args, offset, limit, order, context, count) _name = 'res.partner.job' - _description ='Contact Job Title' + _description ='Contact Partner Function' _order = 'sequence_contact' _columns = { 'name': fields.related('address_id','partner_id', type='many2one', relation='res.partner', string='Partner'), 'address_id':fields.many2one('res.partner.address','Address'), 'contact_id':fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'), - 'function_id': fields.many2one('res.partner.function','Job Title'), + 'function_id': fields.many2one('res.partner.function','Partner Function'), 'sequence_contact':fields.integer('Sequence',help='Order of importance of this address in the list of addresses of the linked contact'), 'sequence_partner':fields.integer('Sequence',help='Order of importance of this job title in the list of job title of the linked partner'), 'email': fields.char('E-Mail', size=240), From 988263fd7cdac8eefd6ebbc96e0074b0391c4a87 Mon Sep 17 00:00:00 2001 From: "Apa (Open ERP)" Date: Sat, 27 Dec 2008 10:44:44 +0530 Subject: [PATCH 14/15] modify bzr revid: apa@tinyerp.com-20081227051444-9mflf9m5vjj2n071 --- addons/account_payment/payment_report.xml | 2 +- addons/account_payment/report/payment_order.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_payment/payment_report.xml b/addons/account_payment/payment_report.xml index 0f39148f719..699207e1733 100644 --- a/addons/account_payment/payment_report.xml +++ b/addons/account_payment/payment_report.xml @@ -1,6 +1,6 @@ - + diff --git a/addons/account_payment/report/payment_order.py b/addons/account_payment/report/payment_order.py index f3e9b612d62..ee4dcefed5c 100644 --- a/addons/account_payment/report/payment_order.py +++ b/addons/account_payment/report/payment_order.py @@ -31,4 +31,4 @@ class payment_order(report_sxw.rml_parse): 'time': time, }) -report_sxw.report_sxw('report.payment.order', 'payement.order', 'addons/account_payment/report/payment_order.rml', parser=payment_order,header=False) \ No newline at end of file +report_sxw.report_sxw('report.payment.order', 'payment.order', 'addons/account_payment/report/payment_order.rml', parser=payment_order,header=False) \ No newline at end of file From 06882ed8a0c5bd9c660e9a87f11c0a5af0ab93e4 Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Sat, 27 Dec 2008 14:40:14 +0530 Subject: [PATCH 15/15] base module quality bzr revid: mra@tinyerp.com-20081227091014-ds6ad7ylqtfkgi6j --- .../base_module_quality.py | 78 +++++++++++++---- .../base_module_quality_wizard.xml | 16 +++- .../method_test/method_test.py | 31 ++++--- .../pylint_test/pylint_test.py | 29 +++++-- .../speed_test/speed_test.py | 85 ++++++++++--------- .../wizard/module_quality_check.py | 16 +++- 6 files changed, 167 insertions(+), 88 deletions(-) diff --git a/addons/base_module_quality/base_module_quality.py b/addons/base_module_quality/base_module_quality.py index ef4a0c3c515..101043b498c 100644 --- a/addons/base_module_quality/base_module_quality.py +++ b/addons/base_module_quality/base_module_quality.py @@ -26,34 +26,51 @@ class abstract_quality_check(object): This Class provide... ''' - #This float have to store the rating of the module. - #Used to compute the final score (average of all scores). - score = 0.0 - - #This char have to store the result. - #Used to display the result of the test. - result = "" - - #This char have to store the result with more details. - #Used to provide more details if necessary. - result_details = "" - - #This bool defines if the test can be run only if the module is installed. - #True => the module have to be installed. - #False => the module can be uninstalled. - bool_installed_only = True +# #This float have to store the rating of the module. +# #Used to compute the final score (average of all scores). +# score = 0.0 +# +# #This char have to store the result. +# #Used to display the result of the test. +# result = "" +# +# #This char have to store the result with more details. +# #Used to provide more details if necessary. +# result_details = "" +# +# #This bool defines if the test can be run only if the module is installed. +# #True => the module have to be installed. +# #False => the module can be uninstalled. +# bool_installed_only = True def __init__(self): ''' this method should initialize the var ''' - raise 'Not Implemented' + #This float have to store the rating of the module. + #Used to compute the final score (average of all scores). + self.score = 0.0 + + #This char have to store the result. + #Used to display the result of the test. + self.result = "" + + #This char have to store the result with more details. + #Used to provide more details if necessary. + self.result_details = "" + + #This bool defines if the test can be run only if the module is installed. + #True => the module have to be installed. + #False => the module can be uninstalled. + self.bool_installed_only = True + +# raise 'Not Implemented' def run_test(self, cr, uid, module_path=""): ''' this method should do the test and fill the score, result and result_details var ''' - raise 'Not Implemented' +# raise 'Not Implemented' def get_objects(self, cr, uid, module): # This function returns all object of the given module.. @@ -77,5 +94,30 @@ class abstract_quality_check(object): result_ids[obj] = ids return result_ids + def format_table(self, test='', header=[], data_list=[]): + res_format = {} + if test=='method': + detail = "" + detail += "\n===Method Test===\n" + detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % (header[0].ljust(40), header[1].ljust(16), header[2].ljust(20), header[3].ljust(16)) + for res in data_list[1][0]: + detail += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, data_list[1][0][res][0], data_list[1][0][res][1], data_list[1][0][res][2]) + res_format['summary'] = [data_list[0][0]] + res_format['detail'] = [detail + '\n|}'] + elif test=='pylint': + res_format['summary'] = data_list[0] + res_format['detail'] = data_list[1] + elif test=='speed': + detail = "" + detail += "\n===Speed Test===\n" + detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % (header[0].ljust(40), header[1].ljust(10), header[2].ljust(10), header[3].ljust(10), header[4].ljust(10), header[5].ljust(20)) + for data in data_list[1]: + detail += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (data[0], data[1], data[2], data[3], data[4], data[5]) + res_format['summary'] = data_list[0] + res_format['detail'] = [detail + '\n|}\n'] + return res_format + + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/base_module_quality_wizard.xml b/addons/base_module_quality/base_module_quality_wizard.xml index b49c17667a7..f85c19ab6f7 100644 --- a/addons/base_module_quality/base_module_quality_wizard.xml +++ b/addons/base_module_quality/base_module_quality_wizard.xml @@ -9,8 +9,20 @@ form
- - + + + + + + + + + + + + + + diff --git a/addons/base_module_quality/method_test/method_test.py b/addons/base_module_quality/method_test/method_test.py index 0ef59cc2b29..b2015723dcb 100644 --- a/addons/base_module_quality/method_test/method_test.py +++ b/addons/base_module_quality/method_test/method_test.py @@ -30,12 +30,13 @@ import pooler class quality_test(base_module_quality.abstract_quality_check): def __init__(self): - self.result = """ -===Method Test===: - -This test checks if the module classes are raising exception when calling basic methods or no. - -""" + super(quality_test, self).__init__() +# self.result = """ +#===Method Test===: +# +#This test checks if the module classes are raising exception when calling basic methods or no. +# +#""" self.bool_installed_only = True return None @@ -46,7 +47,6 @@ This test checks if the module classes are raising exception when calling basic result = {} ok_count = 0 ex_count = 0 - for obj in obj_list: temp = [] try: @@ -71,13 +71,18 @@ This test checks if the module classes are raising exception when calling basic temp.append('Exception') ex_count += 1 result[obj] = temp - self.result += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % ('Object Name'.ljust(40), 'search()'.ljust(16), 'fields_view_get()'.ljust(20), 'read()'.ljust(16)) - - for res in result: - self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2]) - - self.result += '\n|}' +# self.result += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % ('Object Name'.ljust(40), 'search()'.ljust(16), 'fields_view_get()'.ljust(20), 'read()'.ljust(16)) + header_list = ['Object Name', 'search()', 'fields_view_get', 'read'] +# for res in result: +# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2]) +# self.result += '\n|}' self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0 + summary = """\n ===Method Test===: + +This test checks if the module classes are raising exception when calling basic methods or no. + +""" + "Score: " + str(self.score) + "/10\n" + self.result = self.format_table(test='method', header=header_list, data_list=[[summary],[result]]) return None diff --git a/addons/base_module_quality/pylint_test/pylint_test.py b/addons/base_module_quality/pylint_test/pylint_test.py index bc05b5fc850..5bf240346d1 100644 --- a/addons/base_module_quality/pylint_test/pylint_test.py +++ b/addons/base_module_quality/pylint_test/pylint_test.py @@ -30,12 +30,13 @@ from base_module_quality import base_module_quality class quality_test(base_module_quality.abstract_quality_check): def __init__(self): - self.result = """ -===Pylint Test===: - - This test checks if the module satisfy the current coding standard used by OpenERP. - -""" + super(quality_test, self).__init__() +# self.result = """ +#===Pylint Test===: +# +# This test checks if the module satisfy the current coding standard used by OpenERP. +# +#""" self.bool_installed_only = False return None @@ -50,6 +51,8 @@ class quality_test(base_module_quality.abstract_quality_check): n = 0 score = 0.0 + detail = "" + detail = "\n===Pylint Test===\n" for file in list_files: if file.split('.')[-1] == 'py' and not file.endswith('__init__.py') and not file.endswith('__terp__.py'): file_path = os.path.join(module_path, file) @@ -64,13 +67,21 @@ class quality_test(base_module_quality.abstract_quality_check): try: score += float(res[leftchar+1:rightchar]) - self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n" +# self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n" + detail += file + ": " + res[leftchar+1:rightchar] + "/10\n" except: score += 0 - self.result += file + ": Unable to parse the result. Check the details.\n" - +# self.result += file + ": Unable to parse the result. Check the details.\n" + detail += file + ": Unable to parse the result. Check the details.\n" self.result_details += res self.score = n and score / n or score + summary =""" +===Pylint Test===: + + This test checks if the module satisfy the current coding standard used by OpenERP. + +""" + "Score: " + str(self.score) + "/10\n" + self.result = self.format_table(test='pylint', data_list=[[summary],[detail]]) return None diff --git a/addons/base_module_quality/speed_test/speed_test.py b/addons/base_module_quality/speed_test/speed_test.py index 55c05e594b9..5a9176e4946 100644 --- a/addons/base_module_quality/speed_test/speed_test.py +++ b/addons/base_module_quality/speed_test/speed_test.py @@ -34,74 +34,75 @@ from base_module_quality import base_module_quality class quality_test(base_module_quality.abstract_quality_check): def __init__(self): - self.result = """ -===Speed Test===: - -This test checks the speed of the module. - -""" + super(quality_test, self).__init__() +# self.result = """ +#===Speed Test===: +# +#This test checks the speed of the module. +# +#""" self.bool_installed_only = True return None - def run_test(self, cr, uid, module_path): pool = pooler.get_pool(cr.dbname) module_name = module_path.split('/')[-1] - self.result+=('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % ('Object Name'.ljust(40), 'Size (S)'.ljust(10), '1'.ljust(10), 'S/2'.ljust(10), 'S'.ljust(10), 'Complexity'.ljust(20)) +# self.result+=('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % ('Object Name'.ljust(40), 'Size-Number of Records (S)'.ljust(10), '1'.ljust(10), 'S/2'.ljust(10), 'S'.ljust(10), 'Complexity using query'.ljust(20)) + header_list = ['Object Name', 'Size-Number of Records (S)', '1', 'S/2', 'S', 'Complexity using query'] obj_list = self.get_objects(cr, uid, module_name) obj_counter = 0 score = 0 obj_ids = self.get_ids(cr, uid, obj_list) + detail = "" + list1 = [] for obj in obj_ids: obj_counter += 1 ids = obj_ids[obj] ids = ids[:100] size = len(ids) if size: - c1 = time.time() + c1 = cr.count + pool.get(obj).read(cr, uid, ids[0]) - c2 = time.time() - base_time = c2 - c1 - c1 = time.time() + pool.get(obj).read(cr, uid, ids[0]) + code_base_complexity = cr.count - c1 + pool.get(obj).read(cr, uid, ids[:size/2]) - c2 = time.time() - halfsize_time = c2 - c1 - c1 = time.time() + pool.get(obj).read(cr, uid, ids[:size/2]) + code_half_complexity = cr.count - c1 + pool.get(obj).read(cr, uid, ids) - c2 = time.time() - size_time = c2 - c1 + pool.get(obj).read(cr, uid, ids) + code_size_complexity = cr.count - c1 + if size < 5: self.score += -2 - self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, base_time, halfsize_time, size_time, "Warning! Not enough demo data") +# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data") + list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data"] + list1.append(list) else: - tolerated_margin = 5/100 - complexity = "not recognized" - if min(size_time,base_time,halfsize_time) != base_time: + if code_size_complexity <= (code_base_complexity + size): complexity = "O(1)" - score += 10 - + score = 10 else: - k1 = (halfsize_time - base_time)*1000 / ((size/2) - 1) - k2 = (size_time - base_time)*1000 / ((size) - 1) - tmp = k1 * tolerated_margin - if (k1 - tmp) < k2 and k2 < (k1 + tmp): - complexity = "O(n)" - if round(tmp) == 0: - complexity = "O(1)" - score += 10 - else: - score += 5 - else: - complexity = "O(n²) or worst" - score += 0 - - self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, base_time, halfsize_time, size_time, complexity) + complexity = "O(n) or worst" + score = 0 +# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity) + list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity] + list1.append(list) else: score += -5 - self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, "", "", "", "Warning! Object has no demo data") - - - self.result += '\n|}\n' +# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, "", "", "", "Warning! Object has no demo data") + list = [obj, size, "", "", "", "Warning! Object has no demo data"] + list1.append(list) +# self.result += '\n|}\n' self.score = obj_counter and score/obj_counter or 0.0 + summary = """ +===Speed Test===: + + This test checks the speed of the module. + +"""+ "Score: " + str(self.score) + "/10\n" + self.result = self.format_table(test='speed', header=header_list, data_list=[[summary],list1]) return None # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/wizard/module_quality_check.py b/addons/base_module_quality/wizard/module_quality_check.py index e029a94b137..48a04f8f921 100644 --- a/addons/base_module_quality/wizard/module_quality_check.py +++ b/addons/base_module_quality/wizard/module_quality_check.py @@ -56,9 +56,9 @@ class wiz_quality_check(osv.osv_memory): # general_info = "" _name = 'wizard.quality.check' - def _check(self, cr, uid, data, context={}): string_ret = "" + string_detail = "" from tools import config data['ids'] = data.get('module_id', False) pool = pooler.get_pool(cr.dbname) @@ -72,7 +72,7 @@ class wiz_quality_check(osv.osv_memory): if module_data[0].name == 'base': ad = tools.config['root_path']+'/addons' module_path = os.path.join(ad, module_data[0].name) - item2 = 'base_module_quality.'+item+'.'+item + item2 = 'base_module_quality.' + item +'.' + item x = __import__(item2) x2 = getattr(x, item) x3 = getattr(x2, item) @@ -81,9 +81,14 @@ class wiz_quality_check(osv.osv_memory): val.run_test(cr, uid, str(module_path)) else: val.result += "The module has to be installed before running this test." - string_ret += val.result + string_ret += val.result['summary'][0] + string_detail += val.result['detail'][0] + self.string_detail = string_detail return string_ret + def _check_detail(self, cr, uid, data, context={}): + return self.string_detail + # def _general_info(self, cr, uid, data, context={}): # return self.general_info @@ -102,9 +107,12 @@ class wiz_quality_check(osv.osv_memory): #~ }, _columns = { 'general_info': fields.text('General Info', readonly="1",), + 'detail' : fields.text('Detail', readonly="1",), + 'verbose_detail' : fields.text('Verbose Detail', readonly="1",) } _defaults = { - 'general_info': _check + 'general_info': _check, + 'detail': _check_detail } wiz_quality_check()