diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 1ac806c4412..5621597dc02 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -274,11 +274,13 @@ def get_modules(): def create_graph(module_list, force=None): - if not force: - force = [] graph = Graph() - packages = [] + return upgrade_graph(graph, module_list, force) +def upgrade_graph(graph, module_list, force=None): + if force is None: + force = [] + packages = [] for module in module_list: try: mod_path = get_module_path(module) @@ -556,7 +558,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): migrations = MigrationManager(cr, graph) - check_rules = False + has_updates = False modobj = None for package in graph: @@ -579,7 +581,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): idref = {} status['progress'] = (float(statusi)+0.4) / len(graph) if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): - check_rules = True + has_updates = True init_module_objects(cr, m, modules) for kind in ('init', 'update'): for filename in package.data.get('%s_xml' % kind, []): @@ -614,6 +616,8 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): cr.execute('update ir_module_module set demo=%s where id=%s', (True, mid)) package_todo.append(package.name) + migrations.migrate_module(package, 'post') + if modobj: ver = release.major_version + '.' + package.data.get('version', '1.0') # Set new modules and dependencies @@ -622,24 +626,24 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): # Update translations for all installed languages modobj.update_translations(cr, 1, [mid], None) cr.commit() + + package.state = 'installed' + for kind in ('init', 'demo', 'update'): + if hasattr(package, kind): + delattr(package, kind) - migrations.migrate_module(package, 'post') statusi += 1 - if perform_checks and check_rules: - cr.execute("""select model,name from ir_model where id not in (select model_id from ir_model_access)""") - for (model, name) in cr.fetchall(): - logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name)) - - + cr.execute('select model from ir_model where state=%s', ('manual',)) for model in cr.dictfetchall(): pool.get('ir.model').instanciate(cr, 1, model['model'], {}) pool.get('ir.model.data')._process_end(cr, 1, package_todo) cr.commit() - + + return has_updates def load_modules(db, force_demo=False, status=None, update_module=False): if not status: @@ -652,9 +656,11 @@ def load_modules(db, force_demo=False, status=None, update_module=False): pool = pooler.get_pool(cr.dbname) try: report = tools.assertion_report() + STATES_TO_LOAD = ['installed', 'to upgrade'] + graph = create_graph(['base'], force) + has_updates = False if update_module: - basegraph = create_graph(['base'], force) - load_module_graph(cr, basegraph, status, perform_checks=False, report=report) + has_updates = load_module_graph(cr, graph, status, perform_checks=False, report=report) modobj = pool.get('ir.module.module') logger.notifyChannel('init', netsvc.LOG_INFO, 'updating modules list') @@ -673,20 +679,31 @@ def load_modules(db, force_demo=False, status=None, update_module=False): modobj.button_upgrade(cr, 1, ids) cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base')) - cr.execute("select name from ir_module_module where state in ('installed', 'to install', 'to upgrade')") - else: - cr.execute("select name from ir_module_module where state in ('installed', 'to upgrade')") - module_list = [name for (name,) in cr.fetchall()] - graph = create_graph(module_list, force) + + STATES_TO_LOAD += ['to install'] + + while True: + cr.execute("SELECT name from ir_module_module WHERE state in (%s)" % ','.join(['%s']*len(STATES_TO_LOAD)), STATES_TO_LOAD) - # the 'base' module has already been updated - base = graph['base'] - base.state = 'installed' - for kind in ('init', 'demo', 'update'): - if hasattr(base, kind): - delattr(base, kind) + module_list = [name for (name,) in cr.fetchall() if name not in graph] + if not module_list: + break + + upgrade_graph(graph, module_list, force) + r = load_module_graph(cr, graph, status, report=report) + has_updates = has_updates or r - load_module_graph(cr, graph, status, report=report) + if has_updates: + cr.execute("""select model,name from ir_model where id not in (select model_id from ir_model_access)""") + for (model, name) in cr.fetchall(): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name)) + + cr.execute("SELECT model from ir_model") + for (model,) in cr.fetchall(): + obj = pool.get(model) + if obj: + obj._check_removed_columns(cr, log=True) + if report.get_report(): logger.notifyChannel('init', netsvc.LOG_INFO, report) @@ -697,7 +714,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if update_module: cr.execute("select id,name from ir_module_module where state=%s", ('to remove',)) for mod_id, mod_name in cr.fetchall(): - pool = pooler.get_pool(cr.dbname) cr.execute('select model,res_id from ir_model_data where noupdate=%s and module=%s order by id desc', (False, mod_name,)) for rmod, rid in cr.fetchall(): uid = 1 @@ -726,7 +742,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): else: logger.notifyChannel('init', netsvc.LOG_INFO, 'removed %d unused menus' % (cr.rowcount,)) - cr.execute("update ir_module_module set state=%s where state in ('to remove')", ('uninstalled', )) + cr.execute("update ir_module_module set state=%s where state=%s", ('uninstalled', 'to remove',)) cr.commit() finally: cr.close() diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index e8c706a7b29..6b70a1a34a3 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -402,7 +402,7 @@ class actions_server(osv.osv): ], 'Action Type', required=True, size=32, help="Type of the Action that is to be executed"), 'code':fields.text('Python Code', help="Python code to be executed"), 'sequence': fields.integer('Sequence', help="Important when you deal with multiple actions, the execution order will be decided based on this, low number is higher priority."), - 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the obect on which the action will work (read, write, create)."), + 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create)."), 'action_id': fields.many2one('ir.actions.actions', 'Client Action', help="Select the Action Window, Report, Wizard to be executed."), 'trigger_name': fields.selection(_select_signals, string='Trigger Name', size=128, help="Select the Signal name that is to be used as the trigger."), 'wkf_model_id': fields.many2one('ir.model', 'Workflow On', help="Workflow to be executed on this model."), diff --git a/bin/addons/base/ir/ir_sequence.py b/bin/addons/base/ir/ir_sequence.py index 31828569d6c..202aac754d2 100644 --- a/bin/addons/base/ir/ir_sequence.py +++ b/bin/addons/base/ir/ir_sequence.py @@ -70,14 +70,18 @@ class ir_sequence(osv.osv): } def get_id(self, cr, uid, sequence_id, test='id=%s', context={}): - cr.execute('select id,number_next,number_increment,prefix,suffix,padding from ir_sequence where '+test+' and active=True FOR UPDATE', (sequence_id,)) - res = cr.dictfetchone() - if res: - cr.execute('update ir_sequence set number_next=number_next+number_increment where id=%s and active=True', (res['id'],)) - if res['number_next']: - return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix']) - else: - return self._process(res['prefix']) + self._process(res['suffix']) + try: + cr.execute('lock table ir_sequence') + cr.execute('select id,number_next,number_increment,prefix,suffix,padding from ir_sequence where '+test+' and active=True', (sequence_id,)) + res = cr.dictfetchone() + if res: + cr.execute('update ir_sequence set number_next=number_next+number_increment where id=%s and active=True', (res['id'],)) + if res['number_next']: + return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix']) + else: + return self._process(res['prefix']) + self._process(res['suffix']) + finally: + cr.commit() return False def get(self, cr, uid, code): diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index 9eb5e46e575..8176565a871 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -469,7 +469,7 @@ class module(osv.osv): for lang in filter_lang: f = os.path.join(modpath, 'i18n', lang + '.po') if os.path.exists(f): - logger.notifyChannel("init", netsvc.LOG_INFO, 'module %s: loading translation file for language %s' % (mod.name, lang)) + logger.notifyChannel("i18n", netsvc.LOG_INFO, 'module %s: loading translation file for language %s' % (mod.name, lang)) tools.trans_load(cr.dbname, f, lang, verbose=False) diff --git a/bin/addons/base/module/report/ir_module_reference.rml b/bin/addons/base/module/report/ir_module_reference.rml index 52ffd04fd7f..1e09766e3e6 100644 --- a/bin/addons/base/module/report/ir_module_reference.rml +++ b/bin/addons/base/module/report/ir_module_reference.rml @@ -230,7 +230,7 @@ - Object: [[ object.name ]] [[ objdoc(object.model) ]] + Object: [[ object.model ]] [[ objdoc(object.model) ]] diff --git a/bin/addons/base/module/report/ir_module_reference.sxw b/bin/addons/base/module/report/ir_module_reference.sxw index ad3ecff7717..48e94634f98 100644 Binary files a/bin/addons/base/module/report/ir_module_reference.sxw and b/bin/addons/base/module/report/ir_module_reference.sxw differ diff --git a/bin/addons/base/report/corporate_defaults.xml b/bin/addons/base/report/corporate_defaults.xml new file mode 100644 index 00000000000..cef5acdd020 --- /dev/null +++ b/bin/addons/base/report/corporate_defaults.xml @@ -0,0 +1,23 @@ + + + + + + + + <name type="field" name="partner_id.name"/> + <address type="zoom" name="partner_id.address"> + <street type="field" name="street"/> + <zip type="field" name="zip"/> + <city type="field" name="city"/> + <state type="field" name="state_id.name"/> + <country type="field" name="country_id.name"/> + <phone type="field" name="phone"/> + <email type="field" name="email"/> + </address> + </corporation> + <user> + <name type="field" name="name"/> + <signature type="field" name="signature"/> + </user> +</corporate-header> diff --git a/bin/addons/base/report/corporate_odt_header.xml b/bin/addons/base/report/corporate_odt_header.xml new file mode 100644 index 00000000000..b27eeda8ccb --- /dev/null +++ b/bin/addons/base/report/corporate_odt_header.xml @@ -0,0 +1,248 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" office:version="1.1"> + <office:font-face-decls> + <style:font-face style:name="Helvetica" svg:font-family="Helvetica"/> + <style:font-face style:name="Times" svg:font-family="Times"/> + <style:font-face style:name="Helvetica1" svg:font-family="Helvetica" style:font-family-generic="swiss"/> + <style:font-face style:name="Monospace" svg:font-family="Monospace" style:font-pitch="fixed"/> + <style:font-face style:name="DejaVu Sans" svg:font-family="'DejaVu Sans'" style:font-family-generic="system" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="graphic"> + <style:graphic-properties draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="true"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" fo:font-size="12pt" fo:language="en" fo:country="IN" style:letter-kerning="true" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"/> + </style:default-style> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/> + <style:text-properties style:use-window-font-color="true" style:font-name="Times" fo:font-size="12pt" fo:language="en" fo:country="IN" style:letter-kerning="true" style:font-name-asian="DejaVu Sans" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="DejaVu Sans" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/> + </style:default-style> + <style:default-style style:family="table"> + <style:table-properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:table-row-properties fo:keep-together="always"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> + <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.212cm"/> + </style:style> + <style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text"> + <style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:keep-with-next="always"/> + <style:text-properties style:font-name="Helvetica" fo:font-size="14pt" style:font-name-asian="DejaVu Sans" style:font-size-asian="14pt" style:font-name-complex="DejaVu Sans" style:font-size-complex="14pt"/> + </style:style> + <style:style style:name="List" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="list"> + <style:text-properties style:font-name="Times" style:font-size-asian="12pt"/> + </style:style> + <style:style style:name="Header" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties text:number-lines="false" text:line-number="0"> + <style:tab-stops> + <style:tab-stop style:position="8.498cm" style:type="center"/> + <style:tab-stop style:position="16.999cm" style:type="right"/> + </style:tab-stops> + </style:paragraph-properties> + <style:text-properties fo:color="#0000ff" style:font-size-asian="10.5pt"/> + </style:style> + <style:style style:name="Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties text:number-lines="false" text:line-number="0"> + <style:tab-stops> + <style:tab-stop style:position="8.498cm" style:type="center"/> + <style:tab-stop style:position="16.999cm" style:type="right"/> + </style:tab-stops> + </style:paragraph-properties> + </style:style> + <style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties text:number-lines="false" text:line-number="0"/> + </style:style> + <style:style style:name="Table_20_Heading" style:display-name="Table Heading" style:family="paragraph" style:parent-style-name="Table_20_Contents" style:class="extra"> + <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/> + <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties fo:margin-top="0.212cm" fo:margin-bottom="0.212cm" text:number-lines="false" text:line-number="0"/> + <style:text-properties style:font-name="Times" fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-size-complex="12pt" style:font-style-complex="italic"/> + </style:style> + <style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index"> + <style:paragraph-properties text:number-lines="false" text:line-number="0"/> + <style:text-properties style:font-name="Times" style:font-size-asian="12pt"/> + </style:style> + <style:style style:name="Footnote_20_Symbol" style:display-name="Footnote Symbol" style:family="text"/> + <style:style style:name="Endnote_20_Symbol" style:display-name="Endnote Symbol" style:family="text"/> + <style:style style:name="Graphics" style:family="graphic"> + <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" style:wrap="dynamic" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/> + </style:style> + <text:outline-style> + <text:outline-level-style text:level="1" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="2" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="3" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="4" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="5" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="6" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="7" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="8" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="9" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="10" style:num-format=""> + <style:list-level-properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + </text:outline-style> + <text:notes-configuration text:note-class="footnote" text:citation-style-name="Footnote_20_Symbol" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="page"/> + <text:notes-configuration text:note-class="endnote" text:citation-style-name="Endnote_20_Symbol" text:master-page-name="Endnote" style:num-format="1" text:start-value="0"/> + <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="Table2" style:family="table"> + <style:table-properties style:width="16.999cm" table:align="margins"/> + </style:style> + <style:style style:name="Table2.A" style:family="table-column"> + <style:table-column-properties style:column-width="4.235cm" style:rel-column-width="16329*"/> + </style:style> + <style:style style:name="Table2.B" style:family="table-column"> + <style:table-column-properties style:column-width="12.764cm" style:rel-column-width="49206*"/> + </style:style> + <style:style style:name="Table2.A1" style:family="table-cell"> + <style:table-cell-properties style:vertical-align="bottom" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.018cm solid #000000"/> + </style:style> + <style:style style:name="Table3" style:family="table"> + <style:table-properties style:width="7.936cm" table:align="left"/> + </style:style> + <style:style style:name="Table3.A" style:family="table-column"> + <style:table-column-properties style:column-width="1.933cm"/> + </style:style> + <style:style style:name="Table3.B" style:family="table-column"> + <style:table-column-properties style:column-width="6.003cm"/> + </style:style> + <style:style style:name="Table3.A1" style:family="table-cell"> + <style:table-cell-properties style:vertical-align="bottom" fo:padding="0.097cm" fo:border="none"/> + </style:style> + <style:style style:name="Table3.A2" style:family="table-cell"> + <style:table-cell-properties style:vertical-align="bottom" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.018cm solid #000000"/> + </style:style> + <style:style style:name="Table1" style:family="table"> + <style:table-properties style:width="16.999cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="16.999cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:background-color="transparent" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.018cm solid #000000" fo:border-bottom="none"> + <style:background-image/> + </style:table-cell-properties> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header"> + <style:text-properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="30pt" style:font-name-asian="Monospace" style:font-size-asian="30pt" style:font-name-complex="Monospace" style:font-size-complex="30pt"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/> + <style:text-properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Header"> + <style:text-properties style:font-name="Monospace" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P4" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:text-properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-size-asian="8.75pt" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P5" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/> + <style:text-properties fo:color="#0000ff" style:font-name="Monospace" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P6" style:family="paragraph" style:parent-style-name="Header"> + <style:text-properties style:font-name="Helvetica1" fo:font-size="10pt" style:font-size-asian="8.75pt" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P7" style:family="paragraph" style:parent-style-name="Footer"> + <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/> + <style:text-properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style> + <style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-bottom="0.499cm"/> + </style:header-style> + <style:footer-style> + <style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.499cm"/> + </style:footer-style> + </style:page-layout> + <style:page-layout style:name="pm2"> + <style:page-layout-properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> + <style:footnote-sep style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"> + <style:header> + <table:table table:name="Table2" table:style-name="Table2"> + <table:table-column table:style-name="Table2.A"/> + <table:table-column table:style-name="Table2.B"/> + <table:table-row> + <table:table-cell table:style-name="Table2.A1" office:value-type="string"> + <text:p text:style-name="P1">Tiny sprl</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table2.A1" office:value-type="string"> + <text:p text:style-name="P2"/> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P3"/> + <text:p text:style-name="P3">- </text:p> + <table:table table:name="Table3" table:style-name="Table3"> + <table:table-column table:style-name="Table3.A"/> + <table:table-column table:style-name="Table3.B"/> + <table:table-row> + <table:table-cell table:style-name="Table3.A1" office:value-type="string"> + <text:p text:style-name="P4">Phone :</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table3.A1" office:value-type="string"> + <text:p text:style-name="P5"/> + </table:table-cell> + </table:table-row> + <table:table-row> + <table:table-cell table:style-name="Table3.A2" office:value-type="string"> + <text:p text:style-name="P4">Mail :</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table3.A2" office:value-type="string"> + <text:p text:style-name="P5"/> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P6"/> + </style:header> + <style:footer> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" office:value-type="string"> + <text:p text:style-name="P7"/> + <text:p text:style-name="P7"/> + <text:p text:style-name="P7">Contact : Administrator</text:p> + </table:table-cell> + </table:table-row> + </table:table> + </style:footer> + </style:master-page> + <style:master-page style:name="Endnote" style:page-layout-name="pm2"/> + </office:master-styles> +</office:document-styles> \ No newline at end of file diff --git a/bin/addons/base/report/corporate_sxw_header.xml b/bin/addons/base/report/corporate_sxw_header.xml new file mode 100644 index 00000000000..2f6f885f3ba --- /dev/null +++ b/bin/addons/base/report/corporate_sxw_header.xml @@ -0,0 +1,246 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document-styles xmlns:office="http://openoffice.org/2000/office" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="http://openoffice.org/2000/meta" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" office:version="1.0"> + <office:font-decls> + <style:font-decl style:name="Helvetica" fo:font-family="Helvetica"/> + <style:font-decl style:name="Times" fo:font-family="Times"/> + <style:font-decl style:name="Helvetica1" fo:font-family="Helvetica" style:font-family-generic="swiss"/> + <style:font-decl style:name="Monospace" fo:font-family="Monospace" style:font-pitch="fixed"/> + <style:font-decl style:name="DejaVu Sans" fo:font-family="'DejaVu Sans'" style:font-family-generic="system" style:font-pitch="variable"/> + </office:font-decls> + <office:styles> + <style:default-style style:family="graphics"> + <style:properties draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false" style:use-window-font-color="true" fo:font-size="12pt" fo:language="en" fo:country="IN" style:letter-kerning="true" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"> + <style:tab-stops/> + </style:properties> + </style:default-style> + <style:default-style style:family="paragraph"> + <style:properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page" style:use-window-font-color="true" style:font-name="Times" fo:font-size="12pt" fo:language="en" fo:country="IN" style:letter-kerning="true" style:font-name-asian="DejaVu Sans" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="DejaVu Sans" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/> + </style:default-style> + <style:default-style style:family="table"> + <style:properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:properties fo:keep-together="always"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:style style:name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> + <style:properties fo:margin-top="0cm" fo:margin-bottom="0.212cm"/> + </style:style> + <style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text body" style:class="text"> + <style:properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:keep-with-next="true" style:font-name="Helvetica" fo:font-size="14pt" style:font-name-asian="DejaVu Sans" style:font-size-asian="14pt" style:font-name-complex="DejaVu Sans" style:font-size-complex="14pt"/> + </style:style> + <style:style style:name="List" style:family="paragraph" style:parent-style-name="Text body" style:class="list"> + <style:properties style:font-name="Times" style:font-size-asian="12pt"/> + </style:style> + <style:style style:name="Header" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:properties text:number-lines="false" text:line-number="0" fo:color="#0000ff" style:font-size-asian="10.5pt"> + <style:tab-stops> + <style:tab-stop style:position="8.498cm" style:type="center"/> + <style:tab-stop style:position="16.999cm" style:type="right"/> + </style:tab-stops> + </style:properties> + </style:style> + <style:style style:name="Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:properties text:number-lines="false" text:line-number="0"> + <style:tab-stops> + <style:tab-stop style:position="8.498cm" style:type="center"/> + <style:tab-stop style:position="16.999cm" style:type="right"/> + </style:tab-stops> + </style:properties> + </style:style> + <style:style style:name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:properties text:number-lines="false" text:line-number="0"/> + </style:style> + <style:style style:name="Table Heading" style:family="paragraph" style:parent-style-name="Table Contents" style:class="extra"> + <style:properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0" fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:properties fo:margin-top="0.212cm" fo:margin-bottom="0.212cm" text:number-lines="false" text:line-number="0" style:font-name="Times" fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-size-complex="12pt" style:font-style-complex="italic"/> + </style:style> + <style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index"> + <style:properties text:number-lines="false" text:line-number="0" style:font-name="Times" style:font-size-asian="12pt"/> + </style:style> + <style:style style:name="Footnote Symbol" style:family="text"/> + <style:style style:name="Endnote Symbol" style:family="text"/> + <style:style style:name="Graphics" style:family="graphics"> + <style:properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" style:wrap="dynamic" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/> + </style:style> + <text:outline-style> + <text:outline-level-style text:level="1" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="2" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="3" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="4" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="5" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="6" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="7" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="8" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="9" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + <text:outline-level-style text:level="10" style:num-format=""> + <style:properties text:min-label-distance="0.381cm"/> + </text:outline-level-style> + </text:outline-style> + <text:footnotes-configuration text:citation-style-name="Footnote Symbol" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="page"/> + <text:endnotes-configuration text:citation-style-name="Endnote Symbol" text:master-page-name="Endnote" style:num-format="1" text:start-value="0"/> + <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="Table2" style:family="table"> + <style:properties style:width="16.999cm" table:align="margins"/> + </style:style> + <style:style style:name="Table2.A" style:family="table-column"> + <style:properties style:column-width="4.235cm" style:rel-column-width="16329*"/> + </style:style> + <style:style style:name="Table2.B" style:family="table-column"> + <style:properties style:column-width="12.764cm" style:rel-column-width="49206*"/> + </style:style> + <style:style style:name="Table2.A1" style:family="table-cell"> + <style:properties fo:vertical-align="bottom" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.018cm solid #000000"/> + </style:style> + <style:style style:name="Table3" style:family="table"> + <style:properties style:width="7.936cm" table:align="left"/> + </style:style> + <style:style style:name="Table3.A" style:family="table-column"> + <style:properties style:column-width="1.933cm"/> + </style:style> + <style:style style:name="Table3.B" style:family="table-column"> + <style:properties style:column-width="6.003cm"/> + </style:style> + <style:style style:name="Table3.A1" style:family="table-cell"> + <style:properties fo:vertical-align="bottom" fo:padding="0.097cm" fo:border="none"/> + </style:style> + <style:style style:name="Table3.A2" style:family="table-cell"> + <style:properties fo:vertical-align="bottom" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.018cm solid #000000"/> + </style:style> + <style:style style:name="Table1" style:family="table"> + <style:properties style:width="16.999cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:properties style:column-width="16.999cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:properties fo:background-color="transparent" fo:padding="0.097cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.018cm solid #000000" fo:border-bottom="none"> + <style:background-image/> + </style:properties> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header"> + <style:properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="30pt" style:font-name-asian="Monospace" style:font-size-asian="30pt" style:font-name-complex="Monospace" style:font-size-complex="30pt"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table Contents"> + <style:properties fo:text-align="end" style:justify-single-word="false" fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Header"> + <style:properties style:font-name="Monospace" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P4" style:family="paragraph" style:parent-style-name="Table Contents"> + <style:properties fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-size-asian="8.75pt" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P5" style:family="paragraph" style:parent-style-name="Table Contents"> + <style:properties fo:text-align="end" style:justify-single-word="false" fo:color="#0000ff" style:font-name="Monospace" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P6" style:family="paragraph" style:parent-style-name="Header"> + <style:properties style:font-name="Helvetica1" fo:font-size="10pt" style:font-size-asian="8.75pt" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P7" style:family="paragraph" style:parent-style-name="Footer"> + <style:properties fo:text-align="center" style:justify-single-word="false" fo:color="#0000ff" style:font-name="Helvetica1" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="P8" style:family="paragraph" style:parent-style-name="Footer"> + <style:properties fo:text-align="center" style:justify-single-word="false" style:font-name="Helvetica1" fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:properties fo:color="#0000ff"/> + </style:style> + <style:style style:name="T2" style:family="text"> + <style:properties fo:color="#0000ff" fo:font-size="10pt" style:font-name-asian="Monospace" style:font-size-asian="10pt" style:font-name-complex="Monospace" style:font-size-complex="10pt"/> + </style:style> + <style:page-master style:name="pm1"> + <style:properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:properties> + <style:header-style> + <style:properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-bottom="0.499cm"/> + </style:header-style> + <style:footer-style> + <style:properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.499cm"/> + </style:footer-style> + </style:page-master> + <style:page-master style:name="pm2"> + <style:properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> + <style:footnote-sep style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:properties> + <style:header-style/> + <style:footer-style/> + </style:page-master> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-master-name="pm1"> + <style:header> + <table:table table:name="Table2" table:style-name="Table2"> + <table:table-column table:style-name="Table2.A"/> + <table:table-column table:style-name="Table2.B"/> + <table:table-row> + <table:table-cell table:style-name="Table2.A1" table:value-type="string"> + <text:p text:style-name="P1">[[ company.partner_id.name ]]</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table2.A1" table:value-type="string"> + <text:p text:style-name="P2">[[ company.rml_header1 ]]</text:p> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P3">[[ company.partner_id.address and company.partner_id.address[0].street ]]</text:p> + <text:p text:style-name="P3">[[ company.partner_id.address and company.partner_id.address[0].zip ]] [[ company.partner_id.address and company.partner_id.address[0].city ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name ]]</text:p> + <table:table table:name="Table3" table:style-name="Table3"> + <table:table-column table:style-name="Table3.A"/> + <table:table-column table:style-name="Table3.B"/> + <table:table-row> + <table:table-cell table:style-name="Table3.A1" table:value-type="string"> + <text:p text:style-name="P4">Phone :</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table3.A1" table:value-type="string"> + <text:p text:style-name="P5">[[ company.partner_id.address and company.partner_id.address[0].phone ]]</text:p> + </table:table-cell> + </table:table-row> + <table:table-row> + <table:table-cell table:style-name="Table3.A2" table:value-type="string"> + <text:p text:style-name="P4">Mail :</text:p> + </table:table-cell> + <table:table-cell table:style-name="Table3.A2" table:value-type="string"> + <text:p text:style-name="P5">[[ company.partner_id.address and company.partner_id.address[0].email ]]</text:p> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P6"/> + </style:header> + <style:footer> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" table:value-type="string"> + <text:p text:style-name="P7">[[ company.rml_footer1 ]]</text:p> + <text:p text:style-name="P7">[[ company.rml_footer2 ]]</text:p> + <text:p text:style-name="P7">Contact : [[ user.name ]]</text:p> + </table:table-cell> + </table:table-row> + </table:table> + </style:footer> + </style:master-page> + <style:master-page style:name="Endnote" style:page-master-name="pm2"/> + </office:master-styles> +</office:document-styles> diff --git a/bin/addons/base/report/custom_report.xml b/bin/addons/base/report/custom_report.xml new file mode 100644 index 00000000000..c7c4cedbb33 --- /dev/null +++ b/bin/addons/base/report/custom_report.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<openerp> + <data> + + </data> +</openerp> diff --git a/bin/addons/base/report/custom_view.xml b/bin/addons/base/report/custom_view.xml new file mode 100644 index 00000000000..ebc084668b7 --- /dev/null +++ b/bin/addons/base/report/custom_view.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + </data> +</openerp> diff --git a/bin/addons/base/res/partner/partner_view.xml b/bin/addons/base/res/partner/partner_view.xml index 5493eee02a3..0b21de05dd5 100644 --- a/bin/addons/base/res/partner/partner_view.xml +++ b/bin/addons/base/res/partner/partner_view.xml @@ -257,6 +257,8 @@ <field name="zip"/> <field name="city"/> <field name="country_id"/> + <field name="phone"/> + <field name="email"/> </tree> </field> <separator colspan="4" string="Categories"/> diff --git a/bin/addons/base/res/partner/report/partner_address.xsl b/bin/addons/base/res/partner/report/partner_address.xsl index 8661dec2b58..01fcc120c23 100644 --- a/bin/addons/base/res/partner/report/partner_address.xsl +++ b/bin/addons/base/res/partner/report/partner_address.xsl @@ -72,7 +72,9 @@ <xsl:apply-templates select="contact[1]"/> </xsl:otherwise> </xsl:choose> - <nextFrame/> + <xsl:if test="position() < last()"> + <nextFrame/> + </xsl:if> </xsl:template> <xsl:template match="contact"> diff --git a/bin/addons/base/res/res_company.py b/bin/addons/base/res/res_company.py index 59bc0ab4ef5..2158035abb3 100644 --- a/bin/addons/base/res/res_company.py +++ b/bin/addons/base/res/res_company.py @@ -21,6 +21,7 @@ ############################################################################## from osv import fields,osv +import os import tools class res_company(osv.osv): @@ -122,7 +123,7 @@ class res_company(osv.osv): </header>""" def _get_header(self,cr,uid,ids): try : - return tools.file_open('custom/corporate_rml_header.rml').read() + return tools.file_open(os.path.join('base', 'report', 'corporate_rml_header.rml')).read() except: return """ <header> diff --git a/bin/addons/base/res/res_lang.py b/bin/addons/base/res/res_lang.py index 6a8801b7b19..3aa67a6e033 100644 --- a/bin/addons/base/res/res_lang.py +++ b/bin/addons/base/res/res_lang.py @@ -55,6 +55,10 @@ class lang(osv.osv): 'decimal_point':lambda *a: '.', 'thousands_sep':lambda *a: ',', } + _sql_constraints = [ + ('name_uniq', 'unique (name)', 'The name of the language must be unique !'), + ('code_uniq', 'unique (code)', 'The code of the language must be unique !'), + ] def _group(self,cr,uid,ids,s, monetary=False): conv = localeconv() diff --git a/bin/netsvc.py b/bin/netsvc.py index 36e88add4a2..b03dfad7e31 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -113,8 +113,8 @@ def init_logger(): os.makedirs(dirname) handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30) except Exception, ex: - sys.stderr.write("ERROR: couldn't create the logfile directory\n") - handler = logging.StreamHandler(sys.stdout) + sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n") + handler = logging.StreamHandler(sys.stdout) else: # Normal Handler on standard output handler = logging.StreamHandler(sys.stdout) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index fdf81eccb20..f5f74b1cfb7 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -467,8 +467,7 @@ class orm_template(object): datas += self.__export_row(cr, uid, row, fields, context) return datas - def import_data(self, cr, uid, fields, datas, mode='init', - current_module=None, noupdate=False, context=None, filename=None): + def import_data(self, cr, uid, fields, datas, mode='init', current_module=None, noupdate=False, context=None, filename=None): if not context: context = {} fields = map(lambda x: x.split('/'), fields) @@ -768,8 +767,7 @@ class orm_template(object): # call the 'dynamic selection' function res[f]['selection'] = self._columns[f].selection(self, cr, user, context) - if res[f]['type'] in ('one2many', 'many2many', - 'many2one', 'one2one'): + if res[f]['type'] in ('one2many', 'many2many', 'many2one', 'one2one'): res[f]['relation'] = self._columns[f]._obj res[f]['domain'] = self._columns[f]._domain res[f]['context'] = self._columns[f]._context @@ -1195,6 +1193,8 @@ class orm_template(object): self.pool.get(table).write_string(cr, uid, id, langs, vals, context) return True + def _check_removed_columns(self, cr, log=False): + raise NotImplementedError() class orm_memory(orm_template): _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count'] @@ -1378,6 +1378,10 @@ class orm_memory(orm_template): 'id': id }) return result + + def _check_removed_columns(self, cr, log=False): + # nothing to check in memory... + pass class orm(orm_template): _sql_constraints = [] @@ -1430,6 +1434,26 @@ class orm(orm_template): if (val<>False) or (type(val)<>bool): cr.execute(update_query, (ss[1](val), key)) + def _check_removed_columns(self, cr, log=False): + logger = netsvc.Logger() + # iterate on the database columns to drop the NOT NULL constraints + # of fields which were required but have been removed (or will be added by another module) + columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)] + columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns + cr.execute("SELECT a.attname, a.attnotnull" + " FROM pg_class c, pg_attribute a" + " WHERE c.relname=%%s" + " AND c.oid=a.attrelid" + " AND a.attisdropped=%%s" + " AND pg_catalog.format_type(a.atttypid, a.atttypmod) NOT IN ('cid', 'tid', 'oid', 'xid')" + " AND a.attname NOT IN (%s)" % ",".join(['%s']*len(columns)), + [self._table, False] + columns) + for column in cr.dictfetchall(): + if log: + logger.notifyChannel("orm", netsvc.LOG_DEBUG, "column %s is in the table %s but not in the corresponding object %s" % (column['attname'], self._table, self._name)) + if column['attnotnull']: + cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname'])) + def _auto_init(self, cr, context={}): store_compute = False logger = netsvc.Logger() @@ -1475,24 +1499,8 @@ class orm(orm_template): if not cr.rowcount: cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k])) cr.commit() - - # iterate on the database columns to drop the NOT NULL constraints - # of fields which were required but have been removed - columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)] - columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns - cr.execute("SELECT a.attname, a.attnotnull" - " FROM pg_class c, pg_attribute a" - " WHERE c.relname=%%s" - " AND c.oid=a.attrelid" - " AND a.attisdropped=%%s" - " AND pg_catalog.format_type(a.atttypid, a.atttypmod) NOT IN ('cid', 'tid', 'oid', 'xid')" - " AND a.attname NOT IN (%s)" % ",".join(['%s']*len(columns)), - [self._table, False] + columns) - for column in cr.dictfetchall(): - # TODO display this information only when all modules are loaded - logger.notifyChannel("orm", netsvc.LOG_DEBUG, "column %s is in the table %s but not in the corresponding object %s" % (column['attname'], self._table, self._name)) - if column['attnotnull']: - cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname'])) + + self._check_removed_columns(cr, log=False) # iterate on the "object columns" todo_update_store = [] @@ -2359,7 +2367,13 @@ class orm(orm_template): default.append(f) if len(default): - vals.update(self.default_get(cr, user, default, context)) + default_values = self.default_get(cr, user, default, context) + for dv in default_values: + if dv in self._columns and self._columns[dv]._type == 'many2many': + if default_values[dv] and isinstance(default_values[dv][0], (int, long)): + default_values[dv] = [(6, 0, default_values[dv])] + + vals.update(default_values) tocreate = {} for v in self._inherits: diff --git a/bin/report/interface.py b/bin/report/interface.py index 74f952128d5..d11d5a7a21e 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -20,7 +20,8 @@ # ############################################################################## -import os,re +import os +import re #Ged> Why do we use libxml2 here instead of xml.dom like in other places of the code? import libxml2 @@ -121,7 +122,7 @@ class report_rml(report_int): pos_xml = i.end() doc = print_xml.document(cr, uid, {}, {}) - tmpl_path = addons.get_module_resource('custom', 'corporate_defaults.xml') + tmpl_path = addons.get_module_resource('base', 'report', 'corporate_defaults.xml') doc.parse(tmpl_path, [uid], 'res.users', context) corporate_header = doc.xml_get() doc.close() diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index cec9e630c93..d34e0c1e2d0 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -715,10 +715,8 @@ class report_sxw(report_rml): if want_header: #Add corporate header/footer - if report_type=='odt': - rml = tools.file_open('custom/corporate_odt_header.xml').read() - if report_type=='sxw': - rml = tools.file_open('custom/corporate_sxw_header.xml').read() + if report_type in ('odt', 'sxw'): + rml = tools.file_open(os.path.join('base', 'report', 'corporate_%s_header.xml' % report_type)).read() rml_parser = self.parser(cr, uid, self.name2, context) rml_parser.parents = sxw_parents rml_parser.tag = sxw_tag diff --git a/bin/service/web_services.py b/bin/service/web_services.py index 44c853a6d4b..53936d202f5 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -204,7 +204,7 @@ class db(netsvc.Service): cr = db.cursor() cr.autocommit(True) try: - cr.execute('CREATE DATABASE "%s" ENCODING \'unicode\'' % db_name) + cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE 'template0'""" % db_name) finally: cr.close() sql_db.close_db('template1') diff --git a/bin/tools/__init__.py b/bin/tools/__init__.py index ad693e14aa1..f188864820d 100644 --- a/bin/tools/__init__.py +++ b/bin/tools/__init__.py @@ -19,6 +19,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## +import copy from config import * from misc import * from convert import * diff --git a/bin/tools/config.py b/bin/tools/config.py index fc5659d03bc..d79a997561c 100644 --- a/bin/tools/config.py +++ b/bin/tools/config.py @@ -180,9 +180,19 @@ class configmanager(object): (opt, args) = parser.parse_args() - assert not (bool(opt.syslog) and bool(opt.logfile)), "the syslog and logfile options are exclusive" - assert not (opt.translate_in and (not opt.language or not opt.db_name)), "the i18n-import option cannot be used without the language (-l) and the database (-d) options" - assert not (opt.translate_out and (not opt.db_name)), "the i18n-export option cannot be used without the database (-d) option" + def die(cond, msg): + if cond: + print msg + sys.exit(1) + + die(bool(opt.syslog) and bool(opt.logfile), + "the syslog and logfile options are exclusive") + + die(opt.translate_in and (not opt.language or not opt.db_name), + "the i18n-import option cannot be used without the language (-l) and the database (-d) options") + + die(opt.translate_out and (not opt.db_name), + "the i18n-export option cannot be used without the database (-d) option") # place/search the config file on Win32 near the server installation # (../etc from the server) @@ -246,10 +256,62 @@ class configmanager(object): self.options['pg_path'] = opt.pg_path if self.options.get('language', False): - assert len(self.options['language'])<=5, 'ERROR: The Lang name must take max 5 chars, Eg: -lfr_BE' + if len(self.options['language']) <= 5: + raise Exception('ERROR: The Lang name must take max 5 chars, Eg: -lfr_BE') + + if not self.options['db_user']: + try: + import getpass + self.options['db_user'] = getpass.getuser() + except: + self.options['db_user'] = None + + die(not self.options['db_user'], 'ERROR: No user specified for the connection to the database') + + if self.options['db_password']: + if sys.platform == 'win32' and not self.options['db_host']: + self.options['db_host'] = 'localhost' + if self.options['db_host']: + self._generate_pgpassfile() + if opt.save: self.save() + def _generate_pgpassfile(self): + """ + Generate the pgpass file with the parameters from the command line (db_host, db_user, + db_password) + + Used because pg_dump and pg_restore can not accept the password on the command line. + """ + is_win32 = sys.platform == 'win32' + if is_win32: + filename = os.path.join(os.environ['APPDATA'], 'pgpass.conf') + else: + filename = os.path.join(os.environ['HOME'], '.pgpass') + + text_to_add = "%(db_host)s:*:*:%(db_user)s:%(db_password)s" % self.options + + if os.path.exists(filename): + content = [x.strip() for x in file(filename, 'r').readlines()] + if text_to_add in content: + return + + fp = file(filename, 'a+') + fp.write(text_to_add + "\n") + fp.close() + + if is_win32: + import _winreg + x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) + y = _winreg.OpenKey(x, r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", 0,_winreg.KEY_ALL_ACCESS) + _winreg.SetValueEx(y,"PGPASSFILE", 0, _winreg.REG_EXPAND_SZ, filename ) + _winreg.CloseKey(y) + _winreg.CloseKey(x) + else: + import stat + os.chmod(filename, stat.S_IRUSR + stat.S_IWUSR) + def _check_addons_path(self, option, opt, value, parser): res = os.path.abspath(os.path.expanduser(value)) if not os.path.exists(res): diff --git a/bin/tools/copy.py b/bin/tools/copy.py new file mode 100644 index 00000000000..e301b710976 --- /dev/null +++ b/bin/tools/copy.py @@ -0,0 +1,416 @@ +""" +FROM Python 2.5 +Generic (shallow and deep) copying operations. + +Interface summary: + + import copy + + x = copy.copy(y) # make a shallow copy of y + x = copy.deepcopy(y) # make a deep copy of y + +For module specific errors, copy.Error is raised. + +The difference between shallow and deep copying is only relevant for +compound objects (objects that contain other objects, like lists or +class instances). + +- A shallow copy constructs a new compound object and then (to the + extent possible) inserts *the same objects* into it that the + original contains. + +- A deep copy constructs a new compound object and then, recursively, + inserts *copies* into it of the objects found in the original. + +Two problems often exist with deep copy operations that don't exist +with shallow copy operations: + + a) recursive objects (compound objects that, directly or indirectly, + contain a reference to themselves) may cause a recursive loop + + b) because deep copy copies *everything* it may copy too much, e.g. + administrative data structures that should be shared even between + copies + +Python's deep copy operation avoids these problems by: + + a) keeping a table of objects already copied during the current + copying pass + + b) letting user-defined classes override the copying operation or the + set of components copied + +This version does not copy types like module, class, function, method, +nor stack trace, stack frame, nor file, socket, window, nor array, nor +any similar types. + +Classes can use the same interfaces to control copying that they use +to control pickling: they can define methods called __getinitargs__(), +__getstate__() and __setstate__(). See the documentation for module +"pickle" for information on these methods. +""" + +import types +from copy_reg import dispatch_table + +class Error(Exception): + pass +error = Error # backward compatibility + +try: + from org.python.core import PyStringMap +except ImportError: + PyStringMap = None + +__all__ = ["Error", "copy", "deepcopy"] + +def copy(x): + """Shallow copy operation on arbitrary Python objects. + + See the module's __doc__ string for more info. + """ + + cls = type(x) + + copier = _copy_dispatch.get(cls) + if copier: + return copier(x) + + copier = getattr(cls, "__copy__", None) + if copier: + return copier(x) + + reductor = dispatch_table.get(cls) + if reductor: + rv = reductor(x) + else: + reductor = getattr(x, "__reduce_ex__", None) + if reductor: + rv = reductor(2) + else: + reductor = getattr(x, "__reduce__", None) + if reductor: + rv = reductor() + else: + raise Error("un(shallow)copyable object of type %s" % cls) + + return _reconstruct(x, rv, 0) + + +_copy_dispatch = d = {} + +def _copy_immutable(x): + return x +for t in (type(None), int, long, float, bool, str, tuple, + frozenset, type, xrange, types.ClassType, + types.BuiltinFunctionType, + types.FunctionType): + d[t] = _copy_immutable +for name in ("ComplexType", "UnicodeType", "CodeType"): + t = getattr(types, name, None) + if t is not None: + d[t] = _copy_immutable + +def _copy_with_constructor(x): + return type(x)(x) +for t in (list, dict, set): + d[t] = _copy_with_constructor + +def _copy_with_copy_method(x): + return x.copy() +if PyStringMap is not None: + d[PyStringMap] = _copy_with_copy_method + +def _copy_inst(x): + if hasattr(x, '__copy__'): + return x.__copy__() + if hasattr(x, '__getinitargs__'): + args = x.__getinitargs__() + y = x.__class__(*args) + else: + y = _EmptyClass() + y.__class__ = x.__class__ + if hasattr(x, '__getstate__'): + state = x.__getstate__() + else: + state = x.__dict__ + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + y.__dict__.update(state) + return y +d[types.InstanceType] = _copy_inst + +del d + +def deepcopy(x, memo=None, _nil=[]): + """Deep copy operation on arbitrary Python objects. + + See the module's __doc__ string for more info. + """ + + if memo is None: + memo = {} + + d = id(x) + y = memo.get(d, _nil) + if y is not _nil: + return y + + cls = type(x) + + copier = _deepcopy_dispatch.get(cls) + if copier: + y = copier(x, memo) + else: + try: + issc = issubclass(cls, type) + except TypeError: # cls is not a class (old Boost; see SF #502085) + issc = 0 + if issc: + y = _deepcopy_atomic(x, memo) + else: + copier = getattr(x, "__deepcopy__", None) + if copier: + y = copier(memo) + else: + reductor = dispatch_table.get(cls) + if reductor: + rv = reductor(x) + else: + reductor = getattr(x, "__reduce_ex__", None) + if reductor: + rv = reductor(2) + else: + reductor = getattr(x, "__reduce__", None) + if reductor: + rv = reductor() + else: + raise Error( + "un(deep)copyable object of type %s" % cls) + y = _reconstruct(x, rv, 1, memo) + + memo[d] = y + _keep_alive(x, memo) # Make sure x lives at least as long as d + return y + +_deepcopy_dispatch = d = {} + +def _deepcopy_atomic(x, memo): + return x +d[type(None)] = _deepcopy_atomic +d[int] = _deepcopy_atomic +d[long] = _deepcopy_atomic +d[float] = _deepcopy_atomic +d[bool] = _deepcopy_atomic +try: + d[complex] = _deepcopy_atomic +except NameError: + pass +d[str] = _deepcopy_atomic +try: + d[unicode] = _deepcopy_atomic +except NameError: + pass +try: + d[types.CodeType] = _deepcopy_atomic +except AttributeError: + pass +d[type] = _deepcopy_atomic +d[xrange] = _deepcopy_atomic +d[types.ClassType] = _deepcopy_atomic +d[types.BuiltinFunctionType] = _deepcopy_atomic +d[types.FunctionType] = _deepcopy_atomic + +def _deepcopy_list(x, memo): + y = [] + memo[id(x)] = y + for a in x: + y.append(deepcopy(a, memo)) + return y +d[list] = _deepcopy_list + +def _deepcopy_tuple(x, memo): + y = [] + for a in x: + y.append(deepcopy(a, memo)) + d = id(x) + try: + return memo[d] + except KeyError: + pass + for i in range(len(x)): + if x[i] is not y[i]: + y = tuple(y) + break + else: + y = x + memo[d] = y + return y +d[tuple] = _deepcopy_tuple + +def _deepcopy_dict(x, memo): + y = {} + memo[id(x)] = y + for key, value in x.iteritems(): + y[deepcopy(key, memo)] = deepcopy(value, memo) + return y +d[dict] = _deepcopy_dict +if PyStringMap is not None: + d[PyStringMap] = _deepcopy_dict + +def _keep_alive(x, memo): + """Keeps a reference to the object x in the memo. + + Because we remember objects by their id, we have + to assure that possibly temporary objects are kept + alive by referencing them. + We store a reference at the id of the memo, which should + normally not be used unless someone tries to deepcopy + the memo itself... + """ + try: + memo[id(memo)].append(x) + except KeyError: + # aha, this is the first one :-) + memo[id(memo)]=[x] + +def _deepcopy_inst(x, memo): + if hasattr(x, '__deepcopy__'): + return x.__deepcopy__(memo) + if hasattr(x, '__getinitargs__'): + args = x.__getinitargs__() + args = deepcopy(args, memo) + y = x.__class__(*args) + else: + y = _EmptyClass() + y.__class__ = x.__class__ + memo[id(x)] = y + if hasattr(x, '__getstate__'): + state = x.__getstate__() + else: + state = x.__dict__ + state = deepcopy(state, memo) + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + y.__dict__.update(state) + return y +d[types.InstanceType] = _deepcopy_inst + +def _reconstruct(x, info, deep, memo=None): + if isinstance(info, str): + return x + assert isinstance(info, tuple) + if memo is None: + memo = {} + n = len(info) + assert n in (2, 3, 4, 5) + callable, args = info[:2] + if n > 2: + state = info[2] + else: + state = {} + if n > 3: + listiter = info[3] + else: + listiter = None + if n > 4: + dictiter = info[4] + else: + dictiter = None + if deep: + args = deepcopy(args, memo) + y = callable(*args) + memo[id(x)] = y + if listiter is not None: + for item in listiter: + if deep: + item = deepcopy(item, memo) + y.append(item) + if dictiter is not None: + for key, value in dictiter: + if deep: + key = deepcopy(key, memo) + value = deepcopy(value, memo) + y[key] = value + if state: + if deep: + state = deepcopy(state, memo) + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + else: + slotstate = None + if state is not None: + y.__dict__.update(state) + if slotstate is not None: + for key, value in slotstate.iteritems(): + setattr(y, key, value) + return y + +del d + +del types + +# Helper for instance creation without calling __init__ +class _EmptyClass: + pass + +def _test(): + l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], + {'abc': 'ABC'}, (), [], {}] + l1 = copy(l) + print l1==l + l1 = map(copy, l) + print l1==l + l1 = deepcopy(l) + print l1==l + class C: + def __init__(self, arg=None): + self.a = 1 + self.arg = arg + if __name__ == '__main__': + import sys + file = sys.argv[0] + else: + file = __file__ + self.fp = open(file) + self.fp.close() + def __getstate__(self): + return {'a': self.a, 'arg': self.arg} + def __setstate__(self, state): + for key, value in state.iteritems(): + setattr(self, key, value) + def __deepcopy__(self, memo=None): + new = self.__class__(deepcopy(self.arg, memo)) + new.a = self.a + return new + c = C('argument sketch') + l.append(c) + l2 = copy(l) + print l == l2 + print l + print l2 + l2 = deepcopy(l) + print l == l2 + print l + print l2 + l.append({l[1]: l, 'xyz': l[2]}) + l3 = copy(l) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) + l3 = deepcopy(l) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) + +if __name__ == '__main__': + _test() diff --git a/bin/tools/translate.py b/bin/tools/translate.py index 24f606f3550..224f26bec71 100644 --- a/bin/tools/translate.py +++ b/bin/tools/translate.py @@ -478,7 +478,7 @@ def trans_generate(lang, modules, dbname=None): push_translation(module, report_type, name, 0, t) except IOError, xml.dom.expatbuilder.expat.ExpatError: if fname: - logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't export translation for report %s %s %s" % (name, report_type, fname)) + logger.notifyChannel("i18n", netsvc.LOG_ERROR, "couldn't export translation for report %s %s %s" % (name, report_type, fname)) for constraint in pool.get(model)._constraints: msg = constraint[1] @@ -540,14 +540,13 @@ def trans_load(db_name, filename, lang, strict=False, verbose=True): return r except IOError: if verbose: - logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read translation file %s" % (filename,)) + logger.notifyChannel("i18n", netsvc.LOG_ERROR, "couldn't read translation file %s" % (filename,)) return None def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=None, verbose=True): logger = netsvc.Logger() if verbose: - logger.notifyChannel("init", netsvc.LOG_INFO, - 'loading translation file for language %s' % (lang)) + logger.notifyChannel("i18n", netsvc.LOG_INFO, 'loading translation file for language %s' % (lang)) pool = pooler.get_pool(db_name) lang_obj = pool.get('res.lang') trans_obj = pool.get('ir.translation') @@ -617,8 +616,9 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name= langs = lang_obj.read(cr, uid, lang_ids) ls = map(lambda x: (x['code'],x['name']), langs) - fileobj.seek(0) + # now, the serious things: we read the language file + fileobj.seek(0) if fileformat == 'csv': reader = csv.reader(fileobj, quotechar='"', delimiter=',') # read the first line of the file (it contains columns titles) @@ -701,11 +701,11 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name= cr.commit() cr.close() if verbose: - logger.notifyChannel("init", netsvc.LOG_INFO, + logger.notifyChannel("i18n", netsvc.LOG_INFO, "translation file loaded succesfully") except IOError: filename = '[lang: %s][format: %s]' % (lang or 'new', fileformat) - logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read translation file %s" % (filename,)) + logger.notifyChannel("i18n", netsvc.LOG_ERROR, "couldn't read translation file %s" % (filename,)) cr.commit() cr.close() except: diff --git a/bin/wizard/__init__.py b/bin/wizard/__init__.py index 5635b1169dd..3a576c9caa4 100644 --- a/bin/wizard/__init__.py +++ b/bin/wizard/__init__.py @@ -21,7 +21,7 @@ ############################################################################## import netsvc -import copy +from tools import copy from tools.misc import UpdateableStr, UpdateableDict from tools.translate import translate from xml import dom @@ -110,6 +110,11 @@ class interface(netsvc.Service): if not isinstance(fields[val]['selection'], (tuple, list)): fields[val] = copy.copy(fields[val]) fields[val]['selection'] = fields[val]['selection'](self, cr, uid, context) + elif lang: + res_name = "%s,%s,%s" % (self.wiz_name, state, val) + trans = lambda x: translate(cr, res_name, 'selection', lang, x) or x + for idx, (key, val2) in enumerate(fields[val]['selection']): + fields[val]['selection'][idx] = (key, trans(val2)) if lang: # translate fields @@ -119,11 +124,6 @@ class interface(netsvc.Service): trans = translate(cr, res_name, 'wizard_field', lang) if trans: fields[field]['string'] = trans - - if 'selection' in fields[field]: - trans = lambda x: translate(cr, res_name, 'selection', lang, x) or x - for idx, (key, val) in enumerate(fields[field]['selection']): - fields[field]['selection'][idx] = (key, trans(val)) if 'help' in fields[field]: t = translate(cr, res_name, 'help', lang, fields[field]['help']) diff --git a/doc/INSTALL b/doc/INSTALL index 1b7539bf859..97684d6b3fd 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -8,12 +8,14 @@ Required dependencies: You need the following software installed: - * Python 2.3 or above - * Postgresql 7 or above - * Psycopg python module for python2.3 - * libxml2 and python2.3 bindings - * libxslt and python2.3 bindings - * Reportlab pdf generation library for python2.3 + * Python 2.4 or 2.5 + * Postgresql 8.2 or above + * Psycopg2 python module + * libxml2 and python bindings + * libxslt and python bindings + * Reportlab pdf generation library for python + * lxml python module + * pytz python module Some dependencies are only required for specific purposes: @@ -22,33 +24,24 @@ for rendering workflows graphs, you need: * pyparsing for generating reports using non .jpg images, you need: - * Python Imaging Library for python2.3 + * Python Imaging Library for python For Debian-based distributions, the required packages can be installed with the -following commands: - - apt-get install python2.3 python2.3-xml postgresql postgresql-client libxml2-python2.3 - apt-get install libxslt1-python2.3 python2.3-psycopg python2.3-reportlab - apt-get install python2.3-imaging python2.3-pyparsing graphviz - -For newer Debian-based distributions such as Etch, the required packages can be -installed with the following commands: - - apt-get install python2.4 python-xml postgresql postgresql-client python-libxml2 - apt-get install python-libxslt1 python-psycopg python-reportlab - apt-get install python-imaging python-pyparsing graphviz +following command: + #> apt-get install -y postgresql graphviz python-psycopg2 python-xml python-lxml python-libxml2 python-libxslt1 python-tz python-imaging For Fedora if they are not installed, install: python and postgresql uses yum or you can recover required packages on fedora web site in "core" or "extra" repository : -postgresql-python- +postgresql-python libxml2-python libxslt-python +python-lxml python-imaging -python-psycopg +python-psycopg2 python-reportlab graphviz You can find pyparsing at http://pyparsing.sourceforge.net/ diff --git a/rpminstall_sh.txt b/rpminstall_sh.txt index c184585e94f..bb7bb3fc10c 100644 --- a/rpminstall_sh.txt +++ b/rpminstall_sh.txt @@ -7,6 +7,8 @@ # Need to overwrite the install-part of the RPM to append the # compression-suffix onto the filenames for the man-pages. # +python -c "import compileall, os; compileall.compile_dir(os.path.join(os.environ['PWD'], 'doc'), force=True)" +python -O -c "import compileall, os; compileall.compile_dir(os.path.join(os.environ['PWD'], 'doc'), force=True)" python setup.py install --optimize 1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES SUFFIX=gz