diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 7364ea505f6..0debdf11492 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -20,7 +20,7 @@ ############################################################################## from openerp.osv import fields, osv -from openerp.osv.osv import object_proxy +import openerp.service.model from openerp.tools.translate import _ from openerp import pooler import time @@ -171,355 +171,360 @@ class audittrail_log_line(osv.osv): 'field_description': fields.char('Field Description', size=64), } -class audittrail_objects_proxy(object_proxy): - """ Uses Object proxy for auditing changes on object of subscribed Rules""" +# Monkeypatch the model RPC endpoint for auditing changes. - def get_value_text(self, cr, uid, pool, resource_pool, method, field, value): - """ - Gets textual values for the fields. - If the field is a many2one, it returns the name. - If it's a one2many or a many2many, it returns a list of name. - In other cases, it just returns the value. - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID for security checks, - :param pool: current db's pooler object. - :param resource_pool: pooler object of the model which values are being changed. - :param field: for which the text value is to be returned. - :param value: value of the field. - :param recursive: True or False, True will repeat the process recursively - :return: string value or a list of values(for O2M/M2M) - """ +def get_value_text(cr, uid, pool, resource_pool, method, field, value): + """ + Gets textual values for the fields. + If the field is a many2one, it returns the name. + If it's a one2many or a many2many, it returns a list of name. + In other cases, it just returns the value. + :param cr: the current row, from the database cursor, + :param uid: the current user’s ID for security checks, + :param pool: current db's pooler object. + :param resource_pool: pooler object of the model which values are being changed. + :param field: for which the text value is to be returned. + :param value: value of the field. + :param recursive: True or False, True will repeat the process recursively + :return: string value or a list of values(for O2M/M2M) + """ - field_obj = (resource_pool._all_columns.get(field)).column - if field_obj._type in ('one2many','many2many'): - data = pool.get(field_obj._obj).name_get(cr, uid, value) - #return the modifications on x2many fields as a list of names - res = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - #return the modifications on a many2one field as its value returned by name_get() - res = value and value[1] or value - else: - res = value - return res + field_obj = (resource_pool._all_columns.get(field)).column + if field_obj._type in ('one2many','many2many'): + data = pool.get(field_obj._obj).name_get(cr, uid, value) + #return the modifications on x2many fields as a list of names + res = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + #return the modifications on a many2one field as its value returned by name_get() + res = value and value[1] or value + else: + res = value + return res - def create_log_line(self, cr, uid, log_id, model, lines=None): - """ - Creates lines for changed fields with its old and new values +def create_log_line(cr, uid, log_id, model, lines=None): + """ + Creates lines for changed fields with its old and new values - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param model: Object which values are being changed - @param lines: List of values for line is to be created - """ - if lines is None: - lines = [] - pool = pooler.get_pool(cr.dbname) - obj_pool = pool.get(model.model) - model_pool = pool.get('ir.model') - field_pool = pool.get('ir.model.fields') - log_line_pool = pool.get('audittrail.log.line') - for line in lines: - field_obj = obj_pool._all_columns.get(line['name']) - assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) - field_obj = field_obj.column - old_value = line.get('old_value', '') - new_value = line.get('new_value', '') - search_models = [model.id] - if obj_pool._inherits: - search_models += model_pool.search(cr, uid, [('model', 'in', obj_pool._inherits.keys())]) - field_id = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', search_models)]) - if field_obj._type == 'many2one': - old_value = old_value and old_value[0] or old_value - new_value = new_value and new_value[0] or new_value - vals = { - "log_id": log_id, - "field_id": field_id and field_id[0] or False, - "old_value": old_value, - "new_value": new_value, - "old_value_text": line.get('old_value_text', ''), - "new_value_text": line.get('new_value_text', ''), - "field_description": field_obj.string - } - line_id = log_line_pool.create(cr, uid, vals) - return True - - def log_fct(self, cr, uid_orig, model, method, fct_src, *args, **kw): - """ - Logging function: This function is performing the logging operation - @param model: Object whose values are being changed - @param method: method to log: create, read, write, unlink, action or workflow action - @param fct_src: execute method of Object proxy - - @return: Returns result as per method of Object proxy - """ - pool = pooler.get_pool(cr.dbname) - resource_pool = pool.get(model) - model_pool = pool.get('ir.model') - model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - assert model_id, _("'%s' Model does not exist..." %(model)) - model = model_pool.browse(cr, SUPERUSER_ID, model_id) - - # fields to log. currently only used by log on read() - field_list = [] - old_values = new_values = {} - - if method == 'create': - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - if res: - res_ids = [res] - new_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) - elif method == 'read': - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - # build the res_ids and the old_values dict. Here we don't use get_data() to - # avoid performing an additional read() - res_ids = [] - for record in res: - res_ids.append(record['id']) - old_values[(model.id, record['id'])] = {'value': record, 'text': record} - # log only the fields read - field_list = args[1] - elif method == 'unlink': - res_ids = args[0] - old_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - else: # method is write, action or workflow action - res_ids = [] - if args: - res_ids = args[0] - if isinstance(res_ids, (long, int)): - res_ids = [res_ids] - if res_ids: - # store the old values into a dictionary - old_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) - # process the original function, workflow trigger... - res = fct_src(cr, uid_orig, model.model, method, *args, **kw) - if method == 'copy': - res_ids = [res] - if res_ids: - # check the new values and store them into a dictionary - new_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) - # compare the old and new values and create audittrail log if needed - self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) - return res - - def get_data(self, cr, uid, pool, res_ids, model, method): - """ - This function simply read all the fields of the given res_ids, and also recurisvely on - all records of a x2m fields read that need to be logged. Then it returns the result in - convenient structure that will be used as comparison basis. - - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID. This parameter is currently not used as every - operation to get data is made as super admin. Though, it could be usefull later. - :param pool: current db's pooler object. - :param res_ids: Id's of resource to be logged/compared. - :param model: Object whose values are being changed - :param method: method to log: create, read, unlink, write, actions, workflow actions - :return: dict mapping a tuple (model_id, resource_id) with its value and textual value - { (model_id, resource_id): { 'value': ... - 'textual_value': ... - }, + @param cr: the current row, from the database cursor, + @param uid: the current user’s ID for security checks, + @param model: Object which values are being changed + @param lines: List of values for line is to be created + """ + if lines is None: + lines = [] + pool = pooler.get_pool(cr.dbname) + obj_pool = pool.get(model.model) + model_pool = pool.get('ir.model') + field_pool = pool.get('ir.model.fields') + log_line_pool = pool.get('audittrail.log.line') + for line in lines: + field_obj = obj_pool._all_columns.get(line['name']) + assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) + field_obj = field_obj.column + old_value = line.get('old_value', '') + new_value = line.get('new_value', '') + search_models = [model.id] + if obj_pool._inherits: + search_models += model_pool.search(cr, uid, [('model', 'in', obj_pool._inherits.keys())]) + field_id = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', search_models)]) + if field_obj._type == 'many2one': + old_value = old_value and old_value[0] or old_value + new_value = new_value and new_value[0] or new_value + vals = { + "log_id": log_id, + "field_id": field_id and field_id[0] or False, + "old_value": old_value, + "new_value": new_value, + "old_value_text": line.get('old_value_text', ''), + "new_value_text": line.get('new_value_text', ''), + "field_description": field_obj.string } - """ - data = {} - resource_pool = pool.get(model.model) - # read all the fields of the given resources in super admin mode - for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids): - values = {} - values_text = {} - resource_id = resource['id'] - # loop on each field on the res_ids we just have read - for field in resource: - if field in ('__last_update', 'id'): - continue - values[field] = resource[field] - # get the textual value of that field for this record - values_text[field] = self.get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field]) + line_id = log_line_pool.create(cr, uid, vals) + return True - field_obj = resource_pool._all_columns.get(field).column - if field_obj._type in ('one2many','many2many'): - # check if an audittrail rule apply in super admin mode - if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method): - # check if the model associated to a *2m field exists, in super admin mode - x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) - x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False - assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) - x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) - field_resource_ids = list(set(resource[field])) - if model.model == x2m_model.model: - # we need to remove current resource_id from the many2many to prevent an infinit loop - if resource_id in field_resource_ids: - field_resource_ids.remove(resource_id) - data.update(self.get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) - - data[(model.id, resource_id)] = {'text':values_text, 'value': values} - return data +def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw): + """ + Logging function: This function is performing the logging operation + @param model: Object whose values are being changed + @param method: method to log: create, read, write, unlink, action or workflow action + @param fct_src: execute method of Object proxy - def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None): - """ - This function compares the old data (i.e before the method was executed) and the new data - (after the method was executed) and returns a structure with all the needed information to - log those differences. + @return: Returns result as per method of Object proxy + """ + pool = pooler.get_pool(cr.dbname) + resource_pool = pool.get(model) + model_pool = pool.get('ir.model') + model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)]) + model_id = model_ids and model_ids[0] or False + assert model_id, _("'%s' Model does not exist..." %(model)) + model = model_pool.browse(cr, SUPERUSER_ID, model_id) + + # fields to log. currently only used by log on read() + field_list = [] + old_values = new_values = {} + + if method == 'create': + res = fct_src(cr, uid_orig, model.model, method, *args, **kw) + if res: + res_ids = [res] + new_values = get_data(cr, uid_orig, pool, res_ids, model, method) + elif method == 'read': + res = fct_src(cr, uid_orig, model.model, method, *args, **kw) + # build the res_ids and the old_values dict. Here we don't use get_data() to + # avoid performing an additional read() + res_ids = [] + for record in res: + res_ids.append(record['id']) + old_values[(model.id, record['id'])] = {'value': record, 'text': record} + # log only the fields read + field_list = args[1] + elif method == 'unlink': + res_ids = args[0] + old_values = get_data(cr, uid_orig, pool, res_ids, model, method) + res = fct_src(cr, uid_orig, model.model, method, *args, **kw) + else: # method is write, action or workflow action + res_ids = [] + if args: + res_ids = args[0] + if isinstance(res_ids, (long, int)): + res_ids = [res_ids] + if res_ids: + # store the old values into a dictionary + old_values = get_data(cr, uid_orig, pool, res_ids, model, method) + # process the original function, workflow trigger... + res = fct_src(cr, uid_orig, model.model, method, *args, **kw) + if method == 'copy': + res_ids = [res] + if res_ids: + # check the new values and store them into a dictionary + new_values = get_data(cr, uid_orig, pool, res_ids, model, method) + # compare the old and new values and create audittrail log if needed + process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) + return res + +def get_data(cr, uid, pool, res_ids, model, method): + """ + This function simply read all the fields of the given res_ids, and also recurisvely on + all records of a x2m fields read that need to be logged. Then it returns the result in + convenient structure that will be used as comparison basis. :param cr: the current row, from the database cursor, :param uid: the current user’s ID. This parameter is currently not used as every operation to get data is made as super admin. Though, it could be usefull later. :param pool: current db's pooler object. - :param model: model object which values are being changed - :param resource_id: ID of record to which values are being changed + :param res_ids: Id's of resource to be logged/compared. + :param model: Object whose values are being changed :param method: method to log: create, read, unlink, write, actions, workflow actions - :param old_values: dict of values read before execution of the method - :param new_values: dict of values read after execution of the method - :param field_list: optional argument containing the list of fields to log. Currently only - used when performing a read, it could be usefull later on if we want to log the write - on specific fields only. - - :return: dictionary with - * keys: tuples build as ID of model object to log and ID of resource to log - * values: list of all the changes in field values for this couple (model, resource) - return { - (model.id, resource_id): [] - } - - The reason why the structure returned is build as above is because when modifying an existing - record, we may have to log a change done in a x2many field of that object - """ - if field_list is None: - field_list = [] - key = (model.id, resource_id) - lines = { - key: [] - } - # loop on all the fields - for field_name, field_definition in pool.get(model.model)._all_columns.items(): - if field_name in ('__last_update', 'id'): + :return: dict mapping a tuple (model_id, resource_id) with its value and textual value + { (model_id, resource_id): { 'value': ... + 'textual_value': ... + }, + } + """ + data = {} + resource_pool = pool.get(model.model) + # read all the fields of the given resources in super admin mode + for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids): + values = {} + values_text = {} + resource_id = resource['id'] + # loop on each field on the res_ids we just have read + for field in resource: + if field in ('__last_update', 'id'): continue - #if the field_list param is given, skip all the fields not in that list - if field_list and field_name not in field_list: - continue - field_obj = field_definition.column + values[field] = resource[field] + # get the textual value of that field for this record + values_text[field] = get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field]) + + field_obj = resource_pool._all_columns.get(field).column if field_obj._type in ('one2many','many2many'): - # checking if an audittrail rule apply in super admin mode - if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method): - # checking if the model associated to a *2m field exists, in super admin mode + # check if an audittrail rule apply in super admin mode + if check_rules(cr, SUPERUSER_ID, field_obj._obj, method): + # check if the model associated to a *2m field exists, in super admin mode x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) - # the resource_ids that need to be checked are the sum of both old and previous values (because we - # need to log also creation or deletion in those lists). - x2m_old_values_ids = old_values.get(key, {'value': {}})['value'].get(field_name, []) - x2m_new_values_ids = new_values.get(key, {'value': {}})['value'].get(field_name, []) - # We use list(set(...)) to remove duplicates. - res_ids = list(set(x2m_old_values_ids + x2m_new_values_ids)) + field_resource_ids = list(set(resource[field])) if model.model == x2m_model.model: # we need to remove current resource_id from the many2many to prevent an infinit loop - if resource_id in res_ids: - res_ids.remove(resource_id) - for res_id in res_ids: - lines.update(self.prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list)) - # if the value value is different than the old value: record the change - if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]: - data = { - 'name': field_name, - 'new_value': key in new_values and new_values[key]['value'].get(field_name), - 'old_value': key in old_values and old_values[key]['value'].get(field_name), - 'new_value_text': key in new_values and new_values[key]['text'].get(field_name), - 'old_value_text': key in old_values and old_values[key]['text'].get(field_name) - } - lines[key].append(data) - return lines + if resource_id in field_resource_ids: + field_resource_ids.remove(resource_id) + data.update(get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) - def process_data(self, cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None): - """ - This function processes and iterates recursively to log the difference between the old - data (i.e before the method was executed) and the new data and creates audittrail log - accordingly. + data[(model.id, resource_id)] = {'text':values_text, 'value': values} + return data - :param cr: the current row, from the database cursor, - :param uid: the current user’s ID, - :param pool: current db's pooler object. - :param res_ids: Id's of resource to be logged/compared. - :param model: model object which values are being changed - :param method: method to log: create, read, unlink, write, actions, workflow actions - :param old_values: dict of values read before execution of the method - :param new_values: dict of values read after execution of the method - :param field_list: optional argument containing the list of fields to log. Currently only - used when performing a read, it could be usefull later on if we want to log the write - on specific fields only. - :return: True - """ - if field_list is None: - field_list = [] - # loop on all the given ids - for res_id in res_ids: - # compare old and new values and get audittrail log lines accordingly - lines = self.prepare_audittrail_log_line(cr, uid, pool, model, res_id, method, old_values, new_values, field_list) +def prepare_audittrail_log_line(cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None): + """ + This function compares the old data (i.e before the method was executed) and the new data + (after the method was executed) and returns a structure with all the needed information to + log those differences. - # if at least one modification has been found - for model_id, resource_id in lines: - name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1] - vals = { - 'method': method, - 'object_id': model_id, - 'user_id': uid, - 'res_id': resource_id, - 'name': name, - } - if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): - # the resource was not existing so we are forcing the method to 'create' - # (because it could also come with the value 'write' if we are creating - # new record through a one2many field) - vals.update({'method': 'create'}) - if (model_id, resource_id) not in new_values and method not in ('copy', 'read'): - # the resource is not existing anymore so we are forcing the method to 'unlink' - # (because it could also come with the value 'write' if we are deleting the - # record through a one2many field) - vals.update({'method': 'unlink'}) - # create the audittrail log in super admin mode, only if a change has been detected - if lines[(model_id, resource_id)]: - log_id = pool.get('audittrail.log').create(cr, SUPERUSER_ID, vals) - model = pool.get('ir.model').browse(cr, uid, model_id) - self.create_log_line(cr, SUPERUSER_ID, log_id, model, lines[(model_id, resource_id)]) - return True + :param cr: the current row, from the database cursor, + :param uid: the current user’s ID. This parameter is currently not used as every + operation to get data is made as super admin. Though, it could be usefull later. + :param pool: current db's pooler object. + :param model: model object which values are being changed + :param resource_id: ID of record to which values are being changed + :param method: method to log: create, read, unlink, write, actions, workflow actions + :param old_values: dict of values read before execution of the method + :param new_values: dict of values read after execution of the method + :param field_list: optional argument containing the list of fields to log. Currently only + used when performing a read, it could be usefull later on if we want to log the write + on specific fields only. - def check_rules(self, cr, uid, model, method): - """ - Checks if auditrails is installed for that db and then if one rule match - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID, - @param model: value of _name of the object which values are being changed - @param method: method to log: create, read, unlink,write,actions,workflow actions - @return: True or False - """ - pool = pooler.get_pool(cr.dbname) - if 'audittrail.rule' in pool.models: - model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - if model_id: - rule_ids = pool.get('audittrail.rule').search(cr, SUPERUSER_ID, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) - for rule in pool.get('audittrail.rule').read(cr, SUPERUSER_ID, rule_ids, ['user_id','log_read','log_write','log_create','log_unlink','log_action','log_workflow']): - if len(rule['user_id']) == 0 or uid in rule['user_id']: - if rule.get('log_'+method,0): + :return: dictionary with + * keys: tuples build as ID of model object to log and ID of resource to log + * values: list of all the changes in field values for this couple (model, resource) + return { + (model.id, resource_id): [] + } + + The reason why the structure returned is build as above is because when modifying an existing + record, we may have to log a change done in a x2many field of that object + """ + if field_list is None: + field_list = [] + key = (model.id, resource_id) + lines = { + key: [] + } + # loop on all the fields + for field_name, field_definition in pool.get(model.model)._all_columns.items(): + if field_name in ('__last_update', 'id'): + continue + #if the field_list param is given, skip all the fields not in that list + if field_list and field_name not in field_list: + continue + field_obj = field_definition.column + if field_obj._type in ('one2many','many2many'): + # checking if an audittrail rule apply in super admin mode + if check_rules(cr, SUPERUSER_ID, field_obj._obj, method): + # checking if the model associated to a *2m field exists, in super admin mode + x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) + x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False + assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) + x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) + # the resource_ids that need to be checked are the sum of both old and previous values (because we + # need to log also creation or deletion in those lists). + x2m_old_values_ids = old_values.get(key, {'value': {}})['value'].get(field_name, []) + x2m_new_values_ids = new_values.get(key, {'value': {}})['value'].get(field_name, []) + # We use list(set(...)) to remove duplicates. + res_ids = list(set(x2m_old_values_ids + x2m_new_values_ids)) + if model.model == x2m_model.model: + # we need to remove current resource_id from the many2many to prevent an infinit loop + if resource_id in res_ids: + res_ids.remove(resource_id) + for res_id in res_ids: + lines.update(prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list)) + # if the value value is different than the old value: record the change + if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]: + data = { + 'name': field_name, + 'new_value': key in new_values and new_values[key]['value'].get(field_name), + 'old_value': key in old_values and old_values[key]['value'].get(field_name), + 'new_value_text': key in new_values and new_values[key]['text'].get(field_name), + 'old_value_text': key in old_values and old_values[key]['text'].get(field_name) + } + lines[key].append(data) + return lines + +def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None): + """ + This function processes and iterates recursively to log the difference between the old + data (i.e before the method was executed) and the new data and creates audittrail log + accordingly. + + :param cr: the current row, from the database cursor, + :param uid: the current user’s ID, + :param pool: current db's pooler object. + :param res_ids: Id's of resource to be logged/compared. + :param model: model object which values are being changed + :param method: method to log: create, read, unlink, write, actions, workflow actions + :param old_values: dict of values read before execution of the method + :param new_values: dict of values read after execution of the method + :param field_list: optional argument containing the list of fields to log. Currently only + used when performing a read, it could be usefull later on if we want to log the write + on specific fields only. + :return: True + """ + if field_list is None: + field_list = [] + # loop on all the given ids + for res_id in res_ids: + # compare old and new values and get audittrail log lines accordingly + lines = prepare_audittrail_log_line(cr, uid, pool, model, res_id, method, old_values, new_values, field_list) + + # if at least one modification has been found + for model_id, resource_id in lines: + name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1] + vals = { + 'method': method, + 'object_id': model_id, + 'user_id': uid, + 'res_id': resource_id, + 'name': name, + } + if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): + # the resource was not existing so we are forcing the method to 'create' + # (because it could also come with the value 'write' if we are creating + # new record through a one2many field) + vals.update({'method': 'create'}) + if (model_id, resource_id) not in new_values and method not in ('copy', 'read'): + # the resource is not existing anymore so we are forcing the method to 'unlink' + # (because it could also come with the value 'write' if we are deleting the + # record through a one2many field) + vals.update({'method': 'unlink'}) + # create the audittrail log in super admin mode, only if a change has been detected + if lines[(model_id, resource_id)]: + log_id = pool.get('audittrail.log').create(cr, SUPERUSER_ID, vals) + model = pool.get('ir.model').browse(cr, uid, model_id) + create_log_line(cr, SUPERUSER_ID, log_id, model, lines[(model_id, resource_id)]) + return True + +def check_rules(cr, uid, model, method): + """ + Checks if auditrails is installed for that db and then if one rule match + @param cr: the current row, from the database cursor, + @param uid: the current user’s ID, + @param model: value of _name of the object which values are being changed + @param method: method to log: create, read, unlink,write,actions,workflow actions + @return: True or False + """ + pool = pooler.get_pool(cr.dbname) + if 'audittrail.rule' in pool.models: + model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', model)]) + model_id = model_ids and model_ids[0] or False + if model_id: + rule_ids = pool.get('audittrail.rule').search(cr, SUPERUSER_ID, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) + for rule in pool.get('audittrail.rule').read(cr, SUPERUSER_ID, rule_ids, ['user_id','log_read','log_write','log_create','log_unlink','log_action','log_workflow']): + if len(rule['user_id']) == 0 or uid in rule['user_id']: + if rule.get('log_'+method,0): + return True + elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): + if rule['log_action']: return True - elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): - if rule['log_action']: - return True - def execute_cr(self, cr, uid, model, method, *args, **kw): - fct_src = super(audittrail_objects_proxy, self).execute_cr - if self.check_rules(cr,uid,model,method): - return self.log_fct(cr, uid, model, method, fct_src, *args, **kw) - return fct_src(cr, uid, model, method, *args, **kw) +# Replace the openerp.service.model functions. - def exec_workflow_cr(self, cr, uid, model, method, *args, **kw): - fct_src = super(audittrail_objects_proxy, self).exec_workflow_cr - if self.check_rules(cr,uid,model,'workflow'): - return self.log_fct(cr, uid, model, method, fct_src, *args, **kw) - return fct_src(cr, uid, model, method, *args, **kw) +original_execute_cr = openerp.service.model.execute_cr +original_exec_workflow_cr = openerp.service.model.exec_workflow_cr -audittrail_objects_proxy() +def execute_cr(cr, uid, model, method, *args, **kw): + fct_src = original_execute_cr + if check_rules(cr,uid,model,method): + return log_fct(cr, uid, model, method, fct_src, *args, **kw) + return fct_src(cr, uid, model, method, *args, **kw) + +def exec_workflow_cr(cr, uid, model, method, *args, **kw): + fct_src = original_exec_workflow_cr + if check_rules(cr,uid,model,'workflow'): + return log_fct(cr, uid, model, method, fct_src, *args, **kw) + return fct_src(cr, uid, model, method, *args, **kw) + +openerp.service.model.execute_cr = execute_cr +openerp.service.model.exec_workflow_cr = exec_workflow_cr # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index ab0d8d324b4..ca75c9e20fc 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -24,12 +24,13 @@ from dateutil import parser from dateutil import rrule from dateutil.relativedelta import relativedelta from openerp.osv import fields, osv -from openerp.service import web_services from openerp.tools.translate import _ import pytz import re import time + from openerp import tools, SUPERUSER_ID +import openerp.service.report months = { 1: "January", 2: "February", 3: "March", 4: "April", \ @@ -1729,27 +1730,25 @@ class ir_model(osv.osv): ir_model() -class virtual_report_spool(web_services.report_spool): +original_exp_report = openerp.service.report.exp_report - def exp_report(self, db, uid, object, ids, data=None, context=None): - """ - Export Report - @param self: The object pointer - @param db: get the current database, - @param uid: the current user's ID for security checks, - @param context: A standard dictionary for contextual values - """ +def exp_report(db, uid, object, ids, data=None, context=None): + """ + Export Report + @param db: get the current database, + @param uid: the current user's ID for security checks, + @param context: A standard dictionary for contextual values + """ - if object == 'printscreen.list': - return super(virtual_report_spool, self).exp_report(db, uid, \ - object, ids, data, context) - new_ids = [] - for id in ids: - new_ids.append(base_calendar_id2real_id(id)) - if data.get('id', False): - data['id'] = base_calendar_id2real_id(data['id']) - return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, data, context) + if object == 'printscreen.list': + original_exp_report(db, uid, object, ids, data, context) + new_ids = [] + for id in ids: + new_ids.append(base_calendar_id2real_id(id)) + if data.get('id', False): + data['id'] = base_calendar_id2real_id(data['id']) + return original_exp_report(db, uid, object, new_ids, data, context) -virtual_report_spool() +openerp.service.report.exp_report = exp_report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_import/i18n/hr.po b/addons/base_import/i18n/hr.po index 7a119f19aaf..bc644bdfad5 100644 --- a/addons/base_import/i18n/hr.po +++ b/addons/base_import/i18n/hr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-14 22:33+0000\n" -"Last-Translator: Goran Kliska \n" +"PO-Revision-Date: 2013-02-12 22:11+0000\n" +"Last-Translator: Davor Bojkić \n" "Language-Team: Croatian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-22 06:07+0000\n" -"X-Generator: Launchpad (build 16378)\n" +"X-Launchpad-Export-Date: 2013-02-13 04:36+0000\n" +"X-Generator: Launchpad (build 16491)\n" #. module: base_import #. openerp-web @@ -29,7 +29,7 @@ msgstr "Dohvati sve moguće vrijednosti" #: code:addons/base_import/static/src/xml/import.xml:71 #, python-format msgid "Need to import data from an other application?" -msgstr "" +msgstr "Potreban je uvoz podataka iz druge aplikacije?" #. module: base_import #. openerp-web @@ -47,6 +47,15 @@ msgid "" "give \n" " you an example for Products and their Categories." msgstr "" +"Kada koristite vanjske ID-eve, možete uvesti csv datoteke \n" +" sa kolonom \"External ID\" " +"definirate vanjski ID svakog zapisa \n" +" koji uvozite. Tada ćete biti " +"u mogućnosti napraviti referencu \n" +" na taj zapis sa kolonama tipa " +"\"polje/External ID\". Sljedeća dvije \n" +" csv datoteke daju primjer za " +"proizvode i njihove kategorije." #. module: base_import #. openerp-web @@ -56,13 +65,16 @@ msgid "" "How to export/import different tables from an SQL \n" " application to OpenERP?" msgstr "" +"Kako izvesti/uvesti različite tablice iz SQL \n" +" " +"programa u OpenERP" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/js/import.js:310 #, python-format msgid "Relation Fields" -msgstr "" +msgstr "Relacijska polja" #. module: base_import #. openerp-web @@ -72,6 +84,9 @@ msgid "" "Country/Database ID: the unique OpenERP ID for a \n" " record, defined by the ID postgresql column" msgstr "" +"Država/ID baze: jedinstveni OpenERP ID za \n" +" " +" zapis, definran kolonom postgres kolonom ID" #. module: base_import #. openerp-web @@ -87,6 +102,16 @@ msgid "" "\n" " have a unique Database ID)" msgstr "" +"Korištenje \n" +" Država/ID " +"BAze : ovo bi trebali rijetko koristiti\n" +" za " +"označavanje. Ovo je većinom korišteno od strane programera\n" +" jer je " +"glavna prednost ovoga to što nikad nema konflikata \n" +" (možete " +"imati više zapisa istog naziva, ali uvjek sa jedinstvenim IDentifikatorom u " +"Bazi)" #. module: base_import #. openerp-web @@ -96,6 +121,9 @@ msgid "" "For the country \n" " Belgium, you can use one of these 3 ways to import:" msgstr "" +"Za državu \n" +" " +" Belgiju, možete koristiti jedan od ova 3 načina uza uvoz:" #. module: base_import #. openerp-web @@ -121,13 +149,20 @@ msgid "" "companies) TO \n" " '/tmp/company.csv' with CSV HEADER;" msgstr "" +"kopirajte \n" +" (select " +"'company_'||id as \"External ID\",company_name\n" +" as " +"\"Name\",'True' as \"Is a Company\" from companies) TO\n" +" " +"'/tmp/company.csv' with CSV HEADER;" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:206 #, python-format msgid "CSV file for Manufacturer, Retailer" -msgstr "" +msgstr "CSV datoteka za Proizvođače, Veletrgovce" #. module: base_import #. openerp-web @@ -139,6 +174,11 @@ msgid "" "\n" " data from a third party application." msgstr "" +"Koristi \n" +" Država/Vanjski ID. " +"koristite vanjski ID kad uvozite \n" +" podatke iz drugih " +"aplikacija." #. module: base_import #. openerp-web @@ -152,7 +192,7 @@ msgstr "" #: code:addons/base_import/static/src/xml/import.xml:80 #, python-format msgid "XXX/External ID" -msgstr "" +msgstr "XXX/Vanjski ID" #. module: base_import #. openerp-web @@ -181,6 +221,14 @@ msgid "" "\n" " See the following question." msgstr "" +"Primjetite da vaša csv datoteka \n" +" ima tabulator za " +"odvajanje, a OpenERP neće \n" +" primjetiti ta odvajanja. " +"Morate promjineiti format \n" +" zapisa u vašem tabličnom " +"kalkulatoru. \n" +" Vidi sljedeće pitanje." #. module: base_import #. openerp-web @@ -199,7 +247,7 @@ msgstr "" #: code:addons/base_import/static/src/xml/import.xml:239 #, python-format msgid "Can I import several times the same record?" -msgstr "" +msgstr "Mogu li isti zapis uvesti nekoliko puta?" #. module: base_import #. openerp-web @@ -213,7 +261,7 @@ msgstr "Potvrdi" #: code:addons/base_import/static/src/xml/import.xml:55 #, python-format msgid "Map your data to OpenERP" -msgstr "" +msgstr "Mapirajte vaše podatke na OpenERP" #. module: base_import #. openerp-web @@ -224,6 +272,10 @@ msgid "" " the easiest way when your data come from CSV files \n" " that have been created manually." msgstr "" +"Korištenje Države: ovo je \n" +" najlakši način kada vaši " +"podaci dolaze iz csv datoteka\n" +" koje su sastavljene ručno." #. module: base_import #. openerp-web @@ -233,6 +285,8 @@ msgid "" "What's the difference between Database ID and \n" " External ID?" msgstr "" +"Koja je razlika izmeži ID Baze i \n" +" vanjski ID?" #. module: base_import #. openerp-web @@ -244,25 +298,30 @@ msgid "" "\n" " you 3 different fields to import:" msgstr "" +"Na primjer, \n" +" referenciranje države " +"kontakta, OpenERP predlaže \n" +" 3 različita polja za " +"uvoz :" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:175 #, python-format msgid "What can I do if I have multiple matches for a field?" -msgstr "" +msgstr "Što da radim ako imam više istih zapisa za polje?" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:302 #, python-format msgid "External ID,Name,Is a Company" -msgstr "" +msgstr "Vanjski ID , Naziv, Je Tvrtka" #. module: base_import #: field:base_import.tests.models.preview,somevalue:0 msgid "Some Value" -msgstr "" +msgstr "Neka vrijednost" #. module: base_import #. openerp-web @@ -272,6 +331,9 @@ msgid "" "The following CSV file shows how to import \n" " suppliers and their respective contacts" msgstr "" +"Sljedeća csv datoteka pokazuje kako uvesti \n" +" " +" dobavljače i njihove pripadne kontakte" #. module: base_import #. openerp-web @@ -281,6 +343,9 @@ msgid "" "How can I change the CSV file format options when \n" " saving in my spreadsheet application?" msgstr "" +"Kako da promijenim opcije csv formata \n" +" " +"kada spremam datoteku u tabličnom kalkulatoru?" #. module: base_import #. openerp-web @@ -301,6 +366,21 @@ msgid "" "orignial \n" " database)." msgstr "" +"kako možete vidjeti iz ove datoteke, Fabien i Laurence \n" +" " +" rade za organizaciju Biggies (company_1), a \n" +" " +" Eric radi za Organi. Pozezivanje osoba i " +"organizacija se radi \n" +" " +" korištenjem Vanjskog ID-a organizacije. Morali smo " +"staviti prefix \n" +" " +" naziva tablice na Vanjski ID da izbjegnemo konflikt " +"istog ID-a osobe \n" +" " +" i organizacije (osoba_1 i organizacija_1 koji dijele " +"isti ID u originalnoj bazi)." #. module: base_import #. openerp-web @@ -315,13 +395,20 @@ msgid "" "\n" " '/tmp/person.csv' with CSV" msgstr "" +"kopirajte \n" +" (select'person_'||id as \"External ID\",person_name " +"as\n" +" \"Name\",'False' as \"Is a " +"Company\",'company_'||company_id\n" +" as \"Related Company/External ID\" from persons) TO\n" +" '/tmp/person.csv' with CSV" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:148 #, python-format msgid "Country: Belgium" -msgstr "" +msgstr "Država : Belgija" #. module: base_import #: model:ir.model,name:base_import.model_base_import_tests_models_char_stillreadonly @@ -342,7 +429,7 @@ msgstr "" #: code:addons/base_import/static/src/xml/import.xml:233 #, python-format msgid "Suppliers and their respective contacts" -msgstr "" +msgstr "Dobavljači i njihovi pripadni kontakti" #. module: base_import #. openerp-web @@ -375,6 +462,11 @@ msgid "" "\n" " PSQL:" msgstr "" +"Za stvaranje csv datoteke za osobe povezane sa \n" +" " +" organizacijama, koristimo ljedeću SQL naredbu u \n" +" " +" PSQL:" #. module: base_import #. openerp-web @@ -386,6 +478,13 @@ msgid "" " (in 'Save As' dialog box > click 'Tools' dropdown \n" " list > Encoding tab)." msgstr "" +"Microsoft Excell će vam omogućiti \n" +" da promjenite kodnu stranu " +"jedino kod snimanja \n" +" (U 'Save as' dijalogu > " +"kliknite na 'Tools' padajući izbornik > \n" +" odaberite 'Encoding' " +"karticu)" #. module: base_import #: field:base_import.tests.models.preview,othervalue:0 @@ -402,6 +501,13 @@ msgid "" " later, it's thus good practice to specify it\n" " whenever possible" msgstr "" +"će također biti korišteno za ažuriranje originalnog \n" +" " +"uvoza, ako kasnije trebate ponovo uvesti \n" +" " +"izmjenjene podatke, zato se smatra dobrom praksom \n" +" " +"koristiti kad god je moguće" #. module: base_import #. openerp-web @@ -411,6 +517,9 @@ msgid "" "file to import. If you need a sample importable file, you\n" " can use the export tool to generate one." msgstr "" +"datoteka za uvoz. Ako trebate uzorak datoteke koja se može uvesti,\n" +" možete koristiti " +"alat za izvoz da napravite jednu." #. module: base_import #. openerp-web @@ -419,7 +528,7 @@ msgstr "" msgid "" "Country/Database \n" " ID: 21" -msgstr "" +msgstr "Država/Baza" #. module: base_import #: model:ir.model,name:base_import.model_base_import_tests_models_char @@ -429,14 +538,14 @@ msgstr "" #. module: base_import #: help:base_import.import,file:0 msgid "File to check and/or import, raw binary (not base64)" -msgstr "" +msgstr "Datoteke za provjeru i/ili uvoz, raw binary ( ne base64)" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:230 #, python-format msgid "Purchase orders with their respective purchase order lines" -msgstr "" +msgstr "Narudžbe i njihove pripadne stavke" #. module: base_import #. openerp-web @@ -448,6 +557,14 @@ msgid "" " field corresponding to the column. This makes imports\n" " simpler especially when the file has many columns." msgstr "" +"Ako datoteka sadrži\n" +" nazive kolona, OpenERP može " +"pokušati \n" +" automatski odrediti polja koja " +"odgovaraju kolonama. \n" +" Ovo čini uvoz jednostavnijim " +"pogotovo ako datoteka ima \n" +" mnogo kolona." #. module: base_import #. openerp-web @@ -464,6 +581,8 @@ msgid "" ". The issue is\n" " usually an incorrect file encoding." msgstr "" +". Problem je \n" +" obično netočna kodna strana." #. module: base_import #: model:ir.model,name:base_import.model_base_import_tests_models_m2o_required @@ -519,7 +638,7 @@ msgstr "ID baze podataka" #: code:addons/base_import/static/src/xml/import.xml:313 #, python-format msgid "It will produce the following CSV file:" -msgstr "" +msgstr "Će napraviti sljedeću csv datoteku:" #. module: base_import #. openerp-web @@ -548,7 +667,7 @@ msgstr "" #: code:addons/base_import/static/src/xml/import.xml:360 #, python-format msgid "Import preview failed due to:" -msgstr "" +msgstr "Predpregled uvoza nije uspio zbog:" #. module: base_import #. openerp-web @@ -643,7 +762,7 @@ msgstr "Uvezi CSV datoteku" #: code:addons/base_import/static/src/js/import.js:74 #, python-format msgid "Quoting:" -msgstr "" +msgstr "Navođenje:" #. module: base_import #: model:ir.model,name:base_import.model_base_import_tests_models_m2o_required_related @@ -670,7 +789,7 @@ msgstr "Uvoz" #: code:addons/base_import/static/src/js/import.js:407 #, python-format msgid "Here are the possible values:" -msgstr "" +msgstr "Evo mogućih vrijednosti:" #. module: base_import #. openerp-web @@ -687,13 +806,15 @@ msgid "" "A single column was found in the file, this often means the file separator " "is incorrect" msgstr "" +"U datoteci je nađena samo jedna kolona, to često znači da je format " +"razdjelnika neispravan." #. module: base_import #. openerp-web #: code:addons/base_import/static/src/xml/import.xml:293 #, python-format msgid "dump of such a PostgreSQL database" -msgstr "" +msgstr "dump takve PostgereSQL baze" #. module: base_import #. openerp-web @@ -710,6 +831,9 @@ msgid "" "The following CSV file shows how to import purchase \n" " orders with their respective purchase order lines:" msgstr "" +"Sljedeća csv datoteka pokazuje kako uvesti \n" +" naloge za nabavu sa " +"njihovm pripadnim stavkama :" #. module: base_import #. openerp-web @@ -719,6 +843,9 @@ msgid "" "What can I do when the Import preview table isn't \n" " displayed correctly?" msgstr "" +"Što mogu uraditi kada se tablice Predpregleda za uvoz\n" +" " +" ne prikazuju ispravno?" #. module: base_import #: field:base_import.tests.models.char,value:0 @@ -770,7 +897,7 @@ msgstr "" #: code:addons/base_import/static/src/js/import.js:396 #, python-format msgid "(%d more)" -msgstr "" +msgstr "(%d više)" #. module: base_import #. openerp-web @@ -829,7 +956,7 @@ msgstr "" #: code:addons/base_import/static/src/js/import.js:373 #, python-format msgid "Everything seems valid." -msgstr "" +msgstr "Sve se čini u redu." #. module: base_import #. openerp-web @@ -914,6 +1041,15 @@ msgid "" " will set the EMPTY value in the field, instead of \n" " assigning the default value." msgstr "" +"Ako ne postavite sva polja u vašoj csv datoteci, \n" +" OpenERP će " +"dodijeliti zadane vrijednosti za svako \n" +" nedefinirano " +"polje, ali ako postavite polja sa praznim virjenostima u csv-u \n" +" OpenERP će " +"postaviti vrijednost tih polja na \"PRAZNO\", umjesto da im \n" +" dodijeli zadane " +"vrijednosti" #. module: base_import #. openerp-web @@ -930,6 +1066,9 @@ msgid "" "What happens if I do not provide a value for a \n" " specific field?" msgstr "" +"Što se dešava ako ne dajem vrijednost za \n" +" " +"pojedino polje?" #. module: base_import #. openerp-web @@ -957,6 +1096,11 @@ msgid "" "spreadsheet \n" " application." msgstr "" +"Ovo vam \n" +" omogućuje da " +"koristite alat za Uvoz/Izvoz OpenERP-a \n" +" za izmjenu serija " +"zapisa u vašem omiljenom tabličnom kalkulatoru" #. module: base_import #. openerp-web @@ -993,14 +1137,14 @@ msgstr "" #: code:addons/base_import/static/src/xml/import.xml:169 #, python-format msgid "CSV file for categories" -msgstr "" +msgstr "CSV datoteka za kategorije" #. module: base_import #. openerp-web #: code:addons/base_import/static/src/js/import.js:309 #, python-format msgid "Normal Fields" -msgstr "" +msgstr "Normalna polja" #. module: base_import #. openerp-web @@ -1012,6 +1156,11 @@ msgid "" " identifier from the original application and\n" " map it to the" msgstr "" +"kako bi ponovo napravili relacije između\n" +" " +"različitih zapisa, trebali bi koristiti jedinstveni\n" +" " +"identifikator iz originalnog zapisa i njega mapirati na" #. module: base_import #. openerp-web @@ -1054,7 +1203,7 @@ msgstr "Naziv" #: code:addons/base_import/static/src/xml/import.xml:80 #, python-format msgid "to the original unique identifier." -msgstr "" +msgstr "originalni jedinstveni identifikator" #. module: base_import #. openerp-web @@ -1131,14 +1280,14 @@ msgstr "Vanjski ID" #: code:addons/base_import/static/src/xml/import.xml:39 #, python-format msgid "File Format Options…" -msgstr "" +msgstr "Opcije Formata datoteka..." #. module: base_import #. openerp-web #: code:addons/base_import/static/src/js/import.js:392 #, python-format msgid "between rows %d and %d" -msgstr "" +msgstr "između reda %d i %d" #. module: base_import #. openerp-web @@ -1163,4 +1312,4 @@ msgstr "" #. module: base_import #: field:base_import.import,file:0 msgid "File" -msgstr "" +msgstr "Datoteka" diff --git a/addons/document/document.py b/addons/document/document.py index 1671b6bc1ba..85468e00509 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -31,11 +31,11 @@ from StringIO import StringIO import psycopg2 import openerp -from openerp import netsvc from openerp import pooler from openerp import tools from openerp.osv import fields, osv from openerp.osv.orm import except_orm +import openerp.report.interface from openerp.tools.misc import ustr from openerp.tools.translate import _ from openerp.tools.safe_eval import safe_eval @@ -456,7 +456,7 @@ class document_directory_content(osv.osv): if node.extension != '.pdf': raise Exception("Invalid content: %s" % node.extension) report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.report_id, context=context) - srv = netsvc.Service._services['report.'+report.report_name] + srv = openerp.report.interface.report_int._reports['report.'+report.report_name] ctx = node.context.context.copy() ctx.update(node.dctx) pdf,pdftype = srv.create(cr, uid, [node.act_id,], {}, context=ctx) diff --git a/addons/document_ftp/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py index a9efac5819c..b746f189700 100644 --- a/addons/document_ftp/ftpserver/abstracted_fs.py +++ b/addons/document_ftp/ftpserver/abstracted_fs.py @@ -10,6 +10,7 @@ import glob import fnmatch from openerp import pooler, netsvc, sql_db +import openerp.service from openerp.service import security from openerp.osv import osv @@ -60,7 +61,7 @@ class abstracted_fs(object): def db_list(self): """Get the list of available databases, with FTPd support """ - s = netsvc.ExportService.getService('db') + s = openerp.service.db result = s.exp_list(document=True) self.db_name_list = [] for db_name in result: diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index e5756f5df91..1781a02d76e 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -38,6 +38,7 @@ except ImportError: import openerp from openerp import pooler, sql_db, netsvc +import openerp.service from openerp.tools import misc from cache import memoize @@ -372,7 +373,7 @@ class openerp_dav_handler(dav_interface): @memoize(4) def _all_db_list(self): """return all databases who have module document_webdav installed""" - s = netsvc.ExportService.getService('db') + s = openerp.service.db result = s.exp_list() self.db_name_list=[] for db_name in result: diff --git a/addons/edi/edi_service.py b/addons/edi/edi_service.py index fd911139170..d5dc5c09f74 100644 --- a/addons/edi/edi_service.py +++ b/addons/edi/edi_service.py @@ -21,45 +21,46 @@ import logging import openerp -import openerp.netsvc as netsvc _logger = logging.getLogger(__name__) -class edi(netsvc.ExportService): +# TODO this is not needed anymore: +# - the exposed new service just forward to the model service +# - the service is called by the web controller, which can +# now directly call into openerp as the web server is always +# embedded in openerp. - def __init__(self, name="edi"): - netsvc.ExportService.__init__(self, name) +def _edi_dispatch(db_name, method_name, *method_args): + try: + registry = openerp.modules.registry.RegistryManager.get(db_name) + assert registry, 'Unknown database %s' % db_name + edi = registry['edi.edi'] + cr = registry.db.cursor() + res = None + res = getattr(edi, method_name)(cr, *method_args) + cr.commit() + except Exception, e: + _logger.exception('Failed to execute EDI method %s with args %r.', + method_name, method_args) + raise + finally: + cr.close() + return res - def _edi_dispatch(self, db_name, method_name, *method_args): - try: - registry = openerp.modules.registry.RegistryManager.get(db_name) - assert registry, 'Unknown database %s' % db_name - edi = registry['edi.edi'] - cr = registry.db.cursor() - res = None - res = getattr(edi, method_name)(cr, *method_args) - cr.commit() - except Exception: - _logger.exception('Failed to execute EDI method %s with args %r.', method_name, method_args) - raise - finally: - cr.close() - return res +def exp_import_edi_document(db_name, uid, passwd, edi_document, context=None): + return _edi_dispatch(db_name, 'import_edi', uid, edi_document, None) - def exp_import_edi_document(self, db_name, uid, passwd, edi_document, context=None): - return self._edi_dispatch(db_name, 'import_edi', uid, edi_document, None) +def exp_import_edi_url(db_name, uid, passwd, edi_url, context=None): + return _edi_dispatch(db_name, 'import_edi', uid, None, edi_url) - def exp_import_edi_url(self, db_name, uid, passwd, edi_url, context=None): - return self._edi_dispatch(db_name, 'import_edi', uid, None, edi_url) +@openerp.http.rpc('edi') +def dispatch(method, params): + if method in ['import_edi_document', 'import_edi_url']: + (db, uid, passwd) = params[0:3] + openerp.service.security.check(db, uid, passwd) + else: + raise KeyError("Method not found: %s." % method) + fn = globals()['exp_' + method] + return fn(*params) - def dispatch(self, method, params): - if method in ['import_edi_document', 'import_edi_url']: - (db, uid, passwd ) = params[0:3] - openerp.service.security.check(db, uid, passwd) - else: - raise KeyError("Method not found: %s." % method) - fn = getattr(self, 'exp_'+method) - return fn(*params) - -edi() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/i18n/hu.po b/addons/mail/i18n/hu.po index 65385c23ef0..3d3117c1b51 100644 --- a/addons/mail/i18n/hu.po +++ b/addons/mail/i18n/hu.po @@ -7,19 +7,19 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-12-21 10:09+0000\n" -"Last-Translator: Herczeg Péter \n" +"PO-Revision-Date: 2013-02-12 17:52+0000\n" +"Last-Translator: krnkris \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-22 06:04+0000\n" -"X-Generator: Launchpad (build 16378)\n" +"X-Launchpad-Export-Date: 2013-02-13 04:36+0000\n" +"X-Generator: Launchpad (build 16491)\n" #. module: mail #: view:mail.followers:0 msgid "Followers Form" -msgstr "" +msgstr "Követők űrlapjai" #. module: mail #: model:ir.model,name:mail.model_publisher_warranty_contract @@ -45,7 +45,7 @@ msgstr "Üzenet címzettjei" #. module: mail #: help:mail.message.subtype,default:0 msgid "Activated by default when subscribing." -msgstr "" +msgstr "Alapértelmezetten aktiválva lesz a feliratkozásnál." #. module: mail #: view:mail.message:0 @@ -70,6 +70,8 @@ msgid "" "The name of the email alias, e.g. 'jobs' if you want to catch emails for " "" msgstr "" +"Az e-mail álnáv neve, pl. 'állások' ha az " +"helyről akarjuk az e-maileket megkapni" #. module: mail #: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard @@ -82,7 +84,7 @@ msgstr "Email írás" #: code:addons/mail/static/src/xml/mail.xml:132 #, python-format msgid "Add them into recipients and followers" -msgstr "" +msgstr "A címzettekhez és a követőkhőz adja hozzá" #. module: mail #: view:mail.group:0 @@ -111,6 +113,8 @@ msgid "" "Email address of the sender. This field is set when no matching partner is " "found for incoming emails." msgstr "" +"A küldő e-mail címei. Ez a mező lesz beállítva, ha nem talált egyező " +"partnert a bejövő levelekhez." #. module: mail #: model:ir.model,name:mail.model_mail_compose_message @@ -122,12 +126,12 @@ msgstr "Email varázsló" #: code:addons/mail/static/src/xml/mail_followers.xml:23 #, python-format msgid "Add others" -msgstr "" +msgstr "Hozzáadás" #. module: mail #: field:mail.message.subtype,parent_id:0 msgid "Parent" -msgstr "" +msgstr "Szülő" #. module: mail #: field:mail.group,message_unread:0 @@ -149,6 +153,9 @@ msgid "" "Members of those groups will automatically added as followers. Note that " "they will be able to manage their subscription manually if necessary." msgstr "" +"Ezeknek a csoportoknak a tagjai automatikusan hozzá lesznek adva a " +"követőkhöz. Megjegyezve, hogy ha szükséges szerkeszteni tudják a " +"feliratkozásukat." #. module: mail #. openerp-web @@ -161,7 +168,7 @@ msgstr "Valóban törölni kívánja ezt az üzenetet?" #: view:mail.message:0 #: field:mail.notification,read:0 msgid "Read" -msgstr "" +msgstr "Olvas" #. module: mail #: view:mail.group:0 @@ -173,7 +180,7 @@ msgstr "Csoportok keresése" #: code:addons/mail/static/src/js/mail_followers.js:156 #, python-format msgid "followers" -msgstr "Követők" +msgstr "követők" #. module: mail #: code:addons/mail/mail_message.py:726 @@ -188,18 +195,21 @@ msgid "" "image, with aspect ratio preserved. Use this field in form views or some " "kanban views." msgstr "" +"Közepes méretű fotó a csoportról. Automatikusa át lesz méretezve 128x128px " +"képpé, az arányok megtartásával. Használja ezt a mezőt az osztályozott " +"nézetban és egyes kanban nézetekben." #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:194 #, python-format msgid "Uploading error" -msgstr "" +msgstr "Feltöltési hiba" #. module: mail #: model:mail.group,name:mail.group_support msgid "Support" -msgstr "" +msgstr "Támogatás" #. module: mail #: code:addons/mail/mail_message.py:727 @@ -210,6 +220,10 @@ msgid "" "\n" "(Document type: %s, Operation: %s)" msgstr "" +"Az igényelt műveletet nem lehetett végrehajtani biztonsági korlátok miatt. " +"Kérem vegye fel a kapcsolatot a rendszer adminisztrátorral.\n" +"\n" +"(Dokumentum típus: %s, Művelet: %s)" #. module: mail #: view:mail.mail:0 @@ -227,24 +241,24 @@ msgstr "Szál" #: code:addons/mail/static/src/xml/mail.xml:37 #, python-format msgid "Open the full mail composer" -msgstr "" +msgstr "Nyissa meg a taljes levél szerkesztőt" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:37 #, python-format msgid "ò" -msgstr "" +msgstr "ò" #. module: mail #: field:base.config.settings,alias_domain:0 msgid "Alias Domain" -msgstr "" +msgstr "Domain álnév" #. module: mail #: field:mail.group,group_ids:0 msgid "Auto Subscription" -msgstr "" +msgstr "Auto feliratkozás" #. module: mail #: field:mail.mail,references:0 @@ -256,12 +270,12 @@ msgstr "Hivatkozások" #: code:addons/mail/static/src/xml/mail.xml:188 #, python-format msgid "No messages." -msgstr "" +msgstr "Nincs üzenet." #. module: mail #: model:ir.model,name:mail.model_mail_group msgid "Discussion group" -msgstr "" +msgstr "Tárgyalási csoport" #. module: mail #. openerp-web @@ -276,7 +290,7 @@ msgstr "feltöltés" #: code:addons/mail/static/src/xml/mail_followers.xml:52 #, python-format msgid "more." -msgstr "" +msgstr "több." #. module: mail #: help:mail.compose.message,type:0 @@ -285,6 +299,8 @@ msgid "" "Message type: email for email message, notification for system message, " "comment for other messages such as user replies" msgstr "" +"Üzenet típus: email az email üzenetre, figyelmeztetés egy rendszer üzenetre, " +"hozzászólás egy másik üzenetre mint felhasználói válaszok" #. module: mail #: help:mail.message.subtype,relation_field:0 @@ -293,6 +309,8 @@ msgid "" "automatic subscription on a related document. The field is used to compute " "getattr(related_document.relation_field)." msgstr "" +"A mező az ide vonatkozó modell hivatkozására használt az altípus modellhez, " +"ha automatikus feliratkozást használ az ide vonatkozó dokumentumhoz." #. module: mail #: selection:mail.mail,state:0 @@ -308,25 +326,25 @@ msgstr "Válaszcím" #: code:addons/mail/wizard/invite.py:36 #, python-format msgid "
You have been invited to follow %s.
" -msgstr "" +msgstr "
Önt meghívták, hogy kövesse: %s
" #. module: mail #: help:mail.group,message_unread:0 #: help:mail.thread,message_unread:0 #: help:res.partner,message_unread:0 msgid "If checked new messages require your attention." -msgstr "" +msgstr "Ha be van jelölve, akkor figyelje az új üzeneteket." #. module: mail #: field:mail.group,image_medium:0 msgid "Medium-sized photo" -msgstr "" +msgstr "Közepes méretű fotó" #. module: mail #: model:ir.actions.client,name:mail.action_mail_to_me_feeds #: model:ir.ui.menu,name:mail.mail_tomefeeds msgid "To: me" -msgstr "" +msgstr "Címzett: én" #. module: mail #: field:mail.message.subtype,name:0 @@ -344,28 +362,28 @@ msgstr "Automatikus törlés" #: view:mail.group:0 #, python-format msgid "Unfollow" -msgstr "Követés leállításA" +msgstr "Követés leállítása" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:261 #, python-format msgid "show one more message" -msgstr "" +msgstr "mutass még egy üzenetet" #. module: mail #: code:addons/mail/mail_mail.py:71 #: code:addons/mail/res_users.py:79 #, python-format msgid "Invalid Action!" -msgstr "" +msgstr "Érvénytelen lépés!" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:25 #, python-format msgid "User img" -msgstr "" +msgstr "Felhasználói kép" #. module: mail #: model:ir.actions.act_window,name:mail.action_view_mail_mail @@ -378,7 +396,7 @@ msgstr "E-mailek" #. module: mail #: field:mail.followers,partner_id:0 msgid "Related Partner" -msgstr "" +msgstr "Kapcsolódó partner" #. module: mail #: help:mail.group,message_summary:0 @@ -388,6 +406,8 @@ msgid "" "Holds the Chatter summary (number of messages, ...). This summary is " "directly in html format in order to be inserted in kanban views." msgstr "" +"A chettelés összegzést megállítja (üzenetek száma,...). Ez az összegzés " +"direkt HTML formátumú ahhoz hogy beilleszthető legyen a kanban nézetekbe." #. module: mail #: help:mail.alias,alias_model_id:0 @@ -396,11 +416,14 @@ msgid "" "incoming email that does not reply to an existing record will cause the " "creation of a new record of this model (e.g. a Project Task)" msgstr "" +"A modell (OpenERP Documentum féle) amivel ez az álnév összhangban van. " +"Bármely beérkező email ami nem válaszol a meglévő rekordra az egy, a " +"modellhez tartozó új rekord létrehozást okozza (pl. a Projekt feladat)" #. module: mail #: field:mail.message.subtype,relation_field:0 msgid "Relation field" -msgstr "" +msgstr "Reléciós/összefüggés mező" #. module: mail #: selection:mail.compose.message,type:0 @@ -463,7 +486,7 @@ msgstr "Küldés" #: code:addons/mail/static/src/js/mail_followers.js:152 #, python-format msgid "No followers" -msgstr "" +msgstr "Nincs követő" #. module: mail #: view:mail.mail:0 @@ -481,7 +504,7 @@ msgstr "Sikertelen" #: field:res.partner,message_follower_ids:0 #, python-format msgid "Followers" -msgstr "" +msgstr "Követők" #. module: mail #: model:ir.actions.client,name:mail.action_mail_archives_feeds @@ -495,7 +518,7 @@ msgstr "Archívum" #: code:addons/mail/static/src/xml/mail.xml:94 #, python-format msgid "Delete this attachment" -msgstr "" +msgstr "Törli ezt a mellékletet" #. module: mail #. openerp-web @@ -510,41 +533,41 @@ msgstr "Válasz" #: code:addons/mail/static/src/js/mail_followers.js:154 #, python-format msgid "One follower" -msgstr "" +msgstr "Egy követő" #. module: mail #: field:mail.compose.message,type:0 #: field:mail.message,type:0 msgid "Type" -msgstr "" +msgstr "Típus" #. module: mail #: selection:mail.compose.message,type:0 #: view:mail.mail:0 #: selection:mail.message,type:0 msgid "Email" -msgstr "" +msgstr "E-mail" #. module: mail #: field:ir.ui.menu,mail_group_id:0 msgid "Mail Group" -msgstr "" +msgstr "Levelezési csoport" #. module: mail #: selection:res.partner,notification_email_send:0 msgid "Comments and Emails" -msgstr "" +msgstr "Megjegyzések és e-mailok" #. module: mail #: field:mail.alias,alias_defaults:0 msgid "Default Values" -msgstr "" +msgstr "Alapértelmezett értékek" #. module: mail #: code:addons/mail/res_users.py:100 #, python-format msgid "%s has joined the %s network." -msgstr "" +msgstr "%s csatlakozott a %s hálózathoz." #. module: mail #: help:mail.group,image_small:0 @@ -553,6 +576,9 @@ msgid "" "image, with aspect ratio preserved. Use this field anywhere a small image is " "required." msgstr "" +"Kis mérető fotó a csoportról. Automatikusan át lesz méretezve 64x64px képpé, " +"az arány megtartása mellett. Használja ezt a mezőt bárhol ahol kisméretű " +"képet szeretne." #. module: mail #: view:mail.compose.message:0 @@ -565,41 +591,41 @@ msgstr "Címzettek" #: code:addons/mail/static/src/xml/mail.xml:127 #, python-format msgid "<<<" -msgstr "" +msgstr "<<<" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:43 #, python-format msgid "Write to the followers of this document..." -msgstr "" +msgstr "Bejegyzés írás a dokumentum követőinek..." #. module: mail #: field:mail.group,group_public_id:0 msgid "Authorized Group" -msgstr "" +msgstr "Jogosult csoport" #. module: mail #: view:mail.group:0 msgid "Join Group" -msgstr "" +msgstr "Csatlakozás a csoporthoz" #. module: mail #: help:mail.mail,email_from:0 msgid "Message sender, taken from user preferences." -msgstr "" +msgstr "Üzenet küldő, a felhasználói meghatározásokból vett." #. module: mail #: code:addons/mail/wizard/invite.py:39 #, python-format msgid "
You have been invited to follow a new document.
" -msgstr "" +msgstr "
Önt meghívták, hogy kövessen egy új dokumentumot.
" #. module: mail #: field:mail.compose.message,parent_id:0 #: field:mail.message,parent_id:0 msgid "Parent Message" -msgstr "" +msgstr "Szülő üzenet" #. module: mail #: field:mail.compose.message,res_id:0 @@ -607,7 +633,7 @@ msgstr "" #: field:mail.message,res_id:0 #: field:mail.wizard.invite,res_id:0 msgid "Related Document ID" -msgstr "" +msgstr "Kapcsolódó dokument azonosító ID" #. module: mail #: model:ir.actions.client,help:mail.action_mail_to_me_feeds @@ -619,23 +645,29 @@ msgid "" "

\n" " " msgstr "" +"

\n" +"Nincs privát üzenet.\n" +"

\n" +"Ez a lista az önnek küldött üzeneteket tartalmazza.\n" +"

\n" +" " #. module: mail #: model:mail.group,name:mail.group_rd msgid "R&D" -msgstr "" +msgstr "R&D" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:61 #, python-format msgid "/web/binary/upload_attachment" -msgstr "" +msgstr "/web/binary/upload_attachment" #. module: mail #: model:ir.model,name:mail.model_mail_thread msgid "Email Thread" -msgstr "" +msgstr "E-mail összafűzés" #. module: mail #: view:mail.mail:0 @@ -647,19 +679,19 @@ msgstr "Speciális" #: code:addons/mail/static/src/xml/mail.xml:226 #, python-format msgid "Move to Inbox" -msgstr "" +msgstr "Bejövő üzenetekbe mozgatás" #. module: mail #: code:addons/mail/wizard/mail_compose_message.py:165 #, python-format msgid "Re:" -msgstr "" +msgstr "Vissza:" #. module: mail #: field:mail.compose.message,to_read:0 #: field:mail.message,to_read:0 msgid "To read" -msgstr "" +msgstr "Elolvas" #. module: mail #: code:addons/mail/res_users.py:79 @@ -668,19 +700,21 @@ msgid "" "You may not create a user. To create new users, you should use the " "\"Settings > Users\" menu." msgstr "" +"Talán nem hozott létre felhasználót. Egy felhasználó létrehozásához, " +"használja a \"Beállítások > Felhasználók\" menüt." #. module: mail #: help:mail.followers,res_model:0 #: help:mail.wizard.invite,res_model:0 msgid "Model of the followed resource" -msgstr "" +msgstr "A követett forrás modellje" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:286 #, python-format msgid "like" -msgstr "" +msgstr "hasonló" #. module: mail #: view:mail.compose.message:0 @@ -694,12 +728,12 @@ msgstr "Mégsem" #: code:addons/mail/static/src/xml/mail.xml:44 #, python-format msgid "Share with my followers..." -msgstr "" +msgstr "Üzenet a követőimnek..." #. module: mail #: field:mail.notification,partner_id:0 msgid "Contact" -msgstr "" +msgstr "Kapcsolat" #. module: mail #: view:mail.group:0 @@ -707,21 +741,23 @@ msgid "" "Only the invited followers can read the\n" " discussions on this group." msgstr "" +"Csak a meghívott követők olvashatják ennek a\n" +" csoportnak a beszélgetését." #. module: mail #: model:ir.model,name:mail.model_ir_ui_menu msgid "ir.ui.menu" -msgstr "" +msgstr "ir.ui.menu" #. module: mail #: view:mail.message:0 msgid "Has attachments" -msgstr "" +msgstr "Vannak mellékletei" #. module: mail #: view:mail.mail:0 msgid "on" -msgstr "" +msgstr "ezen:" #. module: mail #: code:addons/mail/mail_message.py:916 @@ -730,6 +766,8 @@ msgid "" "The following partners chosen as recipients for the email have no email " "address linked :" msgstr "" +"A következő partnerek lettek kiválasztva mint címzettek, azokhoz az e-" +"mailekhez amelyekhez nem lett kapcsolva e-mail cím :" #. module: mail #: help:mail.alias,alias_defaults:0 @@ -737,11 +775,13 @@ msgid "" "A Python dictionary that will be evaluated to provide default values when " "creating new records for this alias." msgstr "" +"Egy Python szótár aminak a kiértékelésével alapértékeket biztosít, ha ehhez " +"az álnévhez új rekordokat hoz létre." #. module: mail #: model:ir.model,name:mail.model_mail_message_subtype msgid "Message subtypes" -msgstr "" +msgstr "Üzenet altípusok" #. module: mail #: help:mail.compose.message,notified_partner_ids:0 @@ -749,13 +789,15 @@ msgstr "" msgid "" "Partners that have a notification pushing this message in their mailboxes" msgstr "" +"Partnerek akiknek van egy értesítésük ennek az üzenetnek a levelező " +"ládájukba való mozgatására" #. module: mail #: selection:mail.compose.message,type:0 #: view:mail.mail:0 #: selection:mail.message,type:0 msgid "Comment" -msgstr "" +msgstr "Megjegyzés" #. module: mail #: model:ir.actions.client,help:mail.action_mail_inbox_feeds @@ -771,18 +813,28 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Szép munka! Az ön postafiókja üres.\n" +"

\n" +" A \"Beérkezett üzenetek\" az önnek küldött privát " +"üzeneteket vagy email-eket,\n" +" továbbá az ön által követett dokumentumokhoz vagy " +"emberekhez kapcsolódó\n" +" információkat tartalmaz.\n" +"

\n" +" " #. module: mail #: field:mail.mail,notification:0 msgid "Is Notification" -msgstr "" +msgstr "Ez egy üzenet" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:170 #, python-format msgid "Compose a new message" -msgstr "" +msgstr "Új üzenet küldés" #. module: mail #: view:mail.mail:0 @@ -795,6 +847,7 @@ msgstr "Küldés most" msgid "" "Unable to send email, please configure the sender's email address or alias." msgstr "" +"Nem tud e-mailt küldeni, kérem állítsa be a küldő e-mail címét vagy álnevet" #. module: mail #: help:res.users,alias_id:0 @@ -802,11 +855,13 @@ msgid "" "Email address internally associated with this user. Incoming emails will " "appear in the user's notifications." msgstr "" +"E-mail cím belsőleg összekapcsolva ezzel a felhasználóval. Bejövő e-mail-ok " +"megjelennek a felhasználó értesítéseinél." #. module: mail #: field:mail.group,image:0 msgid "Photo" -msgstr "" +msgstr "Fénykép" #. module: mail #. openerp-web @@ -815,13 +870,13 @@ msgstr "" #: view:mail.wizard.invite:0 #, python-format msgid "or" -msgstr "" +msgstr "vagy" #. module: mail #: help:mail.compose.message,vote_user_ids:0 #: help:mail.message,vote_user_ids:0 msgid "Users that voted for this message" -msgstr "" +msgstr "Felhasználók akik szavaztak erre az üzenetre" #. module: mail #: help:mail.group,alias_id:0 @@ -829,6 +884,8 @@ msgid "" "The email address associated with this group. New emails received will " "automatically create new topics." msgstr "" +"Az ezzel a csoporttal társított e-mail cím. Új beérkezett e-mailek " +"automatikusan új témákat hoznak létre." #. module: mail #: view:mail.mail:0 @@ -844,7 +901,7 @@ msgstr "E-mail keresésée" #: field:mail.compose.message,child_ids:0 #: field:mail.message,child_ids:0 msgid "Child Messages" -msgstr "" +msgstr "Alcsoportba rakott üzenetek" #. module: mail #: field:mail.alias,alias_user_id:0 @@ -927,12 +984,12 @@ msgstr "" #. module: mail #: view:mail.wizard.invite:0 msgid "Add Followers" -msgstr "" +msgstr "Követők hozzáadása" #. module: mail #: view:mail.compose.message:0 msgid "Followers of selected items and" -msgstr "" +msgstr "A kijelölt elemek követői és" #. module: mail #: field:mail.alias,alias_force_thread_id:0 @@ -942,7 +999,7 @@ msgstr "" #. module: mail #: model:ir.ui.menu,name:mail.mail_group_root msgid "My Groups" -msgstr "" +msgstr "Saját csoportok" #. module: mail #: model:ir.actions.client,help:mail.action_mail_archives_feeds @@ -1063,7 +1120,7 @@ msgstr "Dátum" #: code:addons/mail/static/src/xml/mail.xml:34 #, python-format msgid "Post" -msgstr "" +msgstr "Elküld" #. module: mail #: view:mail.mail:0 @@ -1075,14 +1132,14 @@ msgstr "Kiterjesztett szűrők…" #: code:addons/mail/static/src/xml/mail.xml:107 #, python-format msgid "To:" -msgstr "" +msgstr "Címzett:" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail.xml:175 #, python-format msgid "Write to my followers" -msgstr "" +msgstr "Bejegyzés írás a követőimnek" #. module: mail #: model:ir.model,name:mail.model_res_groups @@ -1169,7 +1226,7 @@ msgstr "" #: code:addons/mail/static/src/xml/mail_followers.xml:13 #, python-format msgid "Following" -msgstr "" +msgstr "Követés" #. module: mail #: sql_constraint:mail.alias:0 @@ -1257,14 +1314,14 @@ msgstr "" #. module: mail #: model:mail.message.subtype,name:mail.mt_comment msgid "Discussions" -msgstr "" +msgstr "Hozzászólások" #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/mail_followers.xml:11 #, python-format msgid "Follow" -msgstr "" +msgstr "Követ" #. module: mail #: field:mail.group,name:0 @@ -1413,7 +1470,7 @@ msgstr "" #: model:ir.actions.act_window,name:mail.action_view_groups #: model:ir.ui.menu,name:mail.mail_allgroups msgid "Join a group" -msgstr "" +msgstr "Csoporthoz csatlakozás" #. module: mail #: model:ir.actions.client,help:mail.action_mail_group_feeds @@ -1492,7 +1549,7 @@ msgstr "" #: model:ir.actions.client,name:mail.action_mail_star_feeds #: model:ir.ui.menu,name:mail.mail_starfeeds msgid "To-do" -msgstr "" +msgstr "Feladat" #. module: mail #: view:mail.alias:0 @@ -1598,7 +1655,7 @@ msgstr "" #. module: mail #: selection:mail.group,public:0 msgid "Private" -msgstr "" +msgstr "Privát" #. module: mail #: model:ir.actions.client,help:mail.action_mail_star_feeds diff --git a/addons/product/i18n/lo.po b/addons/product/i18n/lo.po new file mode 100644 index 00000000000..0f63a200e88 --- /dev/null +++ b/addons/product/i18n/lo.po @@ -0,0 +1,2479 @@ +# Lao translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-02-12 05:53+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lao \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-02-13 04:36+0000\n" +"X-Generator: Launchpad (build 16491)\n" + +#. module: product +#: field:product.packaging,rows:0 +msgid "Number of Layers" +msgstr "ຈໍານວນຊັ້ນ" + +#. module: product +#: help:product.pricelist.item,base:0 +msgid "Base price for computation." +msgstr "ລາຄາພື້ນຖານໃນການຄິດໄລ່" + +#. module: product +#: help:product.product,seller_qty:0 +msgid "This is minimum quantity to purchase from Main Supplier." +msgstr "ນີ້ແມ່ນປະລິມານໜ້ອຍສຸດທີ່ຊື້ຈາກຜູ້ຈໍາໜ່າຍ" + +#. module: product +#: model:product.template,name:product.product_product_34_product_template +msgid "Webcam" +msgstr "ກ້ອງຖ່າຍຮູບ" + +#. module: product +#: field:product.product,incoming_qty:0 +msgid "Incoming" +msgstr "ກໍາລັງມາຮອດ" + +#. module: product +#: view:product.product:0 +msgid "Product Name" +msgstr "ຊື່ຜະລິດຕະພັນ" + +#. module: product +#: view:product.template:0 +msgid "Second Unit of Measure" +msgstr "ຫົວໜ່ວຍສໍາຮອງ" + +#. module: product +#: help:res.partner,property_product_pricelist:0 +msgid "" +"This pricelist will be used, instead of the default one, for sales to the " +"current partner" +msgstr "" +"ລາຍການລາຄານີ້ຈະຖຶກນໍາໃຊ້, ແທນທີ່ຈະຕັ້ງຄ່າເທົ່າກັບໜື່ງ " +"ເພື່ອຂາຍໃຫ້ແກ່ລູກຄ້າໃນປະຈຸບັນ" + +#. module: product +#: field:product.product,seller_qty:0 +msgid "Supplier Quantity" +msgstr "ຈໍານວນຜູ້ສະໜອງ" + +#. module: product +#: selection:product.template,mes_type:0 +msgid "Fixed" +msgstr "ກໍານົດ" + +#. module: product +#: model:product.template,name:product.product_product_10_product_template +msgid "Mouse, Optical" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Base Prices" +msgstr "" + +#. module: product +#: field:product.pricelist.item,name:0 +msgid "Rule Name" +msgstr "" + +#. module: product +#: help:product.template,list_price:0 +msgid "" +"Base price to compute the customer price. Sometimes called the catalog price." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_3_product_template +msgid "PC Assemble SC234" +msgstr "" + +#. module: product +#: help:product.product,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: product +#: code:addons/product/pricelist.py:179 +#: code:addons/product/product.py:208 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: product +#: field:product.product,image_small:0 +msgid "Small-sized image" +msgstr "" + +#. module: product +#: code:addons/product/product.py:176 +#, python-format +msgid "" +"Conversion from Product UoM %s to Default UoM %s is not possible as they " +"both belong to different Category!." +msgstr "" + +#. module: product +#: selection:product.template,cost_method:0 +msgid "Average Price" +msgstr "" + +#. module: product +#: help:product.pricelist.item,name:0 +msgid "Explicit rule name for this pricelist line." +msgstr "" + +#. module: product +#: field:product.template,uos_coeff:0 +msgid "Unit of Measure -> UOS Coeff" +msgstr "" + +#. module: product +#: field:product.price_list,price_list:0 +msgid "PriceList" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_4_product_template +msgid "PC Assemble SC349" +msgstr "" + +#. module: product +#: help:product.product,seller_delay:0 +msgid "" +"This is the average delay in days between the purchase order confirmation " +"and the reception of goods for this product and for the default supplier. It " +"is used by the scheduler to order requests based on reordering delays." +msgstr "" + +#. module: product +#: model:product.pricelist.version,name:product.ver0 +msgid "Default Public Pricelist Version" +msgstr "" + +#. module: product +#: selection:product.template,cost_method:0 +msgid "Standard Price" +msgstr "" + +#. module: product +#: model:product.pricelist.type,name:product.pricelist_type_sale +#: field:res.partner,property_product_pricelist:0 +msgid "Sale Pricelist" +msgstr "" + +#. module: product +#: view:product.template:0 +#: field:product.template,type:0 +msgid "Product Type" +msgstr "" + +#. module: product +#: code:addons/product/product.py:412 +#, python-format +msgid "Products: " +msgstr "" + +#. module: product +#: constraint:decimal.precision:0 +msgid "" +"Error! You cannot define the decimal precision of 'Account' as greater than " +"the rounding factor of the company's main currency" +msgstr "" + +#. module: product +#: field:product.category,parent_id:0 +msgid "Parent Category" +msgstr "ໜວດຫຼັກ" + +#. module: product +#: model:product.template,description:product.product_product_33_product_template +msgid "Headset for laptop PC with USB connector." +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_all +msgid "All products" +msgstr "ຜະລິດຕະພັນທັງໝັດ" + +#. module: product +#: model:process.node,note:product.process_node_supplier0 +msgid "Supplier name, price, product code, ..." +msgstr "ຊື່ຜູ້ສະໜອງ, ລາຄາ, ລະຫັດຜະລິດຕະພັນ" + +#. module: product +#: constraint:res.currency:0 +msgid "" +"Error! You cannot define a rounding factor for the company's main currency " +"that is smaller than the decimal precision of 'Account'." +msgstr "" + +#. module: product +#: help:product.product,outgoing_qty:0 +msgid "" +"Quantity of products that are planned to leave.\n" +"In a context with a single Stock Location, this includes goods leaving this " +"Location, or any of its children.\n" +"In a context with a single Warehouse, this includes goods leaving the Stock " +"Location of this Warehouse, or any of its children.\n" +"In a context with a single Shop, this includes goods leaving the Stock " +"Location of the Warehouse of this Shop, or any of its children.\n" +"Otherwise, this includes goods leaving any Stock Location with 'internal' " +"type." +msgstr "" + +#. module: product +#: model:product.template,description_sale:product.product_product_42_product_template +msgid "" +"Office Editing Software with word processing, spreadsheets, presentations, " +"graphics, and databases..." +msgstr "" + +#. module: product +#: field:product.product,seller_id:0 +msgid "Main Supplier" +msgstr "ຜູ້ສະໜອງຫຼັກ" + +#. module: product +#: model:ir.actions.act_window,name:product.product_ul_form_action +#: model:ir.model,name:product.model_product_packaging +#: model:ir.ui.menu,name:product.menu_product_ul_form_action +#: view:product.packaging:0 +#: view:product.product:0 +#: view:product.ul:0 +msgid "Packaging" +msgstr "ການຫຸ້ມຫໍ່" + +#. module: product +#: help:product.product,active:0 +msgid "" +"If unchecked, it will allow you to hide the product without removing it." +msgstr "" + +#. module: product +#: view:product.product:0 +#: field:product.template,categ_id:0 +#: field:product.uom,category_id:0 +msgid "Category" +msgstr "ໝວດ" + +#. module: product +#: model:product.template,name:product.product_product_25_product_template +msgid "Laptop E5023" +msgstr "" + +#. module: product +#: help:product.packaging,ul_qty:0 +msgid "The number of packages by layer" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_30_product_template +msgid "Pen drive, SP-4" +msgstr "" + +#. module: product +#: field:product.packaging,qty:0 +msgid "Quantity by Package" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_29_product_template +msgid "Pen drive, SP-2" +msgstr "" + +#. module: product +#: view:product.product:0 +#: view:product.template:0 +#: field:product.template,state:0 +msgid "Status" +msgstr "" + +#. module: product +#: help:product.template,categ_id:0 +msgid "Select category for the current product" +msgstr "" + +#. module: product +#: field:product.product,outgoing_qty:0 +msgid "Outgoing" +msgstr "" + +#. module: product +#: model:product.price.type,name:product.list_price +#: field:product.product,lst_price:0 +msgid "Public Price" +msgstr "" + +#. module: product +#: field:product.price_list,qty5:0 +msgid "Quantity-5" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_ul_form_action +msgid "" +"

\n" +" Click to add a new packaging type.\n" +"

\n" +" The packaging type define the dimensions as well as the " +"number\n" +" of products per package. This will ensure salesperson sell " +"the\n" +" right number of products according to the package selected.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: field:product.template,product_manager:0 +msgid "Product Manager" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_7_product_template +msgid "17” LCD Monitor" +msgstr "" + +#. module: product +#: field:product.supplierinfo,product_name:0 +msgid "Supplier Product Name" +msgstr "" + +#. module: product +#: view:product.pricelist:0 +msgid "Products Price Search" +msgstr "" + +#. module: product +#: view:product.template:0 +#: field:product.template,description_sale:0 +msgid "Sale Description" +msgstr "" + +#. module: product +#: help:product.packaging,length:0 +msgid "The length of the package" +msgstr "" + +#. module: product +#: field:product.product,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: product +#: help:product.template,weight_net:0 +msgid "The net weight in Kg." +msgstr "" + +#. module: product +#: field:pricelist.partnerinfo,min_quantity:0 +#: field:product.supplierinfo,qty:0 +msgid "Quantity" +msgstr "" + +#. module: product +#: view:product.price_list:0 +msgid "Calculate Product Price per Unit Based on Pricelist Version." +msgstr "" + +#. module: product +#: help:product.pricelist.item,product_id:0 +msgid "" +"Specify a product if this rule only applies to one product. Keep empty " +"otherwise." +msgstr "" + +#. module: product +#: model:product.uom.categ,name:product.product_uom_categ_kgm +msgid "Weight" +msgstr "" + +#. module: product +#: help:product.product,virtual_available:0 +msgid "" +"Forecast quantity (computed as Quantity On Hand - Outgoing + Incoming)\n" +"In a context with a single Stock Location, this includes goods stored in " +"this location, or any of its children.\n" +"In a context with a single Warehouse, this includes goods stored in the " +"Stock Location of this Warehouse, or any of its children.\n" +"In a context with a single Shop, this includes goods stored in the Stock " +"Location of the Warehouse of this Shop, or any of its children.\n" +"Otherwise, this includes goods stored in any Stock Location with 'internal' " +"type." +msgstr "" + +#. module: product +#: field:product.packaging,height:0 +msgid "Height" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Procurements" +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_mrp_properties +msgid "Manage Properties of Product" +msgstr "" + +#. module: product +#: help:product.uom,factor:0 +msgid "" +"How much bigger or smaller this unit is compared to the reference Unit of " +"Measure for this category:\n" +"1 * (reference unit) = ratio * (this unit)" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_pricelist_partnerinfo +msgid "pricelist.partnerinfo" +msgstr "" + +#. module: product +#: field:product.price_list,qty2:0 +msgid "Quantity-2" +msgstr "" + +#. module: product +#: field:product.price_list,qty3:0 +msgid "Quantity-3" +msgstr "" + +#. module: product +#: field:product.price_list,qty1:0 +msgid "Quantity-1" +msgstr "" + +#. module: product +#: field:product.price_list,qty4:0 +msgid "Quantity-4" +msgstr "" + +#. module: product +#: view:res.partner:0 +msgid "Sales & Purchases" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_44_product_template +msgid "GrapWorks Software" +msgstr "" + +#. module: product +#: model:product.uom.categ,name:product.uom_categ_wtime +msgid "Working Time" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_42_product_template +msgid "Office Suite" +msgstr "" + +#. module: product +#: field:product.template,mes_type:0 +msgid "Measure Type" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_32_product_template +msgid "Headset standard" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_day +msgid "Day(s)" +msgstr "ມື້" + +#. module: product +#: help:product.product,incoming_qty:0 +msgid "" +"Quantity of products that are planned to arrive.\n" +"In a context with a single Stock Location, this includes goods arriving to " +"this Location, or any of its children.\n" +"In a context with a single Warehouse, this includes goods arriving to the " +"Stock Location of this Warehouse, or any of its children.\n" +"In a context with a single Shop, this includes goods arriving to the Stock " +"Location of the Warehouse of this Shop, or any of its children.\n" +"Otherwise, this includes goods arriving to any Stock Location with " +"'internal' type." +msgstr "" + +#. module: product +#: constraint:product.template:0 +msgid "" +"Error: The default Unit of Measure and the purchase Unit of Measure must be " +"in the same category." +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_uom_categ +msgid "Product uom categ" +msgstr "" + +#. module: product +#: model:product.ul,name:product.product_ul_box +msgid "Box 20x20x40" +msgstr "" + +#. module: product +#: field:product.template,warranty:0 +msgid "Warranty" +msgstr "ຮັບປະກັນ" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Price Computation" +msgstr "" + +#. module: product +#: constraint:product.product:0 +msgid "" +"You provided an invalid \"EAN13 Barcode\" reference. You may use the " +"\"Internal Reference\" field instead." +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_purchase_pricelist +msgid "Purchase Pricelists" +msgstr "ລາຍການລາຄາຊື້" + +#. module: product +#: model:product.template,name:product.product_product_5_product_template +msgid "PC Assemble + Custom (PC on Demand)" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_27_product_template +msgid "Custom Laptop based on customer's requirement." +msgstr "" + +#. module: product +#: help:product.packaging,width:0 +msgid "The width of the package" +msgstr "" + +#. module: product +#: code:addons/product/product.py:361 +#, python-format +msgid "Unit of Measure categories Mismatch!" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_36_product_template +msgid "Blank DVD-RW" +msgstr "" + +#. module: product +#: selection:product.category,type:0 +msgid "View" +msgstr "ເບຶ່ງ" + +#. module: product +#: model:ir.actions.act_window,name:product.product_template_action_tree +msgid "Product Templates" +msgstr "" + +#. module: product +#: field:product.category,parent_left:0 +msgid "Left Parent" +msgstr "" + +#. module: product +#: help:product.pricelist.item,price_max_margin:0 +msgid "Specify the maximum amount of margin over the base price." +msgstr "" + +#. module: product +#: constraint:product.pricelist.item:0 +msgid "" +"Error! You cannot assign the Main Pricelist as Other Pricelist in PriceList " +"Item!" +msgstr "" + +#. module: product +#: view:product.price_list:0 +msgid "or" +msgstr "ຫຼື" + +#. module: product +#: constraint:product.packaging:0 +msgid "Error: Invalid ean code" +msgstr "" + +#. module: product +#: field:product.pricelist.item,min_quantity:0 +msgid "Min. Quantity" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_12_product_template +msgid "Mouse, Wireless" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_22_product_template +msgid "Processor Core i5 2.70 Ghz" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_price_type +msgid "Price Type" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Max. Margin" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Base Price" +msgstr "" + +#. module: product +#: help:product.supplierinfo,name:0 +msgid "Supplier of this product" +msgstr "" + +#. module: product +#: help:product.pricelist.version,active:0 +msgid "" +"When a version is duplicated it is set to non active, so that the dates do " +"not overlaps with original version. You should change the dates and " +"reactivate the pricelist" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_18_product_template +msgid "HDD SH-2" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_17_product_template +msgid "HDD SH-1" +msgstr "" + +#. module: product +#: field:product.supplierinfo,name:0 +#: field:product.template,seller_ids:0 +msgid "Supplier" +msgstr "ຜູ້ສະໜອງ" + +#. module: product +#: help:product.template,cost_method:0 +msgid "" +"Standard Price: The cost price is manually updated at the end of a specific " +"period (usually every year). \n" +"Average Price: The cost price is recomputed at each incoming shipment." +msgstr "" + +#. module: product +#: field:product.product,qty_available:0 +msgid "Quantity On Hand" +msgstr "" + +#. module: product +#: field:product.price.type,name:0 +msgid "Price Name" +msgstr "" + +#. module: product +#: help:product.product,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: product +#: field:product.product,ean13:0 +msgid "EAN13 Barcode" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.action_product_price_list +#: model:ir.model,name:product.model_product_price_list +#: view:product.price_list:0 +#: report:product.pricelist:0 +#: field:product.pricelist.version,pricelist_id:0 +msgid "Price List" +msgstr "ລາຍການລາຄາ" + +#. module: product +#: field:product.product,virtual_available:0 +msgid "Forecasted Quantity" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Purchase" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_33_product_template +msgid "Headset USB" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Suppliers" +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_sale_pricelist +msgid "Sales Pricelists" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "New Price =" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_7 +msgid "Accessories" +msgstr "" + +#. module: product +#: model:process.transition,name:product.process_transition_supplierofproduct0 +msgid "Supplier of the product" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_28_product_template +msgid "External Hard disk" +msgstr "" + +#. module: product +#: help:product.template,standard_price:0 +msgid "" +"Cost price of the product used for standard stock valuation in accounting " +"and used as a base price on purchase orders." +msgstr "" + +#. module: product +#: field:product.category,child_id:0 +msgid "Child Categories" +msgstr "" + +#. module: product +#: field:product.pricelist.version,date_end:0 +msgid "End Date" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_litre +msgid "Liter(s)" +msgstr "" + +#. module: product +#: view:product.price_list:0 +msgid "Print" +msgstr "" + +#. module: product +#: view:product.product:0 +#: field:product.ul,type:0 +#: field:product.uom,uom_type:0 +msgid "Type" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_pricelist_action2 +#: model:ir.actions.act_window,name:product.product_pricelist_action_for_purchase +#: model:ir.ui.menu,name:product.menu_product_pricelist_action2 +#: model:ir.ui.menu,name:product.menu_product_pricelist_main +msgid "Pricelists" +msgstr "" + +#. module: product +#: field:product.product,partner_ref:0 +msgid "Customer ref" +msgstr "" + +#. module: product +#: field:product.pricelist.type,key:0 +msgid "Key" +msgstr "" + +#. module: product +#: model:ir.actions.report.xml,name:product.report_product_pricelist +#: model:ir.model,name:product.model_product_pricelist +#: field:product.product,pricelist_id:0 +#: view:product.supplierinfo:0 +msgid "Pricelist" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_hour +msgid "Hour(s)" +msgstr "" + +#. module: product +#: selection:product.template,state:0 +msgid "In Development" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_res_partner +msgid "Partner" +msgstr "" + +#. module: product +#: model:process.transition,note:product.process_transition_supplierofproduct0 +msgid "" +"1 or several supplier(s) can be linked to a product. All information stands " +"in the product form." +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_round:0 +msgid "Price Rounding" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_1_product_template +msgid "On Site Monitoring" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "days" +msgstr "" + +#. module: product +#: model:process.node,name:product.process_node_supplier0 +#: view:product.supplierinfo:0 +msgid "Supplier Information" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_res_currency +#: field:product.price.type,currency_id:0 +#: report:product.pricelist:0 +#: field:product.pricelist,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_46_product_template +msgid "Datacard" +msgstr "" + +#. module: product +#: help:product.template,uos_coeff:0 +msgid "" +"Coefficient to convert default Unit of Measure to Unit of Sale\n" +" uos = uom * coeff" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_category_action_form +#: model:ir.ui.menu,name:product.menu_product_category_action_form +#: view:product.category:0 +msgid "Product Categories" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Procurement & Locations" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_20_product_template +msgid "Motherboard I9P57" +msgstr "" + +#. module: product +#: field:product.packaging,weight:0 +msgid "Total Package Weight" +msgstr "" + +#. module: product +#: help:product.packaging,code:0 +msgid "The code of the transport unit." +msgstr "" + +#. module: product +#: view:product.price.type:0 +msgid "Products Price Type" +msgstr "" + +#. module: product +#: field:product.product,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: product +#: field:product.product,price_extra:0 +msgid "Variant Price Extra" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_supplierinfo +msgid "Information about a product supplier" +msgstr "" + +#. module: product +#: help:product.uom,factor_inv:0 +msgid "" +"How many times this Unit of Measure is bigger than the reference Unit of " +"Measure in this category:\n" +"1 * (this unit) = ratio * (reference unit)" +msgstr "" + +#. module: product +#: view:product.template:0 +#: field:product.template,description_purchase:0 +msgid "Purchase Description" +msgstr "" + +#. module: product +#: constraint:product.pricelist.version:0 +msgid "You cannot have 2 pricelist versions that overlap!" +msgstr "" + +#. module: product +#: help:product.pricelist.item,min_quantity:0 +msgid "" +"Specify the minimum quantity that needs to be bought/sold for the rule to " +"apply." +msgstr "" + +#. module: product +#: help:product.pricelist.version,date_start:0 +msgid "First valid date for the version." +msgstr "" + +#. module: product +#: help:product.supplierinfo,delay:0 +msgid "" +"Lead time in days between the confirmation of the purchase order and the " +"reception of the products in your warehouse. Used by the scheduler for " +"automatic computation of the purchase order planning." +msgstr "" + +#. module: product +#: model:product.template,description_sale:product.product_product_3_product_template +msgid "" +"17\" LCD Monitor\n" +"Processor AMD 8-Core\n" +"512MB RAM\n" +"HDD SH-1" +msgstr "" + +#. module: product +#: selection:product.template,type:0 +msgid "Stockable Product" +msgstr "" + +#. module: product +#: field:product.packaging,code:0 +msgid "Code" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_27_product_template +msgid "Laptop Customized" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_ul +msgid "Shipping Unit" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_35_product_template +msgid "Blank CD" +msgstr "" + +#. module: product +#: field:pricelist.partnerinfo,suppinfo_id:0 +msgid "Partner Information" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_normal_action_sell +msgid "" +"

\n" +" Click to define a new product.\n" +"

\n" +" You must define a product for everything you sell, whether " +"it's\n" +" a physical product, a consumable or a service you offer to\n" +" customers.\n" +"

\n" +" The product form contains information to simplify the sale\n" +" process: price, notes in the quotation, accounting data,\n" +" procurement methods, etc.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: view:product.price_list:0 +msgid "Cancel" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_37_product_template +msgid "All in one hi-speed printer with fax and scanner." +msgstr "" + +#. module: product +#: help:product.supplierinfo,min_qty:0 +msgid "" +"The minimal quantity to purchase to this supplier, expressed in the supplier " +"Product Unit of Measure if not empty, in the default unit of measure of the " +"product otherwise." +msgstr "" + +#. module: product +#: view:product.product:0 +#: view:product.template:0 +msgid "Information" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Products Listprices Items" +msgstr "" + +#. module: product +#: view:product.packaging:0 +msgid "Other Info" +msgstr "" + +#. module: product +#: field:product.pricelist.version,items_id:0 +msgid "Price List Items" +msgstr "" + +#. module: product +#: field:pricelist.partnerinfo,price:0 +msgid "Unit Price" +msgstr "" + +#. module: product +#: field:product.category,parent_right:0 +msgid "Right Parent" +msgstr "" + +#. module: product +#: field:product.product,price:0 +msgid "Price" +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_surcharge:0 +msgid "Price Surcharge" +msgstr "" + +#. module: product +#: field:product.product,code:0 +#: field:product.product,default_code:0 +msgid "Internal Reference" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_8_product_template +msgid "USB Keyboard, QWERTY" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_9 +msgid "Softwares" +msgstr "" + +#. module: product +#: field:product.product,packaging:0 +msgid "Logistical Units" +msgstr "" + +#. module: product +#: field:product.category,complete_name:0 +#: field:product.category,name:0 +#: field:product.pricelist.type,name:0 +#: field:product.pricelist.version,name:0 +#: field:product.product,name_template:0 +#: field:product.template,name:0 +#: field:product.ul,name:0 +#: field:product.uom.categ,name:0 +msgid "Name" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_4 +msgid "Computers" +msgstr "" + +#. module: product +#: help:product.product,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_kgm +msgid "kg" +msgstr "" + +#. module: product +#: selection:product.template,state:0 +msgid "Obsolete" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_km +msgid "km" +msgstr "" + +#. module: product +#: field:product.template,standard_price:0 +msgid "Cost" +msgstr "" + +#. module: product +#: help:product.category,sequence:0 +msgid "" +"Gives the sequence order when displaying a list of product categories." +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_dozen +msgid "Dozen(s)" +msgstr "" + +#. module: product +#: field:product.uom,factor:0 +#: field:product.uom,factor_inv:0 +msgid "Ratio" +msgstr "" + +#. module: product +#: field:product.packaging,width:0 +msgid "Width" +msgstr "" + +#. module: product +#: help:product.price.type,field:0 +msgid "Associated field in the product form." +msgstr "" + +#. module: product +#: view:product.product:0 +#: view:product.template:0 +#: field:product.template,uom_id:0 +#: field:product.uom,name:0 +msgid "Unit of Measure" +msgstr "" + +#. module: product +#: report:product.pricelist:0 +msgid "Printing Date" +msgstr "" + +#. module: product +#: field:product.template,uos_id:0 +msgid "Unit of Sale" +msgstr "" + +#. module: product +#: field:product.product,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_uom_categ_form_action +#: model:ir.ui.menu,name:product.menu_product_uom_categ_form_action +msgid "Unit of Measure Categories" +msgstr "" + +#. module: product +#: help:product.product,seller_id:0 +msgid "Main Supplier who has highest priority in Supplier List." +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_5 +#: view:product.product:0 +msgid "Services" +msgstr "" + +#. module: product +#: help:product.product,ean13:0 +msgid "International Article Number used for product identification." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_category_action +msgid "" +"

\n" +" Here is a list of all your products classified by category. " +"You\n" +" can click a category to get the list of all products linked " +"to\n" +" this category or to a child of this category.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: code:addons/product/product.py:361 +#, python-format +msgid "" +"New Unit of Measure '%s' must belong to same Unit of Measure category '%s' " +"as of old Unit of Measure '%s'. If you need to change the unit of measure, " +"you may deactivate this product from the 'Procurements' tab and create a new " +"one." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_normal_action +#: model:ir.actions.act_window,name:product.product_normal_action_puchased +#: model:ir.actions.act_window,name:product.product_normal_action_sell +#: model:ir.actions.act_window,name:product.product_normal_action_tree +#: model:ir.ui.menu,name:product.menu_products +#: model:ir.ui.menu,name:product.prod_config_main +#: view:product.product:0 +msgid "Products" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_32_product_template +msgid "" +"Hands free headset for laptop PC with in-line microphone and headphone plug." +msgstr "" + +#. module: product +#: help:product.packaging,rows:0 +msgid "The number of layers on a pallet or box" +msgstr "" + +#. module: product +#: help:product.pricelist.item,price_min_margin:0 +msgid "Specify the minimum amount of margin over the base price." +msgstr "" + +#. module: product +#: field:product.template,weight_net:0 +msgid "Net Weight" +msgstr "" + +#. module: product +#: view:product.packaging:0 +#: view:product.product:0 +msgid "Pallet Dimension" +msgstr "" + +#. module: product +#: help:product.product,image:0 +msgid "" +"This field holds the image used as image for the product, limited to " +"1024x1024px." +msgstr "" + +#. module: product +#: help:product.pricelist.item,categ_id:0 +msgid "" +"Specify a product category if this rule only applies to products belonging " +"to this category or its children categories. Keep empty otherwise." +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Inventory" +msgstr "" + +#. module: product +#: field:product.product,seller_info_id:0 +msgid "Supplier Info" +msgstr "" + +#. module: product +#: code:addons/product/product.py:729 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_2_product_template +msgid "On Site Assistance" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_39_product_template +msgid "Toner Cartridge" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_uom_form_action +#: model:ir.ui.menu,name:product.menu_product_uom_form_action +#: model:ir.ui.menu,name:product.next_id_16 +#: view:product.uom:0 +msgid "Units of Measure" +msgstr "" + +#. module: product +#: field:product.supplierinfo,min_qty:0 +msgid "Minimal Quantity" +msgstr "" + +#. module: product +#: help:product.supplierinfo,product_code:0 +msgid "" +"This supplier's product code will be used when printing a request for " +"quotation. Keep empty to use the internal one." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_43_product_template +msgid "Zed+ Antivirus" +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_version_id:0 +msgid "Price List Version" +msgstr "" + +#. module: product +#: help:product.pricelist.item,sequence:0 +msgid "" +"Gives the order in which the pricelist items will be checked. The evaluation " +"gives highest priority to lowest sequence and stops as soon as a matching " +"item is found." +msgstr "" + +#. module: product +#: view:product.product:0 +#: selection:product.template,type:0 +msgid "Consumable" +msgstr "" + +#. module: product +#: help:product.price.type,currency_id:0 +msgid "The currency the field is expressed in." +msgstr "" + +#. module: product +#: help:product.template,weight:0 +msgid "The gross weight in Kg." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_37_product_template +msgid "Printer, All-in-one" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Procurement" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_23_product_template +msgid "Processor AMD 8-Core" +msgstr "" + +#. module: product +#: view:product.product:0 +#: view:product.template:0 +msgid "Weights" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Description for Quotations" +msgstr "" + +#. module: product +#: help:pricelist.partnerinfo,price:0 +msgid "" +"This price will be considered as a price for the supplier Unit of Measure if " +"any or the default Unit of Measure of the product otherwise" +msgstr "" + +#. module: product +#: field:product.template,uom_po_id:0 +msgid "Purchase Unit of Measure" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Group by..." +msgstr "" + +#. module: product +#: field:product.product,image_medium:0 +msgid "Medium-sized image" +msgstr "" + +#. module: product +#: selection:product.ul,type:0 +#: model:product.uom.categ,name:product.product_uom_categ_unit +msgid "Unit" +msgstr "" + +#. module: product +#: field:product.pricelist.version,date_start:0 +msgid "Start Date" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_38_product_template +msgid "Ink Cartridge" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_cm +msgid "cm" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_uom +msgid "Product Unit of Measure" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_pricelist_action +msgid "" +"

\n" +" Click to add a pricelist version.\n" +"

\n" +" There can be more than one version of a pricelist, each of\n" +" these must be valid during a certain period of time. Some\n" +" examples of versions: Main Prices, 2010, 2011, Summer " +"Sales,\n" +" etc.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: help:product.template,uom_po_id:0 +msgid "" +"Default Unit of Measure used for purchase orders. It must be in the same " +"category than the default unit of measure." +msgstr "" + +#. module: product +#: view:product.pricelist:0 +msgid "Products Price" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_26_product_template +msgid "" +"17\" Monitor\n" +"6GB RAM\n" +"Hi-Speed 234Q Processor\n" +"QWERTY keyboard" +msgstr "" + +#. module: product +#: field:product.uom,rounding:0 +msgid "Rounding Precision" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Consumable products" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_21_product_template +msgid "Motherboard A20Z7" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_1_product_template +#: model:product.template,description_sale:product.product_product_1_product_template +msgid "This type of service include basic monitoring of products." +msgstr "" + +#. module: product +#: help:product.pricelist.version,date_end:0 +msgid "Last valid date for the version." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_19_product_template +msgid "HDD on Demand" +msgstr "" + +#. module: product +#: field:product.price.type,active:0 +#: field:product.pricelist,active:0 +#: field:product.pricelist.version,active:0 +#: field:product.product,active:0 +#: field:product.uom,active:0 +msgid "Active" +msgstr "" + +#. module: product +#: field:product.product,price_margin:0 +msgid "Variant Price Margin" +msgstr "" + +#. module: product +#: field:product.pricelist,name:0 +msgid "Pricelist Name" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_1 +msgid "Saleable" +msgstr "" + +#. module: product +#: sql_constraint:product.uom:0 +msgid "The conversion ratio for a unit of measure cannot be 0!" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_24_product_template +msgid "Graphics Card" +msgstr "" + +#. module: product +#: help:product.packaging,ean:0 +msgid "The EAN code of the package unit." +msgstr "" + +#. module: product +#: help:product.supplierinfo,product_uom:0 +msgid "This comes from the product form." +msgstr "" + +#. module: product +#: field:product.packaging,weight_ul:0 +msgid "Empty Package Weight" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_41_product_template +msgid "Windows Home Server 2011" +msgstr "" + +#. module: product +#: field:product.price.type,field:0 +msgid "Product Field" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_5_product_template +msgid "Custom computer assembled on order based on customer's requirement." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_price_type_action +#: model:ir.ui.menu,name:product.menu_product_price_type +msgid "Price Types" +msgstr "" + +#. module: product +#: help:product.template,uom_id:0 +msgid "Default Unit of Measure used for all stock operation." +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Sales" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_uom_categ_form_action +msgid "" +"

\n" +" Click to add a new unit of measure category.\n" +"

\n" +" Units of measure belonging to the same category can be\n" +" converted between each others. For example, in the category\n" +" 'Time', you will have the following units of " +"measure:\n" +" Hours, Days.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: help:pricelist.partnerinfo,min_quantity:0 +msgid "" +"The minimal quantity to trigger this rule, expressed in the supplier Unit of " +"Measure if any or in the default Unit of Measure of the product otherrwise." +msgstr "" + +#. module: product +#: selection:product.uom,uom_type:0 +msgid "Smaller than the reference Unit of Measure" +msgstr "" + +#. module: product +#: model:product.pricelist,name:product.list0 +msgid "Public Pricelist" +msgstr "" + +#. module: product +#: field:product.supplierinfo,product_code:0 +msgid "Supplier Product Code" +msgstr "" + +#. module: product +#: help:product.pricelist,active:0 +msgid "" +"If unchecked, it will allow you to hide the pricelist without removing it." +msgstr "" + +#. module: product +#: selection:product.ul,type:0 +msgid "Pallet" +msgstr "" + +#. module: product +#: field:product.packaging,ul_qty:0 +msgid "Package by layer" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_product +#: model:process.node,name:product.process_node_product0 +#: model:process.process,name:product.process_process_productprocess0 +#: field:product.packaging,product_id:0 +#: field:product.pricelist.item,product_id:0 +#: view:product.product:0 +#: field:product.supplierinfo,product_id:0 +#: model:res.request.link,name:product.req_link_product +msgid "Product" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Price:" +msgstr "" + +#. module: product +#: field:product.template,weight:0 +msgid "Gross Weight" +msgstr "" + +#. module: product +#: help:product.packaging,qty:0 +msgid "The total number of products you can put by pallet or box." +msgstr "" + +#. module: product +#: field:product.product,variants:0 +msgid "Variants" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_category_action +#: model:ir.ui.menu,name:product.menu_products_category +msgid "Products by Category" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_16_product_template +msgid "Computer Case" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_9_product_template +msgid "USB Keyboard, AZERTY" +msgstr "" + +#. module: product +#: help:product.supplierinfo,sequence:0 +msgid "Assigns the priority to the list of product supplier." +msgstr "" + +#. module: product +#: constraint:product.pricelist.item:0 +msgid "Error! The minimum margin should be lower than the maximum margin." +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_uos +msgid "Manage Secondary Unit of Measure" +msgstr "" + +#. module: product +#: help:product.uom,rounding:0 +msgid "" +"The computed quantity will be a multiple of this value. Use 1.0 for a Unit " +"of Measure that cannot be further split, such as a piece." +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Rounding Method" +msgstr "" + +#. module: product +#: model:ir.actions.report.xml,name:product.report_product_label +msgid "Products Labels" +msgstr "" + +#. module: product +#: model:product.ul,name:product.product_ul_big_box +msgid "Box 30x40x60" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_47_product_template +msgid "Switch, 24 ports" +msgstr "" + +#. module: product +#: selection:product.uom,uom_type:0 +msgid "Bigger than the reference Unit of Measure" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_consultant_product_template +#: selection:product.template,type:0 +msgid "Service" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Internal Description" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_48_product_template +msgid "USB Adapter" +msgstr "" + +#. module: product +#: help:product.template,uos_id:0 +msgid "" +"Sepcify a unit of measure here if invoicing is made in another unit of " +"measure than inventory. Keep empty to use the default unit of measure." +msgstr "" + +#. module: product +#: code:addons/product/product.py:208 +#, python-format +msgid "Cannot change the category of existing Unit of Measure '%s'." +msgstr "" + +#. module: product +#: help:product.packaging,height:0 +msgid "The height of the package" +msgstr "" + +#. module: product +#: view:product.pricelist:0 +msgid "Products Price List" +msgstr "" + +#. module: product +#: field:product.pricelist,company_id:0 +#: field:product.pricelist.item,company_id:0 +#: field:product.pricelist.version,company_id:0 +#: view:product.product:0 +#: field:product.supplierinfo,company_id:0 +#: field:product.template,company_id:0 +msgid "Company" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_26_product_template +msgid "Laptop S3450" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Default Unit of Measure" +msgstr "" + +#. module: product +#: code:addons/product/pricelist.py:377 +#, python-format +msgid "Partner section of the product form" +msgstr "" + +#. module: product +#: help:product.price.type,name:0 +msgid "Name of this kind of price." +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_3 +msgid "Other Products" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_9_product_template +msgid "This product is configured with example of push/pull flows" +msgstr "" + +#. module: product +#: field:product.product,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: product +#: model:product.uom,name:product.product_uom_unit +msgid "Unit(s)" +msgstr "" + +#. module: product +#: code:addons/product/product.py:176 +#, python-format +msgid "Error!" +msgstr "" + +#. module: product +#: field:product.packaging,length:0 +msgid "Length" +msgstr "" + +#. module: product +#: model:product.uom.categ,name:product.uom_categ_length +msgid "Length / Distance" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_8 +msgid "Components" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_pricelist_type +#: field:product.pricelist,type:0 +msgid "Pricelist Type" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_6 +msgid "External Devices" +msgstr "" + +#. module: product +#: field:product.product,color:0 +msgid "Color Index" +msgstr "" + +#. module: product +#: help:product.template,sale_ok:0 +msgid "Specify if the product can be selected in a sales order line." +msgstr "" + +#. module: product +#: view:product.product:0 +#: field:product.template,sale_ok:0 +msgid "Can be Sold" +msgstr "" + +#. module: product +#: field:product.template,produce_delay:0 +msgid "Manufacturing Lead Time" +msgstr "" + +#. module: product +#: field:product.supplierinfo,pricelist_ids:0 +msgid "Supplier Pricelist" +msgstr "" + +#. module: product +#: field:product.pricelist.item,base:0 +msgid "Based on" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_10 +msgid "Raw Materials" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_13_product_template +msgid "RAM SR5" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_14_product_template +msgid "RAM SR2" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_normal_action_puchased +msgid "" +"

\n" +" Click to define a new product.\n" +"

\n" +" You must define a product for everything you purchase, " +"whether\n" +" it's a physical product, a consumable or services you buy " +"to\n" +" subcontractants.\n" +"

\n" +" The product form contains detailed information to improve " +"the\n" +" purchase process: prices, procurement logistics, accounting " +"data,\n" +" available suppliers, etc.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: model:product.template,description_sale:product.product_product_44_product_template +msgid "Full featured image editing software." +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_pricelist_version +#: view:product.pricelist:0 +#: view:product.pricelist.version:0 +msgid "Pricelist Version" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "* ( 1 + " +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_31_product_template +msgid "Multimedia Speakers" +msgstr "" + +#. module: product +#: field:product.product,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Sale Conditions" +msgstr "" + +#. module: product +#: view:product.packaging:0 +#: view:product.product:0 +msgid "Palletization" +msgstr "" + +#. module: product +#: report:product.pricelist:0 +msgid "Price List Name" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Description for Suppliers" +msgstr "" + +#. module: product +#: field:product.supplierinfo,delay:0 +msgid "Delivery Lead Time" +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "months" +msgstr "" + +#. module: product +#: help:product.uom,active:0 +msgid "" +"By unchecking the active field you can disable a unit of measure without " +"deleting it." +msgstr "" + +#. module: product +#: field:product.product,seller_delay:0 +msgid "Supplier Lead Time" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_decimal_precision +msgid "decimal.precision" +msgstr "" + +#. module: product +#: selection:product.ul,type:0 +msgid "Box" +msgstr "" + +#. module: product +#: help:product.pricelist.item,price_surcharge:0 +msgid "" +"Specify the fixed amount to add or substract(if negative) to the amount " +"calculated with the discount." +msgstr "" + +#. module: product +#: help:product.product,qty_available:0 +msgid "" +"Current quantity of products.\n" +"In a context with a single Stock Location, this includes goods stored at " +"this Location, or any of its children.\n" +"In a context with a single Warehouse, this includes goods stored in the " +"Stock Location of this Warehouse, or any of its children.\n" +"In a context with a single Shop, this includes goods stored in the Stock " +"Location of the Warehouse of this Shop, or any of its children.\n" +"Otherwise, this includes goods stored in any Stock Location with 'internal' " +"type." +msgstr "" + +#. module: product +#: help:product.template,type:0 +msgid "" +"Consumable: Will not imply stock management for this product. \n" +"Stockable product: Will imply stock management for this product." +msgstr "" + +#. module: product +#: help:product.pricelist.type,key:0 +msgid "" +"Used in the code to select specific prices based on the context. Keep " +"unchanged." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_normal_action +msgid "" +"

\n" +" Click to define a new product.\n" +"

\n" +" You must define a product for everything you buy or sell,\n" +" whether it's a physical product, a consumable or service.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: view:product.product:0 +msgid "Context..." +msgstr "" + +#. module: product +#: field:product.packaging,ul:0 +msgid "Type of Package" +msgstr "" + +#. module: product +#: help:product.category,type:0 +msgid "" +"A category of the view type is a virtual category that can be used as the " +"parent of another category to create a hierarchical structure." +msgstr "" + +#. module: product +#: selection:product.ul,type:0 +msgid "Pack" +msgstr "" + +#. module: product +#: help:product.pricelist.item,product_tmpl_id:0 +msgid "" +"Specify a template if this rule only applies to one product template. Keep " +"empty otherwise." +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_2_product_template +msgid "" +"This type of service include assistance for security questions, system " +"configuration requirements, implementation or special needs." +msgstr "" + +#. module: product +#: field:product.product,image:0 +msgid "Image" +msgstr "" + +#. module: product +#: view:product.uom.categ:0 +msgid "Units of Measure categories" +msgstr "" + +#. module: product +#: model:product.template,description_sale:product.product_product_4_product_template +msgid "" +"19\" LCD Monitor\n" +"Processor Core i5 2.70 Ghz\n" +"2GB RAM\n" +"HDD SH-1" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Descriptions" +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_stock_packaging +msgid "Manage Product Packaging" +msgstr "" + +#. module: product +#: model:product.category,name:product.product_category_2 +msgid "Internal" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_45_product_template +msgid "Router R430" +msgstr "" + +#. module: product +#: help:product.packaging,sequence:0 +msgid "Gives the sequence order when displaying a list of packaging." +msgstr "" + +#. module: product +#: selection:product.category,type:0 +#: selection:product.template,state:0 +msgid "Normal" +msgstr "" + +#. module: product +#: code:addons/product/pricelist.py:179 +#, python-format +msgid "" +"At least one pricelist has no active version !\n" +"Please create or activate one." +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_max_margin:0 +msgid "Max. Price Margin" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid "Min. Margin" +msgstr "" + +#. module: product +#: help:product.supplierinfo,product_name:0 +msgid "" +"This supplier's product name will be used when printing a request for " +"quotation. Keep empty to use the internal one." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_pricelist_action_for_purchase +msgid "" +"

\n" +" Click to create a pricelist.\n" +"

\n" +" A price list contains rules to be evaluated in order to " +"compute\n" +" the purchase price. The default price list has only one " +"rule; use\n" +" the cost price defined on the product form, so that you do " +"not have to\n" +" worry about supplier pricelists if you have very simple " +"needs.\n" +"

\n" +" But you can also import complex price lists form your " +"supplier\n" +" that may depends on the quantities ordered or the current\n" +" promotions.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: selection:product.template,mes_type:0 +msgid "Variable" +msgstr "" + +#. module: product +#: field:product.template,rental:0 +msgid "Can be Rent" +msgstr "" + +#. module: product +#: model:product.price.type,name:product.standard_price +msgid "Cost Price" +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_min_margin:0 +msgid "Min. Price Margin" +msgstr "" + +#. module: product +#: model:res.groups,name:product.group_uom +msgid "Manage Multiple Units of Measure" +msgstr "" + +#. module: product +#: help:product.packaging,weight:0 +msgid "The weight of a full package, pallet or box." +msgstr "" + +#. module: product +#: view:product.uom:0 +msgid "e.g: 1 * (this unit) = ratio * (reference unit)" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_25_product_template +msgid "" +"17\" Monitor\n" +"4GB RAM\n" +"Standard-1294P Processor\n" +"QWERTY keyboard" +msgstr "" + +#. module: product +#: field:product.category,sequence:0 +#: field:product.packaging,sequence:0 +#: field:product.pricelist.item,sequence:0 +#: field:product.supplierinfo,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: product +#: help:product.template,produce_delay:0 +msgid "" +"Average delay in days to produce this product. In the case of multi-level " +"BOM, the manufacturing lead times of the components will be added." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_assembly_product_template +msgid "Assembly Service Cost" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_pricelist_item +msgid "Pricelist item" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_uom_form_action +msgid "" +"

\n" +" Click to add a new unit of measure.\n" +"

\n" +" You must define a conversion rate between several Units of\n" +" Measure within the same category.\n" +"

\n" +" " +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_11_product_template +msgid "Mouse, Laser" +msgstr "" + +#. module: product +#: view:product.template:0 +msgid "Delays" +msgstr "" + +#. module: product +#: field:product.category,type:0 +msgid "Category Type" +msgstr "" + +#. module: product +#: model:process.node,note:product.process_node_product0 +msgid "Creation of the product" +msgstr "" + +#. module: product +#: field:pricelist.partnerinfo,name:0 +#: field:product.packaging,name:0 +#: report:product.pricelist:0 +#: view:product.product:0 +#: field:product.template,description:0 +msgid "Description" +msgstr "" + +#. module: product +#: field:product.packaging,ean:0 +msgid "EAN" +msgstr "" + +#. module: product +#: view:product.pricelist.item:0 +msgid " ) + " +msgstr "" + +#. module: product +#: field:product.template,volume:0 +#: model:product.uom.categ,name:product.product_uom_categ_vol +msgid "Volume" +msgstr "" + +#. module: product +#: help:product.product,image_small:0 +msgid "" +"Small-sized image of the product. It is automatically resized as a 64x64px " +"image, with aspect ratio preserved. Use this field anywhere a small image is " +"required." +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_40_product_template +msgid "Windows 7 Professional" +msgstr "" + +#. module: product +#: selection:product.uom,uom_type:0 +msgid "Reference Unit of Measure for this category" +msgstr "" + +#. module: product +#: field:product.supplierinfo,product_uom:0 +msgid "Supplier Unit of Measure" +msgstr "" + +#. module: product +#: view:product.product:0 +#: model:res.groups,name:product.group_product_variant +msgid "Product Variant" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_6_product_template +msgid "15” LCD Monitor" +msgstr "" + +#. module: product +#: code:addons/product/pricelist.py:376 +#: field:product.pricelist.item,base_pricelist_id:0 +#, python-format +msgid "Other Pricelist" +msgstr "" + +#. module: product +#: model:ir.actions.act_window,help:product.product_pricelist_action2 +msgid "" +"

\n" +" Click to create a pricelist.\n" +"

\n" +" A price list contains rules to be evaluated in order to " +"compute\n" +" the sales price of the products.\n" +"

\n" +" Price lists may have several versions (2010, 2011, Promotion " +"of\n" +" February 2010, etc.) and each version may have several " +"rules.\n" +" (e.g. the customer price of a product category will be based " +"on\n" +" the supplier price multiplied by 1.80).\n" +"

\n" +" " +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_template +#: field:product.pricelist.item,product_tmpl_id:0 +#: field:product.product,product_tmpl_id:0 +#: view:product.template:0 +msgid "Product Template" +msgstr "" + +#. module: product +#: field:product.template,cost_method:0 +#: model:res.groups,name:product.group_costing_method +msgid "Costing Method" +msgstr "" + +#. module: product +#: model:ir.model,name:product.model_product_category +#: field:product.pricelist.item,categ_id:0 +msgid "Product Category" +msgstr "" + +#. module: product +#: model:product.template,description:product.product_product_19_product_template +msgid "On demand hard-disk having capacity based on requirement." +msgstr "" + +#. module: product +#: selection:product.template,state:0 +msgid "End of Lifecycle" +msgstr "" + +#. module: product +#: model:product.template,name:product.product_product_15_product_template +msgid "RAM SR3" +msgstr "" + +#. module: product +#: help:product.product,packaging:0 +msgid "" +"Gives the different ways to package the same product. This has no impact on " +"the picking order and is mainly used if you use the EDI module." +msgstr "" + +#. module: product +#: model:ir.actions.act_window,name:product.product_pricelist_action +#: model:ir.ui.menu,name:product.menu_product_pricelist_action +#: field:product.pricelist,version_id:0 +msgid "Pricelist Versions" +msgstr "" + +#. module: product +#: help:product.pricelist.item,price_round:0 +msgid "" +"Sets the price so that it is a multiple of this value.\n" +"Rounding is applied after the discount and before the surcharge.\n" +"To have prices that end in 9.99, set rounding 10, surcharge -0.01" +msgstr "" + +#. module: product +#: field:product.template,list_price:0 +msgid "Sale Price" +msgstr "" + +#. module: product +#: help:product.uom,category_id:0 +msgid "" +"Conversion between Units of Measure can only occur if they belong to the " +"same category. The conversion will be made based on the ratios." +msgstr "" + +#. module: product +#: constraint:product.category:0 +msgid "Error ! You cannot create recursive categories." +msgstr "" + +#. module: product +#: help:product.product,image_medium:0 +msgid "" +"Medium-sized image of the product. It is automatically resized as a " +"128x128px image, with aspect ratio preserved, only when the image exceeds " +"one of those sizes. Use this field in form views or some kanban views." +msgstr "" + +#. module: product +#: view:product.uom:0 +msgid "e.g: 1 * (reference unit) = ratio * (this unit)" +msgstr "" + +#. module: product +#: help:product.supplierinfo,qty:0 +msgid "This is a quantity which is converted into Default Unit of Measure." +msgstr "" + +#. module: product +#: help:product.template,volume:0 +msgid "The volume in m3." +msgstr "" + +#. module: product +#: field:product.pricelist.item,price_discount:0 +msgid "Price Discount" +msgstr "" diff --git a/addons/report_webkit/ir_report.py b/addons/report_webkit/ir_report.py index 1385f504928..01b65987a8e 100644 --- a/addons/report_webkit/ir_report.py +++ b/addons/report_webkit/ir_report.py @@ -30,21 +30,22 @@ ############################################################################## from openerp.osv import fields, osv -from openerp import netsvc -from webkit_report import WebKitParser +import openerp.report.interface from openerp.report.report_sxw import rml_parse +from webkit_report import WebKitParser + def register_report(name, model, tmpl_path, parser=rml_parse): """Register the report into the services""" name = 'report.%s' % name - if netsvc.Service._services.get(name, False): - service = netsvc.Service._services[name] + if name in openerp.report.interface.report_int._reports: + service = openerp.report.interface.report_int[name] if isinstance(service, WebKitParser): #already instantiated properly, skip it return if hasattr(service, 'parser'): parser = service.parser - del netsvc.Service._services[name] + del openerp.report.interface.report_int[name] WebKitParser(name, model, tmpl_path, parser=parser)