From fb3f7aa747d4d196abd3963ef1cbdfae910551a5 Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Tue, 10 Jan 2012 13:35:59 +0100 Subject: [PATCH 001/312] [IMP] delivery: move picking's net weight to extended view bzr revid: ls@numerigraphe.fr-20120110123559-1llywc42k606hryj --- addons/delivery/delivery_view.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml index c46253777d2..47ed9d6d274 100644 --- a/addons/delivery/delivery_view.xml +++ b/addons/delivery/delivery_view.xml @@ -194,7 +194,7 @@ - + - + - + @@ -245,7 +245,7 @@ - + @@ -258,7 +258,7 @@ - + @@ -271,7 +271,7 @@ - + From 32781b0268a8b3583869cd14809e466568ee2a7f Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 16 Jan 2012 11:34:06 +0100 Subject: [PATCH 002/312] [FIX] typo in XML file bzr revid: ls@numerigraphe.fr-20120116103406-gwx3w8zlnrnvlyyr --- addons/delivery/delivery_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml index 47ed9d6d274..6c9e8c85cdb 100644 --- a/addons/delivery/delivery_view.xml +++ b/addons/delivery/delivery_view.xml @@ -194,7 +194,7 @@ - @@ -207,7 +207,7 @@ - From 438cde1f2f9b6204a0cb71338eacc7dfa1fab4e9 Mon Sep 17 00:00:00 2001 From: "nicolas.bessi@camptocamp.com" <> Date: Wed, 8 Feb 2012 11:37:15 +0100 Subject: [PATCH 003/312] [FIX] l10n_ch bvr report to follow last patches of report_webkit addons bzr revid: nicolas.bessi@camptocamp.com-20120208103715-gk6upkf3b47av9h1 --- addons/l10n_ch/report/report_webkit_html.py | 154 +++++++------------- 1 file changed, 51 insertions(+), 103 deletions(-) diff --git a/addons/l10n_ch/report/report_webkit_html.py b/addons/l10n_ch/report/report_webkit_html.py index e6f7239c4e4..72158361da7 100644 --- a/addons/l10n_ch/report/report_webkit_html.py +++ b/addons/l10n_ch/report/report_webkit_html.py @@ -20,22 +20,31 @@ ############################################################################## import time -from report import report_sxw -from report_webkit import webkit_report -from report_webkit import report_helper -from osv import osv -from tools import mod10r import sys import os import re + +from mako.template import Template +from mako.lookup import TemplateLookup +from mako import exceptions + + +from report import report_sxw +from report_webkit import webkit_report +from report_webkit import report_helper + +from osv import osv +from osv.osv import except_osv + +from tools import mod10r +from tools.translate import _ +from tools.config import config + import wizard import addons import pooler -from tools.config import config -from mako.template import Template -from mako import exceptions -from tools.translate import _ -from osv.osv import except_osv + + class l10n_ch_report_webkit_html(report_sxw.rml_parse): @@ -143,53 +152,26 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse): 'digits!\nPlease check your company ' 'information for the invoice:\n%s') %(invoice_name))) return '' + +def mako_template(text): + """Build a Mako template. + + This template uses UTF-8 encoding + """ + tmp_lookup = TemplateLookup() #we need it in order to allow inclusion and inheritance + return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup) class BVRWebKitParser(webkit_report.WebKitParser): - def setLang(self, lang): - if not lang: - lang = 'en_US' - self.localcontext['lang'] = lang - - def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False): - """format using the know cursor, language from localcontext""" - if digits is None: - digits = self.parser_instance.get_digits(value) - if isinstance(value, (str, unicode)) and not value: - return '' - pool_lang = self.pool.get('res.lang') - lang = self.localcontext['lang'] - - lang_ids = pool_lang.search(self.parser_instance.cr, self.parser_instance.uid, [('code','=',lang)])[0] - lang_obj = pool_lang.browse(self.parser_instance.cr, self.parser_instance.uid, lang_ids) - - if date or date_time: - if not str(value): - return '' - - date_format = lang_obj.date_format - parse_format = '%Y-%m-%d' - if date_time: - value=value.split('.')[0] - date_format = date_format + " " + lang_obj.time_format - parse_format = '%Y-%m-%d %H:%M:%S' - 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 lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) - def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None): """generate the PDF""" - self.parser_instance = self.parser( - cursor, + context = context or {} + if report_xml.report_type != 'webkit': + return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context) + self.parser_instance = self.parser(cursor, uid, self.name2, - context=context - ) + context=context) self.pool = pooler.get_pool(cursor.dbname) objs = self.getObjects(cursor, uid, ids, context) self.parser_instance.set_context(objs, data, ids, report_xml.report_type) @@ -201,7 +183,7 @@ class BVRWebKitParser(webkit_report.WebKitParser): if not template and report_xml.report_webkit_data : template = report_xml.report_webkit_data if not template : - raise except_osv(_('Webkit Report template not found !'), _('')) + raise except_osv(_('Error'),_('Webkit Report template not found !')) header = report_xml.webkit_header.html footer = report_xml.webkit_header.footer_html if not header and report_xml.header: @@ -210,43 +192,19 @@ class BVRWebKitParser(webkit_report.WebKitParser): _('Please set a header in company settings') ) if not report_xml.header : - #I know it could be cleaner ... - header = u""" - - - - - - - -""" - self.parser_instance.localcontext.update({'setLang':self.setLang}) - self.parser_instance.localcontext.update({'formatLang':self.formatLang}) + header = '' + default_head = addons.get_module_resource('report_webkit', 'default_header.html') + with open(default_head,'r') as f: + header = f.read() css = report_xml.webkit_header.css if not css : css = '' user = self.pool.get('res.users').browse(cursor, uid, uid) company = user.company_id - parse_template = template - #default_filters=['unicode', 'entity'] can be used to set global filter - body_mako_tpl = Template(parse_template ,input_encoding='utf-8', output_encoding='utf-8') + body_mako_tpl = mako_template(template) #BVR specific bvr_path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr.mako')) - body_bvr_tpl = Template(file(bvr_path).read(), input_encoding='utf-8', output_encoding='utf-8') - + body_bvr_tpl = mako_template(file(bvr_path).read()) helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context) ##BVR Specific htmls = [] @@ -254,58 +212,48 @@ class BVRWebKitParser(webkit_report.WebKitParser): self.parser_instance.localcontext['objects'] = [obj] if not company.bvr_only: try: - html = body_mako_tpl.render( - helper=helper, + html = body_mako_tpl.render(helper=helper, css=css, _=self.translate_call, - **self.parser_instance.localcontext - ) + **self.parser_instance.localcontext) except Exception, e: raise Exception(exceptions.text_error_template().render()) htmls.append(html) if not company.invoice_only: try: - bvr = body_bvr_tpl.render( - helper=helper, - css=css, - _=self.translate_call, - **self.parser_instance.localcontext - ) + bvr = body_bvr_tpl.render(helper=helper, + css=css, + _=self.translate_call, + **self.parser_instance.localcontext) except Exception, e: raise Exception(exceptions.text_error_template().render()) htmls.append(bvr) head_mako_tpl = Template(header, input_encoding='utf-8', output_encoding='utf-8') try: - head = head_mako_tpl.render( - helper=helper, + head = head_mako_tpl.render(helper=helper, css=css, _debug=False, _=self.translate_call, - **self.parser_instance.localcontext - ) + **self.parser_instance.localcontext) except Exception, e: raise Exception(exceptions.text_error_template().render()) foot = False if footer and company.invoice_only : foot_mako_tpl = Template(footer, input_encoding='utf-8', output_encoding='utf-8') try: - foot = foot_mako_tpl.render( - helper=helper, + foot = foot_mako_tpl.render(helper=helper, css=css, _=self.translate_call, - **self.parser_instance.localcontext - ) + **self.parser_instance.localcontext) except Exception, e: raise Exception(exceptions.text_error_template().render()) if report_xml.webkit_debug : try: - deb = head_mako_tpl.render( - helper=helper, + deb = head_mako_tpl.render(helper=helper, css=css, _debug=html, _=self.translate_call, - **self.parser_instance.localcontext - ) + **self.parser_instance.localcontext) except Exception, e: raise Exception(exceptions.text_error_template().render()) return (deb, 'html') From 4c54457489044ad7c7e4f8c54241e32dba6d4a10 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Mon, 20 Feb 2012 15:00:37 +0530 Subject: [PATCH 004/312] [FIX]purchase: added domain of supplier in the partner_id field lp bug: https://launchpad.net/bugs/936385 fixed bzr revid: mma@tinyerp.com-20120220093037-uh5ubja5jtnqy8om --- addons/purchase/purchase_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 1c936055aff..e358bfc2ced 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -172,7 +172,7 @@ - + From 156da2b3503a4449106fa78a2883431e1f6663aa Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Sat, 9 Jun 2012 11:45:22 -0400 Subject: [PATCH 005/312] [IMP] Use account.data_account_type. Remove notax. Improve chart of taxes. bzr revid: maxime.chambreuil@savoirfairelinux.com-20120609154522-htduc8596i18pj93 --- addons/l10n_ca/__openerp__.py | 2 - addons/l10n_ca/account_chart_en.xml | 166 +++--- addons/l10n_ca/account_chart_fr.xml | 174 +++--- addons/l10n_ca/account_tax_code_en.xml | 18 +- addons/l10n_ca/account_tax_code_fr.xml | 16 +- addons/l10n_ca/account_tax_en.xml | 481 +++++++++++++---- addons/l10n_ca/account_tax_fr.xml | 477 +++++++++++++---- addons/l10n_ca/account_types_en.xml | 64 --- addons/l10n_ca/account_types_fr.xml | 79 --- addons/l10n_ca/fiscal_templates_en.xml | 712 +++++++++++++++++-------- addons/l10n_ca/fiscal_templates_fr.xml | 522 +++++++++++++----- 11 files changed, 1828 insertions(+), 883 deletions(-) delete mode 100644 addons/l10n_ca/account_types_en.xml delete mode 100644 addons/l10n_ca/account_types_fr.xml diff --git a/addons/l10n_ca/__openerp__.py b/addons/l10n_ca/__openerp__.py index 800ca7937eb..bd5fe4e6ea0 100644 --- a/addons/l10n_ca/__openerp__.py +++ b/addons/l10n_ca/__openerp__.py @@ -33,13 +33,11 @@ Canadian accounting charts and localizations. "depends" : ['base', 'account', 'base_iban', 'base_vat', 'account_chart'], "init_xml" : [], "update_xml" : [ - 'account_types_en.xml', 'account_chart_en.xml', 'account_tax_code_en.xml', 'account_chart_template_en.xml', 'account_tax_en.xml', 'fiscal_templates_en.xml', - 'account_types_fr.xml', 'account_chart_fr.xml', 'account_tax_code_fr.xml', 'account_chart_template_fr.xml', diff --git a/addons/l10n_ca/account_chart_en.xml b/addons/l10n_ca/account_chart_en.xml index 26db0bcef95..14cbc993b2b 100644 --- a/addons/l10n_ca/account_chart_en.xml +++ b/addons/l10n_ca/account_chart_en.xml @@ -8,7 +8,7 @@ Account Chart CA EN view - + @@ -17,7 +17,7 @@ 1 view - + ASSETS @@ -25,7 +25,7 @@ 11 view - + CURRENT ASSETS @@ -33,7 +33,7 @@ 111 view - + CASH @@ -41,7 +41,7 @@ 1111 liquidity - + Checking Account @@ -49,7 +49,7 @@ 112 view - + TREASURY OR TREASURY EQUIVALENTS @@ -57,7 +57,7 @@ 113 view - + CERTIFICATES OF DEPOSITS @@ -65,7 +65,7 @@ 114 view - + STOCKS @@ -73,7 +73,7 @@ 115 view - + ACCOUNTS RECEIVABLES @@ -81,7 +81,7 @@ 1151 receivable - + Customers Account @@ -90,7 +90,7 @@ 1152 view - + ALLOWANCE FOR DOUBTFUL ACCOUNTS @@ -98,7 +98,7 @@ 116 view - + PREPAID EXPENSES @@ -106,7 +106,7 @@ 117 view - + INVESTMENTS HELD FOR TRADING @@ -114,15 +114,15 @@ 118 view - + TAXES RECEIVABLES 1181 - receivable - + other + GST receivable @@ -130,8 +130,8 @@ 1182 - receivable - + other + PST/QST receivable @@ -139,8 +139,8 @@ 1183 - receivable - + other + HST receivable @@ -149,7 +149,7 @@ 15 view - + NON-CURRENT ASSETS @@ -157,7 +157,7 @@ 151 view - + INVESTMENTS AVAILABLE FOR SALE @@ -165,7 +165,7 @@ 152 view - + TANGIBLE ASSETS @@ -173,7 +173,7 @@ 1527 view - + ACCUMULATED DEPRECIATIONS @@ -181,7 +181,7 @@ 153 view - + INTANGIBLE ASSETS @@ -189,7 +189,7 @@ 1531 view - + PATENTS, TRADEMARKS AND COPYRIGHTS @@ -199,7 +199,7 @@ 2 view - + LIABILITIES @@ -207,7 +207,7 @@ 21 view - + CURRENT LIABILITIES @@ -215,7 +215,7 @@ 211 view - + ACCOUNTS PAYABLES @@ -223,7 +223,7 @@ 2111 payable - + Suppliers Account @@ -232,15 +232,15 @@ 212 view - + TAXES PAYABLES 2121 - payable - + other + GST to pay @@ -248,8 +248,8 @@ 2122 - payable - + other + PST/QST to pay @@ -257,8 +257,8 @@ 2123 - payable - + other + HST to pay @@ -267,7 +267,7 @@ 213 view - + CURRENT FINANCIAL DEBTS @@ -275,7 +275,7 @@ 25 view - + NON-CURRENT LIABILITIES @@ -283,7 +283,7 @@ 251 view - + NON-CURRENT FINANCIAL DEBTS @@ -291,7 +291,7 @@ 252 view - + PROVISIONS FOR PENSIONS AND OTHER POST-EMPLOYMENT ADVANTAGES @@ -299,7 +299,7 @@ 253 view - + DEFERRED TAXES @@ -307,7 +307,7 @@ 259 view - + OTHER NON-CURRENT LIABILITIES @@ -317,7 +317,7 @@ 3 view - + EQUITY @@ -325,7 +325,7 @@ 31 view - + SHARE CAPITAL @@ -333,7 +333,7 @@ 32 view - + PREMIUMS @@ -341,7 +341,7 @@ 33 view - + RETAINED EARNINGS @@ -349,7 +349,7 @@ 34 view - + DIVIDENDS @@ -357,7 +357,7 @@ 35 view - + TRANSLATION ADJUSTMENTS @@ -365,7 +365,7 @@ 36 view - + CONTRIBUTED SURPLUS @@ -375,7 +375,7 @@ 4 view - + INCOMES @@ -383,7 +383,7 @@ 41 view - + OPERATING INCOMES @@ -391,7 +391,7 @@ 411 other - + Inside Sales @@ -399,7 +399,7 @@ 412 other - + Harmonized Provinces Sales @@ -407,7 +407,7 @@ 413 other - + Non-Harmonized Provinces Sales @@ -415,7 +415,7 @@ 414 other - + International Sales @@ -423,7 +423,7 @@ 419 view - + OTHER OPERATING INCOMES @@ -431,7 +431,7 @@ 42 view - + NON-OPERATING INCOMES @@ -439,7 +439,7 @@ 421 view - + INTERESTS @@ -447,7 +447,7 @@ 429 view - + OTHER NON-OPERATING INCOMES @@ -457,7 +457,7 @@ 5 view - + EXPENSES @@ -465,7 +465,7 @@ 51 view - + OPERATING EXPENSES @@ -473,7 +473,7 @@ 511 view - + COST OF GOODS SOLD @@ -481,7 +481,7 @@ 5111 other - + Inside Purchases @@ -489,7 +489,7 @@ 5112 other - + Purchases in harmonized provinces @@ -497,7 +497,7 @@ 5113 other - + Purchases in non-harmonized provinces @@ -505,7 +505,7 @@ 5114 other - + International Purchases @@ -513,7 +513,7 @@ 512 view - + LABOUR EXPENSES @@ -521,7 +521,7 @@ 5121 other - + Salaries, wages and commissions @@ -529,7 +529,7 @@ 5122 other - + Holidays @@ -537,7 +537,7 @@ 5123 other - + Employment Insurance @@ -545,7 +545,7 @@ 5124 other - + Health Services Fund @@ -553,7 +553,7 @@ 5125 other - + Annuities @@ -561,7 +561,7 @@ 5126 other - + Parental Insurance @@ -569,7 +569,7 @@ 5127 other - + Labour Health and Safety @@ -577,7 +577,7 @@ 5128 other - + Labour Standards @@ -585,7 +585,7 @@ 513 view - + SALES EXPENSES @@ -593,7 +593,7 @@ 514 view - + GENERAL EXPENSES @@ -601,7 +601,7 @@ 515 view - + RESEARCH AND DEVELOPMENT EXPENSES @@ -609,7 +609,7 @@ 519 view - + OTHER OPERATING EXPENSES @@ -617,7 +617,7 @@ 55 view - + NON-OPERATING EXPENSES @@ -625,7 +625,7 @@ 551 view - + INTEREST EXPENSES @@ -633,7 +633,7 @@ 559 view - + OTHER NON-OPERATING EXPENSES diff --git a/addons/l10n_ca/account_chart_fr.xml b/addons/l10n_ca/account_chart_fr.xml index b66dd5f02ba..e50ac7ff4dc 100644 --- a/addons/l10n_ca/account_chart_fr.xml +++ b/addons/l10n_ca/account_chart_fr.xml @@ -6,7 +6,7 @@ 0 view - + Account Chart CA FR @@ -16,7 +16,7 @@ 1 view - + ACTIF @@ -24,7 +24,7 @@ 11 view - + ACTIFS COURANTS @@ -32,7 +32,7 @@ 111 view - + ENCAISSE @@ -40,7 +40,7 @@ 1111 liquidity - + Compte chèque @@ -48,7 +48,7 @@ 1112 liquidity - + Petite caisse @@ -56,7 +56,7 @@ 112 view - + TRÉSORERIE OU ÉQUIVALENTS DE TRÉSORERIE @@ -64,7 +64,7 @@ 113 view - + CERTIFICATS DE DÉPÔTS @@ -72,7 +72,7 @@ 114 view - + STOCKS @@ -80,7 +80,7 @@ 115 view - + COMPTES CLIENTS @@ -88,7 +88,7 @@ 1151 receivable - + Comptes clients @@ -97,7 +97,7 @@ 1152 view - + PROVISION POUR CRÉANCES DOUTEUSES @@ -105,7 +105,7 @@ 116 view - + FRAIS PAYÉS D'AVANCE @@ -113,7 +113,7 @@ 117 view - + PLACEMENTS DÉTENUS À DES FINS DE TRANSACTION @@ -121,15 +121,15 @@ 118 view - + IMPÔTS À RECEVOIR 1181 - receivable - + other + TPS à recevoir @@ -137,8 +137,8 @@ 1182 - receivable - + other + TVP/TVQ à recevoir @@ -146,8 +146,8 @@ 1183 - receivable - + other + TVH à recevoir @@ -156,7 +156,7 @@ 15 view - + ACTIFS NON-COURANTS @@ -164,7 +164,7 @@ 151 view - + PLACEMENTS DISPONIBLES À LA VENTE @@ -172,7 +172,7 @@ 152 view - + IMMOBILISATIONS CORPORELLES @@ -180,7 +180,7 @@ 1527 view - + AMORTISSEMENTS CUMULÉS @@ -188,7 +188,7 @@ 153 view - + IMMOBILISATIONS INCORPORELLES @@ -196,7 +196,7 @@ 1531 view - + BREVETS, MARQUES DE COMMERCE ET DROITS D'AUTEURS @@ -206,7 +206,7 @@ 2 view - + PASSIF @@ -214,7 +214,7 @@ 21 view - + PASSIFS COURANTS @@ -222,7 +222,7 @@ 211 view - + FOURNISSEURS ET COMPTES RATTACHÉS @@ -230,7 +230,7 @@ 2111 payable - + Comptes fournisseurs @@ -239,7 +239,7 @@ 212 view - + AUTRES COMPTES CRÉDITEURS @@ -247,15 +247,15 @@ 213 view - + IMPÔTS À PAYER 2131 - payable - + other + TPS à payer @@ -263,8 +263,8 @@ 2132 - payable - + other + TVP/TVQ à payer @@ -272,8 +272,8 @@ 2133 - payable - + other + TVH à payer @@ -282,7 +282,7 @@ 214 view - + DETTES FINANCIÈRES COURANTES @@ -290,7 +290,7 @@ 215 view - + PASSIFS LIÉS AUX ACTIFS DÉTENUS EN VUE DE LEUR CESSION @@ -298,7 +298,7 @@ 25 view - + PASSIFS NON-COURANTS @@ -306,7 +306,7 @@ 251 view - + DETTES FINANCIÈRES NON-COURANTES @@ -314,7 +314,7 @@ 252 view - + PROVISIONS POUR RETRAITES ET AUTRES AVANTAGES POSTÉRIEURS À L'EMPLOI @@ -322,7 +322,7 @@ 253 view - + IMPÔTS DIFFÉRÉS @@ -330,7 +330,7 @@ 254 view - + AUTRES PASSIFS NON-COURANTS @@ -340,7 +340,7 @@ 3 view - + CAPITAUX PROPRES @@ -348,7 +348,7 @@ 31 view - + CAPITAL-ACTIONS @@ -356,7 +356,7 @@ 32 view - + PRIMES @@ -364,7 +364,7 @@ 33 view - + BÉNÉFICES NON RÉPARTIS @@ -372,7 +372,7 @@ 34 view - + DIVIDENDES @@ -380,7 +380,7 @@ 35 view - + ÉCARTS DE CONVERSION @@ -388,7 +388,7 @@ 36 view - + SURPLUS D'APPORT @@ -396,7 +396,7 @@ 39 view - + AUTRES ÉLÉMENTS DU RÉSULTAT GLOBAL @@ -406,7 +406,7 @@ 4 view - + PRODUITS @@ -414,7 +414,7 @@ 41 view - + PRODUITS D'EXPLOITATION @@ -422,7 +422,7 @@ 411 other - + Ventes @@ -430,7 +430,7 @@ 412 other - + Ventes avec des provinces harmonisées @@ -438,7 +438,7 @@ 413 other - + Ventes avec des provinces non-harmonisées @@ -446,7 +446,7 @@ 414 other - + Ventes à l'étranger @@ -454,7 +454,7 @@ 419 view - + AUTRES PRODUITS D'EXPLOITATION @@ -462,7 +462,7 @@ 42 view - + PRODUITS NON LIÉS À L'EXPLOITATION @@ -470,7 +470,7 @@ 425 view - + INTÉRÊTS @@ -478,7 +478,7 @@ 429 view - + AUTRES PRODUITS NON LIÉS À L'EXPLOITATION @@ -488,7 +488,7 @@ 5 view - + CHARGES @@ -496,7 +496,7 @@ 51 view - + CHARGES D'EXPLOITATION @@ -504,7 +504,7 @@ 511 view - + COÛT DES PRODUITS VENDUS @@ -512,7 +512,7 @@ 5111 other - + Achats @@ -520,7 +520,7 @@ 5112 other - + Achats dans des provinces harmonisées @@ -528,7 +528,7 @@ 5113 other - + Achats dans des provinces non-harmonisées @@ -536,7 +536,7 @@ 5114 other - + Achats à l'étranger @@ -544,7 +544,7 @@ 512 view - + SALAIRES ET CHARGES SOCIALES @@ -552,7 +552,7 @@ 51201 other - + Salaires @@ -560,7 +560,7 @@ 51202 other - + Vacances @@ -568,7 +568,7 @@ 51203 other - + Assurance Emploi @@ -576,7 +576,7 @@ 51204 other - + Fonds des services de santé @@ -584,7 +584,7 @@ 51205 other - + Rentes @@ -592,7 +592,7 @@ 51206 other - + Assurance parental @@ -600,7 +600,7 @@ 51207 other - + Santé et sécurité au travail @@ -608,7 +608,7 @@ 51208 other - + Normes du travail @@ -616,7 +616,7 @@ 513 view - + FRAIS SUR VENTE @@ -624,7 +624,7 @@ 514 view - + FRAIS GÉNÉRAUX @@ -632,7 +632,7 @@ 515 view - + FRAIS DE RECHERCHE ET DÉVELOPPEMENT @@ -640,7 +640,7 @@ 519 view - + AUTRES FRAIS D'EXPLOITATION @@ -648,7 +648,7 @@ 52 view - + FRAIS NON LIÉS À L'EXPLOITATION @@ -656,7 +656,7 @@ 521 view - + INTÉRÊTS DÉBITEURS @@ -664,7 +664,7 @@ 529 view - + AUTRES FRAIS NON LIÉS À L'EXPLOITATION diff --git a/addons/l10n_ca/account_tax_code_en.xml b/addons/l10n_ca/account_tax_code_en.xml index 2fe144d6086..bb628a39f15 100644 --- a/addons/l10n_ca/account_tax_code_en.xml +++ b/addons/l10n_ca/account_tax_code_en.xml @@ -7,47 +7,47 @@ - Tax Balance to Pay + Tax Balance - Receivable Taxes + Taxes paid - GST to Receive + GST paid - PST to Receive + PST paid - HST to Receive + HST paid - Payable Taxes + Taxes received - GST to Pay + GST received - PST to Pay + PST received - HST to Pay + HST received diff --git a/addons/l10n_ca/account_tax_code_fr.xml b/addons/l10n_ca/account_tax_code_fr.xml index 849842b2453..d8abf73dd93 100644 --- a/addons/l10n_ca/account_tax_code_fr.xml +++ b/addons/l10n_ca/account_tax_code_fr.xml @@ -12,42 +12,42 @@ - Taxes à recevoir + Taxes payées - TPS à recevoir + TPS payée - TVP/TVQ à recevoir + TVP/TVQ payée - TVH à recevoir + TVH payée - Taxes à payer + Taxes reçues - TPS à payer + TPS reçue - TVP/TVQ à payer + TVP/TVQ reçue - TVH à payer + TVH reçue diff --git a/addons/l10n_ca/account_tax_en.xml b/addons/l10n_ca/account_tax_en.xml index 662ac4b52fc..f185f7f9198 100644 --- a/addons/l10n_ca/account_tax_en.xml +++ b/addons/l10n_ca/account_tax_en.xml @@ -2,263 +2,544 @@ + + - + - GST + PST (MB) - GSTPST_MB + GST + PST for sales (MB) + GSTPST_MB_SALE + sale 1 1 percent - + - GST - 5% (MB) + GST for sales - 5% (MB) GST + sale 0.050000 percent 1 - + - - + + - + - + - PST - 7% + PST for sales - 7% PST - 0.070000 + sale + 0.700000 percent - 1 - + 2 + - - + + - + - + - GST + PST (PE) - GSTPST_PE + GST + PST for sales (PE) + GSTPST_PE_SALE + sale 1 1 percent - + - GST - 5% (PE) + GST for sales - 5% (PE) GST + sale 0.050000 percent 1 - + - - + + - + - + - PST - 10% + PST for sale - 10% PST + sale 0.100000 percent - 1 - + 2 + - - + + - + - + - GST + PST (QC) - GSTPST_QC + GST + TVQ for sales + GSTTVQ_SALE + sale 1 1 percent - + - GST - 5% (QC) + GST for sales - 5% (QC) GST + sale 0.050000 percent 1 - + - - + + - + - + - PST - 9.5% - PST + TVQ for sales - 9.5% + TVQ + sale 0.095000 percent - 1 - + 2 + - - + + - + - + - GST + PST (SK) - GSTPST_SK + GST + PST for sales (SK) + GSTPST_SK_SALE + sale 1 1 percent - + - GST - 5% (SK) + GST for sales - 5% (SK) GST + sale 0.050000 percent 1 - + - - + + - + - + - PST - 5% + PST for sales - 5% (SK) PST + sale 0.050000 percent - 1 - + 2 + - - + + - + - + - HST - 12% - HST12 + TVH for sales - 12% + TVH12_SALE + sale 0.120000 percent - + - - + + - + - HST - 13% - HST13 + TVH for sales - 13% + TVH13_SALE + sale 0.130000 percent - + - - + + - + - HST - 13.5% - HST135 + TVH for sales - 13.5% + TVH135_SALE + sale 0.135000 percent - + - - + + - + - HST - 15% - HST15 + TVH for sales - 15% + TVH15_SALE + sale 0.150000 percent - + - - + + - + - GST - 5% - GST + GST for sales - 5% + GST_SALE + sale 0.050000 percent - + - - + + - + + + + + + - No tax - No tax - 0.00 + GST + PST for purchases (MB) + GSTPST_MB_PURC + purchase + 1 + 1 percent + + + GST for purchases - 5% (MB) + GST + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + PST for purchases - 7% + PST + purchase + 0.700000 + percent + 2 + + + + + + + + + + + + + + GST + PST for purchases (PE) + GSTPST_PE_PURC + purchase + 1 + 1 + percent + + + + + GST for purchases - 5% (PE) + GST + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + PST for purchases - 10% + PST + purchase + 0.100000 + percent + 2 + + + + + + + + + + + + + + GST + TVQ for purchases + GSTTVQ_PURC + purchase + 1 + 1 + percent + + + + + GST for purchases - 5% (QC) + GST + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + TVQ for purchases - 9.5% + TVQ + purchase + 0.095000 + percent + 2 + + + + + + + + + + + + + + GST + PST for purchases (SK) + GSTPST_SK_PURC + purchase + 1 + 1 + percent + + + + + GST for purchases - 5% (SK) + GST + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + PST for purchases - 5% (SK) + PST + purchase + 0.050000 + percent + 2 + + + + + + + + + + + + + + TVH for purchases - 12% + TVH12_PURC + purchase + 0.120000 + percent + + + + + + + + + + + TVH for purchases - 13% + TVH13_PURC + purchase + 0.130000 + percent + + + + + + + + + + + TVH for purchases - 13.5% + TVH135_PURC + purchase + 0.135000 + percent + + + + + + + + + + + TVH for purchases - 15% + TVH15_PURC + purchase + 0.150000 + percent + + + + + + + + + + + + + GST for purchases - 5% + GST_PURC + purchase + 0.050000 + percent + + + + + + + + diff --git a/addons/l10n_ca/account_tax_fr.xml b/addons/l10n_ca/account_tax_fr.xml index 5df4446c611..169bfe4f20b 100644 --- a/addons/l10n_ca/account_tax_fr.xml +++ b/addons/l10n_ca/account_tax_fr.xml @@ -2,263 +2,544 @@ + + - + - TPS + TVP (MB) - TPSTVP_MB + TPS + TVP sur les ventes (MB) + TPSTVP_MB_SALE + sale 1 1 percent - + - TPS - 5% (MB) + TPS sur les ventes - 5% (MB) TPS + sale 0.050000 percent 1 - + - - + + - + - + - TVP - 7% + TVP sur les ventes - 7% TVP + sale 0.700000 percent - 1 - + 2 + - - + + - + - + - TPS + TVP (PE) - TPSTVP_PE + TPS + TVP sur les ventes (PE) + TPSTVP_PE_SALE + sale 1 1 percent - + - TPS - 5% (PE) + TPS sur les ventes - 5% (PE) TPS + sale 0.050000 percent 1 - + - - + + - + - + - TVP - 10% + TVP for sale - 10% TVP + sale 0.100000 percent - 1 - + 2 + - - + + - + - + - TPS + TVQ - TPSTVQ + TPS + TVQ sur les ventes + TPSTVQ_SALE + sale 1 1 percent - + - TPS - 5% (QC) + TPS sur les ventes - 5% (QC) TPS + sale 0.050000 percent 1 - + - - + + - + - + - TVQ - 9.5% + TVQ sur les ventes - 9.5% TVQ + sale 0.095000 percent - 1 - + 2 + - - + + - + - + - TPS + TVP (SK) - TPSTVP_SK + TPS + TVP sur les ventes (SK) + TPSTVP_SK_SALE + sale 1 1 percent - + - TPS - 5% (SK) + TPS sur les ventes - 5% (SK) TPS + sale 0.050000 percent 1 - + - - + + - + - + - TVP - 5% (SK) + TVP sur les ventes - 5% (SK) TVP + sale 0.050000 percent - 1 - + 2 + - - + + - + - + - TVH - 12% - TVH12 + TVH sur les ventes - 12% + TVH12_SALE + sale 0.120000 percent - + - - + + - + - TVH - 13% - TVH13 + TVH sur les ventes - 13% + TVH13_SALE + sale 0.130000 percent - + - - + + - + - TVH - 13.5% - TVH135 + TVH sur les ventes - 13.5% + TVH135_SALE + sale 0.135000 percent - + - - + + - + - TVH - 15% - TVH15 + TVH sur les ventes - 15% + TVH15_SALE + sale 0.150000 percent - + - - + + - + - TPS - 5% - TPS + TPS sur les ventes - 5% + TPS_SALE + sale 0.050000 percent - + - - + + - + + + + + + - Pas de taxes - Pas de taxes - 0.00 + TPS + TVP sur les achats (MB) + TPSTVP_MB_PURC + purchase + 1 + 1 percent + + + TPS sur les achats - 5% (MB) + TPS + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + TVP sur les achats - 7% + TVP + purchase + 0.700000 + percent + 2 + + + + + + + + + + + + + + TPS + TVP sur les achats (PE) + TPSTVP_PE_PURC + purchase + 1 + 1 + percent + + + + + TPS sur les achats - 5% (PE) + TPS + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + TVP sur les achats - 10% + TVP + purchase + 0.100000 + percent + 2 + + + + + + + + + + + + + + TPS + TVQ sur les achats + TPSTVQ_PURC + purchase + 1 + 1 + percent + + + + + TPS sur les achats - 5% (QC) + TPS + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + TVQ sur les achats - 9.5% + TVQ + purchase + 0.095000 + percent + 2 + + + + + + + + + + + + + + TPS + TVP sur les achats (SK) + TPSTVP_SK_PURC + purchase + 1 + 1 + percent + + + + + TPS sur les achats - 5% (SK) + TPS + purchase + 0.050000 + percent + 1 + + + + + + + + + + + + + TVP sur les achats - 5% (SK) + TVP + purchase + 0.050000 + percent + 2 + + + + + + + + + + + + + + TVH sur les achats - 12% + TVH12_PURC + purchase + 0.120000 + percent + + + + + + + + + + + TVH sur les achats - 13% + TVH13_PURC + purchase + 0.130000 + percent + + + + + + + + + + + TVH sur les achats - 13.5% + TVH135_PURC + purchase + 0.135000 + percent + + + + + + + + + + + TVH sur les achats - 15% + TVH15_PURC + purchase + 0.150000 + percent + + + + + + + + + + + + + TPS sur les achats - 5% + TPS_PURC + purchase + 0.050000 + percent + + + + + + + + diff --git a/addons/l10n_ca/account_types_en.xml b/addons/l10n_ca/account_types_en.xml deleted file mode 100644 index 1af3fd92205..00000000000 --- a/addons/l10n_ca/account_types_en.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - Receivable - receivable - unreconciled - - - - Payable - payable - unreconciled - - - - View - view - none - - - - Income - income - none - income - - - - Expense - expense - none - expense - - - - Tax - tax - unreconciled - - - - Cash - cash - balance - - - - Asset - asset - balance - asset - - - - Equity - equity - liability - balance - - - - diff --git a/addons/l10n_ca/account_types_fr.xml b/addons/l10n_ca/account_types_fr.xml deleted file mode 100644 index cff6c01e6f2..00000000000 --- a/addons/l10n_ca/account_types_fr.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - Vue - view - none - - - - Capital - capital - asset - balance - - - - Immobilisation - immo - asset - balance - - - - Stock et Encours - stock - asset - balance - - - - Tiers - tiers - balance - - - - Tiers - Recevable - tiers -rec - asset - unreconciled - - - - Tiers - Payable - tiers - pay - liability - unreconciled - - - - Tax - tax - unreconciled - - - - Financier - financier - balance - - - - Charge - charge - expense - none - - - - Produit - produit - income - none - - - - diff --git a/addons/l10n_ca/fiscal_templates_en.xml b/addons/l10n_ca/fiscal_templates_en.xml index d7b6a3ee7da..54f9c21b5e1 100644 --- a/addons/l10n_ca/fiscal_templates_en.xml +++ b/addons/l10n_ca/fiscal_templates_en.xml @@ -39,354 +39,618 @@ + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - - + + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + + + - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - - - - + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/l10n_ca/fiscal_templates_fr.xml b/addons/l10n_ca/fiscal_templates_fr.xml index 2ce50e5d6e1..0acd7388a52 100644 --- a/addons/l10n_ca/fiscal_templates_fr.xml +++ b/addons/l10n_ca/fiscal_templates_fr.xml @@ -39,278 +39,542 @@ + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0fee0cea0079a57d362a5752cf3499a28c58bc43 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 08:45:23 +0200 Subject: [PATCH 006/312] [ADD] backbone-ification of Widgets API bzr revid: xmo@openerp.com-20120611064523-gczdqmfes5f1g9kj --- addons/web/static/src/js/corelib.js | 177 ++++++++++++++++++++++------ 1 file changed, 143 insertions(+), 34 deletions(-) diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 94c748f839c..8455a183f87 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -238,6 +238,20 @@ instance.web.ParentedMixin = { } }; +/** + * Utility function for APIs which can take either a value or a function which + * returns a value + * + * @param {Object} object + * @param {String} property + * @returns {Object} + */ +var getValue = function (object, property) { + if (object == null) { return null; } + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; +}; + /** * Backbone's events. Do not ever use it directly, use EventDispatcherMixin instead. * @@ -490,23 +504,19 @@ instance.web.CallbackEnabledMixin = _.extend({}, instance.web.PropertiesMixin, { * * The semantics of this precisely replace closing over the method call. * - * @param {String} method_name name of the method to invoke + * @param {String|Function} method function or name of the method to invoke * @returns {Function} proxied method */ - proxy: function (method_name) { + proxy: function (method) { var self = this; return function () { - return self[method_name].apply(self, arguments); + var fn = (method instanceof String) ? self[method] : method; + return fn.apply(self, arguments); } } }); instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { - /** - * Tag name when creating a default $element. - * @type string - */ - tagName: 'div', /** * Constructs the widget and sets its parent if a parent is given. * @@ -516,14 +526,9 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { * @param {instance.web.Widget} parent Binds the current instance to the given Widget instance. * When that widget is destroyed by calling destroy(), the current instance will be * destroyed too. Can be null. - * @param {String} element_id Deprecated. Sets the element_id. Only useful when you want - * to bind the current Widget to an already existing part of the DOM, which is not compatible - * with the DOM insertion methods provided by the current implementation of Widget. So - * for new components this argument should not be provided any more. */ init: function(parent) { instance.web.CallbackEnabledMixin.init.call(this); - this.$element = $(document.createElement(this.tagName)); this.setParent(parent); }, /** @@ -533,8 +538,8 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { _.each(this.getChildren(), function(el) { el.destroy(); }); - if(this.$element != null) { - this.$element.remove(); + if(this.$el) { + this.$el.remove(); } instance.web.PropertiesMixin.destroy.call(this); }, @@ -546,7 +551,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { appendTo: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.appendTo(t); + self.$el.appendTo(t); }, target); }, /** @@ -557,7 +562,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { prependTo: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.prependTo(t); + self.$el.prependTo(t); }, target); }, /** @@ -568,7 +573,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { insertAfter: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.insertAfter(t); + self.$el.insertAfter(t); }, target); }, /** @@ -579,7 +584,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { insertBefore: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.insertBefore(t); + self.$el.insertBefore(t); }, target); }, /** @@ -589,7 +594,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { */ replace: function(target) { return this.__widgetRenderAndInsert(_.bind(function(t) { - this.$element.replaceAll(t); + this.$el.replaceAll(t); }, this), target); }, __widgetRenderAndInsert: function(insertion, target) { @@ -612,6 +617,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { * @returns {jQuery.Deferred} */ start: function() { + return $.when(); } }); @@ -688,12 +694,9 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { * @param {instance.web.Widget} parent Binds the current instance to the given Widget instance. * When that widget is destroyed by calling destroy(), the current instance will be * destroyed too. Can be null. - * @param {String} element_id Deprecated. Sets the element_id. Only useful when you want - * to bind the current Widget to an already existing part of the DOM, which is not compatible - * with the DOM insertion methods provided by the current implementation of Widget. So - * for new components this argument should not be provided any more. */ init: function(parent) { + this._uid = _.uniqueId('-widget-'); instance.web.WidgetMixin.init.call(this,parent); this.session = instance.connection; }, @@ -703,20 +706,126 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { * key that references `this`. */ renderElement: function() { - var rendered = null; - if (this.template) - rendered = instance.web.qweb.render(this.template, {widget: this}); - if (_.str.trim(rendered)) { - var elem = $(rendered); - this.$element.replaceWith(elem); - this.$element = elem; + var $el; + if (this.template) { + $el = $(_.str.trim(instance.web.qweb.render( + this.template, {widget: this}))); + } else { + var attrs = _.extend({}, getValue(this, 'attributes') || {}); + if (this.id) { attrs.id = this.id; } + if (this.className) { attrs['class'] = this.className; } + $el = $(this.make(this.tagName, attrs)) + } + this.setElement($el); + }, + + /** + * Re-sets the widget's root element (el/$el/$element). + * + * Includes: + * * re-delegating events + * * re-binding sub-elements + * * if the widget already had a root element, replacing the pre-existing + * element in the DOM + * + * @param {HTMLElement | jQuery} element new root element for the widget + * @return {*} + */ + setElement: function (element) { + if (this.$el) { + this.undelegateEvents(); + this.unbindElements(); + this.$el.replaceWith(element); + } + + this.$element = this.$el = (element instanceof $) ? element : $(element); + this.el = this.$el[0]; + + this.bindElements(); + this.delegateEvents(); + + return this; + }, + + // Backbone-ish API + tagName: 'div', + id: null, + className: null, + attributes: {}, + /** + * Utility function to build small DOM elements. + * + * @param {String} tagName name of the DOM element to create + * @param {Object} [attributes] map of DOM attributes to set on the element + * @param {String} [content] HTML content to set on the element + * @return {Element} + */ + make: function (tagName, attributes, content) { + var el = document.createElement(tagName); + if (attributes) { + $(el).attrs(attributes); + } + if (content) { + $(el).html(content); + } + return el; + }, + events: {}, + delegateEvents: function () { + var events = getValue(this, 'events'); + if (_.isEmpty(events)) { return; } + + for(var key in events) { + if (!events.hasOwnProperty(key)) { continue; } + + var method = this.proxy(events[key]); + + var match = /^(\S+)(\s+(.*))?$/.exec(key); + var event = match[1]; + var selector = match[3]; + + // add namespace for easy un-delegation + event += '.delegated-events' + this._uid; + if (!selector) { + this.$el.on(event, method); + } else { + this.$el.on(event, selector, method); + } + } + }, + undelegateEvents: function () { + this.$el.off('.delegated-events' + this._uid); + }, + elements: {}, + bindElements: function () { + var elements = getValue(this, 'elements'); + if (_.isEmpty(elements)) { return; } + + for (var selector in elements) { + if (!elements.hasOwnProperty(selector)) { continue; } + + // TODO: ensure at least one element matched? + this[elements[selector]] = this.$(selector); + } + }, + unbindElements: function () { + var elements = getValue(this, 'elements'); + if (_.isEmpty(elements)) { return; } + + for (var selector in elements) { + if (!elements.hasOwnProperty(selector)) { continue; } + + delete this[elements[selector]]; } }, /** - * Shortcut for $element.find() like backbone + * Shortcut for ``this.$el.find(selector)`` + * + * @param {String} selector CSS selector, rooted in $el + * @returns {jQuery} selector match */ - "$": function() { - return this.$element.find.apply(this.$element,arguments); + $: function(selector) { + return this.$el.find(selector); }, /** * Informs the action manager to do an action. This supposes that From 459eb54d77f8fce5cce460d56c74121fe8125275 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 10:50:19 +0200 Subject: [PATCH 007/312] [FIX] broken unit tests bzr revid: xmo@openerp.com-20120611085019-z16aggfnuovgh1p4 --- addons/web/static/src/xml/base.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 3764395dc13..7bbc1884beb 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1409,10 +1409,10 @@ -
+
-
+

M Custom Filters

    From 26ec50e0603561128a5470f871d9ea487ed95560 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 11:18:03 +0200 Subject: [PATCH 008/312] [FIX] bug in new 'proxy' implementation revealed by searchview tests bzr revid: xmo@openerp.com-20120611091803-kzo5j5t8p82gwr6i --- addons/web/static/src/js/corelib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 8455a183f87..61464a58930 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -510,7 +510,7 @@ instance.web.CallbackEnabledMixin = _.extend({}, instance.web.PropertiesMixin, { proxy: function (method) { var self = this; return function () { - var fn = (method instanceof String) ? self[method] : method; + var fn = (typeof method === 'string') ? self[method] : method; return fn.apply(self, arguments); } } From 5c701e2b1d8070e49f0dc247f1b649f19ebc7751 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 11:18:20 +0200 Subject: [PATCH 009/312] [FIX] behavior of OldWidget for new Widget implementation bzr revid: xmo@openerp.com-20120611091820-m5gm67psqeh1xxx8 --- addons/web/static/src/js/coresetup.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 4defde54a3c..d419c7ac3c1 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -19,15 +19,15 @@ instance.web.OldWidget = instance.web.Widget.extend({ this._super(parent); this.element_id = element_id; this.element_id = this.element_id || _.uniqueId('widget-'); + var tmp = document.getElementById(this.element_id); - this.$element = tmp ? $(tmp) : $(document.createElement(this.tagName)); + this.setElement(tmp || this.make(this.tagName)); }, renderElement: function() { var rendered = this.render(); if (rendered) { - var elem = $(rendered); - this.$element.replaceWith(elem); - this.$element = elem; + var $el = $(rendered); + this.setElement($el); } return this; }, From 3f1757869c51cadb87d57abbb0392c78cb888bda Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 11:18:57 +0200 Subject: [PATCH 010/312] [IMP] make searchview base widget not inherit from OldWidget anymore bzr revid: xmo@openerp.com-20120611091857-wcpc2oqywoc0gg51 --- addons/web/static/src/js/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 85521a14651..22649197317 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -886,13 +886,13 @@ instance.web.search.Invalid = instance.web.Class.extend( /** @lends instance.web ); } }); -instance.web.search.Widget = instance.web.OldWidget.extend( /** @lends instance.web.search.Widget# */{ +instance.web.search.Widget = instance.web.Widget.extend( /** @lends instance.web.search.Widget# */{ template: null, /** * Root class of all search widgets * * @constructs instance.web.search.Widget - * @extends instance.web.OldWidget + * @extends instance.web.Widget * * @param view the ancestor view of this widget */ From 772bed66f33f16886ac0211cda6bd34ba05e4e3d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 11:48:40 +0200 Subject: [PATCH 011/312] [TEST] Widget#proxy, with both String and Function arguments bzr revid: xmo@openerp.com-20120611094840-mtilgirzwlhkl2qc --- addons/web/static/test/Widget.js | 67 ++++++++++++++++++++++++++++++++ addons/web/static/test/test.html | 1 + 2 files changed, 68 insertions(+) create mode 100644 addons/web/static/test/Widget.js diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js new file mode 100644 index 00000000000..dc86e99b38a --- /dev/null +++ b/addons/web/static/test/Widget.js @@ -0,0 +1,67 @@ +$(document).ready(function () { + var $fix = $('#qunit-fixture'); + var mod = { + setup: function () { + instance = window.openerp.init([]); + window.openerp.web.corelib(instance); + } + }; + var instance; + + module('Widget.proxy', mod); + test('(String)', function () { + var W = instance.web.Widget.extend({ + exec: function () { + this.executed = true; + } + }); + var w = new W; + var fn = w.proxy('exec'); + fn(); + ok(w.executed, 'should execute the named method in the right context'); + }); + test('(String)(*args)', function () { + var W = instance.web.Widget.extend({ + exec: function (arg) { + this.executed = arg; + } + }); + var w = new W; + var fn = w.proxy('exec'); + fn(42); + ok(w.executed, "should execute the named method in the right context"); + equal(w.executed, 42, "should be passed the proxy's arguments"); + }); + test('(String), include', function () { + // the proxy function should handle methods being changed on the class + // and should always proxy "by name", to the most recent one + var W = instance.web.Widget.extend({ + exec: function () { + this.executed = 1; + } + }); + var w = new W; + var fn = w.proxy('exec'); + W.include({ + exec: function () { this.executed = 2; } + }); + + fn(); + equal(w.executed, 2, "should be lazily resolved"); + }); + + test('(Function)', function () { + var w = new (instance.web.Widget.extend({ })); + + var fn = w.proxy(function () { this.executed = true; }); + fn(); + ok(w.executed, "should set the function's context (like Function#bind)"); + }); + test('(Function)(*args)', function () { + var w = new (instance.web.Widget.extend({ })); + + var fn = w.proxy(function (arg) { this.executed = arg; }); + fn(42); + equal(w.executed, 42, "should be passed the proxy's arguments"); + }); +}); diff --git a/addons/web/static/test/test.html b/addons/web/static/test/test.html index e352f63c17c..dd0d08a4986 100644 --- a/addons/web/static/test/test.html +++ b/addons/web/static/test/test.html @@ -55,4 +55,5 @@ + From a0c5057dbacef8e8f1841245c58ad4f52da57ef9 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 13:32:38 +0200 Subject: [PATCH 012/312] [TEST] Widget#renderElement with no template specified, fix Widget#make's handling of attributes bzr revid: xmo@openerp.com-20120611113238-wz516g9tl0xp1igd --- addons/web/static/src/js/corelib.js | 4 +- addons/web/static/test/Widget.js | 68 +++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 61464a58930..83586ec57d4 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -762,8 +762,8 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { */ make: function (tagName, attributes, content) { var el = document.createElement(tagName); - if (attributes) { - $(el).attrs(attributes); + if (!_.isEmpty(attributes)) { + $(el).attr(attributes); } if (content) { $(el).html(content); diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index dc86e99b38a..51a5182845d 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -64,4 +64,72 @@ $(document).ready(function () { fn(42); equal(w.executed, 42, "should be passed the proxy's arguments"); }); + + module('Widget.renderElement', mod); + test('no template, default', function () { + var w = new (instance.web.Widget.extend({ })); + + ok(!w.$el, "should not initially have a root element"); + w.renderElement(); + ok(w.$el, "should have generated a root element"); + strictEqual(w.$element, w.$el, "should provide $element alias"); + ok(w.$el.is(w.el), "should provide raw DOM alias"); + + equal(w.el.nodeName, 'DIV', "should have generated the default element"); + equal(w.el.attributes.length, 0, "should not have generated any attribute"); + ok(_.isEmpty(w.$el.html(), "should not have generated any content")); + }); + test('no template, custom tag', function () { + var w = new (instance.web.Widget.extend({ + tagName: 'ul' + })); + w.renderElement(); + + equal(w.el.nodeName, 'UL', "should have generated the custom element tag"); + }); + test('no template, @id', function () { + var w = new (instance.web.Widget.extend({ + id: 'foo' + })); + w.renderElement(); + + equal(w.el.attributes.length, 1, "should have one attribute"); + equal(w.$el.attr('id'), 'foo', "should have generated the id attribute"); + equal(w.el.id, 'foo', "should also be available via property"); + }); + test('no template, @className', function () { + var w = new (instance.web.Widget.extend({ + className: 'oe_some_class' + })); + w.renderElement(); + + equal(w.el.className, 'oe_some_class', "should have the right property"); + equal(w.$el.attr('class'), 'oe_some_class', "should have the right attribute"); + }); + test('no template, bunch of attributes', function () { + var w = new (instance.web.Widget.extend({ + attributes: { + 'id': 'some_id', + 'class': 'some_class', + 'data-foo': 'data attribute', + 'clark': 'gable', + 'spoiler': 'snape kills dumbledore' + } + })); + w.renderElement(); + + equal(w.el.attributes.length, 5, "should have all the specified attributes"); + + equal(w.el.id, 'some_id'); + equal(w.$el.attr('id'), 'some_id'); + + equal(w.el.className, 'some_class'); + equal(w.$el.attr('class'), 'some_class'); + + equal(w.$el.attr('data-foo'), 'data attribute'); + equal(w.$el.data('foo'), 'data attribute'); + + equal(w.$el.attr('clark'), 'gable'); + equal(w.$el.attr('spoiler'), 'snape kills dumbledore'); + }); }); From c531cb96ca2b0dc74ec6f9569eec8ea24c6506a1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 13:48:49 +0200 Subject: [PATCH 013/312] [TEST] Wisget#renderElement with template bzr revid: xmo@openerp.com-20120611114849-dwk4erae5f1tyc6o --- addons/web/static/test/Widget.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index 51a5182845d..3a2301e53f8 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -132,4 +132,24 @@ $(document).ready(function () { equal(w.$el.attr('clark'), 'gable'); equal(w.$el.attr('spoiler'), 'snape kills dumbledore'); }); + + test('template', function () { + instance.web.qweb = new QWeb2.Engine(); + instance.web.qweb.add_template('' + + '
      ' + + '
    1. ' + + '' + + '
    2. ' + + '
    ' + + '
    '); + + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template' + })); + w.renderElement(); + + equal(w.el.nodeName, 'OL'); + equal(w.$el.children().length, 5); + equal(w.el.textContent, '01234'); + }); }); From 2a9bd73a83c27e3dfab7e7b6438ad9988930ae39 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 14:08:18 +0200 Subject: [PATCH 014/312] [TEST] Widget#$ shortcut bzr revid: xmo@openerp.com-20120611120818-apsawz6kypnpc5m3 --- addons/web/static/test/Widget.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index 3a2301e53f8..f588d9a258c 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -4,6 +4,15 @@ $(document).ready(function () { setup: function () { instance = window.openerp.init([]); window.openerp.web.corelib(instance); + + instance.web.qweb = new QWeb2.Engine(); + instance.web.qweb.add_template('' + + '
      ' + + '
    1. ' + + '' + + '
    2. ' + + '
    ' + + '
    '); } }; var instance; @@ -134,15 +143,6 @@ $(document).ready(function () { }); test('template', function () { - instance.web.qweb = new QWeb2.Engine(); - instance.web.qweb.add_template('' + - '
      ' + - '
    1. ' + - '' + - '
    2. ' + - '
    ' + - '
    '); - var w = new (instance.web.Widget.extend({ template: 'test.widget.template' })); @@ -152,4 +152,15 @@ $(document).ready(function () { equal(w.$el.children().length, 5); equal(w.el.textContent, '01234'); }); + + module('Widget.$', mod); + test('basic-alias', function () { + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template' + })); + w.renderElement(); + + ok(w.$('li:eq(3)').is(w.$el.find('li:eq(3)')), + "should do the same thing as calling find on the widget root"); + }); }); From c64d8859a01933a89cd5c06df4324d7e11081a4f Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 14:48:24 +0200 Subject: [PATCH 015/312] [TEST] declarative events delegation bzr revid: xmo@openerp.com-20120611124824-w83h6betknrajyte --- addons/web/static/test/Widget.js | 49 +++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index f588d9a258c..d797120a341 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -8,7 +8,9 @@ $(document).ready(function () { instance.web.qweb = new QWeb2.Engine(); instance.web.qweb.add_template('' + '
      ' + - '
    1. ' + + '
    2. ' + + '' + '' + '
    3. ' + '
    ' + @@ -163,4 +165,49 @@ $(document).ready(function () { ok(w.$('li:eq(3)').is(w.$el.find('li:eq(3)')), "should do the same thing as calling find on the widget root"); }); + + module('Widget.events', mod); + test('delegate', function () { + var a = []; + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template', + events: { + 'click': function () { + a[0] = true; + strictEqual(this, w, "should trigger events in widget") + }, + 'click li.class-3': 'class3', + 'change input': function () { a[2] = true; } + }, + class3: function () { a[1] = true; } + })); + w.renderElement(); + + w.$el.click(); + w.$('li:eq(3)').click(); + w.$('input:last').val('foo').change(); + + for(var i=0; i<3; ++i) { + ok(a[i], "should pass test " + i); + } + }); + test('undelegate', function () { + var clicked = false, newclicked = false; + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template', + events: { 'click li': function () { clicked = true; } } + })); + w.renderElement(); + w.$el.on('click', 'li', function () { newclicked = true }); + + w.$('li').click(); + ok(clicked, "should trigger bound events"); + ok(newclicked, "should trigger bound events"); + clicked = newclicked = false; + + w.undelegateEvents(); + w.$('li').click(); + ok(!clicked, "undelegate should unbind events delegated"); + ok(newclicked, "undelegate should only unbind events it created"); + }); }); From b19354ae2005e83980a938c8e534fe55b5d1c14e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 14:54:54 +0200 Subject: [PATCH 016/312] [TEST] getValue/events as a callable bzr revid: xmo@openerp.com-20120611125454-nli5gkds9ffksmdm --- addons/web/static/test/Widget.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index d797120a341..36d6795ff7c 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -191,6 +191,17 @@ $(document).ready(function () { ok(a[i], "should pass test " + i); } }); + test('delegate(Function)', function () { + var clicked = false, fn = function () { + return { 'click li': function () { clicked = true; } }; }; + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template', + events: fn + })); + w.renderElement(); + w.$('li:first').click(); + ok(clicked, "should accept #events to be a function"); + }); test('undelegate', function () { var clicked = false, newclicked = false; var w = new (instance.web.Widget.extend({ From d6f376464516709c7b4ad7631ac1e49e4e39fe5e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 16:41:08 +0200 Subject: [PATCH 017/312] [REM] declarative elements binding, not sure there's much point and can add later bzr revid: xmo@openerp.com-20120611144108-pw8pz5p06prsikxe --- addons/web/static/src/js/corelib.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 83586ec57d4..e9fd4e1fedf 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -734,14 +734,12 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { setElement: function (element) { if (this.$el) { this.undelegateEvents(); - this.unbindElements(); this.$el.replaceWith(element); } this.$element = this.$el = (element instanceof $) ? element : $(element); this.el = this.$el[0]; - this.bindElements(); this.delegateEvents(); return this; @@ -796,28 +794,6 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { undelegateEvents: function () { this.$el.off('.delegated-events' + this._uid); }, - elements: {}, - bindElements: function () { - var elements = getValue(this, 'elements'); - if (_.isEmpty(elements)) { return; } - - for (var selector in elements) { - if (!elements.hasOwnProperty(selector)) { continue; } - - // TODO: ensure at least one element matched? - this[elements[selector]] = this.$(selector); - } - }, - unbindElements: function () { - var elements = getValue(this, 'elements'); - if (_.isEmpty(elements)) { return; } - - for (var selector in elements) { - if (!elements.hasOwnProperty(selector)) { continue; } - - delete this[elements[selector]]; - } - }, /** * Shortcut for ``this.$el.find(selector)`` * From d2f7ddb43eeb53973e7957fa9bccf3153d7f7bc5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 11 Jun 2012 17:07:02 +0200 Subject: [PATCH 018/312] [ADD] doc for backbone-ish APIs bzr revid: xmo@openerp.com-20120611150702-r4c9kyxmu8m7g4c0 --- doc/addons.rst | 109 -------------------- doc/index.rst | 1 + doc/widget.rst | 270 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+), 109 deletions(-) create mode 100644 doc/widget.rst diff --git a/doc/addons.rst b/doc/addons.rst index da1f1f28769..35878b04430 100644 --- a/doc/addons.rst +++ b/doc/addons.rst @@ -113,103 +113,6 @@ initializing the addon. Creating new standard roles --------------------------- -Widget -++++++ - -This is the base class for all visual components. It provides a number of -services for the management of a DOM subtree: - -* Rendering with QWeb - -* Parenting-child relations - -* Life-cycle management (including facilitating children destruction when a - parent object is removed) - -* DOM insertion, via jQuery-powered insertion methods. Insertion targets can - be anything the corresponding jQuery method accepts (generally selectors, - DOM nodes and jQuery objects): - - :js:func:`~openerp.base.Widget.appendTo` - Renders the widget and inserts it as the last child of the target, uses - `.appendTo()`_ - - :js:func:`~openerp.base.Widget.prependTo` - Renders the widget and inserts it as the first child of the target, uses - `.prependTo()`_ - - :js:func:`~openerp.base.Widget.insertAfter` - Renders the widget and inserts it as the preceding sibling of the target, - uses `.insertAfter()`_ - - :js:func:`~openerp.base.Widget.insertBefore` - Renders the widget and inserts it as the following sibling of the target, - uses `.insertBefore()`_ - -:js:class:`~openerp.base.Widget` inherits from -:js:class:`~openerp.base.SessionAware`, so subclasses can easily access the -RPC layers. - -Subclassing Widget -~~~~~~~~~~~~~~~~~~ - -:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the -:js:func:`~openerp.base.Class.extend` method), and provides a number of -abstract properties and concrete methods (which you may or may not want to -override). Creating a subclass looks like this: - -.. code-block:: javascript - - var MyWidget = openerp.base.Widget.extend({ - // QWeb template to use when rendering the object - template: "MyQWebTemplate", - - init: function(parent) { - this._super(parent); - // insert code to execute before rendering, for object - // initialization - }, - start: function() { - this._super(); - // post-rendering initialization code, at this point - // ``this.$element`` has been initialized - this.$element.find(".my_button").click(/* an example of event binding * /); - - // if ``start`` is asynchronous, return a promise object so callers - // know when the object is done initializing - return this.rpc(/* … */) - } - }); - -The new class can then be used in the following manner: - -.. code-block:: javascript - - // Create the instance - var my_widget = new MyWidget(this); - // Render and insert into DOM - my_widget.appendTo(".some-div"); - -After these two lines have executed (and any promise returned by ``appendTo`` -has been resolved if needed), the widget is ready to be used. - -.. note:: the insertion methods will start the widget themselves, and will - return the result of :js:func:`~openerp.base.Widget.start()`. - - If for some reason you do not want to call these methods, you will - have to first call :js:func:`~openerp.base.Widget.render()` on the - widget, then insert it into your DOM and start it. - -If the widget is not needed anymore (because it's transient), simply terminate -it: - -.. code-block:: javascript - - my_widget.stop(); - -will unbind all DOM events, remove the widget's content from the DOM and -destroy all widget data. - Views +++++ @@ -541,18 +444,6 @@ Python .. _promise object: http://api.jquery.com/deferred.promise/ -.. _.appendTo(): - http://api.jquery.com/appendTo/ - -.. _.prependTo(): - http://api.jquery.com/prependTo/ - -.. _.insertAfter(): - http://api.jquery.com/insertAfter/ - -.. _.insertBefore(): - http://api.jquery.com/insertBefore/ - .. _Rosetta: .. _Launchpad's own translation tool: https://help.launchpad.net/Translations diff --git a/doc/index.rst b/doc/index.rst index 9f54b879acc..1f660426a88 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -16,6 +16,7 @@ Contents: async rpc + widget search-view Older stuff diff --git a/doc/widget.rst b/doc/widget.rst new file mode 100644 index 00000000000..9868e4030e0 --- /dev/null +++ b/doc/widget.rst @@ -0,0 +1,270 @@ +User Interaction: Widget +======================== + +This is the base class for all visual components. It corresponds to an MVC +view. It provides a number of services to handle a section of a page: + +* Rendering with QWeb + +* Parenting-child relations + +* Life-cycle management (including facilitating children destruction when a + parent object is removed) + +* DOM insertion, via jQuery-powered insertion methods. Insertion targets can + be anything the corresponding jQuery method accepts (generally selectors, + DOM nodes and jQuery objects): + + :js:func:`~openerp.base.Widget.appendTo` + Renders the widget and inserts it as the last child of the target, uses + `.appendTo()`_ + + :js:func:`~openerp.base.Widget.prependTo` + Renders the widget and inserts it as the first child of the target, uses + `.prependTo()`_ + + :js:func:`~openerp.base.Widget.insertAfter` + Renders the widget and inserts it as the preceding sibling of the target, + uses `.insertAfter()`_ + + :js:func:`~openerp.base.Widget.insertBefore` + Renders the widget and inserts it as the following sibling of the target, + uses `.insertBefore()`_ + +* Backbone-compatible shortcuts + +DOM Root +-------- + +A :js:class:`~openerp.web.Widget` is responsible for a section of the +page materialized by the DOM root of the widget. The DOM root is +available via the :js:attr:`~openerp.web.Widget.el` and +:js:attr:`~openerp.web.Widget.$el` attributes, which are respectively +the raw DOM Element and the jQuery wrapper around the DOM element. + +.. note:: + + both attributes are compatible with Backbone's equivalent, there + is also the :js:attr:`~openerp.web.Widget.$element` attribute + which aliases to :js:attr:`~openerp.web.Widget.$el` and remains + for backwards compatiblity reasons. + +There are two main ways to define and generate this DOM root: + +.. js:attribute:: openerp.web.Widget.template + + Should be set to the name of a QWeb template (a + :js:class:`String`). If set, the template will be rendered after + the widget has been initialized but before it has been + started. The root element generated by the template will be set as + the DOM root of the widget. + +.. js:attribute:: openerp.web.Widget.tagName + + Used if the widget has no template defined. Defaults to ``div``, + will be used as the tag name to create the DOM element to set as + the widget's DOM root. It is possible to further customize this + generated DOM root with the following attributes: + + .. js:attribute:: openerp.web.Widget.id + + Used to generate an ``id`` attribute on the generated DOM + root. + + .. js:attribute:: openerp.web.Widget.className + + Used to generate a ``class`` attribute on the generated DOM root. + + .. js:attribute:: openerp.web.Widget.attributes + + Mapping (object literal) of attribute names to attribute + values. Each of these k:v pairs will be set as a DOM attribute + on the generated DOM root. + + None of these is used in case a template is specified on the widget. + +The DOM root can also be defined programmatically by overridding + +.. js:function:: openerp.web.Widget.renderElement + + Renders the widget's DOM root and sets it. The default + implementation will render a set template or generate an element + as described above, and will call + :js:func:`~openerp.web.Widget.setElement` on the result. + + Any override to :js:func:`~openerp.web.Widget.renderElement` which + does not call its ``_super`` **must** call + :js:func:`~openerp.web.Widget.setElement` with whatever it + generated or the widget's behavior is undefined. + +Accessing DOM content +~~~~~~~~~~~~~~~~~~~~~ + +Because a widget is only responsible for the content below its DOM +root, there is a shortcut for selecting sub-sections of a widget's +DOM: + +.. js:function:: openerp.web.Widget.$(selector) + + Applies the CSS selector specified as parameter to the widget's + DOM root. + + .. code-block:: javascript + + this.$(selector); + + is functionally identical to: + + .. code-block:: javascript + + this.$element.find(selector); + + :param String selector: CSS selector + :returns: jQuery object + + .. note:: this helper method is compatible with + ``Backbone.View.$`` + +Resetting the DOM root +~~~~~~~~~~~~~~~~~~~~~~ + +.. js:function:: openerp.web.Widget.setElement(element) + + Re-sets the widget's DOM root to the provided element, also + handles re-setting the various aliases of the DOM root as well as + unsetting and re-setting delegated events. + + :param Element element: a DOM element or jQuery object to set as + the widget's DOM root + + .. note:: should be mostly compatible with `Backbone's + setElement`_ + +DOM events handling +------------------- + +A widget will generally need to respond to user action within its +section of the page. This entails binding events to DOM elements. + +To this end, :js:class:`~openerp.web.Widget` provides an shortcut: + +.. js:attribute:: openerp.web.Widget.events + + Events are a mapping of ``event selector`` (an event name and a + CSS selector separated by a space) to a callback. The callback can + be either a method name in the widget or a function. In either + case, the ``this`` will be set to the widget. + + The selector is used for jQuery's `event delegation`_, the + callback will only be triggered for descendants of the DOM root + matching the selector [0]_. If the selector is left out (only an + event name is specified), the event will be set directly on the + widget's DOM root. + +.. js:function:: openerp.web.Widget.delegateEvents + + This method is in charge of binding + :js:attr:`~openerp.web.Widget.events` to the DOM. It is + automatically called after setting the widget's DOM root. + + It can be overridden to set up more complex events than the + :js:attr:`~openerp.web.Widget.events` map allows, but the parent + should always be called (or :js:attr:`~openerp.web.Widget.events` + won't be handled correctly). + +.. js:function:: openerp.web.Widget.undelegateEvents + + This method is in charge of unbinding + :js:attr:`~openerp.web.Widget.events` from the DOM root when the + widget is destroyed or the DOM root is reset, in order to avoid + leaving "phantom" events. + + It should be overridden to un-set any event set in an override of + :js:func:`~openerp.web.Widget.delegateEvents`. + +.. note:: this behavior should be compatible with `Backbone's + delegateEvents`_, apart from not accepting any argument. + +Subclassing Widget +------------------ + +:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the +:js:func:`~openerp.base.Class.extend` method), and provides a number of +abstract properties and concrete methods (which you may or may not want to +override). Creating a subclass looks like this: + +.. code-block:: javascript + + var MyWidget = openerp.base.Widget.extend({ + // QWeb template to use when rendering the object + template: "MyQWebTemplate", + + init: function(parent) { + this._super(parent); + // insert code to execute before rendering, for object + // initialization + }, + start: function() { + this._super(); + // post-rendering initialization code, at this point + // ``this.$element`` has been initialized + this.$element.find(".my_button").click(/* an example of event binding * /); + + // if ``start`` is asynchronous, return a promise object so callers + // know when the object is done initializing + return this.rpc(/* … */) + } + }); + +The new class can then be used in the following manner: + +.. code-block:: javascript + + // Create the instance + var my_widget = new MyWidget(this); + // Render and insert into DOM + my_widget.appendTo(".some-div"); + +After these two lines have executed (and any promise returned by ``appendTo`` +has been resolved if needed), the widget is ready to be used. + +.. note:: the insertion methods will start the widget themselves, and will + return the result of :js:func:`~openerp.base.Widget.start()`. + + If for some reason you do not want to call these methods, you will + have to first call :js:func:`~openerp.base.Widget.render()` on the + widget, then insert it into your DOM and start it. + +If the widget is not needed anymore (because it's transient), simply terminate +it: + +.. code-block:: javascript + + my_widget.destroy(); + +will unbind all DOM events, remove the widget's content from the DOM and +destroy all widget data. + +.. [0] not all DOM events are compatible with events delegation + +.. _.appendTo(): + http://api.jquery.com/appendTo/ + +.. _.prependTo(): + http://api.jquery.com/prependTo/ + +.. _.insertAfter(): + http://api.jquery.com/insertAfter/ + +.. _.insertBefore(): + http://api.jquery.com/insertBefore/ + +.. _event delegation: + http://api.jquery.com/delegate/ + +.. _Backbone's setElement: + http://backbonejs.org/#View-setElement + +.. _Backbone's delegateEvents: + http://backbonejs.org/#View-delegateEvents + From f0ad5fedacc2e994ef8ba45b05113278ac72db95 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 12 Jun 2012 15:21:20 +0200 Subject: [PATCH 019/312] [IMP] move .replaceWith() back into renderElement * Better formalizes repeated calls to renderElement * Makes setElement cleaner and less surprising to call bzr revid: xmo@openerp.com-20120612132120-egsg4kr5n2riv4zk --- addons/web/static/src/js/corelib.js | 5 +++- addons/web/static/test/Widget.js | 42 ++++++++++++++++++++++------- doc/widget.rst | 12 ++++++++- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index e9fd4e1fedf..73fa6839607 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -716,7 +716,11 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { if (this.className) { attrs['class'] = this.className; } $el = $(this.make(this.tagName, attrs)) } + var $oldel = this.$el; this.setElement($el); + if ($oldel && !$oldel.is(this.$el)) { + $oldel.replaceWith(this.$el); + } }, /** @@ -734,7 +738,6 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { setElement: function (element) { if (this.$el) { this.undelegateEvents(); - this.$el.replaceWith(element); } this.$element = this.$el = (element instanceof $) ? element : $(element); diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index 36d6795ff7c..b50dd233a13 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -6,15 +6,21 @@ $(document).ready(function () { window.openerp.web.corelib(instance); instance.web.qweb = new QWeb2.Engine(); - instance.web.qweb.add_template('' + - '
      ' + - '
    1. ' + - '' + - '' + - '
    2. ' + - '
    ' + - '
    '); + instance.web.qweb.add_template( + '' + + '' + + '
      ' + + '
    1. ' + + '' + + '' + + '
    2. ' + + '
    ' + + '
    ' + + '' + + '

    ' + + '
    ' + + '
    '); } }; var instance; @@ -221,4 +227,22 @@ $(document).ready(function () { ok(!clicked, "undelegate should unbind events delegated"); ok(newclicked, "undelegate should only unbind events it created"); }); + + module('Widget.renderElement', mod); + test('repeated', function () { + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template-value' + })); + w.value = 42; + w.appendTo($fix) + .always(start) + .done(function () { + equal($fix.find('p').text(), '42', "DOM fixture should contain initial value"); + equal(w.$el.text(), '42', "should set initial value"); + w.value = 36; + w.renderElement(); + equal($fix.find('p').text(), '36', "DOM fixture should use new value"); + equal(w.$el.text(), '36', "should set new value"); + }); + }); }); diff --git a/doc/widget.rst b/doc/widget.rst index 9868e4030e0..b29260c5882 100644 --- a/doc/widget.rst +++ b/doc/widget.rst @@ -95,7 +95,17 @@ The DOM root can also be defined programmatically by overridding Any override to :js:func:`~openerp.web.Widget.renderElement` which does not call its ``_super`` **must** call :js:func:`~openerp.web.Widget.setElement` with whatever it - generated or the widget's behavior is undefined. + generated or the widget's behavior is undefined.r + + .. note:: + + The default :js:func:`~openerp.web.Widget.renderElement` can + be called repeatedly, it will *replace* the previous DOM root + (using ``replaceWith``). However, this requires that the + widget correctly sets and unsets its events (and children + widgets). Generally, + :js:func:`~openerp.web.Widget.renderElement` should not be + called repeatedly unless the widget advertizes this feature. Accessing DOM content ~~~~~~~~~~~~~~~~~~~~~ From 2c115e6856f5c6eb7f3d730b0ccfa028b386b009 Mon Sep 17 00:00:00 2001 From: Ronald Portier Date: Fri, 22 Jun 2012 16:19:32 +0200 Subject: [PATCH 020/312] [FIX] Problem with runaway cpu and/or postgres crash on analytic account analysis. lp bug: https://launchpad.net/bugs/1015995 fixed bzr revid: ronald@therp.nl-20120622141932-f6rywvd1nawn186w --- .../account_analytic_analysis.py | 54 +++++++------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index 20c170cb5c0..cedcc9fa533 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -418,41 +418,25 @@ class account_analytic_account_summary_user(osv.osv): } def init(self, cr): - tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user') - cr.execute('CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (' \ - 'SELECT ' \ - '(u.account_id * u.max_user) + u."user" AS id, ' \ - 'u.account_id AS account_id, ' \ - 'u."user" AS "user", ' \ - 'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \ - 'FROM ' \ - '(SELECT ' \ - 'a.id AS account_id, ' \ - 'u1.id AS "user", ' \ - 'MAX(u2.id) AS max_user ' \ - 'FROM ' \ - 'res_users AS u1, ' \ - 'res_users AS u2, ' \ - 'account_analytic_account AS a ' \ - 'GROUP BY u1.id, a.id ' \ - ') AS u ' \ - 'LEFT JOIN ' \ - '(SELECT ' \ - 'l.account_id AS account_id, ' \ - 'l.user_id AS "user", ' \ - 'SUM(l.unit_amount) AS unit_amount ' \ - 'FROM account_analytic_line AS l, ' \ - 'account_analytic_journal AS j ' \ - 'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \ - 'GROUP BY l.account_id, l.user_id ' \ - ') AS l ' - 'ON (' \ - 'u.account_id = l.account_id ' \ - 'AND u."user" = l."user"' \ - ') ' \ - 'GROUP BY u."user", u.account_id, u.max_user' \ - ')') - + cr.execute('''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS ( + with mu as + (select max(id) as max_user from res_users) + , lu AS + (SELECT + l.account_id AS account_id, + coalesce(l.user_id, 0) AS user_id, + SUM(l.unit_amount) AS unit_amount + FROM account_analytic_line AS l, + account_analytic_journal AS j + WHERE (j.type = 'general' ) and (j.id=l.journal_id) + GROUP BY l.account_id, l.user_id + ) + select (lu.account_id * mu.max_user) + lu.user_id as id, + lu.account_id as account_id, + lu.user_id as "user", + unit_amount + from lu, mu)''') + account_analytic_account_summary_user() class account_analytic_account_summary_month(osv.osv): From e0e7597aa037206d34912420cf77c3a1681ab130 Mon Sep 17 00:00:00 2001 From: Antonin Bourguignon Date: Fri, 29 Jun 2012 14:52:09 +0200 Subject: [PATCH 021/312] [IMP] start the portal's contact page new layout bzr revid: abo@openerp.com-20120629125209-03wbu806i8mi2ab7 --- addons/portal_crm/wizard/contact.py | 17 +++++++ addons/portal_crm/wizard/contact_view.xml | 56 +++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/addons/portal_crm/wizard/contact.py b/addons/portal_crm/wizard/contact.py index be21decafa9..7ea4d094ac3 100644 --- a/addons/portal_crm/wizard/contact.py +++ b/addons/portal_crm/wizard/contact.py @@ -5,6 +5,23 @@ class crm_contact_us(osv.TransientModel): _name = 'portal_crm.crm_contact_us' _description = 'Contact form for the portal' _inherit = 'crm.lead' + _columns = { + 'company_ids' : fields.many2many('res.company', string='Companies', readonly=True), + 'employee_ids' : fields.many2many('hr.employee', string='Employees', readonly=True), + } + + def _get_employee(self, cr, uid, context=None): + r = self.pool.get('hr.employee').search(cr, uid, [], context=context) + return r + + def _get_companies(self, cr, uid, context=None): + r = self.pool.get('res.company').search(cr, uid, [], context=context) + return r + + _defaults = { + 'employee_ids' : _get_employee, + 'company_ids' : _get_companies + } def create(self, cr, uid, values, context=None): """ diff --git a/addons/portal_crm/wizard/contact_view.xml b/addons/portal_crm/wizard/contact_view.xml index 904326ea409..3e4afa067f6 100644 --- a/addons/portal_crm/wizard/contact_view.xml +++ b/addons/portal_crm/wizard/contact_view.xml @@ -8,16 +8,52 @@ portal_crm.crm_contact_us form -
    - - - - - - -