Merge branch 'xrg' into optimize

Conflicts:
	bin/osv/orm.py

bzr revid: p_christ@hol.gr-20090828143403-c48ylvbkzgnimvhr
This commit is contained in:
P. Christeas 2009-08-28 17:34:03 +03:00
commit 8558374c2b
101 changed files with 127628 additions and 14057 deletions

43
Makefile Normal file
View File

@ -0,0 +1,43 @@
# -*- makefile -*-
addons-path := bin/addons/
root-path := bin/
port := 8069
net_port := 8070
module := base
database := terp
language := fr_FR
i18n-import := bin/addons/base/i18n/fr_FR.po
interrogation_file := bin/addons/quality_integration_server/base_quality_interrogation.py
login := admin
password := admin
start:
python $(interrogation_file) start-server --root-path=$(root-path) --addons-path=$(addons-path) --port=$(port)
create-db:
python $(interrogation_file) create-db --database=$(database) --root-path=$(root-path) --addons-path=$(addons-path) --port=$(port) --login=$(login) --password=$(password)
drop-db:
python $(interrogation_file) drop-db --database=$(database) --root-path=$(root-path) --addons-path=$(addons-path) --port=$(port)
install-module:
python $(interrogation_file) install-module --modules=$(module) --database=$(database) --root-path=$(root-path) --addons-path=$(addons-path) --port=$(port) --login=$(login) --password=$(password)
upgrade-module:
python $(interrogation_file) upgrade-module --modules=$(module) --database=$(database) --root-path=$(root-path) --addons-path=$(addons-path) --port=$(port) --login=$(login) --password=$(password)
install-translation:
python $(interrogation_file) install-translation --database=$(database) --translate-in=$(i18n-import) --port=$(port) --login=$(login) --password=$(password) --root-path=$(root-path) --addons-path=$(addons-path)
version:
python bin/openerp-server.py --version
check-quality:
python $(interrogation_file) check-quality --database=$(database) --modules=$(module) --port=$(port) --login=$(login) --password=$(password) --addons-path=$(addons-path) --root-path=$(root-path)

View File

@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: OpenERP
Version: 5.0.1
Version: 5.0.3
Author: Tiny.be
Author-email: fp at tiny be
Maintainer: Tiny.be

View File

@ -675,6 +675,17 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
status = {}
cr = db.cursor()
if cr:
cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname='ir_module_module'")
if len(cr.fetchall())==0:
logger.notifyChannel("init", netsvc.LOG_INFO, "init db")
tools.init_db(cr)
# cr.execute("update res_users set password=%s where id=%s",('admin',1))
# in that case, force --init=all
tools.config["init"]["all"] = 1
tools.config['update']['all'] = 1
if not tools.config['without_demo']:
tools.config["demo"]['all'] = 1
force = []
if force_demo:
force.append('demo')

View File

@ -328,7 +328,7 @@ CREATE TABLE ir_model_data (
write_date timestamp without time zone,
write_uid integer,
noupdate boolean,
name character varying(64) NOT NULL,
name character varying(128) NOT NULL,
date_init timestamp without time zone,
date_update timestamp without time zone,
module character varying(64) NOT NULL,

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.1\n"
"Project-Id-Version: OpenERP Server 5.0.2\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-06-17 14:57:53+0000\n"
"PO-Revision-Date: 2009-06-17 14:57:53+0000\n"
"POT-Creation-Date: 2009-08-13 19:05:35+0000\n"
"PO-Revision-Date: 2009-08-13 19:05:35+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -144,8 +144,9 @@ msgid "Burkina Faso"
msgstr ""
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_SORT_ASCENDING"
#: model:ir.actions.act_window,name:base.action_country_state
#: model:ir.ui.menu,name:base.menu_country_state_partner
msgid "Fed. States"
msgstr ""
#. module: base
@ -184,6 +185,11 @@ msgstr ""
msgid "Togo"
msgstr ""
#. module: base
#: field:res.partner.event,type:0
msgid "Type of Event"
msgstr ""
#. module: base
#: field:ir.actions.act_window,res_model:0
#: field:ir.actions.report.custom,model:0
@ -687,8 +693,8 @@ msgid "Connect Events to Actions"
msgstr ""
#. module: base
#: field:res.partner.event,type:0
msgid "Type of Event"
#: selection:ir.ui.menu,icon:0
msgid "STOCK_SORT_ASCENDING"
msgstr ""
#. module: base
@ -1090,8 +1096,8 @@ msgid "Menu :"
msgstr ""
#. module: base
#: field:ir.actions.configuration.wizard,name:0
msgid "Next Wizard"
#: help:ir.rule.group,global:0
msgid "Make the rule global, otherwise it needs to be put on a group"
msgstr ""
#. module: base
@ -4061,6 +4067,11 @@ msgstr ""
msgid "Bank Type"
msgstr ""
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "fi_FI"
msgstr ""
#. module: base
#: field:ir.actions.server,trigger_name:0
msgid "Trigger Name"
@ -4499,6 +4510,11 @@ msgstr ""
msgid "Panama"
msgstr ""
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "Indonesian / Bahasa Indonesia"
msgstr ""
#. module: base
#: model:res.country,name:base.lu
msgid "Luxembourg"
@ -5009,11 +5025,6 @@ msgstr ""
msgid "Menus"
msgstr ""
#. module: base
#: help:ir.rule.group,global:0
msgid "Make the rule global, otherwise it needs to be put on a group or user"
msgstr ""
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_GO_UP"
@ -5352,8 +5363,6 @@ msgid "The rate of the currency to the currency of rate 1"
msgstr ""
#. module: base
#: model:ir.actions.act_window,name:base.action_country_state
#: model:ir.ui.menu,name:base.menu_country_state_partner
#: field:maintenance.contract.wizard,state:0
msgid "States"
msgstr ""
@ -5456,6 +5465,11 @@ msgstr ""
msgid "Report Xml"
msgstr ""
#. module: base
#: field:ir.actions.configuration.wizard,name:0
msgid "Next Wizard"
msgstr ""
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_title_partner
#: model:ir.ui.menu,name:base.menu_partner_title_partner

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-06-08 21:23:39+0000\n"
"POT-Creation-Date: 2009-08-13 19:05:35+0000\n"
"PO-Revision-Date: 2009-07-24 00:40+0300\n"
"Last-Translator: P. Christeas <p_christ@hol.gr>\n"
"Language-Team: Greek <nls@hellug.gr>\n"
@ -150,9 +150,11 @@ msgid "Burkina Faso"
msgstr "Burkina Faso"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_SORT_ASCENDING"
msgstr "STOCK_SORT_ASCENDING"
#: model:ir.actions.act_window,name:base.action_country_state
#: model:ir.ui.menu,name:base.menu_country_state_partner
#, fuzzy
msgid "Fed. States"
msgstr "Νομός"
#. module: base
#: view:ir.model:0 view:res.groups:0
@ -189,6 +191,11 @@ msgstr "Ανήκει"
msgid "Togo"
msgstr "Togo"
#. module: base
#: field:res.partner.event,type:0
msgid "Type of Event"
msgstr "Τύπος Συμβάντος"
#. module: base
#: field:ir.actions.act_window,res_model:0
#: field:ir.actions.report.custom,model:0 field:ir.actions.report.xml,model:0
@ -216,9 +223,15 @@ msgid "Categories of Modules"
msgstr "Κατηγορίες Αρθρωμάτων"
#. module: base
#: view:ir.actions.server:0
msgid "Email Configuration"
msgstr "Ρυθμίσεις Email "
#: help:ir.actions.server,expression:0
msgid ""
"Enter the field/expression that will return the list. E.g. select the sale "
"order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`."
msgstr ""
"Enter the field/expression that will return the list. E.g. select the sale "
"order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`."
#. module: base
#: model:res.country,name:base.cc
@ -256,8 +269,8 @@ msgstr "Header/Footer"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_ZOOM_100"
msgstr "STOCK_ZOOM_100"
msgid "STOCK_MEDIA_PAUSE"
msgstr "STOCK_MEDIA_PAUSE"
#. module: base
#: model:res.country,name:base.ru
@ -700,9 +713,9 @@ msgid "Connect Events to Actions"
msgstr "Σύνδεση Συνβάντων με Ενέργειες"
#. module: base
#: field:res.partner.event,type:0
msgid "Type of Event"
msgstr "Τύπος Συμβάντος"
#: selection:ir.ui.menu,icon:0
msgid "STOCK_SORT_ASCENDING"
msgstr "STOCK_SORT_ASCENDING"
#. module: base
#: selection:maintenance.contract,state:0
@ -1031,6 +1044,11 @@ msgstr ""
"κενό αν δεν επιθυμείτε να αποθηκεύετε τις εκτυπώσεις αναφορών. Μπορείτε να "
"χρησιμοποιήσετε μια έκφραση python με τις παραμέτρους object και time."
#. module: base
#: model:ir.ui.menu,name:base.next_id_10
msgid "Scheduler"
msgstr "Χρονοδιάγραμμα"
#. module: base
#: constraint:ir.model:0
msgid ""
@ -1095,9 +1113,10 @@ msgid "Menu :"
msgstr "Menu :"
#. module: base
#: field:ir.actions.configuration.wizard,name:0
msgid "Next Wizard"
msgstr "Επόμενος Αυτόματος Οδηγός"
#: help:ir.rule.group,global:0
#, fuzzy
msgid "Make the rule global, otherwise it needs to be put on a group"
msgstr "Θέστε τον κανόνα ως γενικό αλλιώς ορίστε τον σε μια ομάδα ή χρήστη"
#. module: base
#: view:ir.values:0
@ -1175,9 +1194,9 @@ msgid "Action to Trigger"
msgstr "Ενέργεια προς Εκκίνηση"
#. module: base
#: model:ir.ui.menu,name:base.next_id_10
msgid "Scheduler"
msgstr "Χρονοδιάγραμμα"
#: selection:ir.ui.menu,icon:0
msgid "STOCK_ZOOM_100"
msgstr "STOCK_ZOOM_100"
#. module: base
#: selection:ir.ui.menu,icon:0
@ -2151,9 +2170,9 @@ msgid "Work Days"
msgstr "Ημέρες Εργασίας"
#. module: base
#: model:ir.model,name:base.model_res_roles
msgid "res.roles"
msgstr "res.roles"
#: model:ir.model,name:base.model_ir_module_module_dependency
msgid "Module dependency"
msgstr "Εξάρτηση Αρθρωμάτων"
#. module: base
#: help:ir.cron,priority:0
@ -2938,7 +2957,7 @@ msgid "Iraq"
msgstr "Iraq"
#. module: base
#: view:ir.attachment:0 field:ir.attachment,datas:0
#: view:ir.attachment:0
msgid "Data"
msgstr "Δεδομένα"
@ -3210,9 +3229,8 @@ msgid "Source Activity"
msgstr "Πηγή Δράσης"
#. module: base
#: field:ir.attachment,res_id:0 field:ir.model.data,res_id:0
#: field:ir.translation,res_id:0 field:workflow.instance,res_id:0
#: field:workflow.triggers,res_id:0
#: field:ir.model.data,res_id:0 field:ir.translation,res_id:0
#: field:workflow.instance,res_id:0 field:workflow.triggers,res_id:0
msgid "Resource ID"
msgstr "Αριθμός Πόρου"
@ -3774,6 +3792,11 @@ msgstr "ΤΚ"
msgid "STOCK_FILE"
msgstr "STOCK_FILE"
#. module: base
#: field:ir.attachment,res_id:0
msgid "Attached ID"
msgstr "Συνημμένη ID"
#. module: base
#: model:res.country,name:base.uz
msgid "Uzbekistan"
@ -4063,9 +4086,9 @@ msgstr ""
"αντικειμένου, π.χ. 'Αγαπητέ [[ object.partner_id.name ]]'"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_MEDIA_PAUSE"
msgstr "STOCK_MEDIA_PAUSE"
#: field:ir.attachment,res_model:0
msgid "Attached Model"
msgstr "Συνδεδεμένο Μοντέλο"
#. module: base
#: field:res.partner.bank,state:0
@ -4073,6 +4096,11 @@ msgstr "STOCK_MEDIA_PAUSE"
msgid "Bank Type"
msgstr "Τύπος Τράπεζας"
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "fi_FI"
msgstr ""
#. module: base
#: field:ir.actions.server,trigger_name:0
msgid "Trigger Name"
@ -4471,7 +4499,6 @@ msgstr "Ημερ/νία Εκκίνησης"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_address_form
#: model:ir.model,name:base.model_res_partner_address
#: model:ir.ui.menu,name:base.menu_partner_address_form
#: view:res.partner.address:0
msgid "Partner Addresses"
msgstr "Διευθύνσεις Συνεργάτη"
@ -4498,6 +4525,11 @@ msgstr "STOCK_PROPERTIES"
msgid "Somalia"
msgstr "Somalia"
#. module: base
#: field:ir.attachment,datas:0
msgid "File Content"
msgstr "Περιεχόμενα Φακέλου"
#. module: base
#: model:res.partner.title,name:base.res_partner_title_sir
msgid "Sir"
@ -4518,6 +4550,11 @@ msgstr "Guinea"
msgid "Panama"
msgstr "Panama"
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "Indonesian / Bahasa Indonesia"
msgstr ""
#. module: base
#: model:res.country,name:base.lu
msgid "Luxembourg"
@ -4815,15 +4852,9 @@ msgid "Force Domain"
msgstr "Επιβολή Τομέα"
#. module: base
#: help:ir.actions.server,expression:0
msgid ""
"Enter the field/expression that will return the list. E.g. select the sale "
"order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`."
msgstr ""
"Enter the field/expression that will return the list. E.g. select the sale "
"order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`."
#: view:ir.actions.server:0
msgid "Email Configuration"
msgstr "Ρυθμίσεις Email "
#. module: base
#: model:ir.model,name:base.model_ir_cron
@ -5018,11 +5049,6 @@ msgstr "Estonian / Eesti keel"
msgid "Menus"
msgstr "Μενού"
#. module: base
#: help:ir.rule.group,global:0
msgid "Make the rule global, otherwise it needs to be put on a group or user"
msgstr "Θέστε τον κανόνα ως γενικό αλλιώς ορίστε τον σε μια ομάδα ή χρήστη"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_GO_UP"
@ -5350,8 +5376,6 @@ msgid "The rate of the currency to the currency of rate 1"
msgstr "Ισοτιμία νομίσματος"
#. module: base
#: model:ir.actions.act_window,name:base.action_country_state
#: model:ir.ui.menu,name:base.menu_country_state_partner
#: field:maintenance.contract.wizard,state:0
msgid "States"
msgstr "Καταστάσεις"
@ -5455,6 +5479,11 @@ msgstr "Κατάσταση"
msgid "Report Xml"
msgstr "Αναφορά Xml"
#. module: base
#: field:ir.actions.configuration.wizard,name:0
msgid "Next Wizard"
msgstr "Επόμενος Αυτόματος Οδηγός"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_title_partner
#: model:ir.ui.menu,name:base.menu_partner_title_partner
@ -5756,6 +5785,11 @@ msgstr "Kazakhstan"
msgid "Azerbaijan"
msgstr "Azerbaijan"
#. module: base
#: model:ir.model,name:base.model_res_roles
msgid "res.roles"
msgstr "res.roles"
#. module: base
#: model:ir.actions.act_window,name:base.open_module_tree_install
#: model:ir.ui.menu,name:base.menu_module_tree_install
@ -6299,9 +6333,9 @@ msgid "closed"
msgstr "κλειστά"
#. module: base
#: model:ir.model,name:base.model_ir_module_module_dependency
msgid "Module dependency"
msgstr "Εξάρτηση Αρθρωμάτων"
#: constraint:res.partner:0
msgid "Error ! You can not create recursive associated members."
msgstr "Σφάλμα! Υπάρχει ήδη ίδια περιγραφή συνδεδεμένου μέλους."
#. module: base
#: selection:ir.report.custom.fields,alignment:0
@ -6798,8 +6832,7 @@ msgid "Arguments"
msgstr "Arguments"
#. module: base
#: field:ir.attachment,res_model:0 field:workflow,osv:0
#: field:workflow.instance,res_type:0
#: field:workflow,osv:0 field:workflow.instance,res_type:0
msgid "Resource Object"
msgstr "Αντικείμενο-Πόρος"
@ -7057,6 +7090,11 @@ msgstr "Μήνας: %(month)s"
msgid "Sales & Purchases"
msgstr "Πωλήσεις & Αγορές"
#. module: base
#: model:ir.ui.menu,name:base.menu_partner_address_form
msgid "Addresses"
msgstr "Διευθύνσεις"
#. module: base
#: model:res.country,name:base.mm
msgid "Myanmar"
@ -7226,9 +7264,6 @@ msgstr "XML Identifier"
#~ msgid "The search method is not implemented on this object !"
#~ msgstr "Η μέθοδος αναζήτησης δεν έχει αναπτυχθεί σε αυτό το αντικείμενο!"
#~ msgid "Attached ID"
#~ msgstr "Συνημμένη ID"
#~ msgid "You can not read this document! (%s)"
#~ msgstr "Δεν μπορείτε να διαβάσετε αυτό το έγγραφο! (%s)"
@ -7240,9 +7275,6 @@ msgstr "XML Identifier"
#~ "απεγκαταστήσετε:\n"
#~ " %s"
#~ msgid "Attached Model"
#~ msgstr "Συνδεδεμένο Μοντέλο"
#~ msgid "Can not remove root user!"
#~ msgstr "Can not remove root user!"
@ -7389,9 +7421,6 @@ msgstr "XML Identifier"
#~ msgid "Macedonia"
#~ msgstr "F.Y.R.O.M."
#~ msgid "Addresses"
#~ msgstr "Διευθύνσεις"
#~ msgid "Records were modified in the meanwhile"
#~ msgstr "Οι εγγραφές έχουν τροποποιηθεί στο μεταξύ"
@ -7447,9 +7476,6 @@ msgstr "XML Identifier"
#~ msgid "This method does not exist anymore"
#~ msgstr "Αυτή η μέθοδος δε χρησιμοποιείται πια"
#~ msgid "File Content"
#~ msgstr "Περιεχόμενα Φακέλου"
#~ msgid "%A - Full weekday name."
#~ msgstr "%A - Πλήρες όνομα ημέρας εβδομάδας"
@ -7465,9 +7491,6 @@ msgstr "XML Identifier"
#~ msgid "Field %d should be a figure"
#~ msgstr "Το πεδίο %d πρέπει να έιναι αριθμός"
#~ msgid "Error ! You can not create recursive associated members."
#~ msgstr "Σφάλμα! Υπάρχει ήδη ίδια περιγραφή συνδεδεμένου μέλους."
#~ msgid "OpenERP Partners"
#~ msgstr "Συνεργάτες OpenERP "

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

10876
bin/addons/base/i18n/fi_FI.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

10859
bin/addons/base/i18n/id_ID.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ from osv.orm import except_orm
import tools
class ir_attachment(osv.osv):
def check(self, cr, uid, ids, mode):
def check(self, cr, uid, ids, mode, context=None):
if not ids:
return
ima = self.pool.get('ir.model.access')
@ -34,7 +34,7 @@ class ir_attachment(osv.osv):
cr.execute('select distinct res_model from ir_attachment where id in ('+','.join(map(str, ids))+')')
for obj in cr.fetchall():
if obj[0]:
ima.check(cr, uid, obj[0], mode)
ima.check(cr, uid, obj[0], mode, context=context)
def search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False):
@ -52,7 +52,7 @@ class ir_attachment(osv.osv):
if m['res_model']:
if m['res_model'] not in cache:
cache[m['res_model']] = ima.check(cr, uid, m['res_model'], 'read',
raise_exception=False)
raise_exception=False, context=context)
if not cache[m['res_model']]:
ids.remove(m['id'])
@ -60,26 +60,26 @@ class ir_attachment(osv.osv):
return len(ids)
return ids
def read(self, cr, uid, ids, *args, **kwargs):
self.check(cr, uid, ids, 'read')
return super(ir_attachment, self).read(cr, uid, ids, *args, **kwargs)
def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):
self.check(cr, uid, ids, 'read', context=context)
return super(ir_attachment, self).read(cr, uid, ids, fields_to_read, context, load)
def write(self, cr, uid, ids, *args, **kwargs):
self.check(cr, uid, ids, 'write')
return super(ir_attachment, self).write(cr, uid, ids, *args, **kwargs)
def write(self, cr, uid, ids, vals, context=None):
self.check(cr, uid, ids, 'write', context=context)
return super(ir_attachment, self).write(cr, uid, ids, vals, context)
def copy(self, cr, uid, id, *args, **kwargs):
self.check(cr, uid, [id], 'write')
return super(ir_attachment, self).copy(cr, uid, id, *args, **kwargs)
def copy(self, cr, uid, id, default=None, context=None):
self.check(cr, uid, [id], 'write', context=context)
return super(ir_attachment, self).copy(cr, uid, id, default, context)
def unlink(self, cr, uid, ids, *args, **kwargs):
self.check(cr, uid, ids, 'unlink')
return super(ir_attachment, self).unlink(cr, uid, ids, *args, **kwargs)
def unlink(self, cr, uid, ids, context=None):
self.check(cr, uid, ids, 'unlink', context=context)
return super(ir_attachment, self).unlink(cr, uid, ids, context)
def create(self, cr, uid, values, *args, **kwargs):
def create(self, cr, uid, values, context=None):
if 'res_model' in values and values['res_model'] != '':
self.pool.get('ir.model.access').check(cr, uid, values['res_model'], 'create')
return super(ir_attachment, self).create(cr, uid, values, *args, **kwargs)
self.pool.get('ir.model.access').check(cr, uid, values['res_model'], 'create', context=context)
return super(ir_attachment, self).create(cr, uid, values, context)
def action_get(self, cr, uid, context=None):
dataobj = self.pool.get('ir.model.data')

View File

@ -73,7 +73,7 @@ class ir_model(osv.osv):
def write(self, cr, user, ids, vals, context=None):
if context:
del context['__last_update']
context.pop('__last_update', None)
return super(ir_model,self).write(cr, user, ids, vals, context)
def create(self, cr, user, vals, context=None):
@ -229,6 +229,9 @@ class ir_model_fields(osv.osv):
'field_description': lambda *a: '',
}
_order = "id"
_sql_constraints = [
('size_gt_zero', 'CHECK (size>0)', 'Size of the field can never be less than 1 !'),
]
def unlink(self, cr, user, ids, context=None):
for field in self.browse(cr, user, ids, context):
if field.state <> 'manual':
@ -244,17 +247,18 @@ class ir_model_fields(osv.osv):
vals['model'] = model_data.model
if context and context.get('manual',False):
vals['state'] = 'manual'
res = super(ir_model_fields,self).create(cr, user, vals, context)
res = super(ir_model_fields,self).create(cr, user, vals, context)
if vals.get('state','base') == 'manual':
if not vals['name'].startswith('x_'):
raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !"))
if 'relation' in vals and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]):
raise except_orm(_('Error'), _("Model %s Does not Exist !" % vals['relation']))
if self.pool.get(vals['model']):
self.pool.get(vals['model']).__init__(self.pool, cr)
self.pool.get(vals['model'])._auto_init(cr, {})
return res
ir_model_fields()
@ -312,7 +316,7 @@ class ir_model_access(osv.osv):
# pass no groups -> no access
return False
def check(self, cr, uid, model, mode='read', raise_exception=True):
def check(self, cr, uid, model, mode='read', raise_exception=True, context=None):
if uid==1:
# User root have all accesses
# TODO: exclude xml-rpc requests
@ -400,7 +404,7 @@ ir_model_access()
class ir_model_data(osv.osv):
_name = 'ir.model.data'
_columns = {
'name': fields.char('XML Identifier', required=True, size=64),
'name': fields.char('XML Identifier', required=True, size=128),
'model': fields.char('Object', required=True, size=64),
'module': fields.char('Module', required=True, size=64),
'res_id': fields.integer('Resource ID'),

View File

@ -22,6 +22,7 @@
import time
from osv import fields,osv
import pooler
class ir_sequence_type(osv.osv):
_name = 'ir.sequence.type'
@ -69,13 +70,12 @@ class ir_sequence(osv.osv):
'sec': time.strftime('%S'),
}
def get_id(self, cr, uid, sequence_id, test='id=%s', context={}):
def get_id(self, cr, uid, sequence_id, test='id=%s', context=None):
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,))
cr.execute('SELECT id, number_next, prefix, suffix, padding FROM ir_sequence WHERE '+test+' AND active=%s FOR UPDATE', (sequence_id, True))
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'],))
cr.execute('UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s AND active=%s', (res['id'], True))
if res['number_next']:
return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix'])
else:

View File

@ -35,7 +35,7 @@ def _check_xml(self, cr, uid, ids, context={}):
if not relaxng.validate(eview):
logger = netsvc.Logger()
logger.notifyChannel('init', netsvc.LOG_ERROR, 'The view does not fit the required schema !')
logger.notifyChannel('init', netsvc.LOG_ERROR, relaxng.error_log.last_error)
logger.notifyChannel('init', netsvc.LOG_ERROR, tools.ustr(relaxng.error_log.last_error))
return False
return True

View File

@ -480,7 +480,7 @@ class module(osv.osv):
if not mod.description:
logger.notifyChannel("init", netsvc.LOG_WARNING, 'module %s: description is empty !' % (mod.name,))
if not mod.certificate:
if not mod.certificate or not mod.certificate.isdigit():
logger.notifyChannel('init', netsvc.LOG_WARNING, 'module %s: no quality certificate' % (mod.name,))
else:
val = long(mod.certificate[2:]) % 97 == 29

View File

@ -7,8 +7,10 @@
<xsl:variable name="rightMargin">1cm</xsl:variable>
<xsl:variable name="topMargin">1cm</xsl:variable>
<xsl:variable name="bottomMargin">1cm</xsl:variable>
<xsl:variable name="pageSize">29.7cm,21cm</xsl:variable>
<!--:variable name="pageSize">29.7cm,21cm</xsl:variable> Or use default width and height for frame -->
<xsl:variable name="pageSize">
<xsl:value-of select="/report/config/PageSize"/>
</xsl:variable>
<xsl:variable name="page_format">a4_letter</xsl:variable>
<xsl:template name="first_page_frames">

View File

@ -325,7 +325,10 @@ class res_partner_address(osv.osv):
if context.get('contact_display', 'contact')=='partner':
ids = self.search(cr, user, [('partner_id',operator,name)], limit=limit, context=context)
else:
ids = self.search(cr, user, [('zip','=',name)] + args, limit=limit, context=context)
if not name:
ids = self.search(cr, user, args, limit=limit, context=context)
else:
ids = self.search(cr, user, [('zip','=',name)] + args, limit=limit, context=context)
if not ids:
ids = self.search(cr, user, [('city',operator,name)] + args, limit=limit, context=context)
if name:

View File

@ -1,284 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * base_setup
#
# P. Christeas <p_christ@hol.gr>, 2009.
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-02-06 15:20:38+0000\n"
"PO-Revision-Date: 2009-06-09 02:47+0300\n"
"Last-Translator: P. Christeas <p_christ@hol.gr>\n"
"Language-Team: Greek <kde-i18n-doc@kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Lokalize 0.3\n"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,city:0
#: wizard_field:base_setup.base_setup,init,city:0
#: wizard_field:base_setup.base_setup,update,city:0
msgid "City"
msgstr "Πόλη"
#. module: base_setup
#: wizard_view:base_setup.base_setup,finish:0
msgid ""
"You can start configuring the system or connect directly to the database "
"using the default setup."
msgstr ""
"Μπορείτε να ξεκινήσετε τις ρυθμίσεις του συστήματος ή να συνδεθείτε απ' "
"ευθείας με τη βάση δεδομένων χρησιμοποιώντας προεπιλεγμένες ρυθμίσεις."
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,zip:0
#: wizard_field:base_setup.base_setup,init,zip:0
#: wizard_field:base_setup.base_setup,update,zip:0
msgid "Zip code"
msgstr "Ταχ. Κώδικας"
#. module: base_setup
#: wizard_view:base_setup.base_setup,init:0
msgid "Select a Profile"
msgstr "Επιλογή Προφίλ"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
msgid "Report header"
msgstr "Κεφαλίδα Αναφορών"
#. module: base_setup
#: wizard_button:base_setup.base_setup,finish,config:0
msgid "Start Configuration"
msgstr "Εκκίνηση Ρυθμίσεων"
#. module: base_setup
#: wizard_view:base_setup.base_setup,init:0
msgid ""
"You'll be able to install more modules later through the Administration menu."
msgstr ""
"θα μπορέσετε να εγκαταστήσετε περισσότερα αρθρώματα του προγράμματος "
"αργότερα, από το μενού της Διαχείρισης."
#. module: base_setup
#: wizard_view:base_setup.base_setup,init:0
msgid ""
"A profile sets a pre-selection of modules for specific needs. These profiles "
"have been setup to help you discover the different aspects of OpenERP. This "
"is just an overview, we have 300+ available modules."
msgstr ""
"Το προφίλ ορίζει μια προεπιλογή αρθρωμάτων για συγκεκριμένες ανάγκες. Αυτά "
"τα προφίλ έχουν δημιουργηθεί για να σας βοηθήσουν να ανακαλύψετε διαφορετικά "
"κομμάτια του OpenERP. Αυτό είναι μόνο μια γενική επισκόπηση, υπάρχουν πάνω "
"από 300 αρθρώματα του προγράμματος. "
#. module: base_setup
#: wizard_button:base_setup.base_setup,company,update:0
#: wizard_button:base_setup.base_setup,init,company:0
msgid "Next"
msgstr "Επόμενο"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,email:0
#: wizard_field:base_setup.base_setup,init,email:0
#: wizard_field:base_setup.base_setup,update,email:0
msgid "E-mail"
msgstr "E-mail"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,state_id:0
#: wizard_field:base_setup.base_setup,init,state_id:0
#: wizard_field:base_setup.base_setup,update,state_id:0
msgid "State"
msgstr ""
#. module: base_setup
#: wizard_view:base_setup.base_setup,finish:0
msgid "Your new database is now fully installed."
msgstr "Η νέα βάση δεδομένων σας εγκαταστάθηκε πλήρως."
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,profile:0
#: wizard_field:base_setup.base_setup,init,profile:0
#: wizard_field:base_setup.base_setup,update,profile:0
msgid "Profile"
msgstr "Προφίλ"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,rml_footer1:0
#: wizard_field:base_setup.base_setup,init,rml_footer1:0
#: wizard_field:base_setup.base_setup,update,rml_footer1:0
msgid "Report Footer 1"
msgstr "Υποσέλιδο Αναφορών 1"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,rml_footer2:0
#: wizard_field:base_setup.base_setup,init,rml_footer2:0
#: wizard_field:base_setup.base_setup,update,rml_footer2:0
msgid "Report Footer 2"
msgstr "Υποσέλιδο Αναφορών 2"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
msgid "General Information"
msgstr "Γενικές Πληροφορίες"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,street2:0
#: wizard_field:base_setup.base_setup,init,street2:0
#: wizard_field:base_setup.base_setup,update,street2:0
msgid "Street2"
msgstr "Οδός 2"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
msgid "Define Main Company"
msgstr "Ορισμός Κύριας Εταιρείας"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,phone:0
#: wizard_field:base_setup.base_setup,init,phone:0
#: wizard_field:base_setup.base_setup,update,phone:0
msgid "Phone"
msgstr "Τηλέφωνο"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
msgid "Report Information"
msgstr "Πληροφορίες Αναφορών"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,name:0
#: wizard_field:base_setup.base_setup,init,name:0
#: wizard_field:base_setup.base_setup,update,name:0
msgid "Company Name"
msgstr "Όνομα Εταιρείας"
#. module: base_setup
#: help:base_setup.base_setup,company,rml_footer2:0
#: help:base_setup.base_setup,init,rml_footer2:0
#: help:base_setup.base_setup,update,rml_footer2:0
msgid ""
"This sentence will appear at the bottom of your reports.\n"
"We suggest you to put bank information here:\n"
"IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701"
msgstr ""
"Αυτή η πρόταση θα εμφανίζεται στο κάτω μέρος των αναφορών σας.\n"
"Σας προτείνουμε να βάλετε εδώ τις οικονομικές πληροφορίες:\n"
"IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - ΑΦΜ: BE0477.472.701"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,country_id:0
#: wizard_field:base_setup.base_setup,init,country_id:0
#: wizard_field:base_setup.base_setup,update,country_id:0
msgid "Country"
msgstr "Χώρα"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
#: wizard_view:base_setup.base_setup,finish:0
#: wizard_view:base_setup.base_setup,init:0
#: wizard_view:base_setup.base_setup,update:0
#: model:ir.actions.wizard,name:base_setup.action_wizard_setup
#: model:ir.actions.wizard,name:base_setup.wizard_base_setup
msgid "Setup"
msgstr "Εγκατάσταση"
#. module: base_setup
#: help:base_setup.base_setup,company,rml_footer1:0
#: help:base_setup.base_setup,init,rml_footer1:0
#: help:base_setup.base_setup,update,rml_footer1:0
msgid ""
"This sentence will appear at the bottom of your reports.\n"
"We suggest you to write legal sentences here:\n"
"Web: http://openerp.com - Fax: +32.81.73.35.01 - Fortis Bank: 126-2013269-07"
msgstr ""
"Αυτή η πρόταση θα εμφανίζεται στο κάτω μέρος των αναφορών σας.\n"
"Σας προτείνουμε να βάλετε εδώ νομικές πληροφορίες:\n"
"Web: http://openerp.com - Fax: +32.81.73.35.01 - Fortis Bank: 126-2013269-07"
#. module: base_setup
#: wizard_view:base_setup.base_setup,update:0
msgid "Summary"
msgstr "Περίληψη"
#. module: base_setup
#: wizard_button:base_setup.base_setup,update,finish:0
msgid "Install"
msgstr "Εγκατάσταση"
#. module: base_setup
#: wizard_view:base_setup.base_setup,finish:0
msgid "Installation Done"
msgstr "Η Εγκατάσταση ολοκληρώθηκε"
#. module: base_setup
#: help:base_setup.base_setup,company,rml_header1:0
#: help:base_setup.base_setup,init,rml_header1:0
#: help:base_setup.base_setup,update,rml_header1:0
msgid ""
"This sentence will appear at the top right corner of your reports.\n"
"We suggest you to put a slogan here:\n"
"\"Open Source Business Solutions\"."
msgstr ""
"Αυτή η πρόταση θα εμφανίζεται στο πάνω δεξιά μέρος των αναφορών σας.\n"
"Σας προτείνουμε να βάλετε ένα σλόγκαν εδώ:\n"
"\"Open Source Business Solutions\"."
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,rml_header1:0
#: wizard_field:base_setup.base_setup,init,rml_header1:0
#: wizard_field:base_setup.base_setup,update,rml_header1:0
msgid "Report Header"
msgstr "Κεφαλίδα Αναφοράς"
#. module: base_setup
#: wizard_view:base_setup.base_setup,company:0
msgid "Your Logo - Use a size of about 450x150 pixels."
msgstr "Το λογότυπό σας: αρχείο μεγέθους 450x150 pixels."
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,currency:0
#: wizard_field:base_setup.base_setup,init,currency:0
#: wizard_field:base_setup.base_setup,update,currency:0
msgid "Currency"
msgstr "Νόμισμα"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,street:0
#: wizard_field:base_setup.base_setup,init,street:0
#: wizard_field:base_setup.base_setup,update,street:0
msgid "Street"
msgstr "Οδός"
#. module: base_setup
#: wizard_button:base_setup.base_setup,finish,menu:0
msgid "Use Directly"
msgstr "Άμεση Χρήση "
#. module: base_setup
#: wizard_button:base_setup.base_setup,init,menu:0
msgid "Cancel"
msgstr "Ακύρωση"
#. module: base_setup
#: wizard_field:base_setup.base_setup,company,logo:0
#: wizard_field:base_setup.base_setup,init,logo:0
#: wizard_field:base_setup.base_setup,update,logo:0
msgid "Logo"
msgstr "Λογότυπο"
#. module: base_setup
#: model:ir.module.module,shortdesc:base_setup.module_meta_information
msgid "Base Setup"
msgstr "Εγκατάσταση Βασικών Ρυθμίσεων"
#. module: base_setup
#: wizard_button:base_setup.base_setup,company,init:0
#: wizard_button:base_setup.base_setup,update,company:0
msgid "Previous"
msgstr "Προηγούμενο"

View File

@ -0,0 +1,311 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import xmlrpclib
import ConfigParser
import optparse
import sys
import thread
import threading
import os
import time
import pickle
import base64
import socket
admin_passwd = 'admin'
waittime = 10
def start_server(root_path, port, addons_path):
if root_path:
root_path += '/'
os.system('python2.5 '+root_path+'openerp-server.py --pidfile=openerp.pid --port=%s --no-netrpc --addons-path=%s' %(str(port),addons_path))
def clean():
if os.path.isfile('openerp.pid'):
ps = open('openerp.pid')
if ps:
pid = int(ps.read())
ps.close()
if pid:
os.kill(pid,9)
def execute(connector, method, *args):
res = False
try:
res = getattr(connector,method)(*args)
except socket.error,e:
if e.args[0] == 111:
print 'Please wait %d sec to start server....'%(waittime)
time.sleep(waittime)
res = execute(connector, method, *args)
else:
raise e
return res
def login(uri, dbname, user, pwd):
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/common')
uid = execute(conn,'login',dbname, user, pwd)
return uid
def import_translate(uri, user, pwd, dbname, translate_in):
uid = login(uri, dbname, user, pwd)
if uid:
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
wiz_id = execute(conn,'create',dbname, uid, pwd, 'module.lang.import')
for trans_in in translate_in:
lang,ext = os.path.splitext(trans_in.split('/')[-1])
state = 'init'
datas = {'form':{}}
while state!='end':
res = execute(conn,'execute',dbname, uid, pwd, wiz_id, datas, state, {})
if 'datas' in res:
datas['form'].update( res['datas'].get('form',{}) )
if res['type']=='form':
for field in res['fields'].keys():
datas['form'][field] = res['fields'][field].get('value', False)
state = res['state'][-1][0]
trans_obj = open(trans_in)
datas['form'].update({
'name': lang,
'code': lang,
'data' : base64.encodestring(trans_obj.read())
})
trans_obj.close()
elif res['type']=='action':
state = res['state']
def check_quality(uri, user, pwd, dbname, modules):
uid = login(uri, dbname, user, pwd)
if uid:
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
qualityresult = {}
final = {}
test_detail = {}
for module in modules:
quality_result = execute(conn,'execute', dbname, uid, pwd,'module.quality.check','check_quality',module)
detail_html = ''
html = '''<html><html><html><html><body><a name="TOP"></a>'''
html +="<h1> Module : %s </h1>"%(quality_result['name'])
html += "<h2> Final score : %s</h2>"%(quality_result['final_score'])
html += "<oi>"
for x,y,detail in quality_result['check_detail_ids']:
if detail.get('detail') != '':
test = detail.get('name')
score = round(float(detail.get('score',0)),2)
html += "<li><a href=\"#%s\">%s (%.2f)</a></li>"%(test,test,score)
detail_html +="<a name=\"%s\"><h3>%s (Score : %s)</h3>%s</a>"%(test,test,score,detail.get('detail'))
detail_html +='''<a href="#TOP">Go to Top</a>'''
test_detail[test] = (score,detail.get('detail',''))
html += "</oi>%s</body></html></html></html></html></html>"%(detail_html)
final[quality_result['name']] = (quality_result['final_score'],html,test_detail)
fp = open('quality_log.pck','wb')
pck_obj = pickle.dump(final,fp)
fp.close()
print "LOG PATH%s"%(os.path.realpath('quality_log.pck'))
return final
else:
print 'Login Failed...'
clean()
sys.exit(1)
def wait(id,url=''):
progress=0.0
sock2 = xmlrpclib.ServerProxy(url+'/db')
while not progress==1.0:
progress,users = execute(sock2,'get_progress',admin_passwd, id)
return True
def create_db(uri, dbname, user='admin', pwd='admin', lang='en_US'):
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/db')
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
wiz_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
login_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/common')
db_list = execute(conn, 'list')
if dbname not in db_list:
id = execute(conn,'create',admin_passwd, dbname, True, lang)
wait(id,uri)
uid = login_conn.login(dbname, user, pwd)
wiz_id = execute(wiz_conn,'create', dbname, uid, user, 'base_setup.base_setup')
state = 'init'
datas = {'form':{}}
while state!='config':
res = execute(wiz_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
if state=='init':
datas['form'].update( res['datas'] )
if res['type']=='form':
for field in res['fields'].keys():
datas['form'][field] = datas['form'].get(field,False)
state = res['state'][-1][0]
datas['form'].update({
'profile': -1
})
elif res['type']=='state':
state = res['state']
res = execute(wiz_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
install_module(uri, dbname, ['base_module_quality'],user,pwd)
return True
def drop_db(uri, dbname):
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/db')
db_list = execute(conn,'list')
if dbname in db_list:
execute(conn, 'drop', admin_passwd, dbname)
return True
def install_module(uri, dbname, modules, user='admin', pwd='admin'):
uid = login(uri, dbname, user, pwd)
if uid:
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
wizard_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','in',modules)])
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_install', module_ids)
wiz_id = execute(wizard_conn, 'create', dbname, uid, pwd, 'module.upgrade.simple')
state = 'init'
datas = {}
#while state!='menu':
while state!='end':
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
if state == 'init':
state = 'start'
elif state == 'start':
state = 'end'
return True
def upgrade_module(uri, dbname, modules, user='admin', pwd='admin'):
uid = login(uri, dbname, user, pwd)
if uid:
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
wizard_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','in',modules)])
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_upgrade', module_ids)
wiz_id = execute(wizard_conn, 'create', dbname, uid, pwd, 'module.upgrade.simple')
state = 'init'
datas = {}
#while state!='menu':
while state!='end':
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
if state == 'init':
state = 'start'
elif state == 'start':
state = 'end'
return True
usage = """%prog command [options]
Basic Commands:
start-server Start Server
create-db Create new database
drop-db Drop database
install-module Install module
upgrade-module Upgrade module
install-translation Install translation file
check-quality Calculate quality and dump quality result into quality_log.pck using pickle
"""
parser = optparse.OptionParser(usage)
parser.add_option("--modules", dest="modules",
help="specify modules to install or check quality")
parser.add_option("--addons-path", dest="addons_path", help="specify the addons path")
parser.add_option("--root-path", dest="root_path", help="specify the root path")
parser.add_option("-p", "--port", dest="port", help="specify the TCP port", type="int")
parser.add_option("-d", "--database", dest="db_name", help="specify the database name")
parser.add_option("--login", dest="login", help="specify the User Login")
parser.add_option("--password", dest="pwd", help="specify the User Password")
parser.add_option("--translate-in", dest="translate_in",
help="specify .po files to import translation terms")
(opt, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
command = args[0]
if command not in ('start-server','create-db','drop-db','install-module','upgrade-module','check-quality','install-translation'):
parser.error("incorrect command")
def die(cond, msg):
if cond:
print msg
sys.exit(1)
die(opt.modules and (not opt.db_name),
"the modules option cannot be used without the database (-d) option")
die(opt.translate_in and (not opt.db_name),
"the translate-in option cannot be used without the database (-d) option")
options = {
'addons-path' : opt.addons_path or 'addons',
'root-path' : opt.root_path or '',
'translate-in': opt.translate_in,
'port' : opt.port or 8069,
'database': opt.db_name or 'terp',
'modules' : opt.modules or [],
'login' : opt.login or 'admin',
'pwd' : opt.pwd or '',
}
options['modules'] = opt.modules and map(lambda m: m.strip(), opt.modules.split(',')) or []
options['translate_in'] = opt.translate_in and map(lambda m: m.strip(), opt.translate_in.split(',')) or []
uri = 'http://localhost:' + str(options['port'])
server_thread = threading.Thread(target=start_server,
args=(options['root-path'], options['port'], options['addons-path']))
try:
server_thread.start()
if command == 'create-db':
create_db(uri, options['database'], options['login'], options['pwd'])
if command == 'drop-db':
drop_db(uri, options['database'])
if command == 'install-module':
install_module(uri, options['database'], options['modules'], options['login'], options['pwd'])
if command == 'upgrade-module':
upgrade_module(uri, options['database'], options['modules'], options['login'], options['pwd'])
if command == 'check-quality':
check_quality(uri, options['login'], options['pwd'], options['database'], options['modules'])
if command == 'install-translation':
import_translate(uri, options['login'], options['pwd'], options['database'], options['translate_in'])
clean()
sys.exit(0)
except xmlrpclib.Fault, e:
print e.faultString
clean()
sys.exit(1)
except Exception, e:
print e
clean()
sys.exit(1)

View File

@ -24,7 +24,6 @@
#
##############################################################################
import SimpleXMLRPCServer
import SocketServer
import logging
@ -79,13 +78,15 @@ def service_exist(name):
LOG_NOTSET = 'notset'
LOG_DEBUG_RPC = 'debug_rpc'
LOG_DEBUG = 'debug'
LOG_DEBUG2 = 'debug2'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'
# add new log level below DEBUG
logging.DEBUG_RPC = logging.DEBUG - 1
logging.DEBUG2 = logging.DEBUG - 1
logging.DEBUG_RPC = logging.DEBUG2 - 1
def init_logger():
import os
@ -121,7 +122,7 @@ def init_logger():
handler = logging.handlers.FileHandler(logf)
except Exception, ex:
sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n")
handler = logging.StreamHandler(sys.stdout)
handler = logging.StreamHandler(sys.stdout)
else:
# Normal Handler on standard output
handler = logging.StreamHandler(sys.stdout)
@ -145,6 +146,7 @@ def init_logger():
mapping = {
'DEBUG_RPC': ('blue', 'white'),
'DEBUG2': ('green', 'white'),
'DEBUG': ('blue', 'default'),
'INFO': ('green', 'default'),
'WARNING': ('yellow', 'default'),
@ -158,9 +160,16 @@ def init_logger():
class Logger(object):
def notifyChannel(self, name, level, msg):
from service.web_services import common
log = logging.getLogger(tools.ustr(name))
if level == LOG_DEBUG2 and not hasattr(log, level):
fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG2, msg, *args, **kwargs)
setattr(log, LOG_DEBUG2, fct)
if level == LOG_DEBUG_RPC and not hasattr(log, level):
fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG_RPC, msg, *args, **kwargs)
setattr(log, LOG_DEBUG_RPC, fct)
@ -171,7 +180,11 @@ class Logger(object):
msg = tools.exception_to_unicode(msg)
try:
result = tools.ustr(msg).strip().split('\n')
msg = tools.ustr(msg).strip()
if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',True):
msg = common().get_server_environment() + msg
result = msg.split('\n')
except UnicodeDecodeError:
result = msg.strip().split('\n')
try:
@ -188,6 +201,12 @@ class Logger(object):
# better ignore the exception and carry on..
pass
def set_loglevel(self, level):
log = logging.getLogger()
log.setLevel(logging.INFO) # make sure next msg is printed
log.info("Log level changed to %s" % logging.getLevelName(level))
log.setLevel(level)
def shutdown(self):
logging.shutdown()
@ -201,7 +220,7 @@ class Agent(object):
def setAlarm(self, fn, dt, db_name, *args, **kwargs):
wait = dt - time.time()
if wait > 0:
self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %s seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %.3g seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
timer = threading.Timer(wait, fn, args, kwargs)
timer.start()
self._timers.setdefault(db_name, []).append(timer)
@ -210,7 +229,7 @@ class Agent(object):
for timer in self._timers[db]:
if not timer.isAlive():
self._timers[db].remove(timer)
@classmethod
def cancel(cls, db_name):
"""Cancel all timers for a given database. If None passed, all timers are cancelled"""
@ -218,7 +237,7 @@ class Agent(object):
if db_name is None or db == db_name:
for timer in cls._timers[db]:
timer.cancel()
@classmethod
def quit(cls):
cls.cancel(None)

0
bin/openerp-server.py Normal file → Executable file
View File

View File

@ -103,14 +103,23 @@ class expression(object):
left, operator, right = e
working_table = table
if left in table._inherit_fields:
working_table = table.pool.get(table._inherit_fields[left][0])
if working_table not in self.__tables.values():
self.__joins.append(('%s.%s=%s.%s' % (working_table._table, 'id', table._table, table._inherits[working_table._name]), working_table._table))
self.__tables[i] = working_table
main_table = table
fargs = left.split('.', 1)
index = i
if left in table._inherit_fields:
while True:
field = main_table._columns.get(fargs[0], False)
if field:
working_table = main_table
self.__tables[i] = working_table
break
working_table = main_table.pool.get(main_table._inherit_fields[left][0])
if working_table not in self.__tables.values():
self.__joins.append(('%s.%s=%s.%s' % (working_table._table, 'id', main_table._table, main_table._inherits[working_table._name]), working_table._table))
self.__tables[index] = working_table
index += 1
main_table = working_table
field = working_table._columns.get(fargs[0], False)
if not field:
if left == 'id' and operator == 'child_of':
@ -198,10 +207,22 @@ class expression(object):
self.__exp[i] = (left, 'in', right)
else:
# other field type
# add the time part to datetime field when it's not there:
if field._type == 'datetime' and self.__exp[i][2] and len(self.__exp[i][2]) == 10:
self.__exp[i] = list(self.__exp[i])
if operator in ('>', '>='):
self.__exp[i][2] += ' 00:00:00'
elif operator in ('<', '<='):
self.__exp[i][2] += ' 23:59:59'
self.__exp[i] = tuple(self.__exp[i])
if field.translate:
if operator in ('like', 'ilike', 'not like', 'not ilike'):
right = '%%%s%%' % right
operator = operator == '=like' and 'like' or operator
query1 = '( SELECT res_id' \
@ -224,7 +245,7 @@ class expression(object):
' SELECT id' \
' FROM "' + working_table._table + '"' \
' WHERE "' + left + '" ' + operator + instr + ")"
query2 = [working_table._name + ',' + left,
context.get('lang', False) or 'en_US',
'model',

View File

@ -53,6 +53,7 @@ def _symbol_set(symb):
class _column(object):
_classic_read = True
_classic_write = True
_prefetch = True
_properties = False
_type = 'unknown'
_obj = None
@ -196,6 +197,7 @@ class binary(_column):
_symbol_get = lambda self, x: x and str(x)
_classic_read = False
_prefetch = False
def __init__(self, string='unknown', filters=None, **args):
_column.__init__(self, string=string, **args)
@ -350,6 +352,7 @@ class many2one(_column):
class one2many(_column):
_classic_read = False
_classic_write = False
_prefetch = False
_type = 'one2many'
def __init__(self, obj, fields_id, string='unknown', limit=None, **args):
@ -426,11 +429,13 @@ class one2many(_column):
return res
def set(self, cr, obj, id, field, values, user=None, context=None):
result = []
if not context:
context = {}
if self._context:
context = context.copy()
context.update(self._context)
context['no_store_function'] = True
if not values:
return
_table = obj.pool.get(self._obj)._table
@ -438,7 +443,8 @@ class one2many(_column):
for act in values:
if act[0] == 0:
act[2][self._fields_id] = id
obj.create(cr, user, act[2], context=context)
id_new = obj.create(cr, user, act[2], context=context)
result += obj._store_get_values(cr, user, [id_new], act[2].keys(), context)
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
@ -455,6 +461,7 @@ class one2many(_column):
cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id not in ('+','.join(map(str, ids2))+')', (id,))
ids3 = map(lambda x:x[0], cr.fetchall())
obj.write(cr, user, ids3, {self._fields_id:False}, context=context or {})
return result
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
return obj.pool.get(self._obj).name_search(cr, uid, value, self._domain, offset, limit)
@ -472,6 +479,7 @@ class one2many(_column):
class many2many(_column):
_classic_read = False
_classic_write = False
_prefetch = False
_type = 'many2many'
def __init__(self, obj, rel, id1, id2, string='unknown', limit=None, **args):
@ -582,6 +590,7 @@ class many2many(_column):
class function(_column):
_classic_read = False
_classic_write = False
_prefetch = False
_type = 'function'
_properties = True
@ -827,15 +836,18 @@ class property(function):
int(prop.value.split(',')[1])) or False
obj = obj.pool.get(self._obj)
existing_ids = obj.search(cr, uid, [('id','in',res.values())])
deleted_ids = []
for res_id in res.values():
if res_id and (res_id not in existing_ids):
if res_id not in deleted_ids:
cr.execute('DELETE FROM ir_property WHERE value=%s', ((obj._name+','+str(res_id)),))
deleted_ids.append(res_id)
names = dict(obj.name_get(cr, uid, filter(None, res.values()), context))
to_check = res.values()
if default_val and default_val not in to_check:
to_check += [default_val]
existing_ids = obj.search(cr, uid, [('id', 'in', to_check)])
for id, res_id in res.items():
if res_id not in existing_ids:
cr.execute('DELETE FROM ir_property WHERE value=%s', ((obj._name+','+str(res_id)),))
res[id] = default_val
names = dict(obj.name_get(cr, uid, existing_ids, context))
for r in res.keys():
if res[r] and res[r] in names:
res[r] = (res[r], names[res[r]])

View File

@ -174,7 +174,7 @@ class browse_record(object):
return None
# if the field is a classic one or a many2one, we'll fetch all classic and many2one fields
if col._classic_write:
if col._prefetch:
# gen the list of "local" (ie not inherited) fields which are classic or many2one
ffields = filter(lambda x: x[1]._classic_write, self._table._columns.items())
# gen the list of inherited fields
@ -390,8 +390,12 @@ class orm_template(object):
vals['select_level']
))
if 'module' in context:
name1 = 'field_' + self._table + '_' + k
cr.execute("select name from ir_model_data where name=%s", (name1,))
if cr.fetchone():
name1 = name1 + "_" + str(id)
cr.execute("INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), %s, %s, %s)", \
(('field_'+self._table+'_'+k)[:64], context['module'], 'ir.model.fields', id)
(name1, context['module'], 'ir.model.fields', id)
)
else:
for key, val in vals.items():
@ -443,32 +447,45 @@ class orm_template(object):
def __export_row(self, cr, uid, row, fields, context=None):
def check_type(type,r):
if type == 'float':
def check_type(field_type):
if field_type == 'float':
return 0.0
elif type == 'integer':
elif field_type == 'integer':
return 0
elif type == 'char':
return ''
return r
elif field_type == 'boolean':
return False
return ''
lines = []
data = map(lambda x: '', range(len(fields)))
done = []
for fpos in range(len(fields)):
f = fields[fpos]
f = fields[fpos]
if f:
r = row
i = 0
while i < len(f):
r = r[f[i]]
if f[i] == 'db_id':
r = r['id']
elif f[i] == 'id':
model_data = self.pool.get('ir.model.data')
data_ids = model_data.search(cr, uid, [('model','=',r._table_name),('res_id','=',r['id'])])
if len(data_ids):
d = model_data.read(cr, uid, data_ids, ['name','module'])[0]
if d['module']:
r = '%s.%s'%(d['module'],d['name'])
else:
r = d['name']
else:
break
else:
r = r[f[i]]
if not r:
if f[i] in self._columns:
r = check_type(self._columns[f[i]]._type,r)
r = check_type(self._columns[f[i]]._type)
elif f[i] in self._inherit_fields:
r = check_type(self._inherit_fields[f[i]][2]._type,r)
data[fpos] = tools.ustr(r)
r = check_type(self._inherit_fields[f[i]][2]._type)
data[fpos] = r
break
if isinstance(r, (browse_record_list, list)):
first = True
@ -476,56 +493,89 @@ class orm_template(object):
or [], fields)
if fields2 in done:
break
done.append(fields2)
done.append(fields2)
for row2 in r:
lines2 = self.__export_row(cr, uid, row2, fields2,
context)
context)
if first:
for fpos2 in range(len(fields)):
if lines2 and lines2[0][fpos2]:
data[fpos2] = lines2[0][fpos2]
if not data[fpos]:
dt = ''
for rr in r :
if isinstance(rr.name, browse_record):
rr = rr.name
dt+=rr.name+','
data[fpos] = dt[:-1]
break
lines += lines2[1:]
first = False
else:
lines += lines2
lines += lines2
break
i += 1
if i == len(f):
if isinstance(r, browse_record):
r = r.name
data[fpos] = tools.ustr(r or '')
return [data] + lines
def export_data(self, cr, uid, ids, fields, context=None):
def export_data(self, cr, uid, ids, fields_to_export, context=None):
if not context:
context = {}
fields = map(lambda x: x.split('/'), fields)
imp_comp = context.get('import_comp',False)
cols = self._columns.copy()
for f in self._inherit_fields:
cols.update({f: self._inherit_fields[f][2]})
fields_to_export = map(lambda x: x.split('/'), fields_to_export)
fields_export = fields_to_export+[]
warning = ''
warning_fields = []
for field in fields_export:
if imp_comp and len(field)>1:
warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field)))
elif len (field) <=1:
if imp_comp and cols.get(field and field[0],False):
if ((isinstance(cols[field[0]], fields.function) and not cols[field[0]].store) \
or isinstance(cols[field[0]], fields.related)\
or isinstance(cols[field[0]], fields.one2many)):
warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field)))
datas = []
if imp_comp and len(warning_fields):
warning = 'Following columns cannot be exported since you select to be import compatible.\n%s' %('\n'.join(warning_fields))
cr.rollback()
return {'warning' : warning}
for row in self.browse(cr, uid, ids, context):
datas += self.__export_row(cr, uid, row, fields, context)
return datas
datas += self.__export_row(cr, uid, row, fields_to_export, context)
return {'datas':datas}
def import_data(self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None):
if not context:
context = {}
fields = map(lambda x: x.split('/'), fields)
logger = netsvc.Logger()
def process_liness(self, datas, prefix, fields_def, position=0):
ir_model_data_obj = self.pool.get('ir.model.data')
def process_liness(self, datas, prefix, current_module, model_name, fields_def, position=0):
line = datas[position]
row = {}
translate = {}
todo = []
warning = ''
data_id = False
data_res_id = False
is_xml_id = False
is_db_id = False
ir_model_data_obj = self.pool.get('ir.model.data')
#
# Import normal fields
#
for i in range(len(fields)):
if i >= len(line):
raise Exception(_('Please check that all your lines have %d columns.') % (len(fields),))
field = fields[i]
if field == ["id"]:
data_id = line[i]
if not line[i]:
continue
field = fields[i]
if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':id'):
res_id = False
if line[i]:
@ -535,8 +585,7 @@ class orm_template(object):
if '.' in word:
module, xml_id = word.rsplit('.', 1)
else:
module, xml_id = current_module, word
ir_model_data_obj = self.pool.get('ir.model.data')
module, xml_id = current_module, word
id = ir_model_data_obj._get_id(cr, uid, module,
xml_id)
res_id2 = ir_model_data_obj.read(cr, uid, [id],
@ -549,8 +598,7 @@ class orm_template(object):
if '.' in line[i]:
module, xml_id = line[i].rsplit('.', 1)
else:
module, xml_id = current_module, line[i]
ir_model_data_obj = self.pool.get('ir.model.data')
module, xml_id = current_module, line[i]
id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
res_res_id = ir_model_data_obj.read(cr, uid, [id],
['res_id'])
@ -565,10 +613,67 @@ class orm_template(object):
continue
if (len(field) == len(prefix)+1) and \
(prefix == field[0:len(prefix)]):
if field[len(prefix)] == "id":
# XML ID
db_id = False
is_xml_id = data_id = line[i]
d = data_id.split('.')
module = len(d)>1 and d[0] or ''
name = len(d)>1 and d[1] or d[0]
data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('name','=',name)])
if len(data_ids):
d = ir_model_data_obj.read(cr, uid, data_ids, ['res_id'])[0]
db_id = d['res_id']
if is_db_id and not db_id:
data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('res_id','=',is_db_id)])
if not len(data_ids):
ir_model_data_obj.create(cr, uid, {'module':module, 'model':model_name, 'name':name, 'res_id':is_db_id})
db_id = is_db_id
if is_db_id and int(db_id) != int(is_db_id):
warning += ("Id is not the same than existing one: " + str(is_db_id) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Id is not the same than existing one: " + str(is_db_id) + ' !\n')
continue
if field[len(prefix)] == "db_id":
# Database ID
try:
line[i]= int(line[i])
except Exception, e:
warning += (str(e) + "!\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
str(e) + '!\n')
continue
is_db_id = line[i]
obj_model = self.pool.get(model_name)
ids = obj_model.search(cr, uid, [('id','=',line[i])])
if not len(ids):
warning += ("Database ID doesn't exist: " + model_name + ": " + str(line[i]) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Database ID doesn't exist: " + model_name + ": " + str(line[i]) + ' !\n')
continue
else:
data_res_id = ids[0]
data_ids = ir_model_data_obj.search(cr, uid, [('model','=',model_name),('res_id','=',line[i])])
if len(data_ids):
d = ir_model_data_obj.read(cr, uid, data_ids, ['name','module'])[0]
data_id = d['name']
if d['module']:
data_id = '%s.%s'%(d['module'],d['name'])
else:
data_id = d['name']
if is_xml_id and not data_id:
data_id = is_xml_id
if is_xml_id and is_xml_id!=data_id:
warning += ("Id is not the same than existing one: " + str(line[i]) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Id is not the same than existing one: " + str(line[i]) + ' !\n')
continue
if fields_def[field[len(prefix)]]['type'] == 'integer':
res = line[i] and int(line[i])
elif fields_def[field[len(prefix)]]['type'] == 'boolean':
res = line[i] and eval(line[i])
res = line[i].lower() not in ('0', 'false', 'off')
elif fields_def[field[len(prefix)]]['type'] == 'float':
res = line[i] and float(line[i])
elif fields_def[field[len(prefix)]]['type'] == 'selection':
@ -580,18 +685,22 @@ class orm_template(object):
sel = fields_def[field[len(prefix)]]['selection'](self,
cr, uid, context)
for key, val in sel:
if str(key) == line[i]:
if line[i] in [tools.ustr(key),tools.ustr(val)]: #Acepting key or value for selection field
res = key
break
if line[i] and not res:
logger.notifyChannel("import", netsvc.LOG_WARNING,
"key '%s' not found in selection field '%s'" % \
(line[i], field[len(prefix)]))
warning += "Key/value '"+ str(line[i]) +"' not found in selection field '"+str(field[len(prefix)])+"'"
elif fields_def[field[len(prefix)]]['type']=='many2one':
res = False
if line[i]:
relation = fields_def[field[len(prefix)]]['relation']
res2 = self.pool.get(relation).name_search(cr, uid,
line[i], [], operator='=')
line[i], [], operator='=', context=context)
res = (res2 and res2[0][0]) or False
if not res:
warning += ('Relation not found: ' + line[i] + \
@ -605,7 +714,7 @@ class orm_template(object):
relation = fields_def[field[len(prefix)]]['relation']
for word in line[i].split(config.get('csv_internal_sep')):
res2 = self.pool.get(relation).name_search(cr,
uid, word, [], operator='=')
uid, word, [], operator='=', context=context)
res3 = (res2 and res2[0][0]) or False
if not res3:
warning += ('Relation not found: ' + \
@ -625,19 +734,20 @@ class orm_template(object):
if field[0] not in todo:
todo.append(field[len(prefix)])
#
# Import one2many fields
# Import one2many, many2many fields
#
nbrmax = 1
for field in todo:
newfd = self.pool.get(fields_def[field]['relation']).fields_get(
relation_obj = self.pool.get(fields_def[field]['relation'])
newfd = relation_obj.fields_get(
cr, uid, context=context)
res = process_liness(self, datas, prefix + [field], newfd, position)
(newrow, max2, w2, translate2, data_id2) = res
res = process_liness(self, datas, prefix + [field], current_module, relation_obj._name, newfd, position)
(newrow, max2, w2, translate2, data_id2, data_res_id2) = res
nbrmax = max(nbrmax, max2)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \
[(0, 0, newrow)]) or []
[(0, 0, newrow)]) or []
i = max2
while (position+i)<len(datas):
ok = True
@ -648,11 +758,11 @@ class orm_template(object):
if not ok:
break
(newrow, max2, w2, translate2, data_id2) = process_liness(
self, datas, prefix+[field], newfd, position+i)
(newrow, max2, w2, translate2, data_id2, data_res_id2) = process_liness(
self, datas, prefix+[field], current_module, relation_obj._name, newfd, position+i)
warning = warning+w2
if reduce(lambda x, y: x or y, newrow.values()):
row[field].append((0, 0, newrow))
row[field].append((0, 0, newrow))
i += max2
nbrmax = max(nbrmax, i)
@ -660,7 +770,7 @@ class orm_template(object):
for i in range(max(nbrmax, 1)):
#if datas:
datas.pop(0)
result = (row, nbrmax, warning, translate, data_id)
result = (row, nbrmax, warning, translate, data_id, data_res_id)
return result
fields_def = self.fields_get(cr, uid, context=context)
@ -675,16 +785,16 @@ class orm_template(object):
counter += 1
res = {}
#try:
(res, other, warning, translate, data_id) = \
process_liness(self, datas, [], fields_def)
if warning:
(res, other, warning, translate, data_id, res_id) = \
process_liness(self, datas, [], current_module, self._name, fields_def)
if warning:
cr.rollback()
return (-1, res, warning, '')
return (-1, res, 'Line ' + str(counter) +' : ' + warning, '')
try:
id = self.pool.get('ir.model.data')._update(cr, uid, self._name,
id = ir_model_data_obj._update(cr, uid, self._name,
current_module, res, xml_id=data_id, mode=mode,
noupdate=noupdate)
noupdate=noupdate, res_id=res_id)
except Exception, e:
import psycopg2
if isinstance(e,psycopg2.IntegrityError):
@ -693,7 +803,7 @@ class orm_template(object):
if key in e[0]:
msg = self.pool._sql_error[key]
break
return (-1, res,msg,'' )
return (-1, res,'Line ' + str(counter) +' : ' + msg,'' )
for lang in translate:
context2 = context.copy()
@ -1223,7 +1333,7 @@ class orm_template(object):
def read_string(self, cr, uid, id, langs, fields=None, context=None):
res = {}
res2 = {}
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'read')
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'read', context=context)
if not fields:
fields = self._columns.keys() + self._inherit_fields.keys()
#FIXME: collect all calls to _get_source into one SQL call.
@ -1247,7 +1357,7 @@ class orm_template(object):
return res
def write_string(self, cr, uid, id, langs, vals, context=None):
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'write')
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'write', context=context)
#FIXME: try to only call the translation in one SQL
for lang in langs:
for field in vals:
@ -1337,10 +1447,10 @@ class orm_memory(orm_template):
self._validate(cr, user, [id_new], context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_write(user, self._name, id_new, cr)
self.vaccum(cr, user)
return id_new
def create(self, cr, user, vals, context=None):
self.vaccum(cr, user)
self.next_id += 1
id_new = self.next_id
default = []
@ -1364,7 +1474,6 @@ class orm_memory(orm_template):
self._validate(cr, user, [id_new], context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_create(user, self._name, id_new, cr)
self.vaccum(cr, user)
return id_new
def default_get(self, cr, uid, fields_list, context=None):
@ -1949,13 +2058,15 @@ class orm(orm_template):
self._inherits_reload_src()
def fields_get(self, cr, user, fields=None, context=None):
read_access = self.pool.get('ir.model.access').check(cr, user, self._name, 'write', raise_exception=False)
ira = self.pool.get('ir.model.access')
read_access = ira.check(cr, user, self._name, 'write', raise_exception=False, context=context) or \
ira.check(cr, user, self._name, 'create', raise_exception=False, context=context)
return super(orm, self).fields_get(cr, user, fields, context, read_access)
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
if not context:
context = {}
self.pool.get('ir.model.access').check(cr, user, self._name, 'read')
self.pool.get('ir.model.access').check(cr, user, self._name, 'read', context=context)
if not fields:
fields = self._columns.keys() + self._inherit_fields.keys()
select = ids
@ -2171,11 +2282,18 @@ class orm(orm_template):
self._check_concurrency(cr, ids, context)
self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink')
self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink', context=context)
properties = self.pool.get('ir.property')
domain = [('res_id', '=', False),
('value', 'in', ['%s,%s' % (self._name, i) for i in ids]),
]
if properties.search(cr, uid, domain, context=context):
raise except_orm(_('Error'), _('Unable to delete this document because it is used as a default property'))
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_delete(uid, self._name, id, cr)
for oid in ids:
wf_service.trg_delete(uid, self._name, oid, cr)
#cr.execute('select * from '+self._table+' where id in ('+str_d+')', ids)
#res = cr.dictfetchall()
@ -2193,7 +2311,7 @@ class orm(orm_template):
if d1:
cr.execute('SELECT id FROM "'+self._table+'" ' \
'WHERE id IN ('+str_d+')'+d1, sub_ids+d2)
if not cr.rowcount == len({}.fromkeys(ids)):
if not cr.rowcount == len(sub_ids):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule (Document type: %s).') % \
self._description)
@ -2205,13 +2323,13 @@ class orm(orm_template):
cr.execute('delete from "'+self._table+'" ' \
'where id in ('+str_d+')', sub_ids)
for order, object, ids, fields in result_store:
for order, object, store_ids, fields in result_store:
if object<>self._name:
obj = self.pool.get(object)
cr.execute('select id from '+obj._table+' where id in ('+','.join(map(str, ids))+')')
ids = map(lambda x: x[0], cr.fetchall())
if ids:
obj._store_set_values(cr, uid, ids, fields, context)
cr.execute('select id from '+obj._table+' where id in ('+','.join(map(str, store_ids))+')')
rids = map(lambda x: x[0], cr.fetchall())
if rids:
obj._store_set_values(cr, uid, rids, fields, context)
return True
#
@ -2248,6 +2366,7 @@ class orm(orm_template):
if not edit:
vals.pop(field)
if not context:
context = {}
if not ids:
@ -2257,7 +2376,8 @@ class orm(orm_template):
self._check_concurrency(cr, ids, context)
self.pool.get('ir.model.access').check(cr, user, self._name, 'write')
self.pool.get('ir.model.access').check(cr, user, self._name, 'write', context=context)
upd0 = []
upd1 = []
@ -2336,10 +2456,11 @@ class orm(orm_template):
src_trans = self.pool.get(self._name).read(cr,user,ids,[f])
self.pool.get('ir.translation')._set_ids(cr, user, self._name+','+f, 'model', context['lang'], ids, vals[f], src_trans[0][f])
# call the 'set' method of fields which are not classic_write
upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority)
# default element in context must be remove when call a one2many or many2many
# default element in context must be removed when call a one2many or many2many
rel_context = context.copy()
for c in context.items():
if c[0].startswith('default_'):
@ -2429,7 +2550,7 @@ class orm(orm_template):
"""
if not context:
context = {}
self.pool.get('ir.model.access').check(cr, user, self._name, 'create')
self.pool.get('ir.model.access').check(cr, user, self._name, 'create', context=context)
default = []
@ -2437,12 +2558,12 @@ class orm(orm_template):
for (t, c) in self._inherits.items():
if c in vals:
avoid_table.append(t)
for f in self._columns.keys(): # + self._inherit_fields.keys():
if not f in vals:
for f in self._columns.keys():
if (not f in vals) and (not isinstance(self._columns[f], fields.property)):
default.append(f)
for f in self._inherit_fields.keys():
if (not f in vals) and (self._inherit_fields[f][0] not in avoid_table):
if (not f in vals) and (self._inherit_fields[f][0] not in avoid_table) and (not isinstance(self._inherit_fields[f][2], fields.property)):
default.append(f)
if len(default):
@ -2451,7 +2572,6 @@ class orm(orm_template):
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 = {}
@ -2492,12 +2612,13 @@ class orm(orm_template):
#End
for field in vals:
if self._columns[field]._classic_write:
upd0 = upd0 + ',"' + field + '"'
upd1 = upd1 + ',' + self._columns[field]._symbol_set[0]
upd2.append(self._columns[field]._symbol_set[1](vals[field]))
else:
upd_todo.append(field)
if field in self._columns:
if self._columns[field]._classic_write:
upd0 = upd0 + ',"' + field + '"'
upd1 = upd1 + ',' + self._columns[field]._symbol_set[0]
upd2.append(self._columns[field]._symbol_set[1](vals[field]))
else:
upd_todo.append(field)
if field in self._columns \
and hasattr(self._columns[field], 'selection') \
and vals[field]:
@ -2547,19 +2668,25 @@ class orm(orm_template):
cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%s', (pleft,))
cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1,pleft+2,id_new))
# default element in context must be remove when call a one2many or many2many
# default element in context must be removed when call a one2many or many2many
rel_context = context.copy()
for c in context.items():
if c[0].startswith('default_'):
del rel_context[c[0]]
result = []
for field in upd_todo:
self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context)
result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []
self._validate(cr, user, [id_new], context)
result = self._store_get_values(cr, user, [id_new], vals.keys(), context)
for order, object, ids, fields in result:
self.pool.get(object)._store_set_values(cr, user, ids, fields, context)
if not context.get('no_store_function', False):
result += self._store_get_values(cr, user, [id_new], vals.keys(), context)
result.sort()
done = []
for order, object, ids, fields2 in result:
if not (object, ids, fields2) in done:
self.pool.get(object)._store_set_values(cr, user, ids, fields2, context)
done.append((object, ids, fields2))
wf_service = netsvc.LocalService("workflow")
wf_service.trg_create(user, self._name, id_new, cr)
@ -2569,6 +2696,15 @@ class orm(orm_template):
result = {}
fncts = self.pool._store_function.get(self._name, [])
for fnct in range(len(fncts)):
if fncts[fnct][3]:
ok = False
for f in (fields or []):
if f in fncts[fnct][3]:
ok = True
break
if not ok:
continue
result.setdefault(fncts[fnct][0], {})
ids2 = fncts[fnct][2](self,cr, uid, ids, context)
for id in filter(None, ids2):
@ -2751,7 +2887,7 @@ class orm(orm_template):
if 'state' in self._defaults:
default['state'] = self._defaults['state'](self, cr, uid, context)
data = self.read(cr, uid, [id], context=context)[0]
fields = self.fields_get(cr, uid)
fields = self.fields_get(cr, uid, context=context)
trans_data=[]
for f in fields:
ftype = fields[f]['type']
@ -2812,11 +2948,11 @@ class orm(orm_template):
def copy(self, cr, uid, id, default=None, context=None):
trans_obj = self.pool.get('ir.translation')
data, trans_data = self.copy_data(cr, uid, id, default, context)
new_id=self.create(cr, uid, data)
new_id = self.create(cr, uid, data, context)
for record in trans_data:
del record['id']
record['res_id']=new_id
trans_obj.create(cr,uid,record)
record['res_id'] = new_id
trans_obj.create(cr, uid, record, context)
return new_id
def exists(self, cr, uid, id, context=None):

View File

@ -67,8 +67,8 @@ class osv_pool(netsvc.Service):
self.abortResponse(1, 'Constraint Error', 'warning', self._sql_error[key])
self.abortResponse(1, 'Integrity Error', 'warning', inst[0])
except Exception, e:
import traceback
tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
import traceback, sys
tb_s = "".join(traceback.format_exception(*sys.exc_info()))
logger = Logger()
logger.notifyChannel('web-services', LOG_ERROR, tb_s)
raise

View File

@ -22,8 +22,7 @@
##############################################################################
name = 'openerp-server'
version = '5.0.1'
release = '0'
version = '5.0.3'
major_version = '5.0'
description = 'OpenERP Server'
long_desc = '''\

View File

@ -240,7 +240,7 @@ class document(object):
txt = str(datas[atr['value']])
else:
txt = datas[atr['value']]
el.append(txt)
el.text = txt
else:
for el_cld in node:
parse_result_tree(el_cld, el, datas)

View File

@ -27,8 +27,10 @@ from lxml import etree
from report import render
import libxml2
import libxslt
import locale
import time, os
import mx.DateTime
class report_printscreen_list(report_int):
def __init__(self, name):
@ -49,7 +51,7 @@ class report_printscreen_list(report_int):
return result
def _parse_string(self, view):
dom = etree.XML(unicode(view, 'utf-8').encode('utf-8'))
dom = etree.XML(view)
return self._parse_node(dom)
def create(self, cr, uid, ids, datas, context=None):
@ -70,7 +72,16 @@ class report_printscreen_list(report_int):
result = model.fields_view_get(cr, uid, view_type='tree', context=context)
fields_order = self._parse_string(result['arch'])
rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context )
rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context)
ids2 = [x['id'] for x in rows] # getting the ids from read result
if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen
rows_new = []
for id in datas['ids']:
element = [elem for elem in rows if elem['id']==id]
rows_new.append(element[0])
rows = rows_new
res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
return (self.obj.get(), 'pdf')
@ -87,7 +98,8 @@ class report_printscreen_list(report_int):
n.text = text
config.append(n)
_append_node('date', time.strftime('%d/%m/%Y'))
#_append_node('date', time.strftime('%d/%m/%Y'))
_append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
_append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
@ -106,7 +118,7 @@ class report_printscreen_list(report_int):
for f in fields_order:
s = 0
ince += 1
if fields[f]['type'] in ('date','time','float','integer'):
if fields[f]['type'] in ('date','time','datetime','float','integer'):
s = 60
strmax -= s
if fields[f]['type'] in ('float','integer'):
@ -127,23 +139,21 @@ class report_printscreen_list(report_int):
for f in fields_order:
field = etree.Element("field")
field.text = fields[f]['string'] or ''
field.text = tools.ustr(fields[f]['string'] or '')
header.append(field)
new_doc.append(header)
lines = etree.Element("lines")
tsum = []
count = len(fields_order)
for i in range(0,count):
tsum.append(0)
for line in results:
node_line = etree.Element("row")
count = -1
for f in fields_order:
float_flag = 0
count += 1
if fields[f]['type']=='many2one' and line[f]:
@ -158,18 +168,41 @@ class report_printscreen_list(report_int):
if fields[f]['type'] in ('one2many','many2many') and line[f]:
line[f] = '( '+tools.ustr(len(line[f])) + ' )'
if fields[f]['type'] == 'float':
if fields[f]['type'] == 'float' and line[f]:
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]='%.2f'%(line[f])
prec ='%.' + str(precision) +'f'
line[f]=prec%(line[f])
float_flag = 1
if fields[f]['type'] == 'date' and line[f]:
format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))
d1= mx.DateTime.strptime(line[f],'%Y-%m-%d')
new_d1 = d1.strftime(format)
line[f] = new_d1
if fields[f]['type'] == 'time' and line[f]:
format = str(locale.nl_langinfo(locale.T_FMT))
d1= mx.DateTime.strptime(line[f],'%H:%M:%S')
new_d1 = d1.strftime(format)
line[f] = new_d1
if fields[f]['type'] == 'datetime' and line[f]:
format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))+' '+str(locale.nl_langinfo(locale.T_FMT))
d1= mx.DateTime.strptime(line[f],'%Y-%m-%d %H:%M:%S')
new_d1 = d1.strftime(format)
line[f] = new_d1
col = etree.Element("col")
col.set('para','yes')
col.set('tree','no')
if line[f] != None:
col.text = tools.ustr(line[f] or '')
if float_flag:
col.set('tree','float')
if temp[count] == 1:
tsum[count] = float(tsum[count]) + float(line[f]);
else:
col.text = '/'
node_line.append(col)
@ -183,21 +216,22 @@ class report_printscreen_list(report_int):
col.set('tree','no')
if tsum[f] != None:
if tsum[f] >= 0.01 :
total = '%.2f'%(tsum[f])
txt = str(total or '')
else :
txt = str(tsum[f] or '')
prec = '%.' + str(tools.config['price_accuracy']) + 'f'
total = prec%(tsum[f])
txt = str(total or '')
col.set('tree','float')
else:
txt = str(tsum[f] or '')
else:
txt = '/'
if f == 0:
txt ='Total'
col.text = txt
col.text = tools.ustr(txt or '')
node_line.append(col)
lines.append(node_line)
new_doc.append(lines)
styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl'))
style = libxslt.parseStylesheetDoc(styledoc)

View File

@ -223,7 +223,7 @@ class _rml_doc(object):
self.canvas.save()
class _rml_canvas(object):
def __init__(self, canvas,localcontext, doc_tmpl=None, doc=None, images={}, path='.', title=None):
def __init__(self, canvas, localcontext, doc_tmpl=None, doc=None, images={}, path='.', title=None):
self.localcontext = localcontext
self.canvas = canvas
self.styles = doc.styles
@ -236,7 +236,8 @@ class _rml_canvas(object):
self.canvas.setTitle(self.title)
def _textual(self, node, x=0, y=0):
rc = utils._process_text(self, node.text or '')
text = node.text and node.text.encode('utf-8') or ''
rc = utils._process_text(self, text)
for n in node:
if n.tag == 'seq':
from reportlab.lib.sequencer import getSequencer
@ -315,7 +316,7 @@ class _rml_canvas(object):
self.canvas.circle(x_cen=utils.unit_get(node.get('x')), y_cen=utils.unit_get(node.get('y')), r=utils.unit_get(node.get('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
def _place(self, node):
flows = _rml_flowable(self.doc, images=self.images, path=self.path, title=self.title).render(node)
flows = _rml_flowable(self.doc, self.localcontext, images=self.images, path=self.path, title=self.title).render(node)
infos = utils.attr_get(node, ['x','y','width','height'])
infos['y']+=infos['height']
@ -453,12 +454,12 @@ class _rml_draw(object):
def render(self, canvas, doc):
canvas.saveState()
cnv = _rml_canvas(canvas,self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
cnv = _rml_canvas(canvas, self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
cnv.render(self.node)
canvas.restoreState()
class _rml_flowable(object):
def __init__(self,doc,localcontext, images={}, path='.', title=None):
def __init__(self, doc, localcontext, images={}, path='.', title=None):
self.localcontext = localcontext
self.doc = doc
self.styles = doc.styles
@ -474,7 +475,7 @@ class _rml_flowable(object):
if key in ('rml_except', 'rml_loop', 'rml_tag'):
del txt_n.attrib[key]
if True or not self._textual(n).isspace():
txt_n.text = self._textual(n)
txt_n.text = utils.xml2str(self._textual(n))
txt_n.tail = ''
rc1 += etree.tostring(txt_n)
#rc1 += utils._process_text(self, node.tail or '')

View File

@ -41,6 +41,7 @@ import re
import reportlab
from lxml import etree
import copy
import tools
_regex = re.compile('\[\[(.+?)\]\]')
@ -111,7 +112,7 @@ def _process_text(self, txt):
pass
if type(txt)==type('') or type(txt)==type(u''):
txt2 = str2xml(txt)
result += txt2
result += tools.ustr(txt2)
elif (txt is not None) and (txt is not False):
result += str(txt)
return result
@ -119,7 +120,7 @@ def _process_text(self, txt):
def text_get(node):
rc = ''
for node in node.getchildren():
rc = rc + node.text
rc = rc + tools.ustr(node.text)
return rc
units = [

View File

@ -189,7 +189,7 @@ class rml_parse(object):
return newtag, attrs
def format(self, text, oldtag=None):
return text
return text.strip()
def removeParentNode(self, tag=None):
raise Exception('Skip')
@ -239,7 +239,7 @@ class rml_parse(object):
self.default_lang[lang] = self.lang_dict.copy()
return True
def formatLang(self, value, digits=2, date=False,date_time=False, grouping=True, monetary=False, currency=None):
def formatLang(self, value, digits=2, date=False,date_time=False, grouping=True, monetary=False):
if isinstance(value, (str, unicode)) and not value:
return ''
if not self.lang_dict_called:
@ -305,7 +305,7 @@ class rml_parse(object):
head_dom = etree.XML(rml_head)
for tag in head_dom.getchildren():
found = rml_dom.find('.//'+tag.tag)
if found is not None:
if found is not None and len(found):
if tag.get('position'):
found.append(tag)
else :
@ -420,12 +420,14 @@ class report_sxw(report_rml, preprocess.report):
return s.getvalue(), results[0][1]
return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
def create_single_pdf(self, cr, uid, ids, data, report_xml, context={}):
def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context={}
logo = None
context = context.copy()
title = report_xml.name
rml = report_xml.report_rml_content
rml_parser = self.parser(cr, uid, self.name2, context)
rml_parser = self.parser(cr, uid, self.name2, context=context)
objs = self.getObjects(cr, uid, ids, context)
rml_parser.set_context(objs, data, ids, report_xml.report_type)
processed_rml = self.preprocess_rml(etree.XML(rml),report_xml.report_type)
@ -437,7 +439,9 @@ class report_sxw(report_rml, preprocess.report):
pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8'))
return (pdf, report_xml.report_type)
def create_single_odt(self, cr, uid, ids, data, report_xml, context={}):
def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context={}
context = context.copy()
report_type = report_xml.report_type
context['parents'] = sxw_parents
@ -447,7 +451,7 @@ class report_sxw(report_rml, preprocess.report):
meta = sxw_z.read('meta.xml')
sxw_z.close()
rml_parser = self.parser(cr, uid, self.name2, context)
rml_parser = self.parser(cr, uid, self.name2, context=context)
rml_parser.parents = sxw_parents
rml_parser.tag = sxw_tag
objs = self.getObjects(cr, uid, ids, context)
@ -514,7 +518,7 @@ class report_sxw(report_rml, preprocess.report):
if report_xml.header:
#Add corporate header/footer
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 = self.parser(cr, uid, self.name2, context=context)
rml_parser.parents = sxw_parents
rml_parser.tag = sxw_tag
objs = self.getObjects(cr, uid, ids, context)
@ -532,13 +536,15 @@ class report_sxw(report_rml, preprocess.report):
sxw_io.close()
return (final_op, report_type)
def create_single_html2html(self, cr, uid, ids, data, report_xml, context={}):
def create_single_html2html(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context = {}
context = context.copy()
report_type = 'html'
context['parents'] = html_parents
html = report_xml.report_rml_content
html_parser = self.parser(cr, uid, self.name2, context)
html_parser = self.parser(cr, uid, self.name2, context=context)
html_parser.parents = html_parents
html_parser.tag = sxw_tag
objs = self.getObjects(cr, uid, ids, context)

View File

@ -25,12 +25,19 @@ import tools
_uid_cache = {}
# When rejecting a password, we need to give as little info as possible
class ExceptionNoTb(Exception):
def __init__(self, msg ):
# self.message = msg # No need in Python 2.6
self.traceback = ('','','')
self.args = (msg, '')
def login(db, login, password):
cr = pooler.get_db(db).cursor()
if password:
cr.execute('select id from res_users where login=%s and password=%s and active', (login.encode('utf-8'), password.encode('utf-8')))
cr.execute('select id from res_users where login=%s and password=%s and active', (tools.ustr(login), tools.ustr(password)))
else:
cr.execute('select id from res_users where login=%s and password is null and active', (login.encode('utf-8'),))
cr.execute('select id from res_users where login=%s and password is null and active', (tools.ustr(login),))
res = cr.fetchone()
cr.close()
if res:
@ -42,20 +49,21 @@ def check_super(passwd):
if passwd == tools.config['admin_passwd']:
return True
else:
raise Exception('AccessDenied')
raise ExceptionNoTb('AccessDenied')
def check(db, uid, passwd):
if _uid_cache.get(db, {}).get(uid) == passwd:
cached_pass = _uid_cache.get(db, {}).get(uid)
if (cached_pass is not None) and cached_pass == passwd:
return True
cr = pooler.get_db(db).cursor()
if passwd:
cr.execute('select count(*) from res_users where id=%s and password=%s', (int(uid), passwd))
cr.execute('select count(1) from res_users where id=%s and password=%s and active=%s', (int(uid), passwd, True))
else:
cr.execute('select count(*) from res_users where id=%s and password is null', (int(uid),))
cr.execute('select count(1) from res_users where id=%s and password is null and active=%s', (int(uid), True))
res = cr.fetchone()[0]
cr.close()
if not bool(res):
raise Exception('AccessDenied')
raise ExceptionNoTb('AccessDenied')
if res:
if _uid_cache.has_key(db):
ulist = _uid_cache[db]
@ -73,7 +81,7 @@ def access(db, uid, passwd, sec_level, ids):
res = cr.fetchone()
cr.close()
if not res:
raise Exception('Bad username or password')
raise ExceptionNoTb('Bad username or password')
return res[0]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -29,7 +29,7 @@ import thread
import threading
import time
import sys
import platform
from tools.translate import _
import addons
import ir
@ -38,7 +38,7 @@ import pooler
import release
import sql_db
import tools
import locale
logging.basicConfig()
class db(netsvc.Service):
@ -60,6 +60,8 @@ class db(netsvc.Service):
self.id = 0
self.id_protect = threading.Semaphore()
self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
def create(self, password, db_name, demo, lang, user_password='admin'):
security.check_super(password)
self.id_protect.acquire()
@ -169,17 +171,28 @@ class db(netsvc.Service):
sql_db.close_db('template1')
return True
def _set_pg_psw_env_var(self):
if os.name == 'nt' and not os.environ.get('PGPASSWORD', ''):
os.environ['PGPASSWORD'] = tools.config['db_password']
self._pg_psw_env_var_is_set = True
def _unset_pg_psw_env_var(self):
if os.name == 'nt' and self._pg_psw_env_var_is_set:
os.environ['PGPASSWORD'] = ''
def dump(self, password, db_name):
security.check_super(password)
logger = netsvc.Logger()
self._set_pg_psw_env_var()
cmd = ['pg_dump', '--format=c', '--no-owner']
if tools.config['db_user']:
cmd.append('--username=' + tools.config['db_user'])
if tools.config['db_host']:
cmd.append('--host=' + tools.config['db_host'])
if tools.config['db_port']:
cmd.append('--port=' + tools.config['db_port'])
cmd.append('--port=' + str(tools.config['db_port']))
cmd.append(db_name)
stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
@ -192,12 +205,17 @@ class db(netsvc.Service):
raise Exception, "Couldn't dump database"
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'DUMP DB: %s' % (db_name))
self._unset_pg_psw_env_var()
return base64.encodestring(data)
def restore(self, password, db_name, data):
security.check_super(password)
logger = netsvc.Logger()
self._set_pg_psw_env_var()
if self.db_exist(db_name):
logger.notifyChannel("web-services", netsvc.LOG_WARNING,
'RESTORE DB: %s already exists' % (db_name,))
@ -218,7 +236,7 @@ class db(netsvc.Service):
if tools.config['db_host']:
cmd.append('--host=' + tools.config['db_host'])
if tools.config['db_port']:
cmd.append('--port=' + tools.config['db_port'])
cmd.append('--port=' + str(tools.config['db_port']))
cmd.append('--dbname=' + db_name)
args2 = tuple(cmd)
@ -238,6 +256,9 @@ class db(netsvc.Service):
raise Exception, "Couldn't restore database"
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'RESTORE DB: %s' % (db_name))
self._unset_pg_psw_env_var()
return True
def rename(self, password, old_name, new_name):
@ -353,6 +374,8 @@ class common(netsvc.Service):
self.exportMethod(self.get_available_updates)
self.exportMethod(self.get_migration_scripts)
self.exportMethod(self.get_server_environment)
self.exportMethod(self.login_message)
self.exportMethod(self.set_loglevel)
def ir_set(self, db, uid, password, keys, args, name, value, replace=True, isobject=False):
security.check(db, uid, password)
@ -505,28 +528,40 @@ GNU Public Licence.
l.notifyChannel('migration', netsvc.LOG_ERROR, tb_s)
raise
def get_server_environment(self,lang=False):
try:
if '.bzr' in os.listdir((os.getcwd()[0:-3])):
fp = open(os.path.join(os.getcwd()[0:-3],'.bzr/branch/last-revision'))
rev_no = fp.read()
fp.close()
else:
rev_no = 'Bazaar Not Installed !'
except:
rev_no = 'Bazaar Not Installed !'
if not lang:
lang = os.environ.get('LANG', '').split('.')[0]
environment = 'Environment_Information : \n' \
'Operating System : %s\n' \
'PlatForm : %s\n' \
'Operating System Version : %s\n' \
'Python Version : %s\n'\
'Locale : %s\n' \
'OpenERP-Server Version : %s\n'\
'OpenERP-Server Last Revision ID : %s' \
%(os.name,sys.platform,str(sys.version.split('\n')[1]),str(sys.version[0:5]), lang, release.version,rev_no)
def get_server_environment(self):
os_lang = '.'.join( [x for x in locale.getdefaultlocale() if x] )
if not os_lang:
os_lang = 'NOT SET'
environment = '\nEnvironment Information : \n' \
'System : %s\n' \
'OS Name : %s\n' \
%(platform.platform(), platform.os.name)
if os.name == 'posix':
if platform.system() == 'Linux':
lsbinfo = os.popen('lsb_release -a').read()
environment += '%s'%(lsbinfo)
else:
environment += 'Your System is not lsb compliant\n'
environment += 'Operating System Release : %s\n' \
'Operating System Version : %s\n' \
'Operating System Architecture : %s\n' \
'Operating System Locale : %s\n'\
'Python Version : %s\n'\
'OpenERP-Server Version : %s'\
%(platform.release(), platform.version(), platform.architecture()[0],
os_lang, platform.python_version(),release.version)
return environment
def login_message(self):
return tools.config.get('login_message', False)
def set_loglevel(self, password, loglevel):
security.check_super(password)
l = netsvc.Logger()
l.set_loglevel(int(loglevel))
return True
common()
class objects_proxy(netsvc.Service):
@ -660,7 +695,6 @@ class report_spool(netsvc.Service):
tb = sys.exc_info()
tb_s = "".join(traceback.format_exception(*tb))
logger = netsvc.Logger()
logger.notifyChannel('web-services', netsvc.LOG_ERROR,common().get_server_environment(context.get('lang',False)))
logger.notifyChannel('web-services', netsvc.LOG_ERROR,
'Exception: %s\n%s' % (str(exception), tb_s))
self._reports[id]['exception'] = ExceptionWithTraceback(tools.exception_to_unicode(exception), tb)

View File

@ -55,7 +55,7 @@ from mx import DateTime as mdt
re_from = re.compile('.* from "?([a-zA-Z_0-9]+)"? .*$');
re_into = re.compile('.* into "?([a-zA-Z_0-9]+)"? .*$');
def log(msg, lvl=netsvc.LOG_DEBUG):
def log(msg, lvl=netsvc.LOG_DEBUG2):
logger = netsvc.Logger()
logger.notifyChannel('sql', lvl, msg)

View File

@ -98,7 +98,9 @@ def amount_to_text(number, currency):
cents_number = int(number * 100) % 100
cents_name = (cents_number > 1) and 'cents' or 'cent'
cents = _100_to_text(cents_number)
cents = cents_number and '%s %s' % (cents, cents_name) or ''
cents = cents_number and '%s %s' % (cents.lower(), cents_name) or ''
if cents:
lacs += ' and %s' % (cents, )
return lacs

View File

@ -79,7 +79,10 @@ class configmanager(object):
'log_level': logging.INFO,
'assert_exit_level': logging.WARNING, # level above which a failed assert will be raise
'cache_timeout': 100000,
'login_message': False,
}
self.misc = {}
hasSSL = check_ssl()
@ -336,6 +339,18 @@ class configmanager(object):
if value=='False' or value=='false':
value = False
self.options[name] = value
#parse the other sections, as well
for sec in p.sections():
if sec == 'options':
continue
if not self.misc.has_key(sec):
self.misc[sec]= {}
for (name, value) in p.items(sec):
if value=='True' or value=='true':
value = True
if value=='False' or value=='false':
value = False
self.misc[sec][name] = value
except IOError:
pass
except ConfigParser.NoSectionError:
@ -352,6 +367,10 @@ class configmanager(object):
p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt]))
else:
p.set('options', opt, self.options[opt])
for sec in self.misc.keys():
for opt in self.misc[sec].keys():
p.set(sec,opt,self.misc[sec][opt])
# try to create the directories and write the file
try:
@ -370,6 +389,9 @@ class configmanager(object):
def get(self, key, default=None):
return self.options.get(key, default)
def get_misc(self, sect, key, default=None):
return self.misc.get(sect,{}).get(key, default)
def __setitem__(self, key, value):
self.options[key] = value

View File

@ -883,7 +883,7 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa
except Exception, e:
logger = netsvc.Logger()
logger.notifyChannel('init', netsvc.LOG_ERROR, 'The XML file does not fit the required schema !')
logger.notifyChannel('init', netsvc.LOG_ERROR, relaxng.error_log.last_error)
logger.notifyChannel('init', netsvc.LOG_ERROR, misc.ustr(relaxng.error_log.last_error))
raise
if idref is None:

View File

@ -612,9 +612,16 @@ class cache(object):
"""
def to_tuple(d):
i = d.items()
i.sort(key=lambda (x,y): x)
return tuple(i)
pairs = d.items()
pairs.sort(key=lambda (k,v): k)
for i, (k, v) in enumerate(pairs):
if isinstance(v, dict):
pairs[i] = (k, to_tuple(v))
if isinstance(v, (list, set)):
pairs[i] = (k, tuple(v))
elif not is_hashable(v):
pairs[i] = (k, repr(v))
return tuple(pairs)
if not self.multi:
key = (('dbname', dbname),) + to_tuple(kwargs2)
@ -631,12 +638,6 @@ class cache(object):
kwargs2 = self.fun_default_values.copy()
kwargs2.update(kwargs)
kwargs2.update(dict(zip(self.fun_arg_names, args[self.skiparg-2:])))
for k in kwargs2:
if isinstance(kwargs2[k], (list, dict, set)):
kwargs2[k] = tuple(kwargs2[k])
elif not is_hashable(kwargs2[k]):
kwargs2[k] = repr(kwargs2[k])
return kwargs2
def clear(self, dbname, *args, **kwargs):
@ -672,9 +673,9 @@ class cache(object):
if time.time()-self.timeout > self.lasttime:
self.lasttime = time.time()
t = time.time()-self.timeout
for key in self.cache.keys():
if self.cache[key][1]<t:
del self.cache[key]
old_keys = [key for key in self.cache if self.cache[key][1] < t]
for key in old_keys:
del self.cache[key]
kwargs2 = self._unify_args(*args, **kwargs)

View File

@ -125,7 +125,11 @@ def translate(cr, name, source_type, lang, source=None):
class GettextAlias(object):
def __call__(self, source):
frame = inspect.stack()[1][0]
try:
frame = inspect.stack()[1][0]
except:
return source
cr = frame.f_locals.get('cr')
try:
lang = (frame.f_locals.get('context') or {}).get('lang', False)
@ -340,8 +344,9 @@ def trans_export(lang, modules, buffer, format, dbname=None):
tmpmoddir = join(tmpdir, mod, 'i18n')
os.makedirs(tmpmoddir)
pofilename = (newlang and mod or lang) + ".po" + (newlang and 't' or '')
buf = open(join(tmpmoddir, pofilename), 'w')
buf = file(join(tmpmoddir, pofilename), 'w')
_process('po', [mod], modrows, buf, lang, newlang)
buf.close()
tar = tarfile.open(fileobj=buffer, mode='w|gz')
tar.add(tmpdir, '')
@ -598,20 +603,28 @@ def trans_generate(lang, modules, dbname=None):
modobj = pool.get('ir.module.module')
installed_modids = modobj.search(cr, uid, [('state', '=', 'installed')])
installed_modules = map(lambda m: m['name'], modobj.read(cr, uid, installed_modids, ['name']))
if tools.config['root_path'] in tools.config['addons_path'] :
path_list = [tools.config['root_path']]
else :
path_list = [tools.config['root_path'],tools.config['addons_path']]
for root, dirs, files in tools.osutil.walksymlinks(tools.config['root_path']):
for fname in fnmatch.filter(files, '*.py'):
fabsolutepath = join(root, fname)
frelativepath = fabsolutepath[len(tools.config['root_path'])+1:]
module = get_module_from_path(frelativepath)
is_mod_installed = module in installed_modules
if (('all' in modules) or (module in modules)) and is_mod_installed:
code_string = tools.file_open(fabsolutepath, subdir='').read()
iter = re.finditer(
'[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)',
code_string, re.M)
for i in iter:
push_translation(module, 'code', frelativepath, 0, encode(i.group(1)))
for path in path_list:
for root, dirs, files in tools.osutil.walksymlinks(path):
for fname in fnmatch.filter(files, '*.py'):
fabsolutepath = join(root, fname)
frelativepath = fabsolutepath[len(path):]
module = get_module_from_path(frelativepath)
is_mod_installed = module in installed_modules
if (('all' in modules) or (module in modules)) and is_mod_installed:
code_string = tools.file_open(fabsolutepath, subdir='').read()
iter = re.finditer('[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)',
code_string, re.S)
if module in installed_modules :
frelativepath =str("addons"+frelativepath)
for i in iter:
push_translation(module, 'code', frelativepath, 0, encode(i.group(1)))
out = [["module","type","name","res_id","src","value"]] # header

View File

@ -43,7 +43,7 @@ def delete(cr, ident):
def validate(cr, inst_id, ident, signal, force_running=False):
cr.execute("select * from wkf_workitem where inst_id=%s", (inst_id,))
stack = None
stack = []
for witem in cr.dictfetchall():
stack = []
workitem.process(cr, witem, ident, signal, force_running, stack=stack)

View File

@ -52,7 +52,7 @@ class workflow_service(netsvc.Service):
cr.execute('select instance_id from wkf_triggers where res_id=%s and model=%s', (res_id,res_type))
res = cr.fetchall()
for (instance_id,) in res:
cr.execute('select uid,res_type,res_id from wkf_instance where id=%s', (instance_id,))
cr.execute('select %s,res_type,res_id from wkf_instance where id=%s', (uid, instance_id,))
ident = cr.fetchone()
instance.update(cr, instance_id, ident)

24
change-loglevel.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
ADMIN_PASSWD='admin'
method_1() {
cat '-' << EOF
<xml>
<methodCall>
<methodName>set_loglevel</methodName>
<params>
<param><value><string>$ADMIN_PASSWD</string></value>
</param>
<param>
<value><string>$1</string></value>
</param>
</params>
</methodCall>
EOF
}
LEVEL=10
if [ -n "$1" ] ; then LEVEL=$1 ; fi
method_1 $LEVEL | POST -c 'text/xml' http://localhost:8069/xmlrpc/common
#eof

486
debian/changelog vendored
View File

@ -1,3 +1,488 @@
openerp-server (5.0.3-0-1ubuntu2) intrepid; urgency=low
* Merge packaging work from Debian official
-- Panos Christeas <p_christ@hol.gr> Mon, 24 Aug 2009 22:10:00 +0300
openerp-server (5.0.3-0-1ubuntu1) intrepid; urgency=low
[ P. Christeas ]
* Introduce 'debug2' loglevel, use it for SQL
[ Christophe Simonis ]
* [IMP] change version number
[ P. Christeas ]
* [IMP]: allow Log level to be changed in runtime.
* Config: misc options. Logger: option to turn env_info off.
* Remove base_setup/i18n/el_GR.po, module is moved to addons repo.
* Merge el_GR translation with template.
* Update translation template.
* Fix +x permission of openerp-server.py
-- Panos Christeas <p_christ@hol.gr> Fri, 14 Aug 2009 20:40:29 +0300
openerp-server (5.0.3-0-1) unstable; urgency=low
* Merging upstream version 5.0.3-0.
* Removing xmlrpc.patch, went upstream.
* Using dedicated storage directory in /var/lib/openerp-server, that
way the addons directory can stay read-only for the unprivileged
user.
* Commenting out db_name in config (Closes: #542391).
* Commenting out port in config (Closes: #542406).
* Renaming logfile to openerp-server.log for consistency.
* Commenting out pidfile in config (Closes: #542427).
* Removing debconf handling in postrm, not possible to do that.
* Removing local storage directory on purge.
-- Daniel Baumann <daniel@debian.org> Mon, 24 Aug 2009 20:16:55 +0200
openerp-server (5.0.2-0-3) unstable; urgency=low
* Wrapping and sorting depends.
* Correcting spelling of Open ERP.
* Updating maintainer field.
* Updating vcs fields.
* Updating to standards version 3.8.3.
* Dropping old depends on python-xml (Closes: #543127).
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
packages and changelog.
-- Daniel Baumann <daniel@debian.org> Mon, 24 Aug 2009 18:23:54 +0200
openerp-server (5.0.2-0-2) unstable; urgency=high
* Adding patch from Panos Christeas <p_christ@hol.gr> to forbid RPC
calls without credentials. All versions of openerp-server affected.
-- Daniel Baumann <daniel@debian.org> Thu, 13 Aug 2009 14:45:17 +0200
openerp-server (5.0.2-0-1ubuntu2) intrepid; urgency=critical
[ P. Christeas ]
* Security: check_creds is not really needed, use "check"
[ Christophe Simonis ]
* [FIX] security issue: avoid access to inactive users
* [FIX] avoid a bug when look in stack when translate code strings
[ P. Christeas ]
* [SEC] [CRITICAL] Forbid RPC calls w/o credentials.
[ Panos Christeas ]
-- Panos Christeas <p_christ@hol.gr> Thu, 13 Aug 2009 15:25:26 +0300
openerp-server (5.0.2-0-1ubuntu1) intrepid; urgency=low
[ P. Christeas ]
* [b98f26433c82] Greek translations, shorten terms.
* [2567b4e8fbc4] [IMP] Partial restrict operator for domains.
* [a507f9bee128] Shortcuts in RNG view definition.
* [e8da054afe0a] [IMP] Allow OS to rotate the logs, use
WatchedFileHandler if needed.
[ Jay (Open ERP) ]
* [8174407a30ec] [FIX] Property : Removed old referenced values from
property
[ mra (Open ERP) ]
* [819f9df328fa] [REV] revert chanegs for revision no 1810
* [70535423260f] [FIX] loading module sequence while creating new
database
[ Fabien Pinckaers ]
* [5aa83e5bb359] [FIX] bug 369947
* [dcde99cd9c5e] [FIX] bug 371496
* [8fbad91c586e] [FIX] bug 371768 bad tooltip
* [f42a9ae9115b] merge
* [db313489098d] merge
[ dsh (Open ERP) ]
* [a86dc3304dde] [IMP] attributes of barcode
[ Jay (Open ERP) ]
* [b2dafdb68cce] [FIX] ir_translation : corrected entry insertion when
adding translation
[ husen daudi ]
* [696445ddfb83] [MERGE]
* [7f9d0d2dd239] [FIX] module:base made name field translatable in
action.server (ref:mga)
[ Jay (Open ERP) ]
* [ed97326339a8] [FIX] Character Truncation problem on updation solved
[ Christophe Simonis ]
* [0b6c92ede314] [IMP] ir_model_data: convert assert to sql constraint
+ exception
[ Jay (Open ERP) ]
* [f98cc5a0bee6] [FIX] Custom report : sorted X-axis values
* [0cf0628f3c8a] [FIX] SQL Constraint failure error on particular
record while importing
[ husen daudi ]
* [d56bb59ca02d] [FIX] xml encoding in header for &.<.>
* [04d765f45692] [Merge] Converted xml reports from xmldom to etree
and better error message with environment information
[ Jay (Open ERP) ]
* [a915dc15dbfd] [FIX] User with blank password(if so) allowed to log
in.
[ Fabien Pinckaers ]
* [19e2f2b84eac] [FIX] avoid required parameters rule (domain_force)
* [b8d383a666e6] merge
* [7cdc6778acb1] merge
* [70c8fcdf67f2] merge
* [7cd04889bd27] [IMP] better error message
[ Jay (Open ERP) ]
* [99f3b0db73f8] [FIX] Fixed oldxml at python2.6 for Ubuntu
8.0.4,9.04
* [14b488955652] [IMP] default_xx in context isuue
[ Fabien Pinckaers ]
* [15a617ecbe04] merge
* [26f02d120db1] [fix] launch signal after action in workflows
[ Jay (Open ERP) ]
* [0ff7ddcd394d] [FIX] ORM: Defult_field name in context belongs to
curent object only, not to its relationals anymore
* [843604436871] [FIX] ir_attachment preview method corrected
[ Stephane Wirtel ]
* [406601019f23] [MERGE]
* [fa17b9e5f302] [FIX] fields.related (m2o poiting to M2M/O2M should
be skipped during write.
[ Jay (Open ERP) ]
* [7feb86ed7ad4] [IMP] Temporarily commented exception for browse
record that broke reports from wizard
[ husen daudi ]
* [665433813e7f] [FIX] Bad commit
* [c866dcb38c74] [FIX] Added PageCount tag in report engine
[ Fabien Pinckaers ]
* [a79d7777c888] merge
* [60d6357d3b2b] modifs
* [9ed525cfcd51] [FIX] bug in report engine
[ Jay (Open ERP) ]
* [2a571396d23e] [FIX] GIF image is previewed
[ Christophe Simonis ]
* [cee0846dff3c] [MERGE]
* [d2a31d33e1b1] [FIX] upgrade doesn't try to delete modules
* [1376272db30b] [MERGE]
* [bbaad3809f36] [FIX] xml: the tag <delete> delete also the reference
to the deleted objects into ir_model_data
* [35d4aa682b36] [FIX] translation export: catch the case when a
object does not exists in database
* [1f0cb7576704] [FIX] browse_record: raise a better exception when
the id doesn't exists
[ dsh (Open ERP) ]
* [0c8fe65fe3c0] [FIX] fix &,<,> problem for html2html-url report
* [71298ebb40b4] [FIX] fix &,<,> problem for html2html report
* [58b9464b7813] [IMP] added style for the url which are as text
[ Fabien Pinckaers ]
* [b934dd73d408] merge
* [fe33fdc8df19] [FIX] translations resynchro terms
* [4efe96b4f584] [FIX] Bugfix translations and float/int format in
reports
* [688883ce8183] bugfix_lang_notavailabel
[ Olivier Laurent ]
* [bee98151efd0] [MERGE]
* [adf826c7285b] [IMP] base: french translations
[ Christophe Simonis ]
* [cf01b2f3ee31] [IMP] maintenance: complete the remarks with the
database name
* [34e10ece0768] [FIX] complete rng file
* [eb179c00941a] [FIX] load the module graph even if it containt only
"base"
[ dsh (Open ERP) ]
* [5f1426c9e322] bug fix(skip text if child nodes are there) for the
html2html and openoffice reports
[ Panos Christeas ]
[ husen daudi ]
* Revert bad commit
[ Christophe Simonis ]
* [REL] 5.0.2
* [MERGE]
* [FIX] ensure sys is imported
[ Jay (Open ERP) ]
* [FIX] _inherits was misbehaving on search
[ Christophe Simonis ]
* [FIX] pass the context to check method of 'ir.model.access'
* [FIX] disallow the deletion of records set as default properties
* [MERGE]
* [FIX] increase size of field "name" of ir.model.data
* [IMP] update french translations
* [IMP] update french translations
[ Jay (Open ERP) ]
* [REF] Unused argument removed
[ Christophe Simonis ]
* [IMP] update po(t) files
[ Jay (Open ERP) ]
* [FIX] Login : Login and password accepting accented characters
* [FIX] Error reporting : library error corrected
* [FIX] default_xxx in context was passed to relational
fields,corrected.
[ P. Christeas ]
* Fix whitespace merging, that broke logging.
[ Jay (Open ERP) ]
* [FIX] Print screen now displays the report as per WYSIWYG
* [FIX]Importation problem for bool fields corrected
[ Christophe Simonis ]
* [IMP] new method that ollow the server to return a message that will
be display on login page
[ Jay (Open ERP) ]
* [FIX] ir_model_data : SQL_Constraint failure covered
* [FIX] Accented characters are displayed on footer now
* [FIX] DB operations(backup,restore) process corrected,were blocked
if db_port was supplied
[ husen daudi ]
* Merged
[ Jay (Open ERP) ]
* [FIX] Expression calculation for Datetime Corrected
* [FIX] Logger notification improved
* [FIX] ir_model : context key deletion
* [FIX] Translation : Text with prefix '_' from py files included for
exports.
* [FIX] Corrected bug of expression calculation in previous commit
[ Olivier Laurent ]
* [FIX] sql expression: in search, add the time part to datetime field
when it's not present
[ P. Christeas ]
* email_send: feature to place mails in a maildir, instead of smtp
* Fix Greek translation of email "subject".
[ Olivier Laurent ]
* [FIX] setup.py: py2exe now adds 'zoneinfo' directory in library.zip
[ Jay (Open ERP) ]
* [FIX] Importation problem corrected for unicode.
* [IMP] Environment Information Notification Improved
[ husen daudi ]
* [FIX] place tag
[ Olivier Laurent ]
* [MERGE]
* [FIX] tools.amount_to_text_en: now displays cents
[ P. Christeas ]
* Greek translations, shorten terms.
[ Olivier Laurent ]
* [MERGE]
* [FIX] RuntimeError in the cache system
[ Jay (Open ERP) ]
* [FIX] Print screen reports will behave acc. to locale for
date,datetime
* [FIX] Import : context provided for language translation
[ dsh (Open ERP) ]
* [FIX] size miss match for page and frame
[ husen daudi ]
* [FIX] removed report etree warning of len
* [FIX] Added sql_constraint on adding field having size<1
[ Quentin De Paoli ]
* [FIX] security on wokflows bugfixed. The security has to be checked
using the current uid, not the one that created the workflow
instance!
[ Harry (Open ERP) ]
* [FIX] export window : use context for import compatable option in
pass argument instend of added new argemenent
* [IMP] import/export : added Database ID, ID
[ P. Christeas ]
* [IMP] Partial restrict operator for domains.
* Shortcuts in RNG view definition.
* [IMP] Allow OS to rotate the logs, use WatchedFileHandler if needed.
[ Olivier Laurent ]
* [MERGE]
* [FIX] supply password problem with pg_dump, pg_restore on win32
* [IMP] french translations
[ Jay (Open ERP) ]
* [FIX] Certificate in non-digit format will not be accepted
* [FIX] Certificate in non-digit format will not be accepted
[ husen daudi ]
* [IMP] Improved environment information message
[ Jay (Open ERP) ]
* [Fix] CSV Import : Accepting 'Value' of selection field
from[(key,value)]
* [FIX] Property : Removed old referenced values from property
[ mra (Open ERP) ]
* [REV] revert chanegs for revision no 1810
* [FIX] loading module sequence while creating new database
[ Fabien Pinckaers ]
* [FIX] bug 369947
* [FIX] bug 371496
* [FIX] bug 371768 bad tooltip
* merge
* merge
[ dsh (Open ERP) ]
* [IMP] attributes of barcode
[ Jay (Open ERP) ]
* [FIX] ir_translation : corrected entry insertion when adding
translation
[ husen daudi ]
* [MERGE]
* [FIX] module:base made name field translatable in action.server
(ref:mga)
[ Jay (Open ERP) ]
* [FIX] Character Truncation problem on updation solved
[ Christophe Simonis ]
* [IMP] ir_model_data: convert assert to sql constraint + exception
[ Jay (Open ERP) ]
* [FIX] Custom report : sorted X-axis values
* [FIX] SQL Constraint failure error on particular record while
importing
[ husen daudi ]
* [FIX] xml encoding in header for &.<.>
* [Merge] Converted xml reports from xmldom to etree and better error
message with environment information
[ Jay (Open ERP) ]
* [FIX] User with blank password(if so) allowed to log in.
[ Fabien Pinckaers ]
* [FIX] avoid required parameters rule (domain_force)
* merge
* merge
* merge
* [IMP] better error message
[ Jay (Open ERP) ]
* [FIX] Fixed oldxml at python2.6 for Ubuntu 8.0.4,9.04
* [IMP] default_xx in context isuue
[ Fabien Pinckaers ]
* merge
* [fix] launch signal after action in workflows
[ Jay (Open ERP) ]
* [FIX] ORM: Defult_field name in context belongs to curent object
only, not to its relationals anymore
* [FIX] ir_attachment preview method corrected
[ Stephane Wirtel ]
* [MERGE]
* [FIX] fields.related (m2o poiting to M2M/O2M should be skipped
during write.
[ Jay (Open ERP) ]
* [IMP] Temporarily commented exception for browse record that broke
reports from wizard
[ husen daudi ]
* [FIX] Bad commit
* [FIX] Added PageCount tag in report engine
[ Fabien Pinckaers ]
* merge
* modifs
* [FIX] bug in report engine
[ Jay (Open ERP) ]
* [FIX] GIF image is previewed
[ Christophe Simonis ]
* [MERGE]
* [FIX] upgrade doesn't try to delete modules
* [MERGE]
* [FIX] xml: the tag <delete> delete also the reference to the deleted
objects into ir_model_data
* [FIX] translation export: catch the case when a object does not
exists in database
* [FIX] browse_record: raise a better exception when the id doesn't
exists
[ dsh (Open ERP) ]
* [FIX] fix &,<,> problem for html2html-url report
* [FIX] fix &,<,> problem for html2html report
* [IMP] added style for the url which are as text
[ Fabien Pinckaers ]
* merge
* [FIX] translations resynchro terms
* [FIX] Bugfix translations and float/int format in reports
* bugfix_lang_notavailabel
[ Olivier Laurent ]
* [MERGE]
* [IMP] base: french translations
[ Christophe Simonis ]
* [IMP] maintenance: complete the remarks with the database name
* [FIX] complete rng file
* [FIX] load the module graph even if it containt only "base"
[ dsh (Open ERP) ]
* bug fix(skip text if child nodes are there) for the html2html and
openoffice reports
[ Panos Christeas ]
-- Panos Christeas <p_christ@hol.gr> Thu, 13 Aug 2009 10:21:28 +0300
openerp-server (5.0.2-0-1) unstable; urgency=low
* Updating standards to 3.8.1.
* Rediffing autobuild.patch (Closes: #538625).
* Upgrading package to standards version 3.8.2.
* Managing setup of unprivileged user account with debconf.
* Using more common directory name to store local debian additions.
* Updating README.Debian to reflect that the database has to be
initialized through the client (Closes: #518675).
* Removing package leftovers in postrm script.
* Merging upstream version 5.0.2-0.
-- Daniel Baumann <daniel@debian.org> Thu, 13 Aug 2009 11:24:59 +0200
openerp-server (5.0.1-0-1ubuntu2) karmic; urgency=low
* Minor updates
@ -10,7 +495,6 @@ openerp-server (5.0.1-0-1ubuntu1) karmic; urgency=low
-- Panagiotis Kranidiotis <kranidiotis@vatica.org> Wed, 17 Jun 2009 18:45:37 +0300
openerp-server (5.0.1-0-1) unstable; urgency=low
* Merging upstream version 5.0.1-0.

24
debian/control vendored
View File

@ -2,28 +2,34 @@ Source: openerp-server
Section: net
Priority: optional
Maintainer: Jimmy Angelakos <vyruss@hellug.gr>
Build-Depends: debhelper (>= 7), quilt, python-dev
Build-Depends-Indep: python-lxml, python-xml, python-libxslt1, python-psycopg2
Standards-Version: 3.8.1
Uploaders: Daniel Baumann <daniel@debian.org>
Build-Depends: debhelper (>= 7), po-debconf, python-dev, quilt
Build-Depends-Indep: python-libxslt1, python-lxml, python-psycopg2
Standards-Version: 3.8.3
Homepage: http://www.openerp.com/
Vcs-Browser: http://git.debian.net/?p=debian/openerp-server.git
Vcs-Git: git://git.debian.net/git/debian/openerp-server.git
Vcs-Browser: http://git.debian-maintainers.org/?p=open-object/openerp-server.git
Vcs-Git: git://git.debian-maintainers.org/git/open-object/openerp-server.git
XSBC-Maintainer-Homepage: http://open-object.debian-maintainers.org/
Package: openerp-server
Section: net
Architecture: all
Depends: ${misc:Depends}, adduser, python, python-lxml, python-xml, python-libxslt1, python-psycopg2, python-reportlab, python-pychart, python-pydot, python-tz
Depends:
${misc:Depends}, adduser, python, python-libxslt1, python-lxml,
python-psycopg2, python-pydot, python-pychart, python-reportlab, python-tz
Conflicts: tinyerp-server
Replaces: tinyerp-server
Recommends: graphviz, ghostscript, postgresql, postgresql-client, python-imaging, python-matplotlib, python-openssl, python-pyparsing
Recommends:
graphviz, ghostscript, postgresql, postgresql-client, python-imaging,
python-matplotlib, python-openssl, python-pyparsing
Suggests: openerp-client
Description: Enterprise Resource Management (server)
OpenERP, previously known as TinyERP, is a complete ERP and CRM. The main
Open ERP, previously known as TinyERP, is a complete ERP and CRM. The main
features are accounting (analytic and financial), stock management, sales and
purchases management, tasks automation, marketing campaigns, help desk, POS,
etc. Technical features include a distributed server, flexible workflows, an
object database, a dynamic GUI, customizable reports, and NET-RPC and XML-RPC
interfaces.
.
This package contains the OpenERP server, install openerp-client package for
This package contains the Open ERP server, install openerp-client package for
the client.

View File

@ -6,10 +6,10 @@ verbose = False
debug_mode = False
# The file where the server pid will be stored (default False).
pidfile = /var/run/openerp.pid
#pidfile = /var/run/openerp.pid
# The file where the server log will be stored (default False).
logfile = /var/log/openerp.log
logfile = /var/log/openerp-server.log
# The unix account on behalf openerp is running.
process_user = openerp
@ -19,7 +19,7 @@ process_user = openerp
interface = localhost
# The TCP port on which the server will listen (default 8069).
port = 8070
#port = 8070
# Enable debug mode (default False).
debug_mode = False
@ -37,7 +37,7 @@ smtp_user = False
smtp_password = False
# Specify the database name.
db_name = openerp
#db_name = openerp
# Specify the database user name (default None).
db_user = openerp

View File

@ -1,7 +1,7 @@
openerp-server for Debian
-------------------------
OpenERP uses a PostgreSQL database to store its data. With the first generation
Open ERP uses a PostgreSQL database to store its data. With the first generation
of packages, you have to setup this database manually. Here is a short
explanation how to achieve this (you need to execute all commands as root):
@ -13,27 +13,23 @@ explanation how to achieve this (you need to execute all commands as root):
the above syvinit script could also be named postgresql-VERSION (whereas
'VERSION' needs to be replace with a version number).
1. Creating the database
1. Creating the database user
# su - postgres -c "createdb -q --encoding=UNICODE openerp"
2. Creating the database user
# su - postgres -c "createuser -q --createdb --adduser openerp"
# su - postgres -c "createuser -q --createdb --no-createrole --pwprompt openerp"
Note: If you want to run the database as another user than 'openerp', you
need to replace 'openerp' above with the user you want instead, and you
need to adjust 'db_user = openerp' in /etc/openerp-server.conf too.
4. Initializing the database
# su - postgres -c "/usr/bin/openerp-server --init=all \
--config=/etc/openerp-server.conf --stop-after-init"
5. Restarting openerp-server
3. Restarting openerp-server
# /etc/init.d/openerp-server restart
4. Initializing the database
Now you can connect with Open ERP client to the database and initialize it.
Now, you're finish. Please be aware of the following things:
* openerp-server has by default two accounts:

10
debian/openerp-server.config vendored Normal file
View File

@ -0,0 +1,10 @@
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_input low openerp-server/username || true
db_go
db_stop

1
debian/openerp-server.examples vendored Normal file
View File

@ -0,0 +1 @@
debian/openerp-server.preseed

View File

@ -9,7 +9,7 @@
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Enterprise Resource Management software
# Description: OpenERP is a complete ERP and CRM software.
# Description: Open ERP is a complete ERP and CRM software.
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin

View File

@ -1 +1 @@
debian/config/* /etc/
debian/local/openerp-server.conf /etc

View File

@ -1 +1,2 @@
/usr/share/man/man5/openerp_serverrc.5.gz /usr/share/man/man5/openerp-server.conf.5.gz
/var/lib/openerp-server/filestore /usr/lib/openerp-server/filestore

View File

@ -2,29 +2,45 @@
set -e
USER="openerp"
. /usr/share/debconf/confmodule
CONFFILE="/etc/openerp-server.conf"
LOGFILE="/var/log/openerp.log"
LOGFILE="/var/log/openerp-server.log"
case "${1}" in
configure)
# Creating system user
adduser --no-create-home --quiet --system ${USER}
db_version 2.0
db_get openerp-server/username
_USERNAME="${RET:-openerp}"
db_stop
if ! getent passwd | grep -q "^${_USERNAME}"
then
adduser --system --no-create-home --quiet --gecos 'Open ERP server' --group ${_USERNAME}
else
echo "Open ERP user (${_USERNAME}) already exists, doing nothing."
fi
sed -i -e "s|^process_user.*$|process_user = ${_USERNAME}|" ${CONFFILE}
# Creating log file
touch ${LOGFILE}
chown ${USER}:adm ${LOGFILE}
chown ${_USERNAME}:adm ${LOGFILE}
chmod 0640 ${LOGFILE}
# Setting ownership
chown ${USER} /usr/lib/openerp-server/addons -R
# Creating local storage directory
mkdir -p /var/lib/openerp-server/filestore
# Setting ownership and permissions
chmod 0640 ${CONFFILE}
chown ${USER} ${CONFFILE}
chown ${_USERNAME}:${_USERNAME} ${CONFFILE}
chown ${_USERNAME}:${_USERNAME} /var/lib/openerp-server -R
echo
echo "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
echo "* OpenERP uses a PostgreSQL database to store its data. With the first *"
echo "* Open ERP uses a PostgreSQL database to store its data. With the first *"
echo "* generation of packages, you have to setup this database manually. *"
echo "* Please read /usr/share/doc/openerp-server/README.Debian how to do it. *"
echo "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"

View File

@ -2,18 +2,31 @@
set -e
USER="openerp"
case "${1}" in
purge)
# Removing system user
remove)
_USERNAME="openerp"
_GROUPNAME="openerp"
if [ -x /usr/sbin/deluser ]
then
deluser --quiet --system ${USER}
deluser --quiet --system ${_USERNAME}
fi
if [ -x /usr/sbin/delgroup ]
then
delgroup --quiet --system --only-if-empty ${_GROUPNAME} || true
fi
rm -f /usr/lib/openerp-server/addons/__init__.pyc
rmdir --ignore-fail-on-non-empty /usr/lib/openerp-server/addons || true
rmdir --ignore-fail-on-non-empty /usr/lib/openerp-server || true
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
purge)
rm -rf /var/lib/openerp-server
;;
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;

5
debian/openerp-server.preseed vendored Normal file
View File

@ -0,0 +1,5 @@
################################################################################
## openerp-server
#openerp-server openerp-server/username string openerp
################################################################################

9
debian/openerp-server.templates vendored Normal file
View File

@ -0,0 +1,9 @@
Template: openerp-server/username
Type: string
Default: openerp
_Description: Dedicated system account for the Open ERP server:
The Open ERP server must use a dedicated account for its operation so that
the system's security is not compromised by running it with superuser
privileges.
.
Please choose that account's username.

View File

@ -2,14 +2,14 @@ Author: Daniel Baumann <daniel@debian.org>
Description: Disable modules check to make it buildable without X11.
diff -Naurp openerp-server.orig/setup.py openerp-server/setup.py
--- openerp-server.orig/setup.py 2008-11-03 21:33:56.000000000 +0000
+++ openerp-server/setup.py 2008-11-09 09:00:02.000000000 +0000
@@ -133,7 +133,7 @@ def data_files():
files.append(('.', [('bin/import_xml.rng')]))
--- openerp-server.orig/setup.py 2009-06-08 15:51:20.000000000 +0000
+++ openerp-server/setup.py 2009-07-26 10:27:49.000000000 +0000
@@ -121,7 +121,7 @@ def data_files():
return files
-check_modules()
+#check_modules()
# create startup script
start_script = \
f = file('openerp-server','w')
start_script = """#!/bin/sh\necho "OpenERP Setup - The content of this file is generated at the install stage\n" """

1
debian/po/POTFILES.in vendored Normal file
View File

@ -0,0 +1 @@
[type: gettext/rfc822deb] openerp-server.templates

39
debian/po/cs.po vendored Normal file
View File

@ -0,0 +1,39 @@
# Czech translation of openerp-server debconf templates.
# Copyright (C) 2009 Vítězslav Kotrla <vitezslav.kotrla@gmail.com>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-05-30 08:24+0000\n"
"PO-Revision-Date: 2009-06-21 08:20+0200\n"
"Last-Translator: Vítězslav Kotrla <vitezslav.kotrla@gmail.com>\n"
"Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Vyhrazený systémový účet, pod kterým bude běžet Open ERP server:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that the "
"system's security is not compromised by running it with superuser privileges."
msgstr ""
"Pokud by byl Open ERP server spuštěn se superuživatelskými oprávněními, mohlo by dojít "
"ke kompromitaci zabezpečení systému. Proto musí Open ERP server pro svoji činnost používat "
"vyhrazený neprivilegovaný účet."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Zvolte prosím název totoho účtu."

40
debian/po/de.po vendored Normal file
View File

@ -0,0 +1,40 @@
# German translation of openerp-server debconf templates.
# Copyright (C) 2009 Kai Wasserbäch <debian@carbon-project.org>
# Copyright (C) 2009 Helge Kreutzmann <debian@helgefjell.de>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-06 19:01+0200\n"
"Last-Translator: Helge Kreutzmann <debian@helgefjell.de>\n"
"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Eigenes Systemkonto für den Open ERP-Server:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Der Open ERP-Server muss ein eigenes Konto für den Betrieb verwenden, um die "
"Sicherheit des Systems nicht durch das Betreiben mit Superuser-Rechten zu "
"kompromittieren."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Bitte wählen Sie den Benutzernamen dieses Kontos."

41
debian/po/es.po vendored Normal file
View File

@ -0,0 +1,41 @@
# Spanish translation of openerp-server debconf templates.
# Copyright (C) 2009 Software in the Public Interest
# 2009 Fernando González de Requena <fgrequena@gmail.com>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-03-30 22:35+0200\n"
"Last-Translator: Fernando González de Requena <fgrequena@gmail.com>\n"
"Language-Team: Spanish <debian-l10n-spanish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Cuenta del sistema dedicada para el servidor Open ERP:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"El servidor de Open ERP debe utilizar una cuenta dedicada para su "
"funcionamiento, de tal modo que la seguridad del sistema no se vea "
"comprometida por su utilización con privilegios de administración."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Elija un nombre de usuario para esa cuenta."

41
debian/po/fi.po vendored Normal file
View File

@ -0,0 +1,41 @@
# Finnish translation of openerp-server debconf templates.
# Copyright (C) 2009 Esko Arajärvi
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-07 22:19+0300\n"
"Last-Translator: Esko Arajärvi <edu@iki.fi>\n"
"Language-Team: Finnish <debian-l10n-finnish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 0.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Dedikoitu järjestelmätunnus Open ERP-taustaohjelman ajamiseen:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Open ERP-palvelimen tulee käyttää dedikoitua tunnusta toiminnoissaan, jotta "
"järjestelmän turvallisuus ei vaarannu kuten käytettäessä "
"pääkäyttäjäoikeuksia."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Valitse kyseisen tunnuksen nimi."

39
debian/po/fr.po vendored Normal file
View File

@ -0,0 +1,39 @@
# French translation of openerp-server debconf templates.
# Copyright (C) 2009 Steve Petruzzello <dlist@bluewin.ch>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-03-26 01:12+0100\n"
"Last-Translator: Steve Petruzzello <dlist@bluewin.ch>\n"
"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Identifiant dédié pour le serveur Open ERP:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Le serveur Open ERP doit être exécuté avec un identifiant spécifique, "
"différent du superutilisateur, afin de ne pas compromettre la sécurité du "
"système."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Veuillez choisir cet identifiant."

41
debian/po/gl.po vendored Normal file
View File

@ -0,0 +1,41 @@
# Galizian translation of openerp-server debconf templates.
# Copyright (C) 2009 Marce Villarino <mvillarino@gmail.com>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-15 21:32+0200\n"
"Last-Translator: marce villarino <mvillarino@users.sourceforge.net>\n"
"Language-Team: Galician <proxecto@trasno.ent>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 0.2\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Conta de usuario do sistema adicada ao servidor Open ERP:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"O servidor Open ERP debe empregar unha conta adicada a el para que a "
"seguridade do sistema non se poña en perigo ao executalo con privilexios de "
"administrador."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Escolla o nome de usuario desa conta."

40
debian/po/it.po vendored Normal file
View File

@ -0,0 +1,40 @@
# Italian translation of openerp-server debconf templates.
# Copyright (C) 2009 Vincenzo Campanella <vinz65@gmail.com>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-03-26 08:52+0100\n"
"Last-Translator: Vincenzo Campanella <vinz65@gmail.com>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Account di sistema dedicato per il server di Open ERP:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Il server Open ERP deve utilizzare un account dedicato per eseguire le "
"proprie operazioni, in modo che la sicurezza del sistema non rischi di "
"essere compromessa eseguendolo con privilegi di superutente."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Scegliere il nome utente di tale account."

38
debian/po/ja.po vendored Normal file
View File

@ -0,0 +1,38 @@
# Japanese translation of openerp-server debconf templates.
# Copyright (C) 2009 Hideki Yamane <henrich@debian.or.jp>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-09 19:20+0900\n"
"Last-Translator: Hideki Yamane (Debian-JP) <henrich@debian.or.jp>\n"
"Language-Team: Japanese <debian-japanese@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Open ERP デーモン専用のシステムアカウント:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Open ERP サーバはその動作について専用のアカウントを使うようになっているため、"
"管理者特権で動作していてもシステムのセキュリティは侵害されません。"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "アカウントのユーザ名を選んでください。"

40
debian/po/pt.po vendored Normal file
View File

@ -0,0 +1,40 @@
# Portuguese translation of openerp-server debconf templates.
# Copyright (C) 2009 Américo Monteiro <a_monteiro@netcabo.pt>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-03-26 19:12+0000\n"
"Last-Translator: Américo Monteiro <a_monteiro@netcabo.pt>\n"
"Language-Team: Portuguese <traduz@debianpt.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Conta dedicada do sistema para o servidor Open ERP:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"O servidor Open ERP tem que usar uma conta dedicada para as suas operações, "
"isto para que a segurança do sistema não seja comprometida ao corrê-lo com "
"privilégios de superutilizador."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Por favor escolha o nome dessa conta."

43
debian/po/ru.po vendored Normal file
View File

@ -0,0 +1,43 @@
# German translation of openerp-server debconf templates.
# Copyright (C) 2009 Sergey Alyoshin <alyoshin.s@gmail.com>
# Copyright (C) 2009 Yuri Kozlov <yuray@komyakino.ru>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server 5.0.1-0-2\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-08 21:08+0400\n"
"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
"Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Специально выделенная системная учётная запись для Open ERP службы:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Для улучшения безопасности системы Open ERP сервер должен использовать "
"специально выделенную учётную запись, а не запускаться с правами "
"суперпользователя."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Укажите имя такой учётной записи."

40
debian/po/sv.po vendored Normal file
View File

@ -0,0 +1,40 @@
# Swedish translation of openerp-server debconf templates.
# Copyright (C) 2009 Martin Bagge <brother@bsnet.se>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-04-07 18:36+0100\n"
"Last-Translator: Martin Bagge <brother@bsnet.se>\n"
"Language-Team: swedish <debian-l10n-swedish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"X-Poedit-Language: Swedish\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "Dedikerat systemkonto för Open ERP server:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Open ERP servern måste ha ett dedikerat konto för att fungera på ett säkert "
"sätt, att använda privilegier från en superanvändare är inte säkert."
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "Ange kontots användarnamn."

38
debian/po/templates.pot vendored Normal file
View File

@ -0,0 +1,38 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr ""
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr ""

38
debian/po/zh_CN.po vendored Normal file
View File

@ -0,0 +1,38 @@
# Simplified Chinese translation of openerp-server debconf templates.
# Copyright (C) 2009 Deng Xiyue <manphiz-guest@users.alioth.debian.org>
# This file is distributed under the same license as the openerp-server package.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-server\n"
"Report-Msgid-Bugs-To: openerp-server@packages.debian.org\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2009-03-26 16:48+0800\n"
"Last-Translator: Deng Xiyue <manphiz-guest@users.alioth.debian.org>\n"
"Language-Team: Debian Chinese GB <debian-chinese-gb@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Dedicated system account for the Open ERP server:"
msgstr "指定操作 Open ERP 守护进程的专用系统帐户:"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid ""
"The Open ERP server must use a dedicated account for its operation so that "
"the system's security is not compromised by running it with superuser "
"privileges."
msgstr ""
"Open ERP 服务器必须使用一个专用的账户来进行操作,这样就不会因为使用超级用户权"
"限运行而破坏系统的安全。"
#. Type: string
#. Description
#: ../openerp-server.templates:1001
msgid "Please choose that account's username."
msgstr "请选择账户的用户名。"

21
debian/rules vendored
View File

@ -1,6 +1,20 @@
#!/usr/bin/make -f
# include /usr/share/quilt/quilt.make
SHELL := sh -e
update:
# Needs: shell-helper
cd debian; \
debconf-create-preseed *.config; \
for FILE in debian/*.preseed; \
do \
grep -v preseed $$FILE > $$FILE.tmp; \
mv $$FILE.tmp $$FILE; \
echo $$FILE >> debian/`basename $$FILE .preseed`.examples; \
done
clean: clean-patched unpatch
clean-patched: patch
@ -9,10 +23,11 @@ clean-patched: patch
rm -f build-stamp
NO_CHECK_MODULES=1 python setup.py clean
rm -rf build openerp-server
-find $(CURDIR) -type f -name "*.pyc" | xargs rm -f
debconf-updatepo
dh_clean
build:
@ -45,8 +60,10 @@ binary-indep: install
dh_testroot
dh_installchangelogs doc/Changelog
dh_installdocs
dh_installexamples
dh_install
dh_installinit --update-rcd-params='defaults 21'
dh_installdebconf
dh_lintian
dh_link
dh_compress

File diff suppressed because it is too large Load Diff

951
doc/Changelog-4.x Normal file
View File

@ -0,0 +1,951 @@
4.2.1
Bugfixes
Fix context for source_count function
Create stock move on production for products without BOM lines
Add IBAN fields in bank view
Fix uninitialize variable in import data
Update due date on invoice when payment term change
Fix store on field function that have type many2one or one2one
Request summary must be truncate
Partner event name must be truncate
Remove parent field on partner contact view
Fix icon type on journal period
Remove exception on the size of char field
Fix reference on move line that comes from invoice (Customer != Supplier)
Add function search on sheet_id of timesheet_sheet
Don't return 0 for balance account if there is no fiscal year
Fix set to draft for expense, now really set to draft
Add product and partner in the recursive call of tax compute
Don't compute balance account for inactive account
Fix bad encoding in log message on report_sxw
Fix overdue report for refund lines
Don't start server in non secure mode if secure mode have been set
Fix default value of move line if move_id is not find
Fix _product_partner_ref for cannot concatenate 'str' and 'bool' objects
Add partner_id in the context of SO for browsing the product
Fix multi-tax code on invoice
Fix tax definition for Belgium chart
Remove compute debit/credit on inactive account
Fix the way the tax are rounded for invoice with tax included prices
Fix SO to use the right uom and price to create invoice
Fix on_chnage uos on SO to return the id not the browse record
Add condition on the button "Sending goods>Packing to be invoiced" to show
only customer packings
Fix zero division error when the quantity is zero on an invoice line
Fix duplicate timesheet line that have been invoiced
Fix invoice report for bad removeParentNode tag
Fix priority for product view
Fix tax line computation when encoding account lines manually
Fix refund supplier invoice to have the same journal
New chinese translation
Pass context to action_done on stock move
Add product_uom change on sale order line
Fix demo data for working time UOM
Fix _sheet function in timesheet_sheet when called with a list of non
unique id
Remove commit inside function validate on account move
Use one function to post account move
Fix computation of sale/purchase amount in segmentation module
Use standar uom converion in analytic lines
Add journal_id in context for account move line search in payment module
Fix wrong id used by pricelist based on partner form
Use partner reference from SO/PO for invoice name if there is one
Make analysis analytic module include child accounts
4.2.0
Summary:
Add new view graph
REPORT_INTRASTAT: new module
KERNEL: add netrpc (speed improvement)
REPORT_STOCK: add report on stock by stock location and production lots
HR_TIMESHEET_INVOICE: add final invoice
MULTI_COMPANY_ACCOUNT: new module
ADD modules publication tools
KERNEL: add timezone
KERNEL: add concurnecy check
BASE: allow to specify many view_id in act_window
BASE: add ir.rules (acces base on record fields)
KERNEL: add search_count on objects
KERNEL: add assert tools (unit test)
KERNEL: improve workflow speed
KERNEL: move some modules to extra_addons
Bugfixes:
Fix pooler for multi-db
REPORT_ANALYTIC: new reports
BOARD_ACCOUNT: new dashboard for accountants
PURCHASE: allow multiple pickings for the same purchase order
STOCK: When refunding picking: confirm & Assign the newly generated picking
PRODUCT: add average price
STOCK: Fix workflow for stock
TOOLS: Fix export translate for wizard
KERNEL: add id in import_data
BASE: add history rate to currency
ACCOUNT: partner_id is now required for an invoice
HR_TIMESHEET: add exception if employee haven't product
I18N: new fr_CH file
HR_EXPENSE: fix domain
ACCOUNT: Fix invoice with currency and payment term
ACCOUNT: Fix currency
KERNEL: add pidfile
ACCOUNT,PURCHASE,SALE: use partner lang for description
Model Acces: Unlink permission (delete) is now available
KERNEL: Remove set for python2.3
HR: add id to Attendance menu
PRODUCT: add dimension to packaging
ACCOUNT: new cash_discount on payment term
KERNEL: Add price accuracy
BASE: Function to remove installed modules
REPORT_SALE: fix for sale without line
PURCHASE: remove use of currency
KERNEL: fix set without values
PURCHASE: fix domain pricelist
INVOICE: use date for currency rate
KERNEL: Fix import many2many by id
KERNEL: run the cron
ACCOUNT: bank statment line now have a ref t othe corresponding invoice
ACCOUNT: Add possibilitty to include tax amount in base amount for the computation of the next taxes
ACCOUNT: Add product in tax compute python code
KERNEL: use reportlab 2.0
BASE: fix import the same lang
ACCOUNT: fix tax code
ACCOUNT: define tax account for invoice and refund
ACCOUNT: add supplier tax to product
ACCOUNT: don't overwrite tax_code on the creation for account line
PURCHASE: use partner code for report order
KERNEL: fix pooler netsvc for multi-db
TOOLS: add ref to function tag
PRODUCT: fix digits on volume and weight, add weight_net
ACCOUNT: split to new module account_cash_discount
ORM : error message on python constraints are now displayed correctly
ACCOUNT: add partner to tax compute context
KERNEL: improve logger
PROJECT: add check_recursion for project
HR_TIMESHEET_INVOICE: improve create invoice
ACCOUNT: add product_id to analytic line create by invoice
KERNEL: fix the inheritance mechanism
KERNEL: Fix use always basename for cvs file
BASE: fix IBAN len to 27
INVOICE: fix invoice number for analytic
REPORT: add replace tag for custom header
ACCOUNT: add ref to analytic line
BASE: prevent exception in ir_cron
SALE: fix uos for tax_amount
MRP: fix dbname in _procure_confirm
HR_EXPENSE: add domain to analytic_account
KERNEL: use 0 instead of False for fix on _fnct_read
SUBSCRIPTION: add required to model
HR_TIMESHEET: add rounding on report
SALE: Fix cancel invoice and recreate invoice, now cancel also the order lines
STOCK-DELIVERY: add wizard invoice_onshipping from delivery to stock
STOCK: use tax from sale for invoice
BASE: improve copy of res.partner
ACCOUNT: pay only invoice if not in state draft
REPORT: fix rml translation, translate before eval
PRODUCT_EXTENDED: don't use seller price for bom price
ACCOUNT_TAX_INCLUDE: fix right amount in account move generate with tax_include
BASE: improve workflow print
SALE: fix workflow error when create invoice from wizard
MRP: Use company currency for Product Cost Structure
BASE: prevent recursion in company
KERNEL: Fix deleted property and many2one
KERNEL: allow directory for import csv
KERNEL: add store option to fields function
ACCOUNT: use property_account_tax on on_change_product
KERNEL: add right-click for translate label
KERNEL: fix log of backtrace
KERNEL: fix search on xxx2many
BASE: use tool to call popen.pipe2
KERNEL: fix print workflow on win32
BASE: fix US states
KERNEL: use python 2.3 format_exception
ACCOUNT: add multi-company into base accounting
KERNEL: check return code for exec_pg_command_pipe
KERNEL: fix search with active args
KERNEL: improve _sql_contsraints, now insert if doesn't exist
KERNEL: remove old inheritor and add _constraints and _sql_constraints to the fields inherited
CRM: bugfix mailgate
PURCHASE: fix the UOM for purchase line and improve update price unit
ACCOUNT: new invoice view
KERNEL,BASE: allow to create zip modules
BASE: add right-to-left
KERNEL: copy now ignore technical values ('create_date', 'create_uid', 'write_date' and 'write_uid')
ACCOUNT_TAX_INCLUDE: Now the module manage correctly the case when the taxes defined on the product differ from the taxes defined on the invoice line
ALL: fix colspan 3 -> 4
KERNEL: use context for search
ACCOUNT: improve speed of analytic account
ACCOUNT: fix search debit/credit on partner
ACCOUNT: fix refund invoice if no product_id nor uos_id on lines
MRP: fix scheduler location of product to produce and method, date of automatic orderpoint
KERNEL: many2many : fix unlink and link action
MRP: add default product_uom from context and add link from product to bom
PROJECT: improve speed for function fields
ALL: remove bad act_window name
KERNEL: modification for compatibility with postgres 7.4
KERNEL: fix size for selection field
KERNEL: fix compatibility for python2.5
KERNEL: add new win32 build script
KERNEL: add test for duplicate report and wizard
ACCOUNT: force round amount fixed in payment term
KERNEL: fix print screen
CRM: Better ergonomy
SERVER: add sum tag on tree view that display sum of the selected lines
KERNEL: allow subfield query on one2many
KERNEL: fix create_date and write_date as there are timestamp now
SERVER: improve language
KERNEL: fix search on fields function of type one2many, many2many
ACCOUNT: fix pay invoice to use period
ACCOUNT: add check recursion in account.tax.code
MRP: fix compute cycle for workcenter
BASE: add constraint uniq module name
BASE: improve update module list
ACCOUNT: add round to last payment term
KERNEL: don't modify the args of the call
KERNEL: don't use mutable as default value in function defintion
KERNEL: fix orm for sql query with reserved words
16/03/2007
4.0.3
Summary:
Improve the migration scripts
Some bugfixes
Print workflow on win32 (with ghostscript)
Bugfixes:
BASE: Fix "set default value"
HR_TIMESHEET_INVOICE: Improve invoice on timesheet
ACCOUNT: Fix tax amount
KERNEL: correct the delete for property
PURCHASE: fix the journal for invoice created by PO
KERNEL: fix the migration for id removed
Add id to some menuitem
BASE: prevent exception in ir_cron when the DB is dropped
HR: Fix sign-in/sign-out, the user is now allowed to provide a date in
the future
SALE: fix uos for the tax amount
MRP: fix wrong dbname in _procure_confirm
HR_EXPENSE: add domain to analytic_account
ACCOUNT: fix debit_get
SUBSCRIPTION: model is required now
HR_TIMESHEET: add rounding value to report
SALE: Fix cancel and recreate invoice, now cancel also the order lines
STOCK: use the tax define in sale for the invoice
ACCOUNT: add test to pay only if invoice not in state draft
KERNEL: root have access to all records
REPORT: fix rml translation to translate before the eval
ACCOUNT_TAX_INCLUDE: Use the right amount in account mmove generate
with tax_include
BASE: Improve the workflow print
SALE: Fix workflow error when creating invoice from the wizard
PRODUCT_EXTENDED: don't use pricelist to compute standard price
MRP: Use company currency for product cost structure
KERNEL: fix where clause when deleting false items
ACCOUNT: product source account depend on the invoice type now
ACCOUNT: use the property account tax for the on_change_product
ACCOUNT: use the invoice date for the date of analytic line
ACCOUNT: Fix the pay invoice when multi-currency
HR_TIMESHEET_PROJECT: use the right product
STOCK: Fix to assign picking with product consumable and call the
workflow
STOCK: Fix the split lot production
PURCHASE: fix workflow for purchase with manual invoice to not set
invoice and paid
DELIVERY: can use any type of journal for invoice
KERNEL: fix search on xxx2many
ACCOUNT: add id to sequence record
KERNEL: set properly the demo flag for module installed
KERNEL: Fix print workflow on win32
LETTER: fix print letter
Migration:
Fix migration for postreSQL 7.4
Fix the default value of demo in module
Fix migration of account_uos to product_uos
Wed Jan 17 15:06:07 CET 2007
4.0.2
Summary:
Improve the migration
Some bugfixes
Improve tax
Bugfixes:
Fix tax for invoice, refund, etc
SALE: fix view priority
PURCHASE: wizard may crash on some data
BASE: Fix import the same lang
BASE: start the cron
PURCHASE: fix domain for pricelist
KERNEL: fix object set without values
REPORT_SALE: fix for sale without line
KERNEL: add pidfile
BASE: remove 'set' for python2.3 compliant
Migration:
Migrate hr_timesheet user_id
Fri Dec 22 12:01:26 CET 2006
4.0.1
Summary:
Improve the migration
Some bugfixes
Bugfixes:
HR_EXPENSE: Fix domain
HR_TIMESHEET: Fix employee without product
TOOLS: Fix export translate
BASE: fix for concurrency of sequence number
MRP: fix report
CRM: fix graph report
KERNEL: fix instance of osv_pool
KERNEL: fix setup.py
Mon Dec 4 18:01:55 CET 2006
4.0.0
Summary:
Some bugfixes
Tue Nov 28 14:44:20 CET 2006
4.0.0-rc1
Summary:
This is a stable version (RC1) with lots of new features. Main
Improvements were:
Accounting: more functions, new modules, more stable
Much more better ergonomy
Lots of simplification to allows non IT people to use and
configure Tiny ERP: manage database, step by step configuration
menu, auto-installers, better help, ...
New:
Skill management module
ACCOUNT:
New and simpler bank statement form
New reports:
on Timesheets (analytic accounting)
Theorical revenue based on time spent
Global timesheet report by month
Chart of accounts
Different taxes methods supported
Gross (brut)
Net
Fixed amount
INVOICE:
invoice on shipping (manufacturing industry)
invoice on timesheet (services)
PURCHASE:
different invoicing control method (on order, on shipping,
manual)
Support of prices tax included /excluded in sales orders
New modules:
Sale_journal, stock_journal for bigger industries:
Divide works in different journals
New invoicing method from partner, to so, to picking
Daily, Monthly (grouped by partner or not)
New modules for prices with taxes included / excluded
New chart of accounts supported:
l10n_be/ l10n_chart_be_frnl/
l10n_chart_id/ l10n_chart_uk/
l10n_ca-qc/ l10n_chart_br/
l10n_chart_it/ l10n_chart_us_general/
l10n_ch/ l10n_chart_ca_en/
l10n_chart_it_cc2424/ l10n_chart_us_manufacturing/
l10n_ch_pcpbl_association/ l10n_chart_ca_fr/
l10n_chart_la/ l10n_chart_us_service/
l10n_ch_pcpbl_independant/ l10n_chart_ch_german/
l10n_chart_nl/ l10n_chart_us_ucoa/
l10n_ch_pcpbl_menage/ l10n_chart_cn/
l10n_chart_nl_standard/ l10n_chart_us_ucoa_ez/
l10n_ch_pcpbl_plangen/ l10n_chart_cn_traditional/
l10n_chart_no/ l10n_chart_ve/
l10n_ch_pcpbl_plangensimpl/ l10n_chart_co/
l10n_chart_pa/ l10n_fr/
l10n_ch_vat_brut/ l10n_chart_cz/
l10n_chart_pl/ l10n_se/
l10n_ch_vat_forfait/ l10n_chart_da/
l10n_chart_sp/ l10n_simple/
l10n_ch_vat_net/ l10n_chart_de_datev_skr03/
l10n_chart_sw/
l10n_chart_at/ l10n_chart_de_skr03/
l10n_chart_sw_church/
l10n_chart_au/ l10n_chart_hu/
l10n_chart_sw_food/
Step by step configuration menu
Setup wizard on first connection
Select a company profile, auto-install language, demo data, ...
Imrovements:
KERNEL: Demo data improved
Better import / export system
KERNEL: Multi-database management system
Backup, Restore, Create, Drop from the client
PRODUCT/PRODUCT_EXTD: Eavily change the product form, use the new
object to compute the pricelist
REPORTS:
Better Sale order, purchase order, invocies and customers reports
ACCOUNT: Support of taxes in accounts
management of the VAT taxes for most european countries:
Support of VAT codes in invoices
Better computation of default values in accounting entries
Preferences in partners, override products
Bugfix when closing a fiscal year
Better ergonomy when writting entries
New Module Management System:
Install / Upgrade new modules directly from the client
Install new languages
KERNEL:
Ability to add select=True at the object level for postgresql indexes
Bugfix in search in some inherited objects
Added the ability to call methods from a browse object
KERNEL+BASE: changed the way the migration system works for menuitems:
now you can change a menuitem defined elsewhere. And this will work
whether that menuitem has an id or not (it use the name of the
menuitem to find it)
KERNEL:
Installing a module from the client
Better Windows Auto-Installer
DELIVERY:
Delivery and invoicing on picking list
KERNEL:
Distinction between active (by default) and installable
ACCOUNT/PROJECT: Added support for the type of invoicing
CRM:
eMAil gateway
Management of different departments and sections
Rule system
About 20 new statistics reporting
eCommerce interface:
Better Joomla (virtuemart, OSCommerce) support
Joomla is now fully functionnal
Bugfixes:
ACCOUNT: tree view on reporting analytic account
KERNEL: Fix the bug that happened when mixing active and child_of
search
KERNEL: Check for the existance of active when computing child_of
PRODUCT: production computation with different UoM
------------------------------------------------------------------------
Fri Oct 6 14:44:05 CEST 2006
Server 3.4.2
Improvements:
BASE: changed workflow print system so that it handles inexisting
workflows more gracefully (patch from Geoff Gardiner)
MRP: new view to take into account the orderpoint exceptions
MRP: made menu title more explicit
Bugfixes:
ACCOUNT: fixed typo in invoice + changed sxw file so that it is in
sync with the rml file
DELIVERY: fixed taxes on delivery line (patch from Brice Vissière)
PROJECT: skip tasks without user in Gantt charts (it crashed the report)
PRODUCT: fixed bug when no active pricelist version was found
PRODUCT_EXTENDED: correct recursive computation of the price
SALE: get product price from price list even when quantity is set after
the product is set
STOCK: fixed partial picking
Packaging:
Changed migration script so that it works on PostgreSQL 7.4
------------------------------------------------------------------------
Tue Sep 12 15:10:31 CEST 2006
Server 3.4.1
Bugfixes:
ACCOUNT: fixed a bug which prevented to reconcile posted moves.
------------------------------------------------------------------------
Mon Sep 11 16:12:10 CEST 2006
Server 3.4.0 (changes since 3.3.0)
New modules:
ESALE_JOOMLA: integration with Joomla CMS
HR_TIMESHEET_ICAL: import iCal to automatically complete timesheet
based on outlook meetings
PARTNER_LDAP: adds partner synchronization with an LDAP server
SALE_REBATE: adds rebates to sale orders
4 new modules for reporting using postgresql views:
REPORT_CRM: reporting on CRM cases: by month, user, ...
REPORT_PROJECT: reporting on projects: tasks closed by project, user,
month, ...
REPORT_PURCHASE: reporting on purchases
REPORT_SALE: reporting on sales by periods and by product, category of
product, ...
New features:
KERNEL: Tiny ERP server and client may now communicate through HTTPS.
To launch the server with HTTPS, use the -S or --secure option
Note that if the server runs on HTTPS, the clients MUST connect
with the "secure" option checked.
KERNEL: the server can now run as a service on Windows
Printscreen function (Tree view print)
KERNEL: added a new --stop-after-init option which stops the server
just before it starts listening
KERNEL: added support for a new forcecreate attribute on XML record
fields: it is useful for records are in a data node marked as
"noupdate" but the record still needs to be added if it doesn't
exit yet. The typical use for that is when you add a new record
to a noupdate file/node.
KERNEL: manage SQL constraints with human-readable error message on the
client side, eg: Unique constraints
KERNEL: added a new system to be able to specify the tooltip for each
field in the definition of the field (by using the new help=""
attribute)
ACCOUNT: new report: aged trial balance system
ACCOUNT: added a wizard to pay an invoice from the invoice form
BASE: print on a module to print the reference guide using introspection
HR: added report on attendance errors
PRODUCT: products now support multi-Level variants
Improvements:
KERNEL: speed improvement in many parts of the system thanks to some
optimizations and a new caching system
KERNEL: New property system which replace the, now deprecated, ir_set
system. This leads to better migration of properties, more
practical use of them (they can be used like normal fields),
they can be translated, they are "multi-company aware", and
you can specify access rights for them on a per field basis.
KERNEL: Under windows, the server looks for its configuration file in
the "etc" sub directory (relative to the installation path).
This was needed so that the server can be run as a windows
service (using the SYSTEM profile).
KERNEL: added ability to import CSV files from the __terp__.py file
KERNEL: force freeing cursor when closing them, so that they are
available again immediately and not when garbage collected.
KERNEL: automatically drop not null/required constraints from removed
fields (ie which are in the database but not in the object)
KERNEL: added a command-line option to specify which smtp server to use
to send emails.
KERNEL: made browse_record hashable
ALL: removed shortcuts for the demo user.
ACCOUNT: better invoice report
ACCOUNT: Modifs for account chart, removed old stock_income account type
ACCOUNT: made the test_paid method on invoices more tolerant to buggy
data (open invoices without move/movelines)
ACCOUNT: better bank statement reconciliation system
ACCOUNT: accounting entries encoding improved a lot (using journal)
ACCOUNT: Adding a date and max Qty field in analytic accounts for
support contract
ACCOUNT: Adding the View type to analytic account / cost account
ACCOUNT: changed test_paid so that the workflow works even if there is
no move line
ACCOUNT: Cleanup credit/debit and balance computation methods. Should
be faster too.
ACCOUNT: use the normal sequence (from the journal) for the name of
moves generated from invoices instead of the longer name.
ACCOUNT: print Payment delay in invoices
ACCOUNT: account chart show subtotals
ACCOUNT: Subtotal in view accounts
ACCOUNT: Replaced some Typo: moves-> entries, Transaction -> entry
ACCOUNT: added quantities in analytic accounts view, and modified
cost ledger report for partners/customers
ACCOUNT: added default value for the currency field in invoices
ACCOUNT: added the comment/notes field on the invoice report
BASE: added menuitem (and action) to access partner functions (in the
definitions menu)
BASE: better demo data
BASE: duplicating a menu item now duplicates its action and submenus
BASE: Bank Details on Partners
CRM: View on all actions made on cases (used by our ISO9002 customer
to manage corrections to actions)
CRM: fixed wizard to create a sale order from a case
CRM: search on non active case, not desactivated by default
CRM: Case ID in fields with search
HR_TIMESHEET: new "sign_in, sign_out" using projects. It fills
timesheets and attendance at the same time.
HR_TIMESHEET: added cost unit to employee demo data
MRP: improvement in the scheduler
MRP: purchase order lines' description generated from a procurement
defaults to the product name instead of procurement name
MRP: Better traceability
MRP: Better view for procurement in exception
MRP: Added production delay in product forms. Use this delay for
average production delay for one product
MRP: dates scheduler, better computation
MRP: added constraint for non 0 BoM lines
PRODUCT: Better pricelist system (on template or variant of product)
PRODUCT_EXTENDED: Compute the price only if there is a supplier
PROJECT: when a task is closed, use the task's customer to warn the
customer if it is set, otherwise use the project contact.
PROJECT: better system to automatically send an email to the customer
when a task is closed or reopened.
PURCHASE: date_planned <= current_time line in red
PURCHASE: better purchase order report
PURCHASE: better purchase order duplication: you can now duplicate non
draft purchase orders and the new one will become draft.
SALE: better sale order report
SALE: better demo data for sale orders
SALE: better view for buttons in sale.order
SALE: select product => description = product name instead of code
SALE: warehouse field in shop is now required
SCRUM: lots of improvements for better useability
STOCK: allows to confirm empty picking lists.
STOCK: speed up stock computation methods
Bugfixes:
KERNEL: fix a huge bug in the search method for objects involving
"old-style" inheritance (inherits) which prevented some records
to be accessible in some cases. Most notable example was some
products were not accessible in the sale order lines if you had
more products in your database than the limit of your search
(80 by default).
KERNEL: fixed bug which caused OO (sxw) reports to behave badly (crash
on Windows and not print correctly on Linux) when data
contained XML entities (&, <, >)
KERNEL: reports are now fully concurrency compliant
KERNEL: fixed bug which caused menuitems without id to cause havoc on
update. The menuitems themselves were not created (which is
correct) but they created a bad "default" action for all
menuitems without action (such as all "menu folders").
KERNEL: fix a small security issue: we should check the password of the
user when a user asks for the result of a report (in addition
to the user id and id of that report)
KERNEL: bugfix in view inheritancy
KERNEL: fixed duplicating resource with a state field whose selection
doesn't contain a 'draft' value (for example project tasks). It
now uses the default value of the resource for that field.
KERNEL: fixed updating many2many fields using the (4, id) syntax
KERNEL: load/save the --logfile option correctly in the config file
KERNEL: fixed duplicating a resource with many2many fields
ALL: all properties should be inside a data tag with "noupdate" and
should have a forcecreate attribute.
ACCOUNT: fixed rounding bug in tax computation method
ACCOUNT: bugfix in balance and aged balance reports
ACCOUNT: fixing precision in function fields methods
ACCOUNT: fixed creation of account move lines without using the client
interface
ACCOUNT: fixed duplicating invoices
ACCOUNT: fixed opening an invoices whose description contained non
ASCII chars at specific position
ACCOUNT: small bugfixes in all accounting reports
ACCOUNT: fixed crash when --without-demo due to missing payment.term
ACCOUNT: fixed bug in automatic reconciliation
ACCOUNT: pass the address to the tax computation method so that it is
available in the tax "python applicable code"
BASE: allows to delete a request which has a history (it now deletes the
history as well as the request)
BASE: override copy method for users so that we can duplicate them
BASE: fixed bug when the user search for a partner by hitting on an
empty many2one field (it searched for a partner with ref=='')
BASE: making ir.sequence call thread-safe.
CRM: fixed a bug which introduced an invalid case state when closing a
case (Thanks to Leigh Willard)
HR: added domain to category tree view so that they are not displayed
twice
HR_TIMESHEET: fixed print graph
HR_TIMESHEET: fixed printing timesheet report
HR_TIMESHEET: Remove a timesheet entry removes the analytic line
MRP: bugfix on "force reservation"
MRP: fixed bugs in some reports and MRP scheduler when a partner has
no address
MRP: fix Force production button if no product available
MRP: when computing lots of procurements, the scheduler could raise
locking error at the database level. Fixed.
PRODUCT: added missing context to compute product list price
PRODUCT: fixed field type of qty_available and virtual_available
(integer->float). This prevented these fields to be displayed
in forms.
PROJECT: fixed the view of unassigned task (form and list) instead of
form only.
PURCHASE: fixed merging orders that made inventory errors when coming
from a procurement (orderpoint).
PURCHASE: fix bug which prevented to make a purchase order with
"manual" lines (ie without product)
PURCHASE: fix wizard to group purchase orders in several ways:
- only group orders if they are to the same location
- only group lines if they are the same except for qty and unit
- fix the workflow redirect method so that procurement are not
canceled when we merge orders
SALE: fixed duplicating a confirmed sale order
SALE: fixed making sale orders with "manual" lines (without product)
STOCK: future stock prevision bugfix (for move when date_planned < now)
STOCK: better view for stock.move
STOCK: fixed partial pickings (waiting for a production)
Miscellaneous minor bugfixes
Packaging:
Fixed bug in setup.py which didn't copy csv files nor some sub-
directories
Added a script to migrate a 3.3.0 server to 3.4.0 (you should read the
README file in doc/migrate/3.3.0-3.4.0)
Removed OsCommerce module
------------------------------------------------------------------------
Fri May 19 10:16:18 CEST 2006
Server 3.3.0
New features:
NEW MODULE: hr_timesheet_project
Automatically maps projects and tasks to analytic account
So that hours spent closing tasks are automatically encoded
KERNEL: Added a logfile and a pidfile option (patch from Dan Horak)
STOCK: Added support for revisions of tracking numbers
STOCK: Added support for revision of production lots
STOCK: Added a "splitting and tracking lines" wizard
PRODUCT_EXTENDED: Added a method to compute the cost of a product
automatically from the cost of its parts
Improvements:
ALL: Small improvements in wizards (order of buttons)
PRODUCT: Remove packaging info from supplierinfo
PROJECT: Better task view (moved unused fields to other tab)
SALE: Keep formating for sale order lines' notes in the sale order report
Bugfixes:
KERNEL: Fixed bug which caused field names with non ascii chars didn't work
in list mode on Windows
KERNEL: Fix concurrency issue with UpdatableStr with the use of
threading.local
KERNEL: Removed browse_record __unicode__ method... It made the sale order
report crash when using product names with non ASCII characters
KERNEL: Fixed bug which caused the translation export to fail when the server
was not launched from the directory its source is.
BASE: Updating a menuitem now takes care its parent menus
BASE: Fixed a cursor locking issue with updates
BASE: Fixed viewing sequence types as a tree/list
HR: Month field needs to be required in the "hours spent" report
PURCHASE: fixed group purchase order wizard:
- if there were orders from several different suppliers, it created a purchase
order for only the first supplier but canceled other orders, even those which
weren't merged in the created order (closes bugzilla #236)
- doesn't trash "manual" lines (ie lines with no product)
- pay attentions to unit factors when adding several lines together
MRP: fixed workcenter load report (prints only the selected workcenters) and
does't crash if the user didn't select all workcenters
Miscellaneous:
Removed pydot from required dependencies
------------------------------------------------------------------------
Server 3.3.0-rc1
================
Changelog for Users
-------------------
New module: OS Commerce
Integration with Tiny ERP and OS Commerce
Synchronisation 100% automated with eSale;
Import of categories of products
Export of products (with photos support)
Import of Orders (with the eslae module)
Export of stock level
Import of OSCommerce Taxes
Multiple shop allowed with different rules/products
Simple Installation
New Module: HR_TIMESHEET
Management by affair, timesheets creates analytic entries in the
accounting to get costs and revenue of each affairs. Affairs are
structured in trees.
New Module: Account Follow Up
Multi-Level and configurable Follows ups for the accounting module
New module; Productivity Analysis of users
A module to compare productivity of users of Tiny ERP
Generic module, you can compare everything (sales, products, partners,
...)
New Modules for localisations:
Accounting localisations for be, ca, fr, de, ch, sw
Fix: corrected encoding (latin1 to utf8) of Swedish account tree XML file
New Module - Sandwich
Allows employees to order the lunch
Keeps employees preferences
New Module TOOLS:
Email automatic importation/integration in the ERP
New Module EDI:
Import of EDI sale orders
Export of shippings
Multi-Company:
Tiny ERP is now fully multi-company !
New Company and configuration can be made in the client side.
ACCOUNTING:
Better Entries > Standard Entries (Editable Tree, like in Excel)
Automatic creation of lines
Journal centralised or not
Counterpart of lines in one line or one counterpart per entry
Analytic accounting recoded from scratch
5 new reports
Completly integrated with:
production,
hr_timesheet > Management by affairs
sales & purchases,
Tasks.
Added unreconciliation functionnalities
Added account tree fast rendering
Better tax computation system supporting worldwide specific countries
Better subscription system
Wizard to close a period
Wizard to clase a fiscal year
Very powerfull, simple and complete multi-currency system
in pricelists, sale order, purchases, ...
Added required fields in currencies (currency code)
Added decimal support
Better search on accounts (on code, shortcut or name)
Added constraint;
on users
on group
on accounts in a journal
added menuitem for automatic reconciliation; Multi-Levels
added factor to analytic units
added form view for budget items dotations
made number of digits in quantity field of the budget spread wizard coherent with the object field
fixed journal on purchase invoices/refunds (SugarCRM #6)
Better bank statement reconciliation
Fixed some reports
STOCK:
Better view for location (using localisation of locations; posx, posy, posz)
MARKETING:
fixed small bug when a partner has no adress
state field of marketing partner set as readonly
fixed marketing steps form view
better history view
disabled completely send sms wizard
fixed send email wizard
good priority -> high priority
fixed 'call again later' button
NETWORK:
added tree view for login/password
HR:
added holiday_status (=type of ...) to expense claim form view
BASE (partner):
fixed email_send and _email_send methods
removed partner without addresses from demo data
Added a date field in the partner form
MRP:
New report: workcenter futur loads
Analytic entries when production done.
SCHEDULER: better error msg in the generated request
Allows services in BoMs (for eg, subcontracting)
Project/Service Management:
create orders from tasks; bugfixes
Completly integrated with the rest of the ERP
Services can now be MTO/MTS, Buy (subcontracting), produce (task), ...
Services can be used anywhere (sale.order, bom, ...)
See this graph;
http://tiny.be/download/flux/flux_procurement.png
tasks sorted by ... AND id, so that the order is not random
within a priority
Automatic translations of all wizards
Scrum Project Management
Better Ergonomy; click on a sprint to view tasks
Planned, Effetive hours and progress in backlog, project and sprint
Better Burndown Chart computation
Better (simpler) view of tasks
Better demo Data
In All modules, eth converted to english
PRODUCT:
computing the weight of the packaging
Added last order date
Alternative suppliers (with delay, prefs, ...) for one product
PRICELISTS:
much more powerfull system
views simplified
one pricelist per usage: sale, order, pvc
price_type on product_view
Multi-Currency pricelist (EUR pricelist can depend on a $ one)
HR-TIMESHEET: fixed bugs in hours report:
sum all lines for the same day instead of displaying only the first one
it now uses the analytic unit factor, so that mixing hours and days has some sense
close cursor
SALE:
invoices generated from a sale order are pre-computed (taxes are computed)
new invoicing functionnality;
invoice on order quantities or,
invoice on shipped quantities
Invoice on a sale.order or a sale.order.line
added default value for uos_qty in sale order lines (default to 1)
Changelog for Developers
------------------------
New option --debug, that opens a python interpreter when an exception
occurs on the server side.
Better wizard system. Arguements self, cr, uid, context are passed in all
functions of the wizard like normal objects. All wizards converted.
Speed improvements in many views; partners, sale.order, ...
less requests from client to server when opening a form
Better translation system, wizard terms are exported.
Script to render module dependency graph
KERNEL+ALL: pass context to methods computing a selection.
Modification for actions and view definitions:
Actions Window:
New field: view_mode = 'tree,form' or 'form,tree' -> default='form,tree'
New role of view_type: tree (with shortcuts), form (others with switch button)
If you need a form that opens in list mode:
view_mode = 'tree,form' or 'tree'
view_type = form
You can define a view in a view (for example sale.order.line in
sale.order)
less requests on the client side, no need to define 2 views
Better command-line option message
Fixed bug which prevented to search for names using non ASCII
chars in many2one or many2many fields
Report Engine: bugfix for concurrency
Support of SQL constraints
Uniq, check, ...
Good error message in the client side (check an account entry with
credit and debit >0)
Fixed: when an exception was raised, the cursor wasn't closed and this
could cause a freeze in some cases
Sequence can contains code: %(year)s, ... for prefix, suffix
EX: ORDER %(year)/0005
Bugfixes for automatic migration system
bugfix on default value with creation of inherits
Improvement in report_sxw; you can redefine preprocess to do some
preprocessing before printing
Barcode support enabled by default
Fixed OpenOffice reports when the server is not launched from the
directory the code reside
Print workflow use a pipe instead of using a temporary file (now workflows
works on Windows Servers)
Inheritancy improved (multiple arguments: replace, inside, after, before)
Lots of small bugfixes

Some files were not shown because too many files have changed in this diff Show More