commit
aa188ff423
|
@ -166,15 +166,14 @@ class account_account(osv.osv):
|
|||
|
||||
def _get_children_and_consol(self, cr, uid, ids, context={}):
|
||||
#this function search for all the children and all consolidated children (recursively) of the given account ids
|
||||
res = self.search(cr, uid, [('parent_id', 'child_of', ids)])
|
||||
for id in res:
|
||||
this = self.browse(cr, uid, id, context)
|
||||
for child in this.child_consol_ids:
|
||||
if child.id not in res:
|
||||
res.append(child.id)
|
||||
if len(res) != len(ids):
|
||||
return self._get_children_and_consol(cr, uid, res, context)
|
||||
return res
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context)
|
||||
ids3 = []
|
||||
for rec in self.browse(cr, uid, ids2, context=context):
|
||||
for child in rec.child_consol_ids:
|
||||
ids3.append[child.id]
|
||||
if ids3:
|
||||
ids3 = self._get_children_and_consol(cr, uid, ids3, context)
|
||||
return ids2+ids3
|
||||
|
||||
def __compute(self, cr, uid, ids, field_names, arg, context={}, query=''):
|
||||
#compute the balance/debit/credit accordingly to the value of field_name for the given account ids
|
||||
|
@ -1224,15 +1223,15 @@ class account_tax(osv.osv):
|
|||
#
|
||||
'base_code_id': fields.many2one('account.tax.code', 'Base Code', help="Use this code for the VAT declaration."),
|
||||
'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', help="Use this code for the VAT declaration."),
|
||||
'base_sign': fields.float('Base Code Sign', help="Usualy 1 or -1."),
|
||||
'tax_sign': fields.float('Tax Code Sign', help="Usualy 1 or -1."),
|
||||
'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
|
||||
'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
|
||||
|
||||
# Same fields for refund invoices
|
||||
|
||||
'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the VAT declaration."),
|
||||
'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the VAT declaration."),
|
||||
'ref_base_sign': fields.float('Base Code Sign', help="Usualy 1 or -1."),
|
||||
'ref_tax_sign': fields.float('Tax Code Sign', help="Usualy 1 or -1."),
|
||||
'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
|
||||
'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
|
||||
'include_base_amount': fields.boolean('Include in base amount', help="Indicate if the amount of tax must be included in the base amount for the computation of the next taxes"),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
'description': fields.char('Internal Name',size=32),
|
||||
|
|
|
@ -791,6 +791,7 @@ class account_move_line(osv.osv):
|
|||
|
||||
move_id = vals.get('move_id', False)
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, context['journal_id'])
|
||||
is_new_move = False
|
||||
if not move_id:
|
||||
if journal.centralisation:
|
||||
# use the first move ever created for this journal and period
|
||||
|
@ -815,10 +816,7 @@ class account_move_line(osv.osv):
|
|||
vals['move_id'] = move_id
|
||||
else:
|
||||
raise osv.except_osv(_('No piece number !'), _('Can not create an automatic sequence for this piece !\n\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
|
||||
else:
|
||||
if 'date' in vals:
|
||||
self.pool.get('account.move').write(cr, uid, [move_id], {'date':vals['date']}, context=context)
|
||||
del vals['date']
|
||||
is_new_move = True
|
||||
|
||||
ok = not (journal.type_control_ids or journal.account_control_ids)
|
||||
if ('account_id' in vals):
|
||||
|
@ -931,6 +929,8 @@ class account_move_line(osv.osv):
|
|||
if data['tax_code_id']:
|
||||
self.create(cr, uid, data, context)
|
||||
|
||||
if not is_new_move and 'date' in vals:
|
||||
self.pool.get('account.move').write(cr, uid, [move_id], {'date':vals['date']}, context=context)
|
||||
if check:
|
||||
tmp = self.pool.get('account.move').validate(cr, uid, [vals['move_id']], context)
|
||||
if journal.entry_posted and tmp:
|
||||
|
|
|
@ -297,7 +297,7 @@
|
|||
<para style="terp_default_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<blockTable colWidths="211.0,62.0,63.0,63.0,36.0,89.0" style="Table_Header_Invoice_Line">
|
||||
<blockTable colWidths="211.0,62.0,63.0,63.0,40.0,85.0" style="Table_Header_Invoice_Line">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details">Description</para>
|
||||
|
@ -312,7 +312,7 @@
|
|||
<para style="terp_tblheader_Details_Right">Unit Price</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">Disc. (%)</para>
|
||||
<para style="terp_tblheader_Details_Right">Disc.(%)</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Price</para>
|
||||
|
@ -350,7 +350,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_Note">[[ format(l.note or removeParentNode('tr')) ]]</para>
|
||||
<para style="terp_default_Note">[[ format(l.note) or removeParentNode('tr') ]]</para>
|
||||
<para style="terp_default_Note">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
|
@ -463,7 +463,7 @@
|
|||
<blockTable colWidths="530.0" style="Table_Main_Table">
|
||||
<tr>
|
||||
<td>
|
||||
<!-- <para style="terp_default_8">[[ format(o.amount_tax or removeParentNode('blockTable')) ]]</para> -->
|
||||
<!-- <para style="terp_default_8">[[ format(o.amount_tax) or removeParentNode('blockTable') ]]</para> -->
|
||||
<blockTable colWidths="54.0,58.0,67.0" style="Table_Tax_Header">
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -541,7 +541,7 @@
|
|||
<blockTable colWidths="530.0" style="Table_Coment_Payment_Term">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ format(o.comment or removeParentNode('blockTable')) ]]</para>
|
||||
<para style="terp_default_9">[[ format(o.comment) or removeParentNode('blockTable') ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -551,7 +551,7 @@
|
|||
<blockTable colWidths="530.0" style="Table_Payment_Terms">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ format((o.payment_term and o.payment_term.note) or removeParentNode('blockTable')) ]]</para>
|
||||
<para style="terp_default_9">[[ format(o.payment_term and o.payment_term.note) or removeParentNode('blockTable') ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -51,18 +51,19 @@ def _data_load(self, cr, uid, data, context):
|
|||
|
||||
def _data_save(self, cr, uid, data, context):
|
||||
if not data['form']['sure']:
|
||||
raise wizard.except_wizard(_('UserError'), _('Closing of fiscal year canceled, please check the box !'))
|
||||
raise wizard.except_wizard(_('UserError'), _('Closing of fiscal year cancelled, please check the box !'))
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
|
||||
fy_id = data['form']['fy_id']
|
||||
new_fyear = pool.get('account.fiscalyear').browse(cr, uid, data['form']['fy2_id'])
|
||||
start_jp = new_fyear.start_journal_period_id
|
||||
|
||||
if data['form']['report_new']:
|
||||
periods_fy2 = pool.get('account.fiscalyear').browse(cr, uid, data['form']['fy2_id']).period_ids
|
||||
if not periods_fy2:
|
||||
raise wizard.except_wizard(_('UserError'),
|
||||
_('There are no periods defined on New Fiscal Year.'))
|
||||
period=periods_fy2[0]
|
||||
new_fyear = pool.get('account.fiscalyear').browse(cr, uid, data['form']['fy2_id'])
|
||||
start_jp = new_fyear.start_journal_period_id
|
||||
if not start_jp:
|
||||
raise wizard.except_wizard(_('UserError'),
|
||||
_('The new fiscal year should have a journal for new entries define on it'))
|
||||
|
@ -98,7 +99,7 @@ def _data_save(self, cr, uid, data, context):
|
|||
'period_id': period.id,
|
||||
'account_id': account.id
|
||||
}, {'journal_id': new_journal.id, 'period_id':period.id})
|
||||
if accnt_type_data.close_method=='unreconciled':
|
||||
if accnt_type_data.close_method == 'unreconciled':
|
||||
offset = 0
|
||||
limit = 100
|
||||
while True:
|
||||
|
@ -162,8 +163,8 @@ def _data_save(self, cr, uid, data, context):
|
|||
cr.execute('UPDATE account_period SET state = %s ' \
|
||||
'WHERE fiscalyear_id = %s', ('done',fy_id))
|
||||
cr.execute('UPDATE account_fiscalyear ' \
|
||||
'SET state = %s, end_journal_period_id = %s' \
|
||||
'WHERE id = %s', ('done',start_jp.id,fy_id))
|
||||
'SET state = %s, end_journal_period_id = %s ' \
|
||||
'WHERE id = %s', ('done', start_jp and start_jp.id or None, fy_id))
|
||||
return {}
|
||||
|
||||
class wiz_journal_close(wizard.interface):
|
||||
|
|
|
@ -287,11 +287,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="P19">[[ format(o.comment or '') ]]</para>
|
||||
<para style="P19">[[ format(o.comment) or '' ]]</para>
|
||||
<para style="P19">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="P19">[[ format((o.payment_term and o.payment_term.note) or '') ]]</para>
|
||||
<para style="P19">[[ format(o.payment_term and o.payment_term.note) or '' ]]</para>
|
||||
</story>
|
||||
</document>
|
||||
|
||||
|
|
|
@ -287,11 +287,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="P19">[[ format(o.comment or '') ]]</para>
|
||||
<para style="P19">[[ format(o.comment) or '' ]]</para>
|
||||
<para style="P19">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="P19">[[ format((o.payment_term and o.payment_term.note) or '') ]]</para>
|
||||
<para style="P19">[[ format(o.payment_term and o.payment_term.note) or '' ]]</para>
|
||||
<section>
|
||||
<para style="P19">[[ repeatIn((spcl_msg(data['form']) and spcl_msg(data['form']).splitlines()) or [], 'note') ]]</para>
|
||||
<para style="P19">[[ note or removeParentNode('para') ]]</para>
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
##############################################################################
|
||||
import pooler
|
||||
import os
|
||||
import osv
|
||||
from tools import config
|
||||
|
||||
class abstract_quality_check(object):
|
||||
'''
|
||||
This Class provide...
|
||||
This Class provides...
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
|
@ -40,6 +41,9 @@ class abstract_quality_check(object):
|
|||
#This char have to store the name of the test.
|
||||
self.name = ""
|
||||
|
||||
#This char have to store the aim of the test and eventually a note.
|
||||
self.note = ""
|
||||
|
||||
#This char have to store the result.
|
||||
#Used to display the result of the test.
|
||||
self.result = ""
|
||||
|
@ -77,7 +81,8 @@ class abstract_quality_check(object):
|
|||
'''
|
||||
this method should do the test and fill the score, result and result_details var
|
||||
'''
|
||||
raise 'Not Implemented'
|
||||
|
||||
raise osv.except_osv(_('Programming Error'), _('Test Is Not Implemented'))
|
||||
|
||||
def get_objects(self, cr, uid, module):
|
||||
# This function returns all object of the given module..
|
||||
|
@ -103,14 +108,12 @@ class abstract_quality_check(object):
|
|||
|
||||
def format_table(self, header=[], data_list=[]):
|
||||
detail = ""
|
||||
header_list = []
|
||||
final_list = []
|
||||
for head in data_list[1]:
|
||||
header_list.append(head)
|
||||
detail += (header[0]) % tuple(header_list)
|
||||
for res in data_list[0]:
|
||||
data_list[0][res].append(res)
|
||||
detail += (header[1]) % tuple(data_list[0][res])
|
||||
detail += (header[0]) % tuple(header[1])
|
||||
frow = '\n|-'
|
||||
for i in header[1]:
|
||||
frow += '\n| %s'
|
||||
for key, value in data_list.items():
|
||||
detail += (frow) % tuple(value)
|
||||
detail = detail + '\n|}'
|
||||
return detail
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Result">
|
||||
<field name="name" nolabel="1" readonly="1"/>
|
||||
<field name="final_score" nolabel="1" readonly="1"/>
|
||||
<field name="name" readonly="1" search="1"/>
|
||||
<field name="final_score" readonly="1" search="1"/>
|
||||
<separator colspan="4" string="Tests"/>
|
||||
<field name="test_ids" nolabel="1" colspan="4" height="350" width="800" readonly="1"/>
|
||||
</form>
|
||||
|
@ -38,8 +38,11 @@
|
|||
<page string="Summary">
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="score" readonly="1"/>
|
||||
<field name="ponderation" readonly="1"/>
|
||||
<field name="note" readonly="1" colspan="4"/>
|
||||
<field name="summary" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800" readonly="1"/>
|
||||
|
||||
<field name="ponderation" readonly="1"/>
|
||||
<field name="state" readonly="1"/>
|
||||
</page>
|
||||
<page string="Detail">
|
||||
<field name="detail" widget="text_wiki" nolabel="1" colspan="4" readonly="1"/>
|
||||
|
@ -55,8 +58,9 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Result">
|
||||
<field name="name"/>
|
||||
<field name="score"/>
|
||||
<field name="name" required="1"/>
|
||||
<field name="state"/>
|
||||
<field name="score" required="1"/>
|
||||
<field name="ponderation"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
|
|
@ -32,10 +32,11 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
def __init__(self):
|
||||
super(quality_test, self).__init__()
|
||||
self.name = _("Method Test")
|
||||
self.note = _("""
|
||||
This test checks if the module classes are raising exception when calling basic methods or not.
|
||||
""")
|
||||
self.bool_installed_only = True
|
||||
self.ponderation = 1.0
|
||||
self.result_det = {}
|
||||
self.data_list = []
|
||||
return None
|
||||
|
||||
def run_test(self, cr, uid, module_path):
|
||||
|
@ -44,51 +45,41 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
obj_list = self.get_objects(cr, uid, module_name)
|
||||
ok_count = 0
|
||||
ex_count = 0
|
||||
result_dict = {}
|
||||
for obj in obj_list:
|
||||
temp = []
|
||||
temp = [obj]
|
||||
try:
|
||||
res = pool.get(obj).search(cr, uid, [])
|
||||
temp.append('Ok')
|
||||
temp.append(_('Ok'))
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
temp.append(_('Exception'))
|
||||
ex_count += 1
|
||||
try:
|
||||
res1 = pool.get(obj).fields_view_get(cr, uid,)
|
||||
temp.append('Ok')
|
||||
temp.append(_('Ok'))
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
temp.append(_('Exception'))
|
||||
ex_count += 1
|
||||
try:
|
||||
res2 = pool.get(obj).read(cr, uid, [])
|
||||
temp.append('Ok')
|
||||
temp.append(_('Ok'))
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
temp.append(_('Exception'))
|
||||
ex_count += 1
|
||||
self.result_det[obj] = temp
|
||||
self.data_list.append(self.result_det)
|
||||
result_dict[obj] = temp
|
||||
self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0
|
||||
self.result = self.get_result()
|
||||
self.result_details = self.get_result_details()
|
||||
self.result = self.get_result(result_dict)
|
||||
return None
|
||||
|
||||
def get_result(self):
|
||||
summary = """
|
||||
This test checks if the module classes are raising exception when calling basic methods or no.
|
||||
"""
|
||||
return summary
|
||||
|
||||
def get_result_details(self):
|
||||
header_list = []
|
||||
header_list.append('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ')
|
||||
header_list.append('\n|-\n| %s \n| %s \n| %s \n| %s ')
|
||||
header_view = ['Object Name', 'search()', 'fields_view_get', 'read']
|
||||
self.data_list.append(header_view)
|
||||
def get_result(self, dict):
|
||||
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ', [_('Object Name'), 'search()', 'fields_view_get()', 'read()'])
|
||||
detail = ""
|
||||
if not self.error:
|
||||
detail += self.format_table(header=header_list, data_list=self.data_list)
|
||||
detail += self.format_table(header, dict)
|
||||
return detail
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -32,6 +32,7 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
def __init__(self):
|
||||
super(quality_test, self).__init__()
|
||||
self.name = _("Pylint Test")
|
||||
self.note = _("""This test uses Pylint and checks if the module satisfies the coding standard of Python. See http://www.logilab.org/project/name/pylint for further info.\n """)
|
||||
self.bool_installed_only = False
|
||||
self.ponderation = 1.0
|
||||
return None
|
||||
|
@ -47,7 +48,8 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
n = 0
|
||||
score = 0.0
|
||||
self.result += "\nThis test checks if the module satisfies the current coding standard used by OpenERP. \n\n"
|
||||
dict = {}
|
||||
self.result_details += '<nowiki>'
|
||||
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)
|
||||
|
@ -65,36 +67,24 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
rightchar += 1
|
||||
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"
|
||||
dict[file] = [file, res[leftchar+1:rightchar]]
|
||||
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"
|
||||
dict[file] = [file, _("Unable to parse the result. Check the details.")]
|
||||
self.result_details += res
|
||||
|
||||
self.result_details += '</nowiki>'
|
||||
average_score = n and score / n or score
|
||||
self.score = (average_score + 10) /20
|
||||
self.score = (max(average_score,0)) / 10
|
||||
self.result = self.get_result(dict)
|
||||
return None
|
||||
|
||||
def get_result(self, cr, uid, module_path):
|
||||
self.run_test(cr, uid, module_path)
|
||||
if not self.bool_installed_only or module_state=="installed":
|
||||
summary ="""
|
||||
===Pylint Test===:
|
||||
|
||||
This test checks if the module satisfies the current coding standard used by OpenERP.
|
||||
|
||||
""" + "Score: " + str(self.score) + "/10\n"
|
||||
else:
|
||||
summary =""" \n===Pylint Test===:
|
||||
|
||||
The module has to be installed before running this test.\n\n """
|
||||
header_list = ""
|
||||
self.error = True
|
||||
return summary
|
||||
|
||||
def get_result_details(self):
|
||||
detail = "\n===Pylint Test===\n" + self.result
|
||||
return detail
|
||||
def get_result(self, dict):
|
||||
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('File Name'), _('Result (/10)'),])
|
||||
if not self.error:
|
||||
return self.format_table(header, data_list=dict)
|
||||
return ""
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -35,12 +35,15 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
def __init__(self):
|
||||
super(quality_test, self).__init__()
|
||||
self.name = _("Speed Test")
|
||||
self.bool_installed_only = True
|
||||
self.ponderation = 1.0
|
||||
self.result_det = {}
|
||||
self.data_list = []
|
||||
self.name = _("Speed Test")
|
||||
self.note = _("""
|
||||
This test checks the speed of the module. Note that at least 5 demo data is needed in order to run it.
|
||||
|
||||
""")
|
||||
return None
|
||||
|
||||
def run_test(self, cr, uid, module_path):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
module_name = module_path.split('/')[-1]
|
||||
|
@ -48,66 +51,69 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
obj_counter = 0
|
||||
score = 0
|
||||
obj_ids = self.get_ids(cr, uid, obj_list)
|
||||
result_dict = {}
|
||||
result_dict2 = {}
|
||||
self.result_details += _("O(1) means that the number of SQL requests to read the object does not depand on the number of objects we are reading. This feature is hardly wished.\n")
|
||||
for obj in obj_ids:
|
||||
obj_counter += 1
|
||||
ids = obj_ids[obj]
|
||||
ids = ids[:100]
|
||||
size = len(ids)
|
||||
if size:
|
||||
c1 = cr.count
|
||||
list = []
|
||||
|
||||
#we perform the operation twice, and count the number of queries in the second run. This allows to avoid the cache effect. (like translated terms that asks for more queries)
|
||||
pool.get(obj).read(cr, uid, [ids[0]])
|
||||
c = cr.count
|
||||
pool.get(obj).read(cr, uid, [ids[0]])
|
||||
code_base_complexity = cr.count - c1
|
||||
code_base_complexity = cr.count - c
|
||||
|
||||
pool.get(obj).read(cr, uid, ids[:size/2])
|
||||
c = cr.count
|
||||
pool.get(obj).read(cr, uid, ids[:size/2])
|
||||
code_half_complexity = cr.count - c1
|
||||
code_half_complexity = cr.count - c
|
||||
|
||||
pool.get(obj).read(cr, uid, ids)
|
||||
c = cr.count
|
||||
pool.get(obj).read(cr, uid, ids)
|
||||
code_size_complexity = cr.count - c1
|
||||
code_size_complexity = cr.count - c
|
||||
|
||||
if size < 5:
|
||||
self.score += -2
|
||||
list = [size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data"]
|
||||
self.result_det[obj] = list
|
||||
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")]
|
||||
else:
|
||||
if code_size_complexity <= (code_base_complexity + size):
|
||||
complexity = "O(1)"
|
||||
score = 10
|
||||
complexity = _("O(1)")
|
||||
score += 1
|
||||
list2 = [obj, _("Efficient")]
|
||||
else:
|
||||
complexity = "O(n) or worst"
|
||||
score = 0
|
||||
list = [size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
|
||||
self.result_det[obj] = list
|
||||
complexity = _("O(n) or worst")
|
||||
list2 = [obj, _("Not Efficient")]
|
||||
|
||||
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
|
||||
|
||||
else:
|
||||
score += -5
|
||||
list = [size, "", "", "", "Warning! Object has no demo data"]
|
||||
self.result_det[obj] = list
|
||||
self.data_list.append(self.result_det)
|
||||
self.score = obj_counter and score/obj_counter or 0.0
|
||||
self.result = self.get_result()
|
||||
self.result_details = self.get_result_details()
|
||||
list = [obj, size, "", "", "", _("Warning! Object has no demo data")]
|
||||
list2 = [obj, _("No demo data")]
|
||||
result_dict[obj] = list
|
||||
result_dict2[obj] = list2
|
||||
|
||||
self.score = obj_counter and score / obj_counter or 0.0
|
||||
self.result_details += self.get_result_details(result_dict)
|
||||
self.result += self.get_result(result_dict2)
|
||||
|
||||
return None
|
||||
|
||||
def get_result(self):
|
||||
summary = """
|
||||
This test checks the speed of the module.
|
||||
"""
|
||||
return summary
|
||||
|
||||
def get_result_details(self):
|
||||
header_list = []
|
||||
header_list.append('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s')
|
||||
header_list.append('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ')
|
||||
header_view = ['Object Name', 'Size-Number of Records (S)', '1', 'S/2', 'S', 'Complexity using query']
|
||||
detail = ""
|
||||
self.data_list.append(header_view)
|
||||
def get_result(self, dict):
|
||||
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('Object Name'), _('Result'),])
|
||||
if not self.error:
|
||||
detail += self.format_table(header=header_list, data_list=self.data_list)
|
||||
return detail
|
||||
return self.format_table(header, data_list=dict)
|
||||
return ""
|
||||
|
||||
def get_result_details(self, dict):
|
||||
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')])
|
||||
if not self.error:
|
||||
return self.format_table(header, data_list=dict)
|
||||
return ""
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -35,14 +35,18 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
# '''
|
||||
super(quality_test, self).__init__()
|
||||
self.name = _("Terp Test")
|
||||
self.note = _("This test checks if the module satisfies the current coding standard used by OpenERP.")
|
||||
self.bool_installed_only = False
|
||||
self.no_terp = False
|
||||
self.ponderation = 2
|
||||
|
||||
return None
|
||||
|
||||
def run_test(self, cr, uid, module_path):
|
||||
def run_test_terp(self, cr, uid, module_path):
|
||||
list_files = os.listdir(module_path)
|
||||
|
||||
current_module = module_path.split('/')[-1]
|
||||
|
||||
for i in list_files:
|
||||
path = os.path.join(module_path, i)
|
||||
if os.path.isdir(path):
|
||||
|
@ -55,53 +59,81 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
feel_bad_factor = 0
|
||||
if '__terp__.py' not in list_files:
|
||||
self.no_terp = True
|
||||
if self.no_terp:
|
||||
self.result += "The module does not contain the __terp__.py file"
|
||||
self.result += _("The module does not contain the __terp__.py file")
|
||||
return None
|
||||
|
||||
terp_file = os.path.join(module_path,'__terp__.py')
|
||||
res = eval(tools.file_open(terp_file).read())
|
||||
|
||||
terp_keys = ['category', 'name', 'description', 'author', 'website', 'update_xml', 'init_xml', 'depends', 'version', 'active', 'installable', 'demo_xml']
|
||||
terp_keys = ['category', 'name', 'description', 'author', 'website', 'update_xml', 'init_xml', 'depends', 'version', 'active', 'installable', 'demo_xml', 'certificate']
|
||||
|
||||
for key in terp_keys:
|
||||
if key in res:
|
||||
feel_good_factor += 1
|
||||
feel_good_factor += 1 # each tag should appear
|
||||
if isinstance(res[key],(str,unicode)):
|
||||
if not res[key]:
|
||||
feel_bad_factor += 1
|
||||
else:
|
||||
if key == 'description' and res[key] and len(str(res[key]))>=25:
|
||||
|
||||
if key == 'description' and res[key] and len(str(res[key])) >= 150: # no. of chars should be >=150
|
||||
feel_good_factor += 1
|
||||
if res['description'].count('\n') >= 4:# description contains minimum 5 lines
|
||||
feel_good_factor += 1
|
||||
if key == 'website':
|
||||
ptrn = re.compile('https?://[\w\.]*') # reg ex matching on temporary basis.
|
||||
ptrn = re.compile('https?://[\w\.]*') # reg ex matching on temporary basis.Website is correctly formatted
|
||||
result = ptrn.search(str(res[key]))
|
||||
if result:
|
||||
feel_good_factor += 1
|
||||
else:
|
||||
feel_bad_factor += 1
|
||||
|
||||
if isinstance(res[key],bool):
|
||||
if key == 'active':
|
||||
if current_module != 'base':
|
||||
if res[key]:
|
||||
feel_bad_factor += 1
|
||||
else:
|
||||
if not res[key]:
|
||||
feel_bad_factor += 1
|
||||
|
||||
if key == 'installable' and not res[key]: # installable tag is provided and True
|
||||
feel_bad_factor +=1
|
||||
else:
|
||||
feel_bad_factor += 1
|
||||
|
||||
self.score = round((feel_good_factor) / float(feel_good_factor + feel_bad_factor),2)
|
||||
self.result += "\nThis test checks if the module satisfies the current coding standard for __terp__.py file used by OpenERP."
|
||||
score = round((feel_good_factor) / float(feel_good_factor + feel_bad_factor),2)
|
||||
|
||||
# self.result += "__terp__.py : "+ str(self.score) + "/10\n"
|
||||
return [_('__terp__.py file'), score]
|
||||
|
||||
|
||||
def run_test(self, cr, uid, module_path):
|
||||
terp_score = self.run_test_terp(cr, uid, module_path)
|
||||
self.score = terp_score[1]
|
||||
self.result = self.get_result({'__terp__.py': terp_score})
|
||||
return None
|
||||
|
||||
def get_result(self, cr, uid, module_path, module_state):
|
||||
# self.run_test(cr, uid, module_path)
|
||||
# summary = "\n===TERP Test===:\n"
|
||||
if self.no_terp:
|
||||
summary += """
|
||||
The module does not contain the __terp__.py file.\n\n """
|
||||
# else:
|
||||
# summary += """
|
||||
# This test checks if the module satisfies the current coding standard for __terp__.py file used by OpenERP.
|
||||
# """ + "Score: " + str(self.score) + "/10\n"
|
||||
return summary
|
||||
def get_result(self, dict):
|
||||
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('Object Name'), _('Result (/1)'),])
|
||||
if not self.error:
|
||||
return self.format_table(header, data_list=dict)
|
||||
return ""
|
||||
|
||||
def get_result_details(self):
|
||||
detail = "\n===TERP Test===\n" + self.result
|
||||
return detail
|
||||
#~ def get_result(self, cr, uid, module_path, module_state):
|
||||
#~ # self.run_test(cr, uid, module_path)
|
||||
#~ # summary = "\n===TERP Test===:\n"
|
||||
#~ if self.no_terp:
|
||||
#~ summary += """
|
||||
#~ The module does not contain the __terp__.py file.\n\n """
|
||||
#~ # else:
|
||||
#~ # summary += """
|
||||
#~ # This test checks if the module satisfies the current coding standard for __terp__.py file used by OpenERP.
|
||||
#~ # """ + "Score: " + str(self.score) + "/10\n"
|
||||
#~ return summary
|
||||
|
||||
#~ def get_result_details(self):
|
||||
#~ detail = "\n===TERP Test===\n" + self.result
|
||||
#~ return detail
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ class wiz_quality_check(osv.osv):
|
|||
_name = 'wizard.quality.check'
|
||||
_columns = {
|
||||
'name': fields.char('Rated Module', size=64, ),
|
||||
'final_score': fields.char('Final Score', size=10,),
|
||||
'test_ids' : fields.one2many('quality.check.detail', 'quality_check_id', 'Test Details',)
|
||||
'final_score': fields.char('Final Score (%)', size=10,),
|
||||
'test_ids' : fields.one2many('quality.check.detail', 'quality_check_id', 'Tests',)
|
||||
}
|
||||
wiz_quality_check()
|
||||
|
||||
|
@ -46,10 +46,12 @@ class quality_check_detail(osv.osv):
|
|||
_columns = {
|
||||
'quality_check_id': fields.many2one('wizard.quality.check', 'Quality'),
|
||||
'name': fields.char('Name',size=128,),
|
||||
'score': fields.float('Score',),
|
||||
'ponderation': fields.float('Ponderation',),
|
||||
'score': fields.float('Score (%)',),
|
||||
'ponderation': fields.float('Ponderation',help='Some tests are more critical than others, so they have a bigger weight in the computation of final rating'),
|
||||
'note': fields.text('Note',),
|
||||
'summary': fields.text('Summary',),
|
||||
'detail' : fields.text('Details',),
|
||||
'state': fields.selection([('done','Done'),('skipped','Skipped'),], 'State', size=6, help='The test will be completed only if the module is installed or if the test may be processed on uninstalled module.'),
|
||||
}
|
||||
quality_check_detail()
|
||||
|
||||
|
@ -58,8 +60,10 @@ class create_quality_check(wizard.interface):
|
|||
|
||||
def _create_quality_check(self, cr, uid, data, context={}):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
if data['id']:
|
||||
module_data = pool.get('ir.module.module').browse(cr, uid, [data['id']])[0]
|
||||
print data, context
|
||||
objs = []
|
||||
for id in data['ids']:
|
||||
module_data = pool.get('ir.module.module').browse(cr, uid, id)
|
||||
#list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
|
||||
abstract_obj = base_module_quality.abstract_quality_check()
|
||||
score_sum = 0.0
|
||||
|
@ -76,10 +80,12 @@ class create_quality_check(wizard.interface):
|
|||
val.run_test(cr, uid, str(module_path))
|
||||
data = {
|
||||
'name': val.name,
|
||||
'score': val.score,
|
||||
'score': val.score * 100,
|
||||
'ponderation': val.ponderation,
|
||||
'summary': val.result,
|
||||
'detail': val.result_details,
|
||||
'state': 'done',
|
||||
'note': val.note,
|
||||
}
|
||||
create_ids.append((0,0,data))
|
||||
score_sum += val.score * val.ponderation
|
||||
|
@ -87,7 +93,9 @@ class create_quality_check(wizard.interface):
|
|||
else:
|
||||
data = {
|
||||
'name': val.name,
|
||||
'note': val.note,
|
||||
'score': 0,
|
||||
'state': 'skipped',
|
||||
'summary': _("The module has to be installed before running this test.")
|
||||
}
|
||||
create_ids.append((0,0,data))
|
||||
|
@ -99,12 +107,13 @@ class create_quality_check(wizard.interface):
|
|||
'test_ids' : create_ids,
|
||||
}
|
||||
obj = pool.get('wizard.quality.check').create(cr, uid, data, context)
|
||||
return obj
|
||||
objs.append(obj)
|
||||
return objs
|
||||
|
||||
def _open_quality_check(self, cr, uid, data, context):
|
||||
obj_id = self._create_quality_check(cr, uid, data, context)
|
||||
obj_ids = self._create_quality_check(cr, uid, data, context)
|
||||
return {
|
||||
'domain': "[('id','=', "+ str(obj_id)+")]",
|
||||
'domain': "[('id','in', ["+','.join(map(str,obj_ids))+"])]",
|
||||
'name': _('Quality Check'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
|
|
|
@ -395,7 +395,7 @@
|
|||
<blockTable colWidths="534.0" style="Table8">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="P3">[[ format(o.quotation_notes or '') ]]</para>
|
||||
<para style="P3">[[ format(o.quotation_notes) or '' ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -174,7 +174,7 @@ product_ul()
|
|||
#----------------------------------------------------------
|
||||
class product_category(osv.osv):
|
||||
|
||||
def name_get(self, cr, uid, ids, context={}):
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
if not len(ids):
|
||||
return []
|
||||
reads = self.read(cr, uid, ids, ['name','parent_id'], context)
|
||||
|
@ -187,7 +187,7 @@ class product_category(osv.osv):
|
|||
return res
|
||||
|
||||
def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context):
|
||||
res = self.name_get(cr, uid, ids)
|
||||
res = self.name_get(cr, uid, ids, context)
|
||||
return dict(res)
|
||||
|
||||
_name = "product.category"
|
||||
|
|
Loading…
Reference in New Issue