apa-tiny
2010-10-04 15:22:17 +05:30
31 changed files with 477 additions and 241 deletions
+1 -2
View File
@@ -148,7 +148,6 @@ CREATE TABLE res_users (
context_lang varchar(64) default '',
-- No FK references below, will be added later by ORM
-- (when the destination rows exist)
action_id int,
company_id int,
primary key(id)
);
@@ -345,7 +344,7 @@ CREATE TABLE ir_model_data (
-- Users
---------------------------------
insert into res_users (id,login,password,name,action_id,active,company_id) values (1,'admin','admin','Administrator',NULL,True,1);
insert into res_users (id,login,password,name,active,company_id) values (1,'admin','admin','Administrator',True,1);
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_root','base','res.users',True,1);
-- Compatibility purpose, to remove V6.0
+4 -3
View File
@@ -1053,8 +1053,6 @@
<field name="address_id" ref="main_address"/>
<field name="company_id" ref="main_company"/>
<field name="company_ids" eval="[(4, ref('main_company'))]"/>
<field name="action_id" ref="action_menu_admin"/>
<field name="menu_id" ref="action_menu_admin"/>
</record>
<record id="main_partner" model="res.partner">
@@ -1375,6 +1373,9 @@
<field name="currency_id" ref="UAH"/>
<field eval="time.strftime('%Y-01-01')" name="name"/>
</record>
<record id="res_bank_1" model="res.bank">
<field name="name">Reserve</field>
<field name="code">RSV</field>
</record>
</data>
</openerp>
-2
View File
@@ -6,8 +6,6 @@
<field name="password">demo</field>
<field name="name">Demo User</field>
<field name="signature">Mr Demo</field>
<field name="action_id" ref="action_menu_admin"/>
<field name="menu_id" ref="action_menu_admin"/>
<field name="address_id" ref="main_address"/>
<field name="company_id" ref="main_company"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/>
+1 -1
View File
@@ -123,7 +123,7 @@
<field name="user_email" widget="email"/>
<field name="context_lang"/>
<field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
<field name="action_id" required="True"/>
<field name="action_id"/>
<field name="context_tz"/>
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-12 21:46+0000\n"
"Last-Translator: Bojan Markovic <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:03+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:42+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-11 15:00+0000\n"
"Last-Translator: Martin Hood <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:03+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-21 14:25+0000\n"
"Last-Translator: Tanel Kurvits <Unknown>\n"
"PO-Revision-Date: 2010-09-29 07:51+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:43+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-16 19:03+0000\n"
"Last-Translator: Olivier Dony (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:01+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:43+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-19 17:45+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:28+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:44+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+2 -2
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-13 08:00+0000\n"
"PO-Revision-Date: 2010-09-29 08:13+0000\n"
"Last-Translator: ub121 <ubs121@gmail.com>\n"
"Language-Team: Mongolian <mn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:44+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+25 -17
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-09 18:36+0000\n"
"Last-Translator: Anup (OpenERP) <ach@tinyerp.com>\n"
"PO-Revision-Date: 2010-10-01 11:47+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:42+0000\n"
"X-Launchpad-Export-Date: 2010-10-02 05:05+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -3366,7 +3366,7 @@ msgstr "U kunt het menu opnieuw laden met (Ctrl+t Ctrl+r)."
#: view:ir.ui.view_sc:0
#: field:res.partner.title,shortcut:0
msgid "Shortcut"
msgstr "Sneltoets"
msgstr "Snelkoppeling"
#. module: base
#: field:ir.model.data,date_init:0
@@ -8109,34 +8109,35 @@ msgstr "U kunt niet twee gebruikers hebben met dezelfde gebruikersnaam !"
#. module: base
#: sql_constraint:ir.model.fields:0
msgid "Size of the field can never be less than 1 !"
msgstr ""
msgstr "De veldlengte kan nooit kleiner dan 1 zijn !"
#. module: base
#: sql_constraint:ir.ui.view_sc:0
msgid "Shortcut for this menu already exists!"
msgstr ""
msgstr "Dit menu heeft al een snelkoppeling!"
#. module: base
#: sql_constraint:ir.model.data:0
msgid ""
"You cannot have multiple records with the same id for the same module !"
msgstr ""
"U kunt niet meer records hebben met dezelfde id voor dezelfde module !"
#. module: base
#: sql_constraint:maintenance.contract:0
msgid "Your maintenance contract is already subscribed in the system !"
msgstr ""
msgstr "Uw onderhoudscontract is al ingeschreven in het systeem !"
#. module: base
#: sql_constraint:ir.module.module:0
#: sql_constraint:ir.module.web:0
msgid "The name of the module must be unique !"
msgstr ""
msgstr "De modulenaam moet uniek zijn !"
#. module: base
#: sql_constraint:ir.module.module:0
msgid "The certificate ID of the module must be unique !"
msgstr ""
msgstr "Het kwaliteitscertificaat id van de module moet uniek zijn !"
#. module: base
#: sql_constraint:res.partner.function:0
@@ -8146,38 +8147,38 @@ msgstr ""
#. module: base
#: sql_constraint:res.partner:0
msgid "The name of the Partner must be unique !"
msgstr ""
msgstr "De relatienaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.country:0
msgid "The name of the country must be unique !"
msgstr ""
msgstr "De landnaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.country:0
msgid "The code of the country must be unique !"
msgstr ""
msgstr "De landcode moet uniek zijn !"
#. module: base
#: sql_constraint:res.lang:0
msgid "The name of the language must be unique !"
msgstr ""
msgstr "De taalnaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.lang:0
msgid "The code of the language must be unique !"
msgstr ""
msgstr "De taalcode moet uniek zijn !"
#. module: base
#: sql_constraint:res.groups:0
msgid "The name of the group must be unique !"
msgstr ""
msgstr "De groepsnaam moet uniek zijn !"
#. module: base
#: code:addons/osv/osv.py:0
#, python-format
msgid "Constraint Error"
msgstr ""
msgstr "Voorwaarde Fout"
#. module: base
#: code:addons/osv/osv.py:0
@@ -8188,6 +8189,10 @@ msgid ""
"reference it\n"
"- creation/update: a mandatory field is not correctly set"
msgstr ""
"De bewerking kan niet worden afgerond, waarschijnlijk vanwege:\n"
"- verwijdering: u probeert een record te verwijderen terwijl er nog door een "
"ander aan wordt gerefereerd\n"
"- maken/wijzigen: een verplicht veld is niet correct ingevuld"
#. module: base
#: code:addons/osv/osv.py:0
@@ -8197,12 +8202,15 @@ msgid ""
"\n"
"[object with reference: %s - %s]"
msgstr ""
"\n"
"\n"
"[object met referentie: %s - %s]"
#. module: base
#: code:addons/osv/osv.py:0
#, python-format
msgid "Integrity Error"
msgstr ""
msgstr "Integriteit Fout"
#~ msgid "Main Company"
#~ msgstr "Moederorganisatie"
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-26 10:02+0000\n"
"Last-Translator: Michał Węgrzynek <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:34+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:45+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+2 -2
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: pt_BR\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-09 18:12+0000\n"
"PO-Revision-Date: 2010-09-29 08:12+0000\n"
"Last-Translator: Anup (OpenERP) <ach@tinyerp.com>\n"
"Language-Team: <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-27 12:19+0000\n"
"Last-Translator: Daniel Stenlöv (XCLUDE) <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:22+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+24 -2
View File
@@ -28,8 +28,9 @@ from tools.translate import _
import netsvc
import re
import copy
import sys
import os
from xml import dom
from report.report_sxw import report_sxw, report_rml
class actions(osv.osv):
_name = 'ir.actions.actions'
@@ -89,6 +90,27 @@ class report_xml(osv.osv):
res[report.id] = False
return res
def register_all(self, cr):
"""Report registration handler that may be overridden by subclasses to
add their own kinds of report services.
Loads all reports with no manual loaders (auto==True) and
registers the appropriate services to implement them.
"""
opj = os.path.join
cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,))
result = cr.dictfetchall()
svcs = netsvc.Service._services
for r in result:
if svcs.has_key('report.'+r['report_name']):
continue
if r['report_rml'] or r['report_rml_content_data']:
report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'])
if r['report_xsl']:
report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']))
_name = 'ir.actions.report.xml'
_table = 'ir_act_report_xml'
_sequence = 'ir_actions_id_seq'
@@ -98,7 +120,7 @@ class report_xml(osv.osv):
'type': fields.char('Action Type', size=32, required=True),
'report_name': fields.char('Service Name', size=64, required=True),
'usage': fields.char('Action Usage', size=32),
'report_type': fields.selection([ ('pdf','pdf'), ('html','html'), ('raw','raw'), ('sxw','sxw'), ('txt','txt'), ('odt','odt'), ('html2html','HTML from HTML'), ('mako2html','HTML from Mako'), ], string='Report Type', required=True),
'report_type': fields.char('Report Type', size=32, required=True, help="Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..."),
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
'multi': fields.boolean('On multiple doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view."),
'attachment': fields.char('Save As Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'),
+2 -1
View File
@@ -137,7 +137,8 @@ class ir_rule(osv.osv):
def domain_get(self, cr, uid, model_name, mode='read', context={}):
dom = self._compute_domain(cr, uid, model_name, mode=mode)
if dom:
return self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
query = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
return query.where_clause, query.where_clause_params, query.tables
return [], [], ['"'+self.pool.get(model_name)._table+'"']
def unlink(self, cr, uid, ids, context=None):
+23 -19
View File
@@ -19,27 +19,24 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import tarfile
import re
import urllib
import os
import imp
import logging
import tools
from osv import fields, osv, orm
import zipfile
import release
import os
import re
import urllib
import zipimport
import wizard
import addons
import pooler
import netsvc
import pooler
import release
import tools
from tools.parse_version import parse_version
from tools.translate import _
from osv import fields, osv, orm
class module_category(osv.osv):
_name = "ir.module.category"
_description = "Module Category"
@@ -80,8 +77,9 @@ class module(osv.osv):
info = addons.load_information_from_description_file(name)
if 'version' in info:
info['version'] = release.major_version + '.' + info['version']
except:
pass
except Exception:
self.__logger.debug('Error when trying to fetch informations for '
'module %s', name, exc_info=True)
return info
def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context={}):
@@ -116,17 +114,21 @@ class module(osv.osv):
v = view_obj.browse(cr,uid,data_id.res_id)
aa = v.inherit_id and '* INHERIT ' or ''
res[mnames[data_id.module]]['views_by_module'] += aa + v.name + ' ('+v.type+')\n'
except:
pass
except Exception:
self.__logger.debug(
'Unknown error while browsing ir.ui.view[%s]',
data_id.res_id, exc_info=True)
elif key=='ir.actions.report.xml':
res[mnames[data_id.module]]['reports_by_module'] += report_obj.browse(cr,uid,data_id.res_id).name + '\n'
elif key=='ir.ui.menu':
try:
m = menu_obj.browse(cr,uid,data_id.res_id)
res[mnames[data_id.module]]['menus_by_module'] += m.complete_name + '\n'
except:
pass
except KeyError, e:
except Exception:
self.__logger.debug(
'Unknown error while browsing ir.ui.menu[%s]',
data_id.res_id, exc_info=True)
except KeyError:
pass
return res
@@ -393,7 +395,9 @@ class module(osv.osv):
fp = file(fname, 'wb')
fp.write(zipfile)
fp.close()
except Exception, e:
except Exception:
self.__logger.exception('Error when trying to create module '
'file %s', fname)
raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,))
terp = self.get_module_info(mod.name)
self.write(cr, uid, mod.id, self.get_values_from_terp(terp))
+1 -1
View File
@@ -392,7 +392,7 @@ class res_partner_bank(osv.osv):
_columns = {
'name': fields.char('Description', size=128),
'acc_number': fields.char('Account Number', size=64, required=False),
'bank': fields.many2one('res.bank', 'Bank'),
'bank': fields.many2one('res.bank', 'Bank', required=True),
'owner_name': fields.char('Account Owner', size=64),
'street': fields.char('Street', size=128),
'zip': fields.char('Zip', change_default=True, size=24),
+6 -20
View File
@@ -242,8 +242,8 @@ class users(osv.osv):
'signature': fields.text('Signature', size=64),
'address_id': fields.many2one('res.partner.address', 'Company Address'),
'active': fields.boolean('Active'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action'),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."),
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'),
'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'),
@@ -288,15 +288,6 @@ class users(osv.osv):
result = override_password(result)
else:
result = map(override_password, result)
if isinstance(result, list):
for rec in result:
if not rec.get('action_id',True):
rec['action_id'] = (self._get_menu(cr, uid),'Menu')
else:
if not result.get('action_id',True):
result['action_id'] = (self._get_menu(cr, uid),'Menu')
return result
@@ -327,10 +318,6 @@ class users(osv.osv):
self.__admin_ids[cr.dbname] = ir_model_data_obj.read(cr, 1, [mdid], ['res_id'])[0]['res_id']
return self.__admin_ids[cr.dbname]
def _get_action(self,cr, uid, context={}):
ids = self.pool.get('ir.ui.menu').search(cr, uid, [('usage','=','menu')])
return ids and ids[0] or False
def _get_company(self,cr, uid, context=None, uid2=False):
if not uid2:
uid2 = uid
@@ -344,12 +331,12 @@ class users(osv.osv):
return [c]
return False
def _get_menu(self,cr, uid, context={}):
ids = self.pool.get('ir.actions.act_window').search(cr, uid, [('usage','=','menu')])
def _get_menu(self,cr, uid, context=None):
ids = self.pool.get('ir.actions.act_window').search(cr, uid, [('usage','=','menu')], context=context)
return ids and ids[0] or False
def _get_group(self,cr, uid, context={}):
ids = self.pool.get('res.groups').search(cr, uid, [('name','=','Employee')])
def _get_group(self,cr, uid, context=None):
ids = self.pool.get('res.groups').search(cr, uid, [('name','=','Employee')], context=context)
return ids or False
_defaults = {
@@ -357,7 +344,6 @@ class users(osv.osv):
'context_lang': lambda *args: 'en_US',
'active' : lambda *a: True,
'menu_id': _get_menu,
'action_id': _get_menu,
'company_id': _get_company,
'company_ids': _get_companies,
'groups_id': _get_group,
@@ -18,6 +18,7 @@
"access_ir_model_fields_all","ir_model_fields all","model_ir_model_fields",,1,0,0,0
"access_ir_module_category_group_user","ir_module_category group_user","model_ir_module_category","group_system",1,0,0,0
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
"access_ir_module_module_user","ir_module_module user","model_ir_module_module",,1,0,0,0
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
"access_ir_property_group_user","ir_property group_user","model_ir_property",,1,0,0,0
"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
18 access_ir_model_fields_all ir_model_fields all model_ir_model_fields 1 0 0 0
19 access_ir_module_category_group_user ir_module_category group_user model_ir_module_category group_system 1 0 0 0
20 access_ir_module_module_group_user ir_module_module group_user model_ir_module_module group_system 1 1 1 1
21 access_ir_module_module_user ir_module_module user model_ir_module_module 1 0 0 0
22 access_ir_module_module_dependency_group_system ir_module_module_dependency group_system model_ir_module_module_dependency group_system 1 1 1 1
23 access_ir_property_group_user ir_property group_user model_ir_property 1 0 0 0
24 access_ir_property_group_user_manager ir_property group_manager model_ir_property base.group_partner_manager 1 1 1 0
+88 -120
View File
@@ -54,6 +54,7 @@ from tools.config import config
from tools.translate import _
import fields
from query import Query
import tools
from tools.safe_eval import safe_eval as eval
@@ -914,7 +915,7 @@ class orm_template(object):
nbrmax = max(nbrmax, max2)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \
row[field] = newrow and (reduce(lambda x, y: x or y, newrow.values()) and \
[(0, 0, newrow)]) or []
i = max2
while (position+i) < len(datas):
@@ -929,7 +930,7 @@ class orm_template(object):
(newrow, max2, w2, translate2, data_id2, data_res_id2) = process_liness(
self, datas, prefix+[field], current_module, relation_obj._name, newfd, position+i)
warning = warning + w2
if reduce(lambda x, y: x or y, newrow.values()):
if newrow and reduce(lambda x, y: x or y, newrow.values()):
row[field].append((0, 0, newrow))
i += max2
nbrmax = max(nbrmax, i)
@@ -2203,35 +2204,15 @@ class orm(orm_template):
if not fields:
fields = self._columns.keys()
# compute the where, order by, limit and offset clauses
(where_clause, where_clause_params, tables) = self._where_calc(cr, uid, domain, context=context)
# apply direct ir.rules from current model
self._apply_ir_rules(cr, uid, where_clause, where_clause_params, tables, 'read', context=context)
# then apply the ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
previous_tables = list(tables)
if self._apply_ir_rules(cr, uid, where_clause, where_clause_params, tables, 'read', model_name=inherited_model, context=context):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, previous_tables, where_clause)
tables = list(set(tables).union(set(previous_tables)))
query = self._where_calc(cr, uid, domain, context=context)
self._apply_ir_rules(cr, uid, query, 'read', context=context)
# Take care of adding join(s) if groupby is an '_inherits'ed field
groupby_list = groupby
if groupby:
if isinstance(groupby, list):
groupby = groupby[0]
tables, where_clause, qfield = self._inherits_join_calc(groupby, tables, where_clause)
if len(where_clause):
where_clause = ' where ' + ' and '.join(where_clause)
else:
where_clause = ''
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
self._inherits_join_calc(groupby, query)
assert not groupby or groupby in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
@@ -2263,8 +2244,13 @@ class orm(orm_template):
flist += ','
flist += operator+'('+f+') as '+f
gb = groupby and (' group by '+groupby) or ''
cr.execute('select min(%s.id) as id,' % self._table + flist + ' from ' + ','.join(tables) + where_clause + gb + limit_str + offset_str, where_clause_params)
gb = groupby and (' GROUP BY '+groupby) or ''
from_clause, where_clause, where_clause_params = query.get_sql()
where_clause = where_clause and ' WHERE ' + where_clause
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
cr.execute('SELECT min(%s.id) AS id,' % self._table + flist + ' FROM ' + from_clause + where_clause + gb + limit_str + offset_str, where_clause_params)
alldata = {}
groupby = group_by
for r in cr.dictfetchall():
@@ -2303,43 +2289,37 @@ class orm(orm_template):
del d['id']
return data
def _inherits_join_add(self, parent_model_name, tables, where_clause):
def _inherits_join_add(self, parent_model_name, query):
"""
Add missing table SELECT and JOIN clause for reaching the parent table (no duplicates)
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
:param parent_model_name: name of the parent model for which the clauses should be added
:param tables: list of table._table names enclosed in double quotes as returned
by _where_calc()
:param where_clause: current list of WHERE clause params
:param query: query object on which the JOIN should be added
"""
inherits_field = self._inherits[parent_model_name]
parent_model = self.pool.get(parent_model_name)
parent_table_name = parent_model._table
quoted_parent_table_name = '"%s"' % parent_table_name
if quoted_parent_table_name not in tables:
tables.append(quoted_parent_table_name)
where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
return (tables, where_clause)
if quoted_parent_table_name not in query.tables:
query.tables.append(quoted_parent_table_name)
query.where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
def _inherits_join_calc(self, field, tables, where_clause):
def _inherits_join_calc(self, field, query):
"""
Adds missing table select and join clause(s) for reaching
Adds missing table select and join clause(s) to ``query`` for reaching
the field coming from an '_inherits' parent table (no duplicates).
:param tables: list of table._table names enclosed in double quotes as returned
by _where_calc()
:param where_clause: current list of WHERE clause params
:return: (tables, where_clause, qualified_field) where ``tables`` and ``where_clause`` are the updated
versions of the parameters, and ``qualified_field`` is the qualified name of ``field``
in the form ``table.field``, to be referenced in queries.
:param field: name of inherited field to reach
:param query: query object on which the JOIN should be added
:return: qualified name of field, to be used in SELECT clause
"""
current_table = self
while field in current_table._inherit_fields and not field in current_table._columns:
parent_model_name = current_table._inherit_fields[field][0]
parent_table = self.pool.get(parent_model_name)
self._inherits_join_add(parent_model_name, tables, where_clause)
self._inherits_join_add(parent_model_name, query)
current_table = parent_table
return (tables, where_clause, '"%s".%s' % (current_table._table, field))
return '"%s".%s' % (current_table._table, field)
def _parent_store_compute(self, cr):
if not self._parent_store:
@@ -3899,84 +3879,87 @@ class orm(orm_template):
raise NotImplementedError(_('This method does not exist anymore'))
# TODO: ameliorer avec NULL
def _where_calc(self, cr, user, args, active_test=True, context=None):
def _where_calc(self, cr, user, domain, active_test=True, context=None):
"""Computes the WHERE clause needed to implement an OpenERP domain.
:param args: the domain to compute
:type args: list
:param domain: the domain to compute
:type domain: list
:param active_test: whether the default filtering of records with ``active``
field set to ``False`` should be applied.
:return: tuple with 3 elements: (where_clause, where_clause_params, tables) where
``where_clause`` contains a list of where clause elements (to be joined with 'AND'),
``where_clause_params`` is a list of parameters to be passed to the db layer
for the where_clause expansion, and ``tables`` is the list of double-quoted
table names that need to be included in the FROM clause.
:rtype: tuple
:return: the query expressing the given domain as provided in domain
:rtype: osv.query.Query
"""
if not context:
context = {}
args = args[:]
domain = domain[:]
# if the object has a field named 'active', filter out all inactive
# records unless they were explicitely asked for
if 'active' in self._columns and (active_test and context.get('active_test', True)):
if args:
if domain:
active_in_args = False
for a in args:
for a in domain:
if a[0] == 'active':
active_in_args = True
if not active_in_args:
args.insert(0, ('active', '=', 1))
domain.insert(0, ('active', '=', 1))
else:
args = [('active', '=', 1)]
domain = [('active', '=', 1)]
if args:
if domain:
import expression
e = expression.expression(args)
e = expression.expression(domain)
e.parse(cr, user, self, context)
tables = e.get_tables()
qu1, qu2 = e.to_sql()
qu1 = qu1 and [qu1] or []
where_clause, where_params = e.to_sql()
where_clause = where_clause and [where_clause] or []
else:
qu1, qu2, tables = [], [], ['"%s"' % self._table]
where_clause, where_params, tables = [], [], ['"%s"' % self._table]
return (qu1, qu2, tables)
return Query(tables, where_clause, where_params)
def _check_qorder(self, word):
if not regex_order.match(word):
raise except_orm(_('AccessError'), _('Invalid "order" specified. A valid "order" specification is a comma-separated list of valid field names (optionally followed by asc/desc for the direction)'))
return True
def _apply_ir_rules(self, cr, uid, where_clause, where_clause_params, tables, mode='read', model_name=None, context=None):
"""Add what's missing in ``where_clause``, ``where_params``, ``tables`` to implement
all appropriate ir.rules (on the current object but also from it's _inherits parents)
def _apply_ir_rules(self, cr, uid, query, mode='read', context=None):
"""Add what's missing in ``query`` to implement all appropriate ir.rules
(using the ``model_name``'s rules or the current model's rules if ``model_name`` is None)
:param where_clause: list with current elements of the WHERE clause (strings)
:param where_clause_params: list with parameters for ``where_clause``
:param tables: list with double-quoted names of the tables that are joined
in ``where_clause``
:param model_name: optional name of the model whose ir.rules should be applied (default:``self._name``)
This could be useful for inheritance for example, but there is no provision to include
the appropriate JOIN for linking the current model to the one referenced in model_name.
:return: True if additional clauses where applied.
:param query: the current query object
"""
added_clause, added_params, added_tables = self.pool.get('ir.rule').domain_get(cr, uid, model_name or self._name, mode, context=context)
if added_clause:
where_clause += added_clause
where_clause_params += added_params
for table in added_tables:
if table not in tables:
tables.append(table)
return True
return False
def apply_rule(added_clause, added_params, added_tables):
if added_clause:
query.where_clause += added_clause
query.where_clause_params += added_params
for table in added_tables:
if table not in query.tables:
query.tables.append(table)
return True
return False
def _generate_m2o_order_by(self, order_field, tables, where_clause):
# apply main rules on the object
rule_obj = self.pool.get('ir.rule')
apply_rule(*rule_obj.domain_get(cr, uid, self._name, mode, context=context))
# apply ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
if apply_rule(*rule_obj.domain_get(cr, uid, inherited_model, mode, context=context)):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, query)
def _generate_m2o_order_by(self, order_field, query):
"""
Add possibly missing JOIN and generate the ORDER BY clause for m2o fields,
Add possibly missing JOIN to ``query`` and generate the ORDER BY clause for m2o fields,
either native m2o fields or function/related fields that are stored, including
intermediate JOINs for inheritance if required.
:return: the qualified field name to use in an ORDER BY clause to sort by ``order_field``
"""
if order_field not in self._columns and order_field in self._inherit_fields:
# also add missing joins for reaching the table containing the m2o field
tables, where_clause, qualified_field = self._inherits_join_calc(order_field, tables, where_clause)
qualified_field = self._inherits_join_calc(order_field, query)
order_field_column = self._inherit_fields[order_field][2]
else:
qualified_field = '"%s"."%s"' % (self._table, order_field)
@@ -3995,16 +3978,14 @@ class orm(orm_template):
# extract the first field name, to be able to qualify it and add desc/asc
m2o_order = m2o_order.split(",",1)[0].strip().split(" ",1)[0]
# the perhaps missing join:
quoted_model_table = '"%s"' % dest_model._table
if quoted_model_table not in tables:
tables.append(quoted_model_table)
where_clause.append('%s = %s.id' % (qualified_field, quoted_model_table))
return ('%s.%s' % (quoted_model_table, m2o_order), tables, where_clause)
# Join the dest m2o table if it's not joined yet. We use [LEFT] OUTER join here
# as we don't want to exclude results that have NULL values for the m2o
src_table, src_field = qualified_field.replace('"','').split('.', 1)
query.join((src_table, dest_model._table, src_field, 'id'), outer=True)
return '"%s"."%s"' % (dest_model._table, m2o_order)
def _generate_order_by(self, order_spec, tables, where_clause):
def _generate_order_by(self, order_spec, query):
"""
Attempt to consruct an appropriate ORDER BY clause based on order_spec, which must be
a comma-separated list of valid field names, optionally followed by an ASC or DESC direction.
@@ -4024,16 +4005,16 @@ class orm(orm_template):
if order_column._classic_read:
order_by_clause = '"%s"."%s"' % (self._table, order_field)
elif order_column._type == 'many2one':
order_by_clause, tables, where_clause = self._generate_m2o_order_by(order_field, tables, where_clause)
order_by_clause = self._generate_m2o_order_by(order_field, query)
else:
continue # ignore non-readable or "non-joignable" fields
elif order_field in self._inherit_fields:
parent_obj = self.pool.get(self._inherit_fields[order_field][0])
order_column = parent_obj._columns[order_field]
if order_column._classic_read:
tables, where_clause, order_by_clause = self._inherits_join_calc(order_field, tables, where_clause)
order_by_clause = self._inherits_join_calc(order_field, query)
elif order_column._type == 'many2one':
order_by_clause, tables, where_clause = self._generate_m2o_order_by(order_field, tables, where_clause)
order_by_clause = self._generate_m2o_order_by(order_field, query)
else:
continue # ignore non-readable or "non-joignable" fields
order_by_elements.append("%s %s" % (order_by_clause, order_direction))
@@ -4054,34 +4035,21 @@ class orm(orm_template):
if context is None:
context = {}
self.pool.get('ir.model.access').check(cr, access_rights_uid or user, self._name, 'read', context=context)
# compute the where, order by, limit and offset clauses
(where_clause, where_clause_params, tables) = self._where_calc(cr, user, args, context=context)
# apply direct ir.rules from current model
self._apply_ir_rules(cr, user, where_clause, where_clause_params, tables, 'read', context=context)
query = self._where_calc(cr, user, args, context=context)
self._apply_ir_rules(cr, user, query, 'read', context=context)
order_by = self._generate_order_by(order, query)
from_clause, where_clause, where_clause_params = query.get_sql()
# then apply the ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
previous_tables = list(tables)
if self._apply_ir_rules(cr, user, where_clause, where_clause_params, tables, 'read', model_name=inherited_model, context=context):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, previous_tables, where_clause)
tables = list(set(tables).union(set(previous_tables)))
where = where_clause
order_by = self._generate_order_by(order, tables, where_clause)
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
where_str = where and (" WHERE %s" % " AND ".join(where)) or ''
where_str = where_clause and (" WHERE %s" % where_clause) or ''
if count:
cr.execute('select count(%s.id) from ' % self._table +
','.join(tables) + where_str + limit_str + offset_str, where_clause_params)
cr.execute('SELECT count("%s".id) FROM ' % self._table + from_clause + where_str + limit_str + offset_str, where_clause_params)
res = cr.fetchall()
return res[0][0]
cr.execute('select %s.id from ' % self._table + ','.join(tables) + where_str + order_by + limit_str+offset_str, where_clause_params)
cr.execute('SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str, where_clause_params)
res = cr.fetchall()
return [x[0] for x in res]
+122
View File
@@ -0,0 +1,122 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
def _quote(to_quote):
if '"' not in to_quote:
return '"%s"' % to_quote
return to_quote
class Query(object):
"""
Dumb implementation of a Query object, using 3 string lists so far
for backwards compatibility with the (table, where_clause, where_params) previously used.
TODO: To be improved after v6.0 to rewrite part of the ORM and add support for:
- auto-generated multiple table aliases
- multiple joins to the same table with different conditions
- dynamic right-hand-side values in domains (e.g. a.name = a.description)
- etc.
"""
def __init__(self, tables=None, where_clause=None, where_clause_params=None, joins=None):
# holds the list of tables joined using default JOIN.
# the table names are stored double-quoted (backwards compatibility)
self.tables = tables or []
# holds the list of WHERE clause elements, to be joined with
# 'AND' when generating the final query
self.where_clause = where_clause or []
# holds the parameters for the formatting of `where_clause`, to be
# passed to psycopg's execute method.
self.where_clause_params = where_clause_params or []
# holds table joins done explicitly, supporting outer joins. The JOIN
# condition should not be in `where_clause`. The dict is used as follows:
# self.joins = {
# 'table_a': [
# ('table_b', 'table_a_col1', 'table_b_col', 'LEFT JOIN'),
# ('table_c', 'table_a_col2', 'table_c_col', 'LEFT JOIN'),
# ('table_d', 'table_a_col3', 'table_d_col', 'JOIN'),
# ]
# }
# which should lead to the following SQL:
# SELECT ... FROM "table_a" LEFT JOIN "table_b" ON ("table_a"."table_a_col1" = "table_b"."table_b_col")
# LEFT JOIN "table_c" ON ("table_a"."table_a_col2" = "table_c"."table_c_col")
self.joins = joins or {}
def join(self, connection, outer=False):
"""Adds the JOIN specified in ``connection``.
:param connection: a tuple ``(lhs, table, lhs_col, col)``.
The join corresponds to the SQL equivalent of::
``(lhs.lhs_col = table.col)``
:param outer: True if a LEFT OUTER JOIN should be used, if possible
(no promotion to OUTER JOIN is supported in case the JOIN
was already present in the query, as for the moment
implicit INNER JOINs are only connected from NON-NULL
columns so it would not be correct (e.g. for
``_inherits`` or when a domain criterion explicitly
adds filtering)
"""
(lhs, table, lhs_col, col) = connection
lhs = _quote(lhs)
table = _quote(table)
assert lhs in self.tables, "Left-hand-side table must already be part of the query!"
if table in self.tables:
# already joined, must ignore (promotion to outer and multiple joins not supported yet)
pass
else:
# add JOIN
self.tables.append(table)
self.joins.setdefault(lhs, []).append((table, lhs_col, col, outer and 'LEFT JOIN' or 'JOIN'))
return self
def get_sql(self):
"""Returns (query_from, query_where, query_params)"""
query_from = ''
tables_to_process = list(self.tables)
def add_joins_for_table(table, query_from):
for (dest_table, lhs_col, col, join) in self.joins.get(table,[]):
tables_to_process.remove(dest_table)
query_from += ' %s %s ON (%s."%s" = %s."%s")' % \
(join, dest_table, table, lhs_col, dest_table, col)
query_from = add_joins_for_table(dest_table, query_from)
return query_from
for table in tables_to_process:
query_from += table
if table in self.joins:
query_from = add_joins_for_table(table, query_from)
query_from += ','
query_from = query_from[:-1] # drop last comma
return (query_from, " AND ".join(self.where_clause), self.where_clause_params)
def __str__(self):
return '<osv.Query: "SELECT ... FROM %s WHERE %s" with params: %r>' % self.get_sql()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -2
View File
@@ -44,12 +44,11 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False,
cr = db.cursor()
try:
pool.init_set(cr, False)
pool.get('ir.actions.report.xml').register_all(cr)
cr.commit()
finally:
cr.close()
import report
report.interface.register_all(db)
if pooljobs:
pool.get('ir.cron').restart(db.dbname)
return db, pool
-20
View File
@@ -219,25 +219,5 @@ class report_rml(report_int):
obj.render()
return obj.get()
from report_sxw import report_sxw
def register_all(db):
opj = os.path.join
cr = db.cursor()
cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,))
result = cr.dictfetchall()
cr.close()
svcs = netsvc.Service._services
for r in result:
if svcs.has_key('report.'+r['report_name']):
continue
if r['report_rml'] or r['report_rml_content_data']:
report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'])
if r['report_xsl']:
report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1
View File
@@ -98,6 +98,7 @@ class report_printscreen_list(report_int):
continue
child_ids = model.search(cr, uid, inner_domain)
res = model.read(cr, uid, child_ids, result['fields'].keys(), context)
res.sort(lambda x,y: cmp(ids.index(x['id']), ids.index(y['id'])))
rows.extend(res)
dom = [('id','in',ids)]
if self.groupby_no_leaf and len(ids) and not ids[0]:
+34 -1
View File
@@ -39,6 +39,7 @@ import tools
import warnings
import zipfile
import common
from osv.fields import float as float_class, function as function_class
DT_FORMAT = '%Y-%m-%d'
DHM_FORMAT = '%Y-%m-%d %H:%M:%S'
@@ -240,9 +241,36 @@ class rml_parse(object):
self.default_lang[lang] = self.lang_dict.copy()
return True
def formatLang(self, value, digits=2, date=False,date_time=False, grouping=True, monetary=False):
def digits_fmt(self, obj=None, f=None, dp=None):
digits = self.get_digits(obj, f, dp)
return "%%.%df" % (digits, )
def get_digits(self, obj=None, f=None, dp=None):
d = DEFAULT_DIGITS = 2
if dp:
decimal_precision_obj = self.pool.get('decimal.precision')
ids = decimal_precision_obj.search(self.cr, self.uid, [('name', '=', dp)])
if ids:
d = decimal_precision_obj.browse(self.cr, self.uid, ids)[0].digits
elif obj and f:
res_digits = getattr(obj._columns[f], 'digits', lambda x: ((16,DEFAULT_DIGITS)))
if isinstance(res_digits, tuple):
d = res_digits[1]
else:
d = res_digits(self.cr)[1]
elif (hasattr(obj, '_field') and\
isinstance(obj._field, (float_class, function_class)) and\
obj._field.digits):
d = obj._field.digits[1] or DEFAULT_DIGITS
return d
def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False):
if digits is None:
digits = self.get_digits(value)
if isinstance(value, (str, unicode)) and not value:
return ''
if not self.lang_dict_called:
self._get_lang_dict()
self.lang_dict_called = True
@@ -250,6 +278,7 @@ class rml_parse(object):
if date or date_time:
if not str(value):
return ''
date_format = self.lang_dict['date_format']
parse_format = DT_FORMAT
if date_time:
@@ -258,9 +287,11 @@ class rml_parse(object):
parse_format = DHM_FORMAT
if not isinstance(value, time.struct_time):
return time.strftime(date_format, time.strptime(value, parse_format))
else:
date = datetime(*value.timetuple()[:6])
return date.strftime(date_format)
return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
def repeatIn(self, lst, name,nodes_parent=False):
@@ -305,6 +336,8 @@ class rml_parse(object):
def set_context(self, objects, data, ids, report_type = None):
self.localcontext['data'] = data
self.localcontext['objects'] = objects
self.localcontext['digits_fmt'] = self.digits_fmt
self.localcontext['get_digits'] = self.get_digits
self.datas = data
self.ids = ids
self.objects = objects
+27
View File
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import unittest
import test
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromModule(test))
+22
View File
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from test_osv import *
+64
View File
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import unittest
from osv.query import Query
class QueryTestCase(unittest.TestCase):
def test_basic_query(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_product", "res_user", "user_id", "id"), outer=True) # outer join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product" LEFT JOIN "res_user" ON ("product_product"."user_id" = "res_user"."id"),"product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") """.strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id""".strip())
def test_query_chained_explicit_joins(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_category", "res_user", "user_id", "id"), outer=True) # CHAINED outer join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product","product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") LEFT JOIN "res_user" ON ("product_category"."user_id" = "res_user"."id")""".strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id""".strip())
def test_mixed_query_chained_explicit_implicit_joins(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_category", "res_user", "user_id", "id"), outer=True) # CHAINED outer join
query.tables.append('"account.account"')
query.where_clause.append("product_category.expense_account_id = account_account.id") # additional implicit join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product","product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") LEFT JOIN "res_user" ON ("product_category"."user_id" = "res_user"."id"),"account.account" """.strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id AND product_category.expense_account_id = account_account.id""".strip())
def test_raise_missing_lhs(self):
query = Query()
query.tables.append('"product_product"')
self.assertRaises(AssertionError, query.join, ("product_template", "product_category", "categ_id", "id"), outer=False)
+3 -3
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2010-09-15 02:58+0000\n"
"Last-Translator: barge <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:30+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: Korean <ko@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:47+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string
+2 -2
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2010-09-10 03:13+0000\n"
"PO-Revision-Date: 2010-09-29 08:02+0000\n"
"Last-Translator: ub121 <ubs121@gmail.com>\n"
"Language-Team: Mongolian <mn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:47+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string