commit
ba8937a200
|
@ -448,10 +448,10 @@ 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)
|
||||
for inv in self.browse(cr, uid, ids):
|
||||
if inv.move_id:
|
||||
continue
|
||||
self.button_compute(cr, uid, ids, context={},set_total=True)
|
||||
if inv.type in ('in_invoice', 'in_refund') and abs(inv.check_total - inv.amount_total) >= (inv.currency_id.rounding/2.0):
|
||||
raise osv.except_osv(_('Bad total !'), _('Please verify the price of the invoice !\nThe real total does not match the computed total.'))
|
||||
if not inv.date_invoice:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<report auto="True" id="payment_order" model="payment.order" name="payement.order" rml="account_payment/report/order.rml" string="Payment Order"/>
|
||||
<report auto="True" id="payment_order1" model="payment.order" name="payement.order" rml="account_payment/report/order.rml" string="Payment Order"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import payment_order
|
|
@ -0,0 +1,34 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
import datetime
|
||||
from report import report_sxw
|
||||
|
||||
class payment_order(report_sxw.rml_parse):
|
||||
def __init__(self, cr, uid, name, context):
|
||||
super(payment_order, self).__init__(cr, uid, name, context)
|
||||
self.localcontext.update( {
|
||||
'time': time,
|
||||
|
||||
})
|
||||
report_sxw.report_sxw('report.payment.order', 'payement.order', 'addons/account_payment/report/payment_order.rml', parser=payment_order,header=False)
|
|
@ -115,10 +115,6 @@ class account_report_bs(osv.osv):
|
|||
ids = self.search(cr, user, args, limit=limit, context=context)
|
||||
return self.name_get(cr, user, ids, context=context)
|
||||
|
||||
_sql_constraints = [
|
||||
('code_uniq', 'unique (code)', 'The code of the report entry must be unique !')
|
||||
]
|
||||
|
||||
account_report_bs()
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class hr_analytic_timesheet(osv.osv):
|
|||
_inherit = "hr.analytic.timesheet"
|
||||
|
||||
|
||||
def on_change_account_id(self, cr, uid, ids,user_id, account_id, journal_id,unit_amount=0):
|
||||
def on_change_account_id(self, cr, uid, ids,user_id, account_id, unit_amount=0, journal_id=0):
|
||||
res = {}
|
||||
if not (account_id):
|
||||
#avoid a useless call to super
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<field name="inherit_id" ref="hr_timesheet_sheet.hr_timesheet_sheet_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page/field[@name='timesheet_ids']/tree/field[@name='account_id']" position="replace">
|
||||
<field name="account_id" domain="[('type','=','normal'),('state', '<>', 'close')]" on_change="on_change_account_id(user_id, account_id, journal_id, unit_amount)"/>
|
||||
<field name="account_id" domain="[('type','=','normal'),('state', '<>', 'close')]" on_change="on_change_account_id(user_id, account_id, unit_amount, journal_id)"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/field[@name='account_id']" position="replace">
|
||||
<field name="account_id" domain="[('type','=','normal'),('state', '<>', 'close')]" on_change="on_change_account_id(user_id, account_id, journal_id, unit_amount)" select="1"/>
|
||||
<field name="account_id" domain="[('type','=','normal'),('state', '<>', 'close')]" on_change="on_change_account_id(user_id, account_id, unit_amount, journal_id)" select="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -49,7 +49,7 @@ class abstract_quality_check(object):
|
|||
'''
|
||||
raise 'Not Implemented'
|
||||
|
||||
def run_test(self, module_path=""):
|
||||
def run_test(self, cr, uid, module_path=""):
|
||||
'''
|
||||
this method should do the test and fill the score, result and result_details var
|
||||
'''
|
||||
|
|
|
@ -1,6 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>
|
||||
<!--<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>-->
|
||||
|
||||
<record id="view_wizard_quality_check" model="ir.ui.view">
|
||||
<field name="name">Results of Quality Checks</field>
|
||||
<field name="model">wizard.quality.check</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Result">
|
||||
<separator string="Summary" colspan="4"/>
|
||||
<field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<act_window
|
||||
id="act_view_wiz_quality_check"
|
||||
name="Wizard Quality Check"
|
||||
res_model="wizard.quality.check"
|
||||
src_model="ir.module.module"
|
||||
target="new"
|
||||
view_mode="form"
|
||||
context="{'module_id': active_id}"
|
||||
/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
</openerp>
|
||||
|
|
|
@ -31,50 +31,60 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
Method Test:
|
||||
------------
|
||||
|
||||
This test checks if the class method has exception or not.
|
||||
===Method Test===:
|
||||
|
||||
This test checks if the module classes are raising exception when calling basic methods or no.
|
||||
|
||||
"""
|
||||
self.bool_installed_only = False
|
||||
self.bool_installed_only = True
|
||||
return None
|
||||
|
||||
def run_test(self, module_path, module_name=None, cr=None, uid=None):
|
||||
def run_test(self, cr, uid, module_path):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
module_name = module_path.split('/')[-1]
|
||||
ids2 = pool.get('ir.model.data').search(cr, uid, [('module','=', module_name), ('model','=','ir.model')])
|
||||
model_list = []
|
||||
model_data = pool.get('ir.model.data').browse(cr, uid, ids2)
|
||||
for model in model_data:
|
||||
model_list.append(model.res_id)
|
||||
obj_list = []
|
||||
for mod in pool.get('ir.model.data').browse(cr, uid, ids2):
|
||||
object_name = mod.name.split('_')
|
||||
object_name.pop(0)
|
||||
object_name = '.'.join(object_name)
|
||||
obj_list.append(str(object_name))
|
||||
for mod in pool.get('ir.model').browse(cr, uid, model_list):
|
||||
obj_list.append(str(mod.model))
|
||||
result={}
|
||||
self.result += "Module Name:" + module_name + '\n' + '===============\n'
|
||||
ok_count = 0
|
||||
ex_count = 0
|
||||
|
||||
for obj in obj_list:
|
||||
temp=[]
|
||||
temp = []
|
||||
try:
|
||||
res = pool.get(obj).search(cr, uid, [])
|
||||
temp.append('Ok')
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
ex_count += 1
|
||||
try:
|
||||
res1 = pool.get(obj).fields_view_get(cr, uid,)
|
||||
temp.append('Ok')
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
ex_count += 1
|
||||
try:
|
||||
res2 = pool.get(obj).read(cr, uid, [])
|
||||
temp.append('Ok')
|
||||
ok_count += 1
|
||||
except:
|
||||
temp.append('Exception')
|
||||
ex_count += 1
|
||||
result[obj] = temp
|
||||
self.result+=("%-40s %-12s \t %-16s %-12s")%('Object Name'.ljust(40),'search','fields_view_get','read')
|
||||
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))
|
||||
|
||||
for res in result:
|
||||
self.result+=("%-40s %-12s \t %-16s \t %-12s")%(res.ljust(40),result[res][0],result[res][1],result[res][2])
|
||||
self.result+="\n"
|
||||
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
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -31,17 +31,15 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
Pylint Test:
|
||||
------------
|
||||
===Pylint Test===:
|
||||
|
||||
This test checks if the module satisfy the current coding standard used by OpenERP.
|
||||
|
||||
|
||||
"""
|
||||
self.bool_installed_only = False
|
||||
return None
|
||||
|
||||
def run_test(self, module_path):
|
||||
def run_test(self, cr, uid, module_path):
|
||||
config_file_path = config['addons_path']+'/base_module_quality/pylint_test/pylint_test_config.txt'
|
||||
list_files = os.listdir(module_path)
|
||||
for i in list_files:
|
||||
|
@ -50,7 +48,7 @@ Pylint Test:
|
|||
for j in os.listdir(path):
|
||||
list_files.append(os.path.join(i, j))
|
||||
|
||||
n = 0
|
||||
n = 0
|
||||
score = 0.0
|
||||
for file in list_files:
|
||||
if file.split('.')[-1] == 'py' and not file.endswith('__init__.py') and not file.endswith('__terp__.py'):
|
||||
|
@ -66,10 +64,10 @@ Pylint Test:
|
|||
|
||||
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"
|
||||
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"
|
||||
|
||||
self.result_details += res
|
||||
self.score = n and score / n or score
|
||||
|
|
|
@ -24,6 +24,9 @@ import netsvc
|
|||
from osv import fields, osv
|
||||
import os
|
||||
from tools import config
|
||||
import pooler
|
||||
import time
|
||||
|
||||
|
||||
from base_module_quality import base_module_quality
|
||||
|
||||
|
@ -32,19 +35,82 @@ class quality_test(base_module_quality.abstract_quality_check):
|
|||
|
||||
def __init__(self):
|
||||
self.result = """
|
||||
Speed Test:
|
||||
------------
|
||||
===Speed Test===:
|
||||
|
||||
This test checks the speed of the module
|
||||
This test checks the speed of the module.
|
||||
|
||||
|
||||
to be continued...
|
||||
|
||||
"""
|
||||
self.bool_installed_only = True
|
||||
return None
|
||||
|
||||
def run_test(self, module_path):
|
||||
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))
|
||||
ids2 = pool.get('ir.model.data').search(cr, uid, [('module','=', module_name), ('model','=','ir.model')])
|
||||
model_data = pool.get('ir.model.data').browse(cr, uid, ids2)
|
||||
model_list = []
|
||||
for model in model_data:
|
||||
model_list.append(model.res_id)
|
||||
obj_list = []
|
||||
for mod in pool.get('ir.model').browse(cr, uid, model_list):
|
||||
obj_list.append(str(mod.model))
|
||||
|
||||
obj_counter = 0
|
||||
score = 0
|
||||
for obj in obj_list:
|
||||
obj_counter += 1
|
||||
ids = pool.get(obj).search(cr, uid, [])
|
||||
ids = ids[:100]
|
||||
size = len(ids)
|
||||
if size:
|
||||
c1 = time.time()
|
||||
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[:size/2])
|
||||
c2 = time.time()
|
||||
halfsize_time = c2 - c1
|
||||
|
||||
c1 = time.time()
|
||||
pool.get(obj).read(cr, uid, ids)
|
||||
c2 = time.time()
|
||||
size_time = c2 - 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")
|
||||
else:
|
||||
tolerated_margin = 5/100
|
||||
complexity = "not recognized"
|
||||
if min(size_time,base_time,halfsize_time) != base_time:
|
||||
complexity = "O(1)"
|
||||
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)
|
||||
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.score = obj_counter and score/obj_counter or 0.0
|
||||
return None
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -21,81 +21,93 @@
|
|||
##############################################################################
|
||||
import wizard
|
||||
import pooler
|
||||
from osv import osv, fields
|
||||
|
||||
import tools
|
||||
import os
|
||||
|
||||
|
||||
#TODO: (utiliser les nouveaux wizards pour heriter la vue et rajouter un onglet par test?)
|
||||
#TODO: configure pylint
|
||||
#TODO: implement the speed test
|
||||
#TODO: implement the simple test
|
||||
#TODO: add cheks: do the class quality_check inherits the class abstract_quality_check?
|
||||
#TODO: improve translability
|
||||
#TODO: clean
|
||||
|
||||
|
||||
#To keep or not? to be discussed...
|
||||
|
||||
view_form = """<?xml version="1.0"?>
|
||||
<form string="Check quality">
|
||||
<notebook>
|
||||
<page string="Summary">
|
||||
<field name="general_info" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>"""
|
||||
#~ view_form = """<?xml version="1.0"?>
|
||||
#~ <form string="Check quality">
|
||||
#~ <notebook>
|
||||
#~ <page string="Summary">
|
||||
#~ <field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
|
||||
#~ </page>
|
||||
#~ </notebook>
|
||||
#~ </form>"""
|
||||
|
||||
|
||||
view_field = {
|
||||
"general_info": {'type': 'text', 'string': 'General Info', 'readonly':True},
|
||||
}
|
||||
#~ view_field = {
|
||||
#~ "general_info": {'type': 'text', 'string': 'General Info', 'readonly':True},
|
||||
#~ }
|
||||
|
||||
|
||||
class wiz_quality_check(wizard.interface):
|
||||
class wiz_quality_check(osv.osv_memory):
|
||||
|
||||
# general_info = ""
|
||||
_name = 'wizard.quality.check'
|
||||
|
||||
|
||||
def _check(self, cr, uid, data, context={}):
|
||||
string_ret = ""
|
||||
from tools import config
|
||||
data['ids'] = data.get('module_id', False)
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
module_data = pool.get('ir.module.module').browse(cr, uid, data['ids'])
|
||||
module_data = pool.get('ir.module.module').browse(cr, uid, [data['ids']])
|
||||
list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
|
||||
module_name = module_data[0].name
|
||||
for item in list_folders:
|
||||
path = config['addons_path']+'/base_module_quality/'+item
|
||||
if os.path.exists(path+'/'+item+'.py') and item not in ['report', 'wizard', 'security']:
|
||||
ad = tools.config['addons_path']
|
||||
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
|
||||
x = __import__(item2)
|
||||
x2 = getattr(x, item)
|
||||
x3 = getattr(x2, item)
|
||||
val = x3.quality_test()
|
||||
if (not val.bool_installed_only or module_data[0].state == "installed") and item == 'method_test':
|
||||
val.run_test(str(module_path), module_name, cr, uid)
|
||||
elif not val.bool_installed_only or module_data[0].state == "installed" :
|
||||
val.run_test(str(module_path))
|
||||
if (not val.bool_installed_only or module_data[0].state == "installed"):
|
||||
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
|
||||
return string_ret
|
||||
|
||||
return {'general_info':string_ret}
|
||||
# def _general_info(self, cr, uid, data, context={}):
|
||||
# return self.general_info
|
||||
|
||||
states = {
|
||||
#~ states = {
|
||||
|
||||
#~ 'init': {
|
||||
#~ 'actions': [_check],
|
||||
#~ 'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
|
||||
#~ },
|
||||
#~ }
|
||||
#To keep or not? to be discussed...
|
||||
|
||||
#~ 'init': {
|
||||
#~ 'actions': [],
|
||||
#~ 'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]}
|
||||
#~ },
|
||||
'init': {
|
||||
'actions': [_check],
|
||||
'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
|
||||
},
|
||||
}
|
||||
_columns = {
|
||||
'general_info': fields.text('General Info', readonly="1",),
|
||||
}
|
||||
_defaults = {
|
||||
'general_info': _check
|
||||
}
|
||||
|
||||
wiz_quality_check('base.module.quality')
|
||||
wiz_quality_check()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
Loading…
Reference in New Issue