From 1a1e3463023947db05d6c0e9b371e161253d4cbf Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Thu, 4 Mar 2010 10:44:58 +0100 Subject: [PATCH 001/248] [IMP] yaml test: init bzr revid: jth@openerp.com-20100304094458-oru0mdc523veqsbp --- bin/addons/__init__.py | 2 + bin/netsvc.py | 12 +- bin/tools/__init__.py | 1 + bin/tools/yaml_test.py | 406 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 418 insertions(+), 3 deletions(-) create mode 100644 bin/tools/yaml_test.py diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 2910b9fe7c1..ebf0c2fcd05 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -644,6 +644,8 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): new_query = ' '.join(query.split()) if new_query: cr.execute(new_query) + elif ext == '.yaml': + tools.convert_yaml_import(cr, m, fp, idref, mode=mode, **kwargs) else: tools.convert_xml_import(cr, m, fp, idref, mode=mode, **kwargs) fp.close() diff --git a/bin/netsvc.py b/bin/netsvc.py index d8548db5d6a..eae53826a74 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -127,6 +127,7 @@ class ExportService(object): LOG_NOTSET = 'notset' LOG_DEBUG_RPC = 'debug_rpc' LOG_DEBUG = 'debug' +LOG_TEST = 'test' LOG_INFO = 'info' LOG_WARNING = 'warn' LOG_ERROR = 'error' @@ -135,6 +136,9 @@ LOG_CRITICAL = 'critical' logging.DEBUG_RPC = logging.DEBUG - 2 logging.addLevelName(logging.DEBUG_RPC, 'DEBUG_RPC') +logging.TEST = logging.INFO - 5 +logging.addLevelName(logging.TEST, 'TEST') + def init_logger(): import os from tools.translate import resetlocale @@ -195,6 +199,7 @@ def init_logger(): 'DEBUG_RPC': ('blue', 'white'), 'DEBUG': ('blue', 'default'), 'INFO': ('green', 'default'), + 'TEST': ('white', 'blue'), 'WARNING': ('yellow', 'default'), 'ERROR': ('red', 'default'), 'CRITICAL': ('white', 'red'), @@ -220,9 +225,10 @@ class Logger(object): log = logging.getLogger(tools.ustr(name)) - if level == LOG_DEBUG_RPC and not hasattr(log, level): - fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG_RPC, msg, *args, **kwargs) - setattr(log, LOG_DEBUG_RPC, fct) + if level in [LOG_DEBUG_RPC, LOG_TEST] and not hasattr(log, level): + fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs) + setattr(log, level, fct) + level_method = getattr(log, level) diff --git a/bin/tools/__init__.py b/bin/tools/__init__.py index 9b7bb84a57f..78c77edf394 100644 --- a/bin/tools/__init__.py +++ b/bin/tools/__init__.py @@ -24,6 +24,7 @@ import win32 from config import * from misc import * from convert import * +from yaml_test import * from translate import * from graph import graph from amount_to_text import * diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py new file mode 100644 index 00000000000..52ce059a5fd --- /dev/null +++ b/bin/tools/yaml_test.py @@ -0,0 +1,406 @@ +# -*- encoding: utf-8 -*- +import types +import yaml +import time # used to eval time.strftime expressions +import logging + +import pooler +import netsvc + +from config import config + +logger_channel = 'tests' + +class YamlImportException(Exception): + pass + +class YamlImportAbortion(Exception): + pass + +class YamlTag(object): + """Superclass for constructors of custom tags defined in yaml file.""" + + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + def __getitem__(self, key): + return getattr(self, key) + def __getattr__(self, attr): + return None + def __repr__(self): + return "<%s %s>" % (self.__class__.__name__, sorted(self.__dict__.items())) + +class Assert(YamlTag): + def __init__(self, model, id, severity=netsvc.LOG_ERROR, string="NONAME", **kwargs): + self.model = model + self.id = id + self.severity = severity + self.string = string + super(Assert, self).__init__(**kwargs) + +class Record(YamlTag): + def __init__(self, model, id, **kwargs): + self.model = model + self.id = id + super(Record, self).__init__(**kwargs) + +class Python(YamlTag): + def __init__(self, model, severity=netsvc.LOG_ERROR, name="NONAME", **kwargs): + self.model= model + self.severity = severity + self.name = name + super(Python, self).__init__(**kwargs) + +class Workflow(YamlTag): + def __init__(self, model, action, **kwargs): + self.model = model + self.action = action + super(Workflow, self).__init__(**kwargs) + +class Context(YamlTag): + def __init__(self, **kwargs): + super(Context, self).__init__(**kwargs) + +class Eval(YamlTag): + def __init__(self, expression): + self.expression = expression + super(Eval, self).__init__() + +class Ref(YamlTag): + def __init__(self, xmlid): + self.xmlid = xmlid + super(Ref, self).__init__() + +def assert_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Assert(**kwargs) + +def record_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Record(**kwargs) + +def python_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Python(**kwargs) + +def workflow_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Workflow(**kwargs) + +def context_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Context(**kwargs) + +def eval_constructor(loader, node): + expression = loader.construct_scalar(node) + return Eval(expression) + +def ref_constructor(loader, node): + xmlid = loader.construct_scalar(node) + return Ref(xmlid) + +yaml.add_constructor(u"!assert", assert_constructor) +yaml.add_constructor(u"!record", record_constructor) +yaml.add_constructor(u"!python", python_constructor) +yaml.add_constructor(u"!workflow", workflow_constructor) +yaml.add_constructor(u"!context", context_constructor) +yaml.add_constructor(u"!eval", eval_constructor) +yaml.add_constructor(u"!ref", ref_constructor) + +def _is_yaml_mapping(node, tag_constructor): + value = isinstance(node, types.DictionaryType) \ + and len(node.keys()) == 1 \ + and isinstance(node.keys()[0], tag_constructor) + return value + +def is_comment(node): + return isinstance(node, types.StringTypes) + +def is_assert(node): + return _is_yaml_mapping(node, Assert) + +def is_record(node): + return _is_yaml_mapping(node, Record) + +def is_python(node): + return _is_yaml_mapping(node, Python) + +def is_workflow(node): + return isinstance(node, Workflow) \ + or _is_yaml_mapping(node, Workflow) + +def is_context(node): + return isinstance(node, Context) + +def is_eval(node): + return isinstance(node, Eval) + +def is_ref(node): + return isinstance(node, Ref) + + +class TestReport(object): + def __init__(self): + self._report = {} + + def record(self, success, severity): + """Records the result of an assertion for the failed/success count. + Returns success.""" + + if severity in self._report: + self._report[severity][success] += 1 + else: + self._report[severity] = {success: 1, not success: 0} + return success + + def __str__(self): + res = [] + res.append('\nAssertions report:\nLevel\tsuccess\tfailed') + success = failure = 0 + for severity in self._report: + res.append("%s\t%s\t%s" % (severity, self._report[severity][True], self._report[severity][False])) + success += self._report[severity][True] + failure += self._report[severity][False] + res.append("total\t%s\t%s" % (success, failure)) + res.append("end of report (%s assertion(s) checked)" % success + failure) + return "\n".join(res) + + +class YamlInterpreter(object): + def __init__(self, cr, module, id_map, mode, filename, noupdate=False): + self.cr = cr + self.module = module + self.id_map = id_map + self.mode = mode + self.filename = filename + self.assert_report = TestReport() + self.noupdate = noupdate + self.logger = netsvc.Logger() + self.pool = pooler.get_pool(cr.dbname) + self.uid = 1 + self.context = {} + + def _ref(self): + return lambda xml_id: self.get_id(xml_id) + + def get_model(self, model_name): + model = self.pool.get(model_name) + assert model, "The model %s does not exist." % (model_name,) + return model + + def validate_xml_id(self, xml_id): + id = xml_id + if '.' in xml_id: + module, id = xml_id.split('.', 1) + assert '.' not in id, "The ID reference '%s' must contains maximum one dot.\n" \ + "It is used to refer to other modules ID, in the form: module.record_id" \ + % (xml_id,) + if module != self.module: + module_count = self.pool.get('ir.module.module').search_count(self.cr, self.uid, \ + ['&', ('name', '=', module), ('state', 'in', ['installed'])]) + assert module_count == 1, """The ID "%s" refers to an uninstalled module""" % (xml_id,) + if len(id) > 64: # TODO where does 64 come from (DB is 128)? should be a constant or loaded form DB + self.logger.notifyChannel(logger_channel, netsvc.LOG_ERROR, 'id: %s is to long (max: 64)' % (id,)) + + def get_id(self, xml_id): + if isinstance(xml_id, types.IntType): + id = xml_id + elif xml_id in self.id_map: + id = self.id_map[xml_id] + else: + if '.' in xml_id: + module, xml_id = xml_id.split('.', 1) + else: + module = self.module + ir_id = self.pool.get('ir.model.data')._get_id(self.cr, self.uid, module, xml_id) + obj = self.pool.get('ir.model.data').read(self.cr, self.uid, ir_id, ['res_id']) + id = int(obj['res_id']) + self.id_map[xml_id] = id + return id + + def process_comment(self, node): + return node + + def _log_assert_failure(self, severity, msg, *args): + self.assert_report.record(False, severity) + self.logger.notifyChannel(logger_channel, severity, msg % (args)) + if getattr(logging, severity.upper()) >= config['assert_exit_level']: + raise YamlImportAbortion('Severe assertion failure (%s), aborting.' % (severity,)) + return + + def _get_assertion_id(self, assertion): + if assertion.id: + ids = [self.get_id(assertion.id)] + elif assertion.search: + q = eval(assertion.search, {'ref': self._ref}) + ids = self.pool.get(assertion.model).search(self.cr, self.uid, q, context=assertion.context) + if not ids: + raise YamlImportException('Nothing to assert: you must give either an id or a search criteria.') + return ids + + def process_assert(self, node): + assertion, expressions = node.items()[0] + + model = self.get_model(assertion.model) + ids = self._get_assertion_id(assertion) + if assertion.count and len(ids) != assertion.count: + msg = 'assertion "%s" failed!\n' \ + ' Incorrect search count:\n' \ + ' expected count: %d\n' \ + ' obtained count: %d\n' + args = (assertion.string, assertion.count, len(ids)) + self._log_assert_failure(assertion.severity, msg, *args) + else: + test_context = {'ref': self._ref, '_ref': self._ref} # added '_ref' so that record['ref'] is possible + for id in ids: + record = model.browse(self.cr, self.uid, id, assertion.context) + for test in expressions.get('test', ''): + success = eval(test, test_context, record) + if not success: + msg = 'Assertion "%s" FAILED\ntest: %s\n' + args = (assertion.string, test) + self._log_assert_failure(assertion.severity, msg, *args) + return + else: # all tests were successful for this assertion tag (no break) + self.assert_report.record(True, assertion.severity) + + def process_record(self, node): + record, fields = node.items()[0] + + self.validate_xml_id(record.id) + model = self.get_model(record.model) + record_dict = self._create_record(model, fields) + id = self.pool.get('ir.model.data')._update(self.cr, self.uid, record.model, \ + self.module, record_dict, record.id, mode=self.mode) + self.id_map[record.id] = int(id) + if config.get('import_partial', False): + self.cr.commit() + + def _create_record(self, model, fields): + record_dict = {} + for field_name, expression in fields.items(): + field_value = self._eval_field(model, field_name, expression) + record_dict[field_name] = field_value + return record_dict + + def _eval_field(self, model, field_name, expression): + column = model._columns[field_name] + if column._type == "many2one": + value = self.get_id(expression) + elif column._type == "one2many": + other_model = self.get_model(column._obj) + value = [(0, 0, self._create_record(other_model, fields)) for fields in expression] + elif column._type == "many2many": + ids = [self.get_id(xml_id) for xml_id in expression] + value= [(6, 0, ids)] + else: # scalar field + if isinstance(expression, Eval): + value = eval(expression.expression) + else: + value = expression + # raise YamlImportException('Unsupported column "%s" or value %s:%s' % (field_name, type(expression), expression)) + return value + + def process_context(self, node): + self.context = node.__dict__ + if 'uid' in node.__dict__: + self.uid = self.get_id(node.__dict__['uid']) + + def process_python(self, node): + def log(msg): + self.logger.notifyChannel(logger_channel, netsvc.LOG_TEST, msg) + python, statements = node.items()[0] + model = self.get_model(python.model) + statements = statements.replace("\r\n", "\n").replace("\n", ";") + code_context = {'self': model, 'cr': self.cr, 'uid': self.uid, 'log': log, 'context': self.context} + try: + code = compile(statements, self.filename, 'exec') + eval(code, code_context) + except Exception, e: + raise YamlImportException(e) + # TODO log success/failure + + def process_workflow(self, node): + workflow, values = node.items()[0] + model = self.get_model(workflow.model) + if workflow.ref: + id = self.get_id(workflow.ref) + else: + if not values: + raise YamlImportException('You must define a child node if you do not give a ref.') + if not len(values) == 1: + raise YamlImportException('Only one child node is accepted (%d given).' % len(values)) + value = values[0] + if not 'model' in value and not 'eval' in value: + raise YamlImportException('You must provide a model and an expression to evaluate for the workflow.') + value_model = self.get_model(value['model']) + local_context = {'ref': self._ref, '_ref': self._ref} + local_context['obj'] = lambda x: value_model.browse(self.cr, self.uid, x, context=self.context) + local_context.update(self.id_map) + id = eval(value['eval'], local_context) + + if workflow.uid is not None: + uid = workflow.uid + else: + uid = self.uid + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, model, id, workflow.action, self.cr) + + def process(self, yaml_string): + """Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.""" + + is_preceded_by_comment = False + for node in yaml.load(yaml_string): + is_preceded_by_comment = self._log(node, is_preceded_by_comment) + try: + self._process_node(node) + except YamlImportException, e: + self.logger.notifyChannel(logger_channel, netsvc.LOG_ERROR, e) + except YamlImportAbortion, e: + self.logger.notifyChannel(logger_channel, netsvc.LOG_ERROR, e) + return + + def _process_node(self, node): + if is_comment(node): + self.process_comment(node) + elif is_assert(node): + self.process_assert(node) + elif is_record(node): + self.process_record(node) + elif is_python(node): + self.process_python(node) + elif is_context(node): + self.process_context(node) + elif is_workflow(node): + if isinstance(node, types.DictionaryType): + self.process_workflow(node) + else: + self.process_workflow({node: []}) + else: + raise YamlImportException("Can not process YAML block: %s" % node) + + def _log(self, node, is_preceded_by_comment): + if is_comment(node): + is_preceded_by_comment = True + self.logger.notifyChannel(logger_channel, netsvc.LOG_TEST, node) + elif not is_preceded_by_comment: + if isinstance(node, types.DictionaryType): + k, v = node.items()[0] + msg = "Creating %s\n with %s" % (k, v) + self.logger.notifyChannel(logger_channel, netsvc.LOG_TEST, msg) + else: + self.logger.notifyChannel(logger_channel, netsvc.LOG_TEST, node) + else: + is_preceded_by_comment = False + return is_preceded_by_comment + +def yaml_import(cr, module, yamlfile, idref=None, mode='init', noupdate=False, report=None): + if idref is None: + idref = {} + yaml_string = yamlfile.read() + yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, noupdate=noupdate) + yaml_interpreter.process(yaml_string) + +# keeps convention of convert.py +convert_yaml_import = yaml_import + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From b8b60d44363c0062e0588178dc02d641baacb5e3 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Thu, 4 Mar 2010 11:03:55 +0100 Subject: [PATCH 002/248] [FIX] YAML files have '.yml' extension, not '.yaml' bzr revid: jth@openerp.com-20100304100355-0je51f1c0261b25u --- bin/addons/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index ebf0c2fcd05..8137a7fecbb 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -644,7 +644,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): new_query = ' '.join(query.split()) if new_query: cr.execute(new_query) - elif ext == '.yaml': + elif ext == '.yml': tools.convert_yaml_import(cr, m, fp, idref, mode=mode, **kwargs) else: tools.convert_xml_import(cr, m, fp, idref, mode=mode, **kwargs) From b8ebcf689bb31ca3cbefbd954c9d742c0a59c4e0 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Thu, 4 Mar 2010 16:41:59 +0100 Subject: [PATCH 003/248] [IMP] Record python block success in assertion report. bzr revid: jth@openerp.com-20100304154159-m1i6zuqsvg08s1vi --- bin/tools/yaml_test.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index 52ce059a5fd..b91e457791e 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -315,9 +315,15 @@ class YamlInterpreter(object): try: code = compile(statements, self.filename, 'exec') eval(code, code_context) + except AssertionError, e: + msg = 'Assertion "%s" FAILED in Python code.' + args = (python.name,) + self._log_assert_failure(python.severity, msg, *args) + return except Exception, e: - raise YamlImportException(e) - # TODO log success/failure + raise YamlImportAbortion(e) + else: + self.assert_report.record(True, python.severity) def process_workflow(self, node): workflow, values = node.items()[0] From af48a29843cabc84880e3fdbd35dd7360a0d8ff1 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Fri, 5 Mar 2010 10:12:18 +0100 Subject: [PATCH 004/248] [IMP] Added more syntax. bzr revid: jth@openerp.com-20100305091218-2t25717pfnw6iie8 --- bin/tools/yaml_test.py | 284 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 279 insertions(+), 5 deletions(-) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index b91e457791e..5cee9b92d5e 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -50,16 +50,45 @@ class Python(YamlTag): self.name = name super(Python, self).__init__(**kwargs) +class Menuitem(YamlTag): + def __init__(self, id, name, **kwargs): + self.id = id + self.name = name + super(Menuitem, self).__init__(**kwargs) + class Workflow(YamlTag): def __init__(self, model, action, **kwargs): self.model = model self.action = action super(Workflow, self).__init__(**kwargs) +class ActWindow(YamlTag): + def __init__(self, model, action, **kwargs): + self.model = model + self.action = action + super(Workflow, self).__init__(**kwargs) + +class Function(YamlTag): + def __init__(self, model, name, **kwargs): + self.model = model + self.name = name + super(Function, self).__init__(**kwargs) + +class Delete(YamlTag): + def __init__(self, model, id, search, **kwargs): + self.model = model + self.id = id + self.search = search + super(Delete, self).__init__(**kwargs) + class Context(YamlTag): def __init__(self, **kwargs): super(Context, self).__init__(**kwargs) +class Url(YamlTag): + def __init__(self, **kwargs): + super(Url, self).__init__(**kwargs) + class Eval(YamlTag): def __init__(self, expression): self.expression = expression @@ -82,14 +111,34 @@ def python_constructor(loader, node): kwargs = loader.construct_mapping(node) return Python(**kwargs) +def menuitem_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Menuitem(**kwargs) + def workflow_constructor(loader, node): kwargs = loader.construct_mapping(node) return Workflow(**kwargs) +def act_window_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return ActWindow(**kwargs) + +def function_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Function(**kwargs) + +def delete_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Delete(**kwargs) + def context_constructor(loader, node): kwargs = loader.construct_mapping(node) return Context(**kwargs) +def url_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Url(**kwargs) + def eval_constructor(loader, node): expression = loader.construct_scalar(node) return Eval(expression) @@ -101,8 +150,13 @@ def ref_constructor(loader, node): yaml.add_constructor(u"!assert", assert_constructor) yaml.add_constructor(u"!record", record_constructor) yaml.add_constructor(u"!python", python_constructor) +yaml.add_constructor(u"!menuitem", menuitem_constructor) yaml.add_constructor(u"!workflow", workflow_constructor) +yaml.add_constructor(u"!act_window", act_window_constructor) +yaml.add_constructor(u"!function", function_constructor) yaml.add_constructor(u"!context", context_constructor) +yaml.add_constructor(u"!delete", delete_constructor) +yaml.add_constructor(u"!url", url_constructor) yaml.add_constructor(u"!eval", eval_constructor) yaml.add_constructor(u"!ref", ref_constructor) @@ -124,13 +178,29 @@ def is_record(node): def is_python(node): return _is_yaml_mapping(node, Python) +def is_menuitem(node): + return isinstance(node, Menuitem) \ + or _is_yaml_mapping(node, Menuitem) + +def is_function(node): + return isinstance(node, Function) \ + or _is_yaml_mapping(node, Function) + def is_workflow(node): - return isinstance(node, Workflow) \ - or _is_yaml_mapping(node, Workflow) + return isinstance(node, Workflow) + +def is_act_window(node): + return isinstance(node, ActWindow) + +def is_delete(node): + return isinstance(node, Delete) def is_context(node): return isinstance(node, Context) +def is_url(node): + return isinstance(node, Url) + def is_eval(node): return isinstance(node, Eval) @@ -154,7 +224,7 @@ class TestReport(object): def __str__(self): res = [] - res.append('\nAssertions report:\nLevel\tsuccess\tfailed') + res.append('\nAssertions report:\nLevel\tsuccess\tfailure') success = failure = 0 for severity in self._report: res.append("%s\t%s\t%s" % (severity, self._report[severity][True], self._report[severity][False])) @@ -217,6 +287,12 @@ class YamlInterpreter(object): self.id_map[xml_id] = id return id + def get_context(self, node, locals_dict): + context = self.context.copy() + if node.context: + context.update(eval(node.context, locals_dict)) + return context + def process_comment(self, node): return node @@ -336,8 +412,8 @@ class YamlInterpreter(object): if not len(values) == 1: raise YamlImportException('Only one child node is accepted (%d given).' % len(values)) value = values[0] - if not 'model' in value and not 'eval' in value: - raise YamlImportException('You must provide a model and an expression to evaluate for the workflow.') + if not 'model' in value and (not 'eval' in value or not 'search' in value): + raise YamlImportException('You must provide a "model" and an "eval" or "search" to evaluate.') value_model = self.get_model(value['model']) local_context = {'ref': self._ref, '_ref': self._ref} local_context['obj'] = lambda x: value_model.browse(self.cr, self.uid, x, context=self.context) @@ -350,7 +426,192 @@ class YamlInterpreter(object): uid = self.uid wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, model, id, workflow.action, self.cr) + + def process_function(self, node): + if self.mode != 'init': + return + function, values = node.items()[0] + local_context = {'ref': self._ref, '_ref': self._ref} + context = self.get_context(node, local_context) + args = [] + if function.eval: + args = eval(function.eval, local_context) + for value in values: + if not 'model' in value and (not 'eval' in value or not 'search' in value): + raise YamlImportException('You must provide a "model" and an "eval" or "search" to evaluate.') + value_model = self.get_model(value['model']) + local_context = {'ref': self._ref, '_ref': self._ref} + local_context['obj'] = lambda x: value_model.browse(self.cr, self.uid, x, context=context) + local_context.update(self.id_map) + id = eval(value['eval'], local_context) + if id != None: + args.append(id) + model = self.get_model(function.model) + method = function.name + getattr(model, method)(self.cr, self.uid, *args) + def _set_group_values(self, node, values): + if node.groups: + group_names = node.groups.split(',') + groups_value = [] + for group in group_names: + if group.startswith('-'): + group_id = self.get_id(group[1:]) + groups_value.append((3, group_id)) + else: + group_id = self.get_id(group) + groups_value.append((4, group_id)) + values['groups_id'] = groups_value + + def process_menuitem(self, node): + self.validate_xml_id(node.id) + + if not node.parent: + parent_id = False + self.cr.execute('select id from ir_ui_menu where parent_id is null and name=%s', (node.name,)) + res = self.cr.fetchone() + values = {'parent_id': parent_id, 'name': node.name} + else: + parent_id = self.get_id(node.parent) + values = {'parent_id': parent_id} + if node.name: + values['name'] = node.name + try: + res = [ self.get_id(node.id) ] + except: # which exception ? + res = None + + if node.action: + action_type = node.type or 'act_window' + icons = { + "act_window": 'STOCK_NEW', + "report.xml": 'STOCK_PASTE', + "wizard": 'STOCK_EXECUTE', + "url": 'STOCK_JUMP_TO', + } + values['icon'] = icons.get(action_type, 'STOCK_NEW') + if action_type == 'act_window': + action_id = self.get_id(node.action) + self.cr.execute('select view_type,view_mode,name,view_id,target from ir_act_window where id=%s', (action_id,)) + ir_act_window_result = self.cr.fetchone() + assert ir_act_window_result, "No window action defined for this id %s !\n" \ + "Verify that this is a window action or add a type argument." % (node.action,) + action_type, action_mode, action_name, view_id, target = ir_act_window_result + if view_id: + self.cr.execute('SELECT type FROM ir_ui_view WHERE id=%s', (view_id,)) + # TODO guess why action_mode is ir_act_window.view_mode above and ir_ui_view.type here + action_mode = self.cr.fetchone() + self.cr.execute('SELECT view_mode FROM ir_act_window_view WHERE act_window_id=%s ORDER BY sequence LIMIT 1', (action_id,)) + if self.cr.rowcount: + action_mode = self.cr.fetchone() + if action_type == 'tree': + values['icon'] = 'STOCK_INDENT' + elif action_mode and action_mode.startswith('tree'): + values['icon'] = 'STOCK_JUSTIFY_FILL' + elif action_mode and action_mode.startswith('graph'): + values['icon'] = 'terp-graph' + elif action_mode and action_mode.startswith('calendar'): + values['icon'] = 'terp-calendar' + if target == 'new': + values['icon'] = 'STOCK_EXECUTE' + if not values.get('name', False): + values['name'] = action_name + elif action_type == 'wizard': + action_id = self.get_id(node.action) + self.cr.execute('select name from ir_act_wizard where id=%s', (action_id,)) + ir_act_wizard_result = self.cr.fetchone() + if (not values.get('name', False)) and ir_act_wizard_result: + values['name'] = ir_act_wizard_result[0] + else: + raise YamlImportException("Unsupported type '%s' in menuitem tag." % action_type) + if node.sequence: + values['sequence'] = node.sequence + if node.icon: + values['icon'] = node.icon + + self._set_group_values(node, values) + + pid = self.pool.get('ir.model.data')._update(self.cr, self.uid, \ + 'ir.ui.menu', self.module, values, node.id, mode=self.mode, \ + res_id=res and res[0] or False) + + if node.id and parent_id: + self.id_map[node.id] = int(parent_id) + + if node.action and pid: + action_type = node.type or 'act_window' + action_id = self.get_id(node.action) + action = "ir.actions.%s,%d" % (action_type, action_id) + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', \ + 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(parent_id))], action, True, True, xml_id=node.id) + + def process_act_window(self, node): + self.validate_xml_id(node.id) + view_id = False + if node.view: + view_id = self.get_id(node.view) + context = eval(node.context, {'ref': self._ref, '_ref': self._ref}) + + values = { + 'name': node.name, + 'type': type or 'ir.actions.act_window', + 'view_id': view_id, + 'domain': node.domain, + 'context': context, + 'res_model': node.res_model, + 'src_model': node.src_model, + 'view_type': node.view_type or 'form', + 'view_mode': node.view_mode or 'tree,form', + 'usage': node.usage, + 'limit': node.limit, + 'auto_refresh': node.auto_refresh, + } + + self._set_group_values(node, values) + + if node.target: + values['target'] = node.target + id = self.pool.get('ir.model.data')._update(self.cr, self.uid, \ + 'ir.actions.act_window', self.module, values, node.id, mode=self.mode) + self.id_map[node.id] = int(id) + + if node.src_model: + keyword = 'client_action_relate' + value = 'ir.actions.act_window,%s' % id + replace = node.replace or True + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', \ + keyword, node.id, [node.src_model], value, replace=replace, isobject=True, xml_id=node.id) + # TODO add remove ir.model.data + + def process_delete(self, node): + ids = [] + if len(node.search): + ids = self.pool.get(node.model).search(self.cr, self.uid, eval(node.search)) + if len(node.id): + try: + ids.append(self.get_id(node.id)) + except: + pass + if len(ids): + self.pool.get(node.model).unlink(self.cr, self.uid, ids) + self.pool.get('ir.model.data')._unlink(self.cr, self.uid, node.model, ids, direct=True) + + def process_url(self, node): + self.validate_xml_id(node.id) + + res = {'name': node.name, 'url': node.url, 'target': node.target} + + id = self.pool.get('ir.model.data')._update(self.cr, self.uid, \ + "ir.actions.url", self.module, res, node.id, mode=self.mode) + self.id_map[node.id] = int(id) + # ir_set + if (not node.menu or eval(node.menu)) and id: + keyword = node.keyword or 'client_action_multi' + value = 'ir.actions.url,%s' % id + replace = node.replace or True + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, \ + 'action', keyword, node.url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=node.id) + def process(self, yaml_string): """Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.""" @@ -374,13 +635,26 @@ class YamlInterpreter(object): self.process_record(node) elif is_python(node): self.process_python(node) + elif is_menuitem(node): + self.process_menuitem(node) + elif is_delete(node): + self.process_delete(node) + elif is_url(node): + self.process_url(node) elif is_context(node): self.process_context(node) + elif is_act_window(node): + self.process_act_window(node) elif is_workflow(node): if isinstance(node, types.DictionaryType): self.process_workflow(node) else: self.process_workflow({node: []}) + elif is_function(node): + if isinstance(node, types.DictionaryType): + self.process_function(node) + else: + self.process_function({node: []}) else: raise YamlImportException("Can not process YAML block: %s" % node) From 2b3611cb376cd49c57243e74387b0facedd4f537 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Fri, 5 Mar 2010 10:37:22 +0100 Subject: [PATCH 005/248] [IMP] Added ir_set. [FIX] ActWindow __init__ bzr revid: jth@openerp.com-20100305093722-t1ndcr0v8preofkw --- bin/tools/yaml_test.py | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index 5cee9b92d5e..442370ab5dc 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -66,7 +66,7 @@ class ActWindow(YamlTag): def __init__(self, model, action, **kwargs): self.model = model self.action = action - super(Workflow, self).__init__(**kwargs) + super(ActWindow, self).__init__(**kwargs) class Function(YamlTag): def __init__(self, model, name, **kwargs): @@ -94,10 +94,9 @@ class Eval(YamlTag): self.expression = expression super(Eval, self).__init__() -class Ref(YamlTag): - def __init__(self, xmlid): - self.xmlid = xmlid - super(Ref, self).__init__() +class IrSet(YamlTag): + def __init__(self): + super(IrSet, self).__init__() def assert_constructor(loader, node): kwargs = loader.construct_mapping(node) @@ -143,9 +142,9 @@ def eval_constructor(loader, node): expression = loader.construct_scalar(node) return Eval(expression) -def ref_constructor(loader, node): - xmlid = loader.construct_scalar(node) - return Ref(xmlid) +def ir_set_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return IrSet(**kwargs) yaml.add_constructor(u"!assert", assert_constructor) yaml.add_constructor(u"!record", record_constructor) @@ -158,7 +157,7 @@ yaml.add_constructor(u"!context", context_constructor) yaml.add_constructor(u"!delete", delete_constructor) yaml.add_constructor(u"!url", url_constructor) yaml.add_constructor(u"!eval", eval_constructor) -yaml.add_constructor(u"!ref", ref_constructor) +yaml.add_constructor(u"!ir_set", ir_set_constructor) def _is_yaml_mapping(node, tag_constructor): value = isinstance(node, types.DictionaryType) \ @@ -204,8 +203,8 @@ def is_url(node): def is_eval(node): return isinstance(node, Eval) -def is_ref(node): - return isinstance(node, Ref) +def is_ir_set(node): + return _is_yaml_mapping(node, IrSet) class TestReport(object): @@ -611,6 +610,21 @@ class YamlInterpreter(object): replace = node.replace or True self.pool.get('ir.model.data').ir_set(self.cr, self.uid, \ 'action', keyword, node.url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=node.id) + + def process_ir_set(self, node): + if not self.mode == 'init': + return False + _, fields = node.items()[0] + res = {} + for fieldname, expression in fields.items(): + if isinstance(expression, Eval): + value = eval(expression.expression, {'ref': self._ref, '_ref': self._ref}) + else: + value = expression + res[fieldname] = value + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, res['key'], res['key2'], \ + res['name'], res['models'], res['value'], replace=res.get('replace',True), \ + isobject=res.get('isobject', False), meta=res.get('meta',None)) def process(self, yaml_string): """Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.""" @@ -643,6 +657,8 @@ class YamlInterpreter(object): self.process_url(node) elif is_context(node): self.process_context(node) + elif is_ir_set(node): + self.process_ir_set(node) elif is_act_window(node): self.process_act_window(node) elif is_workflow(node): From 88635654ce8aa65af2e0d311178c356dd8e2cd42 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Fri, 5 Mar 2010 11:05:37 +0100 Subject: [PATCH 006/248] [FIX] fixed missing isnoupdate and get_context bzr revid: jth@openerp.com-20100305100537-fnf2dkkylpylrwhq --- bin/tools/yaml_test.py | 46 +++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index 442370ab5dc..d284824e1c1 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -291,6 +291,9 @@ class YamlInterpreter(object): if node.context: context.update(eval(node.context, locals_dict)) return context + + def isnoupdate(self, node): + return self.noupdate or node.noupdate or False def process_comment(self, node): return node @@ -315,6 +318,8 @@ class YamlInterpreter(object): def process_assert(self, node): assertion, expressions = node.items()[0] + if self.isnoupdate(assertion) and self.mode != 'init': + return model = self.get_model(assertion.model) ids = self._get_assertion_id(assertion) if assertion.count and len(ids) != assertion.count: @@ -325,11 +330,12 @@ class YamlInterpreter(object): args = (assertion.string, assertion.count, len(ids)) self._log_assert_failure(assertion.severity, msg, *args) else: - test_context = {'ref': self._ref, '_ref': self._ref} # added '_ref' so that record['ref'] is possible + local_context = {'ref': self._ref, '_ref': self._ref} # added '_ref' so that record['ref'] is possible + context = self.get_context(assertion, local_context) for id in ids: - record = model.browse(self.cr, self.uid, id, assertion.context) + record = model.browse(self.cr, self.uid, id, context) for test in expressions.get('test', ''): - success = eval(test, test_context, record) + success = eval(test, local_context, record) if not success: msg = 'Assertion "%s" FAILED\ntest: %s\n' args = (assertion.string, test) @@ -342,13 +348,14 @@ class YamlInterpreter(object): record, fields = node.items()[0] self.validate_xml_id(record.id) - model = self.get_model(record.model) - record_dict = self._create_record(model, fields) - id = self.pool.get('ir.model.data')._update(self.cr, self.uid, record.model, \ - self.module, record_dict, record.id, mode=self.mode) - self.id_map[record.id] = int(id) - if config.get('import_partial', False): - self.cr.commit() + if self.isnoupdate(record) and self.mode != 'init': + model = self.get_model(record.model) + record_dict = self._create_record(model, fields) + id = self.pool.get('ir.model.data')._update(self.cr, self.uid, record.model, \ + self.module, record_dict, record.id, noupdate=self.isnoupdate(node), mode=self.mode) + self.id_map[record.id] = int(id) + if config.get('import_partial', False): + self.cr.commit() def _create_record(self, model, fields): record_dict = {} @@ -402,6 +409,8 @@ class YamlInterpreter(object): def process_workflow(self, node): workflow, values = node.items()[0] + if self.isnoupdate(workflow) and self.mode != 'init': + return model = self.get_model(workflow.model) if workflow.ref: id = self.get_id(workflow.ref) @@ -427,11 +436,11 @@ class YamlInterpreter(object): wf_service.trg_validate(uid, model, id, workflow.action, self.cr) def process_function(self, node): - if self.mode != 'init': - return function, values = node.items()[0] + if self.isnoupdate(function) and self.mode != 'init': + return local_context = {'ref': self._ref, '_ref': self._ref} - context = self.get_context(node, local_context) + context = self.get_context(function, local_context) args = [] if function.eval: args = eval(function.eval, local_context) @@ -532,7 +541,7 @@ class YamlInterpreter(object): pid = self.pool.get('ir.model.data')._update(self.cr, self.uid, \ 'ir.ui.menu', self.module, values, node.id, mode=self.mode, \ - res_id=res and res[0] or False) + noupdate=self.isnoupdate(node), res_id=res and res[0] or False) if node.id and parent_id: self.id_map[node.id] = int(parent_id) @@ -578,8 +587,8 @@ class YamlInterpreter(object): keyword = 'client_action_relate' value = 'ir.actions.act_window,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', \ - keyword, node.id, [node.src_model], value, replace=replace, isobject=True, xml_id=node.id) + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', keyword, \ + node.id, [node.src_model], value, replace=replace, noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) # TODO add remove ir.model.data def process_delete(self, node): @@ -608,8 +617,9 @@ class YamlInterpreter(object): keyword = node.keyword or 'client_action_multi' value = 'ir.actions.url,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, self.uid, \ - 'action', keyword, node.url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=node.id) + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', \ + keyword, node.url, ["ir.actions.url"], value, replace=replace, \ + noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) def process_ir_set(self, node): if not self.mode == 'init': From c51be2604d770f2feaf9bbfbe7834c3168551dc7 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Fri, 5 Mar 2010 11:42:04 +0100 Subject: [PATCH 007/248] [IMP] Added report tag. bzr revid: jth@openerp.com-20100305104204-yg9ees4miw0hunjs --- bin/tools/yaml_test.py | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index d284824e1c1..65bf16475c3 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -6,6 +6,7 @@ import logging import pooler import netsvc +import misc from config import config @@ -74,6 +75,13 @@ class Function(YamlTag): self.name = name super(Function, self).__init__(**kwargs) +class Report(YamlTag): + def __init__(self, model, name, string, **kwargs): + self.model = model + self.name = name + self.string = string + super(Function, self).__init__(**kwargs) + class Delete(YamlTag): def __init__(self, model, id, search, **kwargs): self.model = model @@ -126,6 +134,10 @@ def function_constructor(loader, node): kwargs = loader.construct_mapping(node) return Function(**kwargs) +def report_constructor(loader, node): + kwargs = loader.construct_mapping(node) + return Report(**kwargs) + def delete_constructor(loader, node): kwargs = loader.construct_mapping(node) return Delete(**kwargs) @@ -153,6 +165,7 @@ yaml.add_constructor(u"!menuitem", menuitem_constructor) yaml.add_constructor(u"!workflow", workflow_constructor) yaml.add_constructor(u"!act_window", act_window_constructor) yaml.add_constructor(u"!function", function_constructor) +yaml.add_constructor(u"!report", report_constructor) yaml.add_constructor(u"!context", context_constructor) yaml.add_constructor(u"!delete", delete_constructor) yaml.add_constructor(u"!url", url_constructor) @@ -185,6 +198,9 @@ def is_function(node): return isinstance(node, Function) \ or _is_yaml_mapping(node, Function) +def is_report(node): + return isinstance(node, Report) + def is_workflow(node): return isinstance(node, Workflow) @@ -636,6 +652,38 @@ class YamlInterpreter(object): res['name'], res['models'], res['value'], replace=res.get('replace',True), \ isobject=res.get('isobject', False), meta=res.get('meta',None)) + def process_report(self, node): + values = {} + for dest, f in (('name','string'), ('model','model'), ('report_name','name')): + values[dest] = getattr(node, f) + assert values[dest], "Attribute %s of report is empty !" % (f,) + for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')): + if getattr(node, field): + values[dest] = getattr(node, field) + if node.auto: + values['auto'] = eval(node.auto) + if node.sxw: + sxw_content = misc.file_open(node.sxw).read() + values['report_sxw_content'] = sxw_content + if node.header: + values['header'] = eval(node.header) + values['multi'] = node.multi and eval(node.multi) + xml_id = node.id + self.validate_xml_id(xml_id) + + self._set_group_values(node, values) + + id = self.pool.get('ir.model.data')._update(self.cr, self.uid, "ir.actions.report.xml", \ + self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode) + self.id_map[xml_id] = int(id) + + if not node.menu or eval(node.menu): + keyword = node.keyword or 'client_print_multi' + value = 'ir.actions.report.xml,%s' % id + replace = node.replace or True + self.pool.get('ir.model.data').ir_set(self.cr, self.uid, 'action', \ + keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id) + def process(self, yaml_string): """Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.""" @@ -671,6 +719,8 @@ class YamlInterpreter(object): self.process_ir_set(node) elif is_act_window(node): self.process_act_window(node) + elif is_report(node): + self.process_report(node) elif is_workflow(node): if isinstance(node, types.DictionaryType): self.process_workflow(node) From 83d7ae2d21b8255ec8d4844b06ba1e56ae2fbda3 Mon Sep 17 00:00:00 2001 From: Julien Thewys Date: Fri, 5 Mar 2010 12:01:28 +0100 Subject: [PATCH 008/248] [FIX] fixde Report __init__ bzr revid: jth@openerp.com-20100305110128-689067jl31nxy547 --- bin/tools/yaml_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/tools/yaml_test.py b/bin/tools/yaml_test.py index 65bf16475c3..b495989991a 100644 --- a/bin/tools/yaml_test.py +++ b/bin/tools/yaml_test.py @@ -80,7 +80,7 @@ class Report(YamlTag): self.model = model self.name = name self.string = string - super(Function, self).__init__(**kwargs) + super(Report, self).__init__(**kwargs) class Delete(YamlTag): def __init__(self, model, id, search, **kwargs): From 13096f9058afd91562afe21d85259a171eaee482 Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Mon, 15 Mar 2010 16:22:27 +0530 Subject: [PATCH 009/248] [IMP] survey :- improve codeing bzr revid: ysa@tinyerp.co.in-20100315105227-2bbiri6v06wqao8a --- addons/document/std_index.py | 4 +- addons/survey/survey.py | 307 +++++++++++++++++++++++++---------- 2 files changed, 222 insertions(+), 89 deletions(-) diff --git a/addons/document/std_index.py b/addons/document/std_index.py index b54ff396480..2d1fd2d7460 100644 --- a/addons/document/std_index.py +++ b/addons/document/std_index.py @@ -55,7 +55,7 @@ class PptIndex(indexer): return [ 'application/ms-word'] def _getExtensions(self): - return ['.ppt','.pptx'] + return ['.ppt'] def _doIndexFile(self,fname): fp = Popen(['ppthtml', fname], shell=False, stdout=PIPE).stdout @@ -68,7 +68,7 @@ class DocIndex(indexer): return [ 'application/ms-word'] def _getExtensions(self): - return ['.doc','.docx'] + return ['.doc'] def _doIndexFile(self,fname): fp = Popen(['antiword', fname], shell=False, stdout=PIPE).stdout diff --git a/addons/survey/survey.py b/addons/survey/survey.py index 101e1c563d3..555db5439ba 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -132,7 +132,7 @@ class survey_page(osv.osv): def default_get(self, cr, uid, fields, context={}): data = super(survey_page, self).default_get(cr, uid, fields, context) - if context.has_key('line_order') and context['line_order']: + if context.get('line_order',False): if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'): data['sequence'] = context['line_order'][-1][2]['sequence'] + 1 if context.has_key('survey_id'): @@ -143,7 +143,7 @@ class survey_page(osv.osv): search_obj = self.pool.get('ir.ui.view') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) surv_name_wiz = self.pool.get('survey.name.wiz') - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] }) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',0) }) return { 'view_type': 'form', "view_mode": 'form', @@ -177,6 +177,7 @@ class survey_question(osv.osv): for id in ids1: val[id] = 0 return val + _columns = { 'page_id' : fields.many2one('survey.page', 'Survey Page', ondelete='cascade', required=1), 'question' : fields.char('Question', size=128, required=1), @@ -274,18 +275,23 @@ class survey_question(osv.osv): val['is_comment_require'] = False val['is_validation_require'] = False val['comment_column'] = False + if type in ['multiple_textboxes_diff_type']: val['in_visible_answer_type'] = False return {'value': val} + if type in ['rating_scale']: val.update({'in_visible_rating_weight':False,'in_visible_menu_choice':True}) return {'value': val} + elif type in ['matrix_of_drop_down_menus']: val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':False}) return {'value': val} + elif type in ['single_textbox']: val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':True}) return {'value': val} + else: val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':True,'in_visible_answer_type':True}) return {'value': val} @@ -300,28 +306,34 @@ class survey_question(osv.osv): col_len += 1 else: col_len -= 1 + if vals.has_key('type'): que_type = vals['type'] else: que_type = question['type'] + if que_type in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']: if not col_len: raise osv.except_osv(_('Error !'),_("You must enter one or more column heading.")) ans_len = len(question['answer_choice_ids']) + if vals.has_key('answer_choice_ids'): for ans in vals['answer_choice_ids']: if type(ans[2]) == type({}): ans_len += 1 else: ans_len -= 1 + if que_type not in ['descriptive_text', 'single_textbox', 'comment','table']: if not ans_len: raise osv.except_osv(_('Error !'),_("You must enter one or more Answer.")) req_type = "" + if vals.has_key('required_type'): req_type = vals['required_type'] else: req_type = question['required_type'] + if que_type in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']: if req_type in ['at least', 'at most', 'exactly']: if vals.has_key('req_ans'): @@ -330,6 +342,7 @@ class survey_question(osv.osv): else: if not question['req_ans'] or question['req_ans'] > ans_len: raise osv.except_osv(_('Error !'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1)) + if req_type == 'a range': minimum_ans = 0 maximum_ans = 0 @@ -351,12 +364,14 @@ class survey_question(osv.osv): raise osv.except_osv(_('Error !'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1)) if maximum_ans <= minimum_ans: raise osv.except_osv(_('Error !'),_("Maximum Required Answer is greater than Minimum Required Answer")) + if question['type'] == 'matrix_of_drop_down_menus' and vals.has_key('column_heading_ids'): for col in vals['column_heading_ids']: if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']: raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading")) elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '': raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading (white spaces not allowed)")) + return super(survey_question, self).write(cr, uid, ids, vals, context=context) def create(self, cr, uid, vals, context): @@ -365,13 +380,16 @@ class survey_question(osv.osv): if vals.has_key('answer_choice_ids') and not len(vals['answer_choice_ids']): if vals.has_key('type') and vals['type'] not in ['descriptive_text', 'single_textbox', 'comment','table']: raise osv.except_osv(_('Error !'),_("You must enter one or more answer.")) + if vals.has_key('column_heading_ids') and not len(vals['column_heading_ids']): if vals.has_key('type') and vals['type'] in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']: raise osv.except_osv(_('Error !'),_("You must enter one or more column heading.")) + if vals['type'] in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']: if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] in ['at least', 'at most', 'exactly']: if vals.has_key('answer_choice_ids') and vals['req_ans'] > len(vals['answer_choice_ids']) or not vals['req_ans']: raise osv.except_osv(_('Error !'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1)) + if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] == 'a range': minimum_ans = vals['minimum_req_ans'] maximum_ans = vals['maximum_req_ans'] @@ -381,12 +399,14 @@ class survey_question(osv.osv): raise osv.except_osv(_('Error !'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1)) if maximum_ans <= minimum_ans: raise osv.except_osv(_('Error !'),_("Maximum Required Answer is greater than Minimum Required Answer")) + if vals['type'] == 'matrix_of_drop_down_menus': for col in vals['column_heading_ids']: if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']: raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading")) elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '': raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading (white spaces not allowed)")) + res = super(survey_question, self).create(cr, uid, vals, context) return res @@ -394,7 +414,7 @@ class survey_question(osv.osv): search_obj = self.pool.get('ir.ui.view') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) surv_name_wiz = self.pool.get('survey.name.wiz') - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] }) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',False) }) return { 'view_type': 'form', "view_mode": 'form', @@ -407,12 +427,12 @@ class survey_question(osv.osv): def default_get(self, cr, uid, fields, context={}): data = super(survey_question, self).default_get(cr, uid, fields, context) - if context.has_key('line_order') and context['line_order']: - + if context.get('line_order',False): if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'): data['sequence'] = context['line_order'][-1][2]['sequence'] + 1 + if context.has_key('page_id'): - data['page_id']= context['page_id'] + data['page_id']= context.get('page_id',False) return data survey_question() @@ -475,7 +495,7 @@ class survey_answer(osv.osv): def _get_in_visible_answer_type(self,cr, uid, context={}): if context.get('in_visible_answer_type',False): - return context['in_visible_answer_type'] + return context.get('in_visible_answer_type',False) return False _columns = { @@ -496,7 +516,7 @@ class survey_answer(osv.osv): def default_get(self, cr, uid, fields, context={}): data = super(survey_answer, self).default_get(cr, uid, fields, context) - if context.has_key('line_order') and context['line_order']: + if context.get('line_order',False): if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'): data['sequence'] = context['line_order'][-1][2]['sequence'] + 1 return data @@ -591,14 +611,14 @@ class survey_name_wiz(osv.osv_memory): context = {} data = super(survey_name_wiz, self).default_get(cr, uid, fields, context) if context.has_key('survey_id'): - data['survey_id'] = context['survey_id'] + data['survey_id'] = context.get('survey_id',False) return data def _get_survey(self, cr, uid, context=None): surv_obj = self.pool.get("survey") result = [] if context.has_key('survey_id'): - for sur in surv_obj.browse(cr, uid, [context['survey_id']]): + for sur in surv_obj.browse(cr, uid, [context.get('survey_id',False)]): result.append((sur.id, sur.title)) return result group_id = self.pool.get('res.groups').search(cr, uid, [('name', '=', 'Survey / Manager')]) @@ -629,21 +649,26 @@ class survey_name_wiz(osv.osv_memory): } def action_next(self, cr, uid, ids, context=None): + survey_obj = self.pool.get('survey') + search_obj = self.pool.get('ir.ui.view') + sur_id = self.read(cr, uid, ids, [])[0] survey_id = sur_id['survey_id'] context.update({'survey_id' : survey_id, 'sur_name_id' : sur_id['id']}) cr.execute('select count(id) from survey_history where user_id=%s\ and survey_id=%s' % (uid,survey_id)) + res = cr.fetchone()[0] - user_limit = self.pool.get('survey').read(cr, uid, survey_id, ['response_user'])['response_user'] + user_limit = survey_obj.read(cr, uid, survey_id, ['response_user'])['response_user'] if user_limit and res >= user_limit: raise osv.except_osv(_('Warning !'),_("You can not give response for this survey more than %s times") % (user_limit)) - survey_obj = self.pool.get('survey') + sur_rec = survey_obj.read(cr,uid,self.read(cr,uid,ids)[0]['survey_id']) if sur_rec['max_response_limit'] and sur_rec['max_response_limit'] <= sur_rec['tot_start_survey']: raise osv.except_osv(_('Warning !'),_("You can not give more response. Please contact the author of this survey for further assistance.")) - search_obj = self.pool.get('ir.ui.view') + search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) + return { 'view_type': 'form', "view_mode": 'form', @@ -669,41 +694,55 @@ class survey_question_wiz(osv.osv_memory): def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False): result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu) surv_name_wiz = self.pool.get('survey.name.wiz') + survey_obj = self.pool.get('survey') + page_obj = self.pool.get('survey.page') + que_obj = self.pool.get('survey.question') + ans_obj = self.pool.get('survey.answer') + sur_response_obj = self.pool.get('survey.response') + que_col_head = self.pool.get('survey.question.column.heading') + user_obj = self.pool.get('res.users') + if view_type in ['form']: wiz_id = 0 if not context.has_key('sur_name_id'): - wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context['survey_id'],'page_no' :-1,'page':'next','transfer' :1,'response':0}) + res_data = { + 'survey_id' : context.get('survey_id', False), + 'page_no' :-1, + 'page':'next', + 'transfer' :1, + 'response':0 + } + wiz_id = surv_name_wiz.create(cr, uid, res_data) sur_name_rec = surv_name_wiz.read(cr, uid, wiz_id, []) context.update({'sur_name_id' :wiz_id}) else: - sur_name_rec = surv_name_wiz.read(cr, uid, context['sur_name_id']) - if context.has_key('active_id'): context.pop('active_id') - survey_id = context['survey_id'] - survey_obj = self.pool.get('survey') - sur_rec = survey_obj.read(cr, uid, survey_id, []) - page_obj = self.pool.get('survey.page') - que_obj = self.pool.get('survey.question') - ans_obj = self.pool.get('survey.answer') + sur_name_rec = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False)) - sur_response_obj = self.pool.get('survey.response') - que_col_head = self.pool.get('survey.question.column.heading') + if context.has_key('active_id'): + context.pop('active_id') + + survey_id = context.get('survey_id', False) + sur_rec = survey_obj.read(cr, uid, survey_id, []) p_id = sur_rec['page_ids'] total_pages = len(p_id) pre_button = False readonly = 0 - if context.has_key('response_id') and context['response_id'] and int(context['response_id'][0]) > 0: + + if context.has_key('response_id') and context.get('response_id', False) and int(context['response_id'][0]) > 0: readonly = 1 + if not sur_name_rec['page_no'] + 1 : - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':{}}) - sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id']) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':{}}) + + sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False)) page_number = int(sur_name_rec['page_no']) if sur_name_read['transfer'] or not sur_name_rec['page_no'] + 1: - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'transfer':False}) flag = False fields = {} - if sur_name_read['page'] == "next" or sur_name_rec['page_no'] == - 1 : - if len(p_id) > sur_name_rec['page_no'] + 1 : - if ((context.has_key('active') and not context['active']) or not context.has_key('active')) and not sur_name_rec['page_no'] + 1: + if sur_name_read['page'] == "next" or sur_name_rec['page_no'] == -1: + if total_pages > sur_name_rec['page_no'] + 1: + if ((context.has_key('active') and not context.get('active', False)) or not context.has_key('active')) and not sur_name_rec['page_no'] + 1: if sur_rec['state'] != "open" : raise osv.except_osv(_('Warning !'),_("You can not give answer because of survey is not open for answer")) cr.execute('select count(id) from survey_history where user_id=%s\ @@ -715,8 +754,9 @@ class survey_question_wiz(osv.osv_memory): if sur_rec['max_response_limit'] and sur_rec['max_response_limit'] <= sur_rec['tot_start_survey'] and not sur_name_rec['page_no'] + 1: survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")}) + p_id = p_id[sur_name_rec['page_no'] + 1] - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'page_no' : sur_name_rec['page_no'] + 1}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'page_no' : sur_name_rec['page_no'] + 1}) flag = True page_number += 1 if sur_name_rec['page_no'] > - 1: @@ -724,46 +764,49 @@ class survey_question_wiz(osv.osv_memory): else: if sur_name_rec['page_no'] != 0: p_id = p_id[sur_name_rec['page_no'] - 1] - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'page_no' : sur_name_rec['page_no'] - 1}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'page_no' : sur_name_rec['page_no'] - 1}) flag = True page_number -= 1 + if sur_name_rec['page_no'] > 1: pre_button = True if flag: pag_rec = page_obj.read(cr, uid, p_id) xml_form = etree.Element('form', {'string': _(tools.ustr(pag_rec['title']))}) xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'}) - if context.has_key('response_id') and context['response_id'] and int(context['response_id'][0]) > 0: + if context.has_key('response_id') and context.get('response_id', False) and int(context.get('response_id',0)[0]) > 0: xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'}) record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']]) etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr('Answer Of :- ' + record.user_id.name + ', Date :- ' + record.date_create.split('.')[0] )), 'align':"0.0"}) - etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(" Response :- " + str(context['response_no'] + 1) +"/" + str(len(context['response_id'])) )), 'align':"0.0"}) - if context['response_no'] > 0: + etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(" Response :- " + str(context.get('response_no',0) + 1) +"/" + str(len(context.get('response_id',0))) )), 'align':"0.0"}) + if context.get('response_no',0) > 0: etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"}) - if context['response_no'] + 1 == len(context['response_id']) and context['response_no'] != 0: - etree.SubElement(xml_group, 'button', {'colspan':"1",'icon': "gtk-go-forward", 'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context)}) - elif context['response_no'] + 1 < len(context['response_id']): + if context.get('response_no',0) + 1 < len(context.get('response_id',0)): etree.SubElement(xml_group, 'button', {'colspan':"1",'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)}) + if wiz_id: fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}} etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0)}) + if pag_rec['note']: xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'}) for que_test in pag_rec['note'].split('\n'): etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"}) que_ids = pag_rec['question_ids'] qu_no = 0 + for que in que_ids: qu_no += 1 que_rec = que_obj.read(cr, uid, que) descriptive_text = "" separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec['question']) - if ((context.has_key('active') and not context['active']) or not context.has_key('active')) and que_rec['is_require_answer']: + if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec['is_require_answer']: star = '*' else: star = '' xml_group = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '4'}) - if context.has_key('active') and context['active'] and context.has_key('edit'): + + if context.has_key('active') and context.get('active',False) and context.has_key('edit'): xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '2'}) etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '3'}) xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'}) @@ -773,8 +816,10 @@ class survey_question_wiz(osv.osv_memory): else: xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'}) etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '4'}) + ans_ids = ans_obj.read(cr, uid, que_rec['answer_choice_ids'], []) xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'}) + if que_rec['type'] == 'multiple_choice_only_one_ans': selection = [] for ans in ans_ids: @@ -782,11 +827,13 @@ class survey_question_wiz(osv.osv_memory): xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'}) etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_selection"}) fields[tools.ustr(que) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"} + elif que_rec['type'] == 'multiple_choice_multiple_ans': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) for ans in ans_ids: etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(ans['id'])}) fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'boolean', 'string':ans['answer']} + elif que_rec['type'] in ['matrix_of_choices_only_one_ans', 'rating_scale']: if que_rec['comment_column']: col = "4" @@ -805,6 +852,7 @@ class survey_question_wiz(osv.osv_memory): if que_rec['comment_column']: fields[tools.ustr(que) + "_commentcolumn_"+tools.ustr(row['id']) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec['column_name']), 'views':{}} etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_commentcolumn_"+tools.ustr(row['id'])+ "_field"}) + elif que_rec['type'] == 'matrix_of_choices_only_multi_ans': xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids']) + 1), 'colspan': '4'}) etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'}) @@ -815,6 +863,7 @@ class survey_question_wiz(osv.osv_memory): for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']): etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id']), 'nolabel':"1"}) fields[tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id'])] = {'type':'boolean', 'string': col['title']} + elif que_rec['type'] == 'matrix_of_drop_down_menus': xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids']) + 1), 'colspan': '4'}) etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'}) @@ -829,6 +878,7 @@ class survey_question_wiz(osv.osv_memory): if item and not item.strip() == '': selection.append((item ,item)) etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id']),'nolabel':'1'}) fields[tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id'])] = {'type':'selection', 'string': col['title'], 'selection':selection} + elif que_rec['type'] == 'multiple_textboxes': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) type = "char" @@ -845,30 +895,37 @@ class survey_question_wiz(osv.osv_memory): fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'char', 'size':255, 'string':ans['answer']} else: fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type': str(type), 'string':ans['answer']} + elif que_rec['type'] == 'numerical_textboxes': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) for ans in ans_ids: etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_numeric"}) fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_numeric"] = {'type':'integer', 'string':ans['answer']} + elif que_rec['type'] == 'date': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) for ans in ans_ids: etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id'])}) fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'date', 'string':ans['answer']} + elif que_rec['type'] == 'date_and_time': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) for ans in ans_ids: etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id'])}) fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'datetime', 'string':ans['answer']} + elif que_rec['type'] == 'descriptive_text': for que_test in que_rec['descriptive_text'].split('\n'): etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"}) + elif que_rec['type'] == 'single_textbox': etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_single", 'nolabel':"1" ,'colspan':"4"}) fields[tools.ustr(que) + "_single"] = {'type':'char', 'size' : 255, 'string':"single_textbox", 'views':{}} + elif que_rec['type'] == 'comment': etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_comment", 'nolabel':"1" ,'colspan':"4"}) fields[tools.ustr(que) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}} + elif que_rec['type'] == 'table': xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids'])), 'colspan': '4'}) for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']): @@ -877,6 +934,7 @@ class survey_question_wiz(osv.osv_memory): for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']): etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_table_" + tools.ustr(col['id']) +"_"+ tools.ustr(row), 'nolabel':"1"}) fields[tools.ustr(que) + "_table_" + tools.ustr(col['id']) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}} + elif que_rec['type'] == 'multiple_textboxes_diff_type': xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) for ans in ans_ids: @@ -895,6 +953,7 @@ class survey_question_wiz(osv.osv_memory): for item in ans['menu_choice'].split('\n'): if item and not item.strip() == '': selection.append((item ,item)) fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans['answer']} + if que_rec['type'] in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans', 'matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale'] and que_rec['is_comment_require']: if que_rec['type'] in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans'] and que_rec['comment_field_type'] in ['char','text'] and que_rec['make_comment_field']: etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_otherfield", 'colspan':"4"}) @@ -914,27 +973,30 @@ class survey_question_wiz(osv.osv_memory): etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec['comment_label'])),'colspan':"4"}) etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_other", 'nolabel':"1" ,'colspan':"4"}) fields[tools.ustr(que) + "_other"] = {'type': 'text', 'string': '', 'views':{}} + etree.SubElement(xml_form, 'separator', {'colspan': '4'}) xml_group = etree.SubElement(xml_form, 'group', {'col': '6', 'colspan': '4'}) etree.SubElement(xml_group, 'field', {'name': 'progress_bar_' + tools.ustr(page_number) , 'widget':'progressbar'}) fields['progress_bar_' + tools.ustr(page_number)] = {'type':'float', 'string':"Progress", 'views':{}} etree.SubElement(xml_group, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages)}) etree.SubElement(xml_group, 'button', {'icon': "gtk-cancel", 'special': "cancel",'string':"Cancel"}) + if pre_button: etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_previous",'string':"Previous",'type':"object"}) but_string = "Next" if int(page_number) + 1 == total_pages: but_string = "Done" - if context.has_key('active') and context['active'] and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context['response_no'] + 1 == len(context['response_id']): + if context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context.get('response_no',0) + 1 == len(context.get('response_id',0)): etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context)}) - elif context.has_key('active') and context['active'] and int(page_number) + 1 == total_pages and context.has_key('response_id'): + elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'): etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)}) - elif context.has_key('active') and context['active'] and int(page_number) + 1 == total_pages: + elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages: etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context)}) else: etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context)}) - if context.has_key('active') and context['active'] and context.has_key('edit'): + + if context.has_key('active') and context.get('active',False) and context.has_key('edit'): etree.SubElement(xml_form, 'separator', {'string' : '','colspan': '4'}) context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec['page_no'] , 'transfer' : sur_name_read['transfer']}) xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'}) @@ -942,6 +1004,7 @@ class survey_question_wiz(osv.osv_memory): etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)}) etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)}) etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)}) + root = xml_form.getroottree() result['arch'] = etree.tostring(root) result['fields'] = fields @@ -949,10 +1012,10 @@ class survey_question_wiz(osv.osv_memory): else: survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec['tot_comp_survey'] + 1}) sur_response_obj.write(cr, uid, [sur_name_read['response']], {'state' : 'done'}) + if sur_rec['send_response']: - user_obj = self.pool.get('res.users') survey_data = survey_obj.browse(cr, uid, int(survey_id)) - response_id = surv_name_wiz.read(cr,uid,context['sur_name_id'])['response'] + response_id = surv_name_wiz.read(cr,uid,context.get('sur_name_id',False))['response'] context.update({'response_id':response_id}) report = self.create_report(cr, uid, [int(survey_id)], 'report.survey.browse.response', survey_data.title,context) attachments = [] @@ -963,15 +1026,18 @@ class survey_question_wiz(osv.osv_memory): file_data += line if not line: break + attachments.append((survey_data.title + ".pdf",file_data)) file.close() os.remove(tools.config['addons_path'] + '/survey/report/' + survey_data.title + ".pdf") user_email = False resp_email = False + if user_obj.browse(cr, uid, uid).address_id.id: cr.execute("select email from res_partner_address where id =%d" % user_obj.browse(cr, uid, uid).address_id.id) user_email = cr.fetchone()[0] resp_id = survey_data.responsible_id.address_id + if resp_id: cr.execute("select email from res_partner_address where id =%d" % resp_id.id) resp_email = cr.fetchone()[0] @@ -1000,23 +1066,28 @@ class survey_question_wiz(osv.osv_memory): fp = open(ret_file_name, 'wb+'); fp.write(result); fp.close(); + except Exception,e: print 'Exception in create report:',e return (False, str(e)) + return (True, ret_file_name) def default_get(self, cr, uid, fields_list, context=None): value = {} for field in fields_list: if field.split('_')[0] == 'progress': - tot_page_id = self.pool.get('survey').browse(cr, uid, context['survey_id']) + tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False)) tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids)) value[field] = tot_per response_obj = self.pool.get('survey.response') - if context.has_key('response_id') and context['response_id'] and int(context['response_id'][0]) > 0: + surv_name_wiz = self.pool.get('survey.name.wiz') + + if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0: data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context) response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']]) fields_list.sort() + for que in response_ans.question_ids: for field in fields_list: if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id): @@ -1024,20 +1095,26 @@ class survey_question_wiz(osv.osv_memory): for ans in que.response_answer_ids: if str(field.split('_')[2]) == str(ans.answer_id.id): value[field] = ans.comment_field + if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table": for ans in que.response_table_ids: if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name): value[field] = ans.value + if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"): value[field] = str(que.comment) + elif que.single_text and field.split('_')[1] == "single": value[field] = str(que.single_text) + elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection": for ans in que.response_answer_ids: if str(field.split('_')[2]) == str( ans.answer_id.id): value[field] = str(ans.column_id.id) + elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection": value[field] = str(que.response_answer_ids[0].answer_id.id) + elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric": for ans in que.response_answer_ids: if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id): @@ -1045,61 +1122,72 @@ class survey_question_wiz(osv.osv_memory): value[field] = ans.value_choice else: value[field] = True + else: for ans in que.response_answer_ids: if str(field.split('_')[1]) == str( ans.answer_id.id): value[field] = ans.answer + else: if not context.has_key('sur_name_id'): return value - if context.has_key('active') and context['active']: + if context.has_key('active') and context.get('active',False): return value - surv_name_wiz = self.pool.get('survey.name.wiz') - sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id']) + + sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False)) ans_list = [] for key,val in sur_name_read['store_ans'].items(): for field in fields_list: if field in list(val): value[field] = val[field] + return value def create(self, cr, uid, vals, context=None): - if context.has_key('active') and context['active']: + if context.has_key('active') and context.get('active',False): return True + for key,val in vals.items(): if key.split('_')[0] == "progress": vals.pop(key) if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid": context.update({'sur_name_id': int(key.split('_')[1])}) vals.pop(key) + click_state = True click_update = [] surv_name_wiz = self.pool.get('survey.name.wiz') surv_all_resp_obj = self.pool.get('survey.response') surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading') - sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id'], []) + survey_obj = self.pool.get('survey') + resp_obj = self.pool.get('survey.response.line') + res_ans_obj = self.pool.get('survey.response.answer') + que_obj = self.pool.get('survey.question') + sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), []) response_id = 0 + if not sur_name_read['response']: response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context['survey_id']}) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'response' : tools.ustr(response_id)}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)}) else: response_id = int(sur_name_read['response']) + if response_id not in surv_all_resp_obj.search(cr, uid, []): - response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context['survey_id']}) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'response' : tools.ustr(response_id)}) + response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context.get('survey_id',False)}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)}) + #click first time on next button then increemnet on total start suvey if not sur_name_read['store_ans']: his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \ 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id']}) - survey_obj = self.pool.get('survey') sur_rec = survey_obj.read(cr, uid, sur_name_read['survey_id']) survey_obj.write(cr, uid, sur_name_read['survey_id'], {'tot_start_survey' : sur_rec['tot_start_survey'] + 1}) if context.has_key('cur_id'): - if context.has_key('request') and context['request']: - self.pool.get(context['object']).write(cr, uid, [int(context['cur_id'])], {'response' : response_id}) - self.pool.get(context['object']).survey_req_done(cr, uid, [int(context['cur_id'])], context) + if context.has_key('request') and context.get('request',False): + self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) + self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context) else: - self.pool.get(context['object']).write(cr, uid, [int(context['cur_id'])], {'response' : response_id}) + self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) for key,val in sur_name_read['store_ans'].items(): for field in vals: @@ -1107,9 +1195,7 @@ class survey_question_wiz(osv.osv_memory): click_state = False click_update.append(key) break - resp_obj = self.pool.get('survey.response.line') - res_ans_obj = self.pool.get('survey.response.answer') - que_obj = self.pool.get('survey.question') + if click_state: que_li = [] resp_id_list = [] @@ -1118,11 +1204,16 @@ class survey_question_wiz(osv.osv_memory): if que_id not in que_li: que_li.append(que_id) que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0] - resp_id = resp_obj.create(cr, uid, {'question_id':que_id, 'date_create':datetime.datetime.now(), \ - 'state':'done','response_id' : response_id }) + res_data = { + 'question_id':que_id, + 'date_create':datetime.datetime.now(), + 'state':'done', + 'response_id' : response_id + } + resp_id = resp_obj.create(cr, uid, res_data) resp_id_list.append(resp_id) sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}}) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) select_count = 0 numeric_sum = 0 selected_value = [] @@ -1130,17 +1221,20 @@ class survey_question_wiz(osv.osv_memory): comment_field = False comment_value = False response_list = [] + for key1, val1 in vals.items(): if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id: surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1}) sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 + elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id: comment_field = True sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) continue + elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id: if len(key1.split('_')) > 2: ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1}) @@ -1150,6 +1244,7 @@ class survey_question_wiz(osv.osv_memory): ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1}) sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 + elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id: if not val1: comment_value = True @@ -1183,12 +1278,15 @@ class survey_question_wiz(osv.osv_memory): for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))) + resp_obj.write(cr, uid, resp_id, {'comment':val1}) sur_name_read['store_ans'][resp_id].update({key1:val1}) + elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id: resp_obj.write(cr, uid, resp_id, {'comment':val1}) sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 + elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')): error = False if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length': @@ -1219,12 +1317,15 @@ class survey_question_wiz(osv.osv_memory): for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))) + if key1.split('_')[1] == "single" : resp_obj.write(cr, uid, resp_id, {'single_text':val1}) else: ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1}) + sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 + elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric': if not val1=="0": try: @@ -1244,33 +1345,41 @@ class survey_question_wiz(osv.osv_memory): else: ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]}) sur_name_read['store_ans'][resp_id].update({key1:True}) + matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1]) select_count += 1 + elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2: ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1}) sur_name_read['store_ans'][resp_id].update({key1:val1}) select_count += 1 - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) + for key,val in vals.items(): if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id: for res_id in response_list: if key.split('_')[2] in res_id.split('_')[1]: a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val}) sur_name_read['store_ans'][resp_id].update({key:val}) + if comment_field and comment_value: for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))) + if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))): for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'")) + if not select_count: resp_obj.write(cr, uid, resp_id, {'state':'skip'}) + if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']: for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))) + if que_rec['type'] in ['multiple_textboxes_diff_type', 'multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']: if matrix_list: if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \ @@ -1281,6 +1390,7 @@ class survey_question_wiz(osv.osv_memory): for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \ (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \ (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \ @@ -1289,10 +1399,12 @@ class survey_question_wiz(osv.osv_memory): for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0: for res in resp_id_list: sur_name_read['store_ans'].pop(res) raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + else: resp_id_list = [] for update in click_update: @@ -1301,7 +1413,7 @@ class survey_question_wiz(osv.osv_memory): surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)])) resp_id_list.append(update) sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}}) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) select_count = 0 numeric_sum = 0 selected_value = [] @@ -1309,6 +1421,7 @@ class survey_question_wiz(osv.osv_memory): comment_field = False comment_value = False response_list = [] + for key, val in vals.items(): ans_id_len = key.split('_') if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']: @@ -1316,12 +1429,14 @@ class survey_question_wiz(osv.osv_memory): surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val}) sur_name_read['store_ans'][update].update({key:val}) resp_obj.write(cr, uid, update, {'state': 'done'}) + elif val and key.split('_')[1] == "otherfield" : comment_field = True sur_name_read['store_ans'][update].update({key:val}) select_count += 1 - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) continue + elif val and key.split('_')[1] == "selection": if len(key.split('_')) > 2: ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val}) @@ -1332,6 +1447,7 @@ class survey_question_wiz(osv.osv_memory): resp_obj.write(cr, uid, update, {'state': 'done'}) sur_name_read['store_ans'][update].update({key:val}) select_count += 1 + elif key.split('_')[1] == "other": if not val: comment_value = True @@ -1364,10 +1480,12 @@ class survey_question_wiz(osv.osv_memory): raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))) resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'}) sur_name_read['store_ans'][update].update({key:val}) + elif val and key.split('_')[1] == "comment": resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'}) sur_name_read['store_ans'][update].update({key:val}) select_count += 1 + elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')): error = False if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length': @@ -1403,6 +1521,7 @@ class survey_question_wiz(osv.osv_memory): ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val}) sur_name_read['store_ans'][update].update({key:val}) select_count += 1 + elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric': if not val=="0": try: @@ -1424,26 +1543,33 @@ class survey_question_wiz(osv.osv_memory): sur_name_read['store_ans'][update].update({key:True}) matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1]) select_count += 1 + elif val and len(key.split('_')) == 2: resp_obj.write(cr, uid, update, {'state': 'done'}) ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[-1], 'answer' : val}) sur_name_read['store_ans'][update].update({key:val}) select_count += 1 - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']}) + for key,val in vals.items(): if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']: for res_id in response_list: if key.split('_')[2] in res_id.split('_')[1]: a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val}) sur_name_read['store_ans'][update].update({key:val}) + if comment_field and comment_value: raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))) + if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))): raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'")) + if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']: raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))) + if not select_count: resp_obj.write(cr, uid, update, {'state': 'skip'}) + if que_rec['type'] in ['multiple_textboxes_diff_type','multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']: if matrix_list: if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \ @@ -1452,14 +1578,17 @@ class survey_question_wiz(osv.osv_memory): (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \ (que_rec['required_type'] == 'a range' and (len(list(set(matrix_list))) < que_rec['minimum_req_ans'] or len(list(set(matrix_list))) > que_rec['maximum_req_ans'])): raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \ (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \ (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \ (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \ (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])): raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0: raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))) + return True def action_new_question(self,cr, uid, ids, context): @@ -1503,7 +1632,7 @@ class survey_question_wiz(osv.osv_memory): 'res_model': 'survey.page', 'type': 'ir.actions.act_window', 'target': 'new', - 'res_id' : int(context['page_id']), + 'res_id' : int(context.get('page_id',0)), 'view_id': view_id, 'context': context } @@ -1512,10 +1641,11 @@ class survey_question_wiz(osv.osv_memory): for key,val in context.items(): if type(key) == type(True): context.pop(key) - self.pool.get('survey.page').unlink(cr, uid, [context['page_id']]) + + self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)]) search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) surv_name_wiz = self.pool.get('survey.name.wiz') - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] }) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',False) }) return { 'view_type': 'form', "view_mode": 'form', @@ -1537,7 +1667,7 @@ class survey_question_wiz(osv.osv_memory): 'res_model': 'survey.question', 'type': 'ir.actions.act_window', 'target': 'new', - 'res_id' : int(context['question_id']), + 'res_id' : int(context.get('question_id',0)), 'view_id': view_id, 'context': context } @@ -1546,11 +1676,12 @@ class survey_question_wiz(osv.osv_memory): for key,val in context.items(): if type(key) == type(True): context.pop(key) + que_obj = self.pool.get('survey.question') - que_obj.unlink(cr, uid, [context['question_id']]) + que_obj.unlink(cr, uid, [context.get('question_id',False)]) search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) surv_name_wiz = self.pool.get('survey.name.wiz') - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] }) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',0) }) return { 'view_type': 'form', "view_mode": 'form', @@ -1565,9 +1696,10 @@ class survey_question_wiz(osv.osv_memory): search_obj = self.pool.get('ir.ui.view') surv_name_wiz = self.pool.get('survey.name.wiz') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) - wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context['survey_id'],'page_no' :-1,'page':'next','transfer' :1,'response':0}) - context.update({'sur_name_id' :wiz_id, 'response_no' : context['response_no'] - 1}) - if context['response_no'] + 1 > len(context['response_id']): + wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0}) + context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) - 1}) + + if context.get('response_no',0) + 1 > len(context.get('response_id',0)): return {} return { 'view_type': 'form', @@ -1583,9 +1715,10 @@ class survey_question_wiz(osv.osv_memory): search_obj = self.pool.get('ir.ui.view') surv_name_wiz = self.pool.get('survey.name.wiz') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) - wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context['survey_id'],'page_no' :-1,'page':'next','transfer' :1,'response':0}) - context.update({'sur_name_id' :wiz_id, 'response_no' : context['response_no'] + 1}) - if context['response_no'] + 1 > len(context['response_id']): + wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0}) + context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1}) + + if context.get('response_no',0) + 1 > len(context.get('response_id',0)): return {} return { 'view_type': 'form', @@ -1601,7 +1734,7 @@ class survey_question_wiz(osv.osv_memory): surv_name_wiz = self.pool.get('survey.name.wiz') search_obj = self.pool.get('ir.ui.view') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page':'next'}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'}) return { 'view_type': 'form', "view_mode": 'form', @@ -1616,7 +1749,7 @@ class survey_question_wiz(osv.osv_memory): surv_name_wiz = self.pool.get('survey.name.wiz') search_obj = self.pool.get('ir.ui.view') search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')]) - surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page':'previous'}) + surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'}) return { 'view_type': 'form', "view_mode": 'form', From 9721577f4aaf7316544d952cc4b46e1c44a1e95b Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Mon, 15 Mar 2010 16:49:53 +0530 Subject: [PATCH 010/248] [IMP] survey :- improve codeing in all report bzr revid: ysa@tinyerp.co.in-20100315111953-ylieyt9xmjm8g336 --- .../survey/report/survey_analysis_report.py | 122 ++++++++------- .../survey/report/survey_browse_response.py | 63 ++++++-- addons/survey/report/survey_form.py | 140 ++++++++++-------- 3 files changed, 198 insertions(+), 127 deletions(-) diff --git a/addons/survey/report/survey_analysis_report.py b/addons/survey/report/survey_analysis_report.py index 44d42610e6f..a3a54bf4950 100755 --- a/addons/survey/report/survey_analysis_report.py +++ b/addons/survey/report/survey_analysis_report.py @@ -106,31 +106,31 @@ class survey_analysis(report_rml): for survey in surv_obj.browse(cr, uid, ids): rml += """ - - - Survey Title - - - Total Started Survey - - - Total Completed Survey - - - - - - - """ + to_xml(tools.ustr(survey.title)) + """ - - - """ + str(survey.tot_start_survey) + """ - - - """ + str(survey.tot_comp_survey) + """ - - - """ + + + Survey Title + + + Total Started Survey + + + Total Completed Survey + + + + + + + """ + to_xml(tools.ustr(survey.title)) + """ + + + """ + str(survey.tot_start_survey) + """ + + + """ + str(survey.tot_comp_survey) + """ + + + """ for page in survey.page_ids: rml += """ # @@ -144,24 +144,27 @@ class survey_analysis(report_rml): """ cols_widhts = [] + if que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans']: cols_widhts.append(200) for col in range(0, len(que.column_heading_ids) + 1): cols_widhts.append(float(300 / (len(que.column_heading_ids) + 1))) colWidths = ",".join(map(tools.ustr, cols_widhts)) matrix_ans = [(0,'')] + for col in que.column_heading_ids: if col.title not in matrix_ans: matrix_ans.append((col.id,col.title)) - rml+="""""" + rml += """""" for mat_col in range(0, len(matrix_ans)): rml+="""""" + to_xml(tools.ustr(matrix_ans[mat_col][1])) + """""" - rml+="""Response Count + rml += """Response Count """ last_col = cols_widhts[-1] + for ans in que.answer_choice_ids: - rml+="""""" + to_xml(tools.ustr(ans.answer)) + """""" - cr.execute("select count(id) from survey_response_answer sra where sra.answer_id = %d"%(ans.id)) + rml += """""" + to_xml(tools.ustr(ans.answer)) + """""" + cr.execute("select count(id) from survey_response_answer sra where sra.answer_id = %d" % ans.id) tot_res = cr.fetchone()[0] cr.execute("select count(id) ,sra.column_id from survey_response_answer sra where sra.answer_id = %d group by sra.column_id" % ans.id) calc_res = cr.dictfetchall() @@ -177,25 +180,27 @@ class survey_analysis(report_rml): rml += """""" + tools.ustr(percantage) +"% (" + tools.ustr(cal_count) + """)""" else: rml += """""" + tools.ustr(percantage) +"% (" + tools.ustr(cal_count) + """)""" - rml+="""""" + tools.ustr(tot_res) + """ + rml += """""" + tools.ustr(tot_res) + """ """ - rml+="""""" + rml += """""" + if que.is_comment_require: cr.execute("select count(id) from survey_response_line where question_id = %d and comment != ''"% que.id) tot_res = cr.fetchone()[0] - rml+="""""" + to_xml(tools.ustr(que.comment_label)) + """ + rml += """""" + to_xml(tools.ustr(que.comment_label)) + """ """ + tools.ustr(tot_res) + """""" elif que.type in['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans', 'multiple_textboxes','date_and_time','date','multiple_textboxes_diff_type']: - rml +="""""" + rml += """""" rml += """ Response Percentage Response Count """ + for ans in que.answer_choice_ids: progress = ans.average * 7 / 100 - rml+="""""" + to_xml(tools.ustr(ans.answer)) + """ + rml += """""" + to_xml(tools.ustr(ans.answer)) + """ @@ -204,13 +209,14 @@ class survey_analysis(report_rml): if progress: rml += """ """ - rml +=""" + rml += """ """ + tools.ustr(ans.average) + """% """ + tools.ustr(ans.response) + """""" - rml+="""""" + rml += """""" + if que.is_comment_require: # if que.make_comment_field: # cr.execute("select count(id) from survey_response_line where question_id = %d and comment != ''"% que.id) @@ -224,12 +230,12 @@ class survey_analysis(report_rml): # else: cr.execute("select count(id) from survey_response_line where question_id = %d and comment != ''"% que.id) tot_res = cr.fetchone()[0] - rml+="""""" + to_xml(tools.ustr(que.comment_label)) + """ + rml += """""" + to_xml(tools.ustr(que.comment_label)) + """ """ + tools.ustr(tot_res) + """""" elif que.type in['single_textbox']: cr.execute("select count(id) from survey_response_line where question_id = %d and single_text!=''" % que.id) - rml +=""" + rml += """ Response Count @@ -237,9 +243,10 @@ class survey_analysis(report_rml): """ + tools.ustr(cr.fetchone()[0]) + """ """ + elif que.type in['comment']: cr.execute("select count(id) from survey_response_line where question_id = %d and comment !=''" % que.id) - rml +=""" + rml += """ Response Count @@ -247,23 +254,26 @@ class survey_analysis(report_rml): """ + tools.ustr(cr.fetchone()[0]) + """ """ + elif que.type in['rating_scale']: cols_widhts.append(200) for col in range(0,len(que.column_heading_ids) + 2): cols_widhts.append(float(300 / (len(que.column_heading_ids) + 2))) colWidths = ",".join(map(tools.ustr, cols_widhts)) matrix_ans = [(0,'')] + for col in que.column_heading_ids: if col.title not in matrix_ans: matrix_ans.append((col.id,col.title)) - rml+="""""" + rml += """""" for mat_col in range(0,len(matrix_ans)): - rml+="""""" + to_xml(tools.ustr(matrix_ans[mat_col][1])) + """""" - rml+="""Rating Average + rml += """""" + to_xml(tools.ustr(matrix_ans[mat_col][1])) + """""" + rml += """Rating Average Response Count """ + for ans in que.answer_choice_ids: - rml+="""""" + to_xml(tools.ustr(ans.answer)) + """""" + rml += """""" + to_xml(tools.ustr(ans.answer)) + """""" res_count = 0 rating_weight_sum = 0 for mat_col in range(1, len(matrix_ans)): @@ -275,11 +285,13 @@ class survey_analysis(report_rml): sqc.question_id = sr.question_id and sra.answer_id = %d and sqc.title ='%s'\ group by sra.answer_id,sqc.rating_weight" % (ans.id,matrix_ans[mat_col][1])) col_weight = cr.fetchone() + if not col_weight: col_weight= (0,0) elif not col_weight[1]: col_weight = (col_weight[0],0) res_count = col_weight[0] + if tot_res and res_count: rating_weight_sum += int(col_weight[1]) * tot_res tot_per = round((float(tot_res) * 100) / int(res_count), 2) @@ -290,12 +302,14 @@ class survey_analysis(report_rml): rml += """""" + tools.ustr(tot_per) + "%(" + tools.ustr(tot_res) + """)""" else: rml += """""" + tools.ustr(tot_per)+"%(" + tools.ustr(tot_res) + """)""" + percantage = 0.00 if res_count: percantage = round((float(rating_weight_sum)/res_count), 2) - rml+="""""" + tools.ustr(percantage) + """ + rml += """""" + tools.ustr(percantage) + """ """ + tools.ustr(res_count) + """""" - rml+="""""" + rml += """""" + elif que.type in['matrix_of_drop_down_menus']: for column in que.column_heading_ids: rml += """ @@ -306,8 +320,9 @@ class survey_analysis(report_rml): for col in range(0, len(menu_choices) + 1): cols_widhts.append(float(300 / (len(menu_choices) + 1))) colWidths = ",".join(map(tools.ustr, cols_widhts)) - rml +=""" + rml += """ """ + for menu in menu_choices: rml += """""" + to_xml(tools.ustr(menu)) + """""" rml += """Response Count""" @@ -317,8 +332,9 @@ class survey_analysis(report_rml): cr.execute("select count(sra.id),sra.value_choice, sra.answer_id, sra.column_id from survey_response_answer sra \ where sra.column_id='%s' group by sra.value_choice ,sra.answer_id, sra.column_id" % (column.id)) calc_percantage = cr.dictfetchall() + for ans in que.answer_choice_ids: - rml+="""""" + to_xml(tools.ustr(ans.answer)) + """""" + rml += """""" + to_xml(tools.ustr(ans.answer)) + """""" for mat_col in range(0, len(menu_choices)): calc = 0 response = 0 @@ -328,19 +344,22 @@ class survey_analysis(report_rml): if ans.id == per['answer_id'] and menu_choices[mat_col] == per['value_choice']: calc = per['count'] percantage = 0.00 + if calc and response: percantage = round((float(calc)* 100) / response,2) if calc: - rml+="""""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)""" + rml += """""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)""" else: - rml+="""""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)""" + rml += """""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)""" + response = 0 for res in res_count: if res['answer_id'] == ans.id: response = res['count'] rml += """""" + tools.ustr(response) + """""" rml += """""" + elif que.type in['numerical_textboxes']: - rml +=""" + rml += """ @@ -355,6 +374,7 @@ class survey_analysis(report_rml): for tot in tot_res: total += int(tot['answer']) per = 0.00 + if len(tot_res): per = round((float(total) / len(tot_res)),2) rml+="""""" + to_xml(tools.ustr(ans.answer)) + """ @@ -377,10 +397,12 @@ class survey_analysis(report_rml): """ rml += """""" + rml += """""" report_type = datas.get('report_type', 'pdf') create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) + return (pdf, report_type) survey_analysis('report.survey.analysis', 'survey','','') diff --git a/addons/survey/report/survey_browse_response.py b/addons/survey/report/survey_browse_response.py index ee58e9536be..25c9a32ce2b 100644 --- a/addons/survey/report/survey_browse_response.py +++ b/addons/survey/report/survey_browse_response.py @@ -31,19 +31,21 @@ class survey_browse_response(report_rml): _divide_columns_for_matrix = 0.7 _display_ans_in_rows = 5 _pageSize = ('29.7cm','21.1cm') - if datas.has_key('form') and datas['form']['orientation']=='vertical': - if datas['form']['paper_size']=='letter': + + if datas.has_key('form') and datas['form'].get('orientation','') == 'vertical': + if datas['form'].get('paper_size','') == 'letter': _pageSize = ('21.6cm','27.9cm') - elif datas['form']['paper_size']=='legal': + elif datas['form'].get('paper_size','') == 'legal': _pageSize = ('21.6cm','35.6cm') - elif datas['form']['paper_size']=='a4': + elif datas['form'].get('paper_size','') == 'a4': _pageSize = ('21.1cm','29.7cm') - elif datas.has_key('form') and datas['form']['orientation']=='horizontal': - if datas['form']['paper_size']=='letter': + + elif datas.has_key('form') and datas['form'].get('orientation',False) == 'horizontal': + if datas['form'].get('paper_size','') == 'letter': _pageSize = ('27.9cm','21.6cm') - elif datas['form']['paper_size']=='legal': + elif datas['form'].get('paper_size','') == 'legal': _pageSize = ('35.6cm','21.6cm') - elif datas['form']['paper_size']=='a4': + elif datas['form'].get('paper_size') == 'a4': _pageSize = ('29.7cm','21.1cm') _frame_width = tools.ustr(_pageSize[0]) @@ -190,9 +192,11 @@ class survey_browse_response(report_rml): response_id = [int(context['response_id'][0])] else: response_id = surv_resp_obj.search(cr, uid, [('survey_id', 'in', ids)]) + surv_resp_line_obj = pooler.get_pool(cr.dbname).get('survey.response.line') surv_obj = pooler.get_pool(cr.dbname).get('survey') surv_ans_obj = pooler.get_pool(cr.dbname).get('survey.answer') + for response in surv_resp_obj.browse(cr, uid, response_id): for survey in surv_obj.browse(cr, uid, [response.survey_id.id]): tbl_width = float(_tbl_widths.replace('cm', '')) @@ -206,6 +210,7 @@ class survey_browse_response(report_rml): """ + to_xml(response.user_id.login) + """ """ + status = "Not Finished" if response.state == "done": status = "Finished" colwidth = str(tbl_width - 7) + "cm," @@ -216,10 +221,12 @@ class survey_browse_response(report_rml): Status :- """ + to_xml(tools.ustr(status)) + """ """ + if survey.note: rml += """ """ + to_xml(tools.ustr(survey.note or '')) + """ """ + for page in survey.page_ids: rml += """ Page :- """ + to_xml(tools.ustr(page.title or '')) + """ @@ -229,16 +236,19 @@ class survey_browse_response(report_rml): """ + to_xml(tools.ustr(page.note or '')) + """ """ + for que in page.question_ids: rml += """ """ + to_xml(to_xml(que.question)) + """ """ + answer = surv_resp_line_obj.browse(cr ,uid, surv_resp_line_obj.search(cr, uid, [('question_id', '=', que.id),('response_id', '=', response.id)])) if que.type in ['descriptive_text']: rml +=""" """ + to_xml(tools.ustr(que.descriptive_text)) + """ """ + elif que.type in ['table']: if len(answer) and answer[0].state == "done": col_heading = pooler.get_pool(cr.dbname).get('survey.tbl.column.heading') @@ -250,18 +260,20 @@ class survey_browse_response(report_rml): colWidths = colWidths + 'cm' matrix_ans = [] rml +="""""" + for col in que.column_heading_ids: if col.title not in matrix_ans: matrix_ans.append(col.title) rml += """ """ + to_xml(tools.ustr(col.title)) +"""""" rml += """""" i = 0 + for row in range(0, que.no_of_rows): - if i%2!=0: - style='tbl_white' + if i%2 != 0: + style = 'tbl_white' else: - style='tbl_gainsboro' - i+=1 + style = 'tbl_gainsboro' + i +=1 rml += """""" table_data = col_heading.browse(cr, uid, col_heading.search(cr, uid, [('response_table_id', '=', answer[0].id), ('name', '=', row)])) for column in matrix_ans: @@ -274,16 +286,19 @@ class survey_browse_response(report_rml): else: rml += """ """ rml += """""" + else: rml +=""" No Response """ + elif que.type in ['multiple_choice_only_one_ans','multiple_choice_multiple_ans']: if len(answer) and answer[0].state == "done": ans_list = [] for ans in answer[0].response_answer_ids: ans_list.append(to_xml(tools.ustr(ans.answer_id.answer))) answer_choice=[] + for ans in que['answer_choice_ids']: answer_choice.append(to_xml(tools.ustr((ans.answer)))) @@ -297,6 +312,7 @@ class survey_browse_response(report_rml): lst.append('') if not lst: del divide_list[divide_list.index(lst):] + for divide in divide_list: a = _divide_columns_for_matrix * len(divide) b = float(_tbl_widths.replace('cm', '')) - float(a) @@ -307,6 +323,7 @@ class survey_browse_response(report_rml): colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = colWidths +'cm' rml += """""" + for div in range(0, len(divide)): if divide[div] != '': if que.type == 'multiple_choice_multiple_ans': @@ -340,6 +357,7 @@ class survey_browse_response(report_rml): else: rml += """""" rml += """""" + if que.is_comment_require and answer[0].comment: rml += """ """ + to_xml(tools.ustr(answer[0].comment)) + """""" @@ -347,6 +365,7 @@ class survey_browse_response(report_rml): rml += """ No Response """ + elif que.type in ['multiple_textboxes_diff_type','multiple_textboxes','date','date_and_time','numerical_textboxes','multiple_textboxes_diff_type']: if len(answer) and answer[0].state == "done": cols_widhts = [] @@ -355,6 +374,7 @@ class survey_browse_response(report_rml): colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = tools.ustr(colWidths) + 'cm' answer_list = {} + for ans in answer[0].response_answer_ids: answer_list[ans.answer_id.answer] = ans.answer for que_ans in que['answer_choice_ids']: @@ -372,6 +392,7 @@ class survey_browse_response(report_rml): rml += """ No Response """ + elif que.type in ['single_textbox']: if len(answer) and answer[0].state == "done": rml += """ @@ -381,6 +402,7 @@ class survey_browse_response(report_rml): rml += """ No Response """ + elif que.type in ['comment']: if len(answer) and answer[0].state == "done": rml += """ @@ -390,6 +412,7 @@ class survey_browse_response(report_rml): rml += """ No Response """ + elif que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans', 'rating_scale', 'matrix_of_drop_down_menus']: if len(answer) and answer[0].state == "done": if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale'] and que.comment_column: @@ -401,6 +424,7 @@ class survey_browse_response(report_rml): cols_widhts.append(float((float(_tbl_widths.replace('cm','')) / float(2.0)) / len(que.column_heading_ids))) else: cols_widhts.append(float(_tbl_widths.replace('cm',''))) + tmp = 0.0 sum = 0.0 i = 0 @@ -415,6 +439,7 @@ class survey_browse_response(report_rml): colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = colWidths + 'cm' matrix_ans = [(0, ''),] + for col in que.column_heading_ids: if col.title not in matrix_ans: matrix_ans.append((col.id, col.title)) @@ -422,11 +447,13 @@ class survey_browse_response(report_rml): if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale'] and que.comment_column: matrix_ans.append(que.column_name) rml += """""" + for mat_col in range(0, len(matrix_ans)): - rml+="""""" + to_xml(tools.ustr(matrix_ans[mat_col][1])) + """""" - rml +="""""" - rml+="""""" - i=0 + rml += """""" + to_xml(tools.ustr(matrix_ans[mat_col][1])) + """""" + rml += """""" + rml += """""" + i = 0 + for ans in que.answer_choice_ids: if i%2 != 0: style = 'ans_tbl_white' @@ -474,6 +501,7 @@ class survey_browse_response(report_rml): comment_value = '' rml += """""" + to_xml(tools.ustr(comment_value)) + """""" rml += """""" + if que.is_comment_require: rml += """ """ + to_xml(tools.ustr(answer[0].comment or '')) + """""" @@ -481,16 +509,19 @@ class survey_browse_response(report_rml): rml += """ No Response """ + if datas.has_key('form') and not datas['form']['without_pagebreak']: rml += """""" elif not datas.has_key('form'): rml += """""" else: rml += """""" + rml += """""" report_type = datas.get('report_type', 'pdf') create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) + return (pdf, report_type) survey_browse_response('report.survey.browse.response', 'survey','','') diff --git a/addons/survey/report/survey_form.py b/addons/survey/report/survey_form.py index ff1e0bc8424..2c1de9cc71d 100644 --- a/addons/survey/report/survey_form.py +++ b/addons/survey/report/survey_form.py @@ -30,39 +30,41 @@ class survey_form(report_rml): _divide_columns_for_matrix = 0.7 _display_ans_in_rows = 5 _pageSize = ('29.7cm','21.1cm') - if datas.has_key('form') and datas['form']['orientation']=='vertical': - if datas['form']['paper_size']=='letter': + if datas.has_key('form') and datas['form'].get('orientation','') == 'vertical': + if datas['form'].get('paper_size','') == 'letter': _pageSize = ('21.6cm','27.9cm') - elif datas['form']['paper_size']=='legal': + elif datas['form'].get('paper_size','') == 'legal': _pageSize = ('21.6cm','35.6cm') - elif datas['form']['paper_size']=='a4': + elif datas['form'].get('paper_size','') == 'a4': _pageSize = ('21.1cm','29.7cm') - elif datas.has_key('form') and datas['form']['orientation']=='horizontal': - if datas['form']['paper_size']=='letter': + elif datas.has_key('form') and datas['form'].get('orientation','') == 'horizontal': + if datas['form'].get('paper_size','') == 'letter': _pageSize = ('27.9cm','21.6cm') - elif datas['form']['paper_size']=='legal': + elif datas['form'].get('paper_size','') == 'legal': _pageSize = ('35.6cm','21.6cm') - elif datas['form']['paper_size']=='a4': + elif datas['form'].get('paper_size','') == 'a4': _pageSize = ('29.7cm','21.1cm') _frame_width = tools.ustr(_pageSize[0]) _frame_height = tools.ustr(float(_pageSize[1].replace('cm','')) - float(1.90))+'cm' _tbl_widths = tools.ustr(float(_pageSize[0].replace('cm','')) - float(2.10))+'cm' + rml=""" @@ -158,9 +160,10 @@ class survey_form(report_rml): """ + to_xml(tools.ustr(survey.note)) + """ """ + seq = 0 for page in survey.page_ids: - seq+=1 + seq += 1 rml += """ """+ tools.ustr(seq) + """. """ + to_xml(tools.ustr(page.title)) + """ @@ -169,9 +172,10 @@ class survey_form(report_rml): rml += """ """ + to_xml(tools.ustr(page.note or '')) + """ """ + for que in page.question_ids: - cols_widhts=[] - rml +=""" + cols_widhts = [] + rml += """ """ + to_xml(tools.ustr(que.question)) + """ @@ -180,8 +184,8 @@ class survey_form(report_rml): if que.type in ['descriptive_text']: cols_widhts.append(float(_tbl_widths.replace('cm',''))) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) - colWidths = colWidths+'cm' - rml+=""" + colWidths = colWidths + 'cm' + rml += """ @@ -189,8 +193,9 @@ class survey_form(report_rml): """ + elif que.type in ['multiple_choice_multiple_ans','multiple_choice_only_one_ans']: - answer=[] + answer = [] for ans in que.answer_choice_ids: answer.append(to_xml(tools.ustr((ans.answer)))) @@ -207,18 +212,19 @@ class survey_form(report_rml): for divide in divide_list: a = _divide_columns_for_matrix*len(divide) b = float(_tbl_widths.replace('cm','')) - float(a) - cols_widhts=[] + cols_widhts = [] + for div in range(0,len(divide)): cols_widhts.append(float(a/len(divide))) cols_widhts.append(float(b/len(divide))) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) - colWidths = colWidths+'cm' + colWidths = colWidths +'cm' rml+=""" """ for div in range(0,len(divide)): - if divide[div]!='': + if divide[div] != '': if que.type == 'multiple_choice_multiple_ans': - rml+=""" + rml += """ @@ -226,7 +232,7 @@ class survey_form(report_rml): """ + divide[div] + """""" else: - rml+=""" + rml += """ @@ -234,11 +240,12 @@ class survey_form(report_rml): """ + divide[div] + """""" else: - rml+=""" + rml += """ """ - rml+=""" + rml += """ """ + elif que.type in ['matrix_of_choices_only_one_ans','rating_scale','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus']: if len(que.column_heading_ids): cols_widhts.append(float(_tbl_widths.replace('cm',''))/float(2.0)) @@ -246,42 +253,45 @@ class survey_form(report_rml): cols_widhts.append(float((float(_tbl_widths.replace('cm',''))/float(2.0))/len(que.column_heading_ids))) else: cols_widhts.append(float(_tbl_widths.replace('cm',''))) - tmp=0.0 + + tmp = 0.0 sum = 0.0 i = 0 if que.comment_column: for col in cols_widhts: - if i==0: + if i == 0: cols_widhts[i] = cols_widhts[i]/2.0 tmp = cols_widhts[i] sum += col - i+=1 + i += 1 cols_widhts.append(round(tmp,2)) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = colWidths+'cm' matrix_ans = ['',] + for col in que.column_heading_ids: if col.title not in matrix_ans: matrix_ans.append(col.title) if que.comment_column: matrix_ans.append(to_xml(tools.ustr(que.column_name))) - rml+=""" - """ + rml+="""""" + for mat_col in matrix_ans: - rml+="""""" + to_xml(tools.ustr(mat_col)) + """""" - rml+="""""" - i=0 + rml += """""" + to_xml(tools.ustr(mat_col)) + """""" + rml += """""" + i = 0 for ans in que.answer_choice_ids: - if i%2!=0: + if i%2 != 0: style='ans_tbl_white' else: style='ans_tbl_gainsboro' - i+=1 - rml+=""" + i += 1 + rml += """ """ + to_xml(tools.ustr(ans.answer)) + """""" rec_width = float((sum-tmp)*10+100) value = "" + if que.type in ['matrix_of_drop_down_menus']: value = """ """ @@ -292,22 +302,23 @@ class survey_form(report_rml): value = """ """ for mat_col in range(1,len(matrix_ans)): - if matrix_ans[mat_col]==que.column_name: - if mat_col==1: - rml+=""" + if matrix_ans[mat_col] == que.column_name: + if mat_col == 1: + rml += """ """ + to_xml(tools.ustr(que.column_name)) + """""" else: - rml+="""""" + rml += """""" else: - rml+="""""" + value + """""" - rml+= """""" - elif que.type in ['multiple_textboxes','numerical_textboxes', 'date_and_time','date','multiple_textboxes_diff_type']: + rml += """""" + value + """""" + rml += """""" + + elif que.type in ['multiple_textboxes', 'numerical_textboxes', 'date_and_time','date','multiple_textboxes_diff_type']: cols_widhts.append(float(_tbl_widths.replace('cm',''))/2) cols_widhts.append(float(_tbl_widths.replace('cm',''))/2) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = tools.ustr(colWidths) + 'cm' for ans in que.answer_choice_ids: - rml +=""" + rml += """ """ + to_xml(tools.ustr(ans.answer)) + """ @@ -318,10 +329,11 @@ class survey_form(report_rml): """ + elif que.type in ['comment']: cols_widhts.append(float(_tbl_widths.replace('cm',''))) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) - rml+=""" + rml += """ @@ -330,10 +342,11 @@ class survey_form(report_rml): """ + elif que.type in ['single_textbox']: cols_widhts.append(float(_tbl_widths.replace('cm',''))) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) - rml+=""" + rml += """ @@ -343,39 +356,44 @@ class survey_form(report_rml): """ + elif que.type in ['table']: tbl_width = float(_tbl_widths.replace('cm','')) for i in range(0,len(que.column_heading_ids)): cols_widhts.append(tbl_width/float(len(que.column_heading_ids))) colWidths = "cm,".join(map(tools.ustr, cols_widhts)) colWidths = colWidths+'cm' - rml+="""""" + rml += """""" for col in que.column_heading_ids: rml+="""""" + to_xml(tools.ustr(col.title)) + """""" - rml+="""""" - i=0 + rml += """""" + i = 0 for r in range(0,que.no_of_rows): - if i%2!=0: - style='tbl_white' + if i%2 != 0: + style = 'tbl_white' else: - style='tbl_gainsboro' - i+=1 - rml+="""""" + style = 'tbl_gainsboro' + i += 1 + rml += """""" for c in que.column_heading_ids: - rml+=""" + rml += """ """ - rml+="""""" + rml += """""" + if datas.has_key('form') and not datas['form']['without_pagebreak']: - rml+="""""" + rml += """""" elif not datas.has_key('form'): - rml+="""""" + rml += """""" else: - rml+="""""" - rml+="""""" + rml += """""" + + rml += """""" report_type = datas.get('report_type', 'pdf') create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) + return (pdf, report_type) + survey_form('report.survey.form', 'survey','','') # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 649a9e785c8449860024eeec187d329d96fa7170 Mon Sep 17 00:00:00 2001 From: "ksa (Open ERP)" Date: Mon, 15 Mar 2010 19:10:23 +0530 Subject: [PATCH 011/248] [IMP]: wiki: Apply Act window on the wiki osv memory wizard,removed unused imports bzr revid: ksa@tinyerp.co.in-20100315134023-01bkf9rtaxq6aweb --- addons/wiki/wiki_view.xml | 40 ----- addons/wiki/wizard/__init__.py | 1 + addons/wiki/wizard/show_diff.py | 7 +- addons/wiki/wizard/wiki_create_menu.py | 12 +- addons/wiki/wizard/wiki_make_index.py | 11 +- addons/wiki/wizard/wiki_make_index_view.xml | 6 + addons/wiki/wizard/wiki_wiki_help_open.py | 13 +- .../wiki/wizard/wiki_wiki_help_open_view.xml | 7 +- addons/wiki/wizard/wiki_wiki_page_open.py | 13 +- .../wiki/wizard/wiki_wiki_page_open_view.xml | 7 +- addons/wiki/wizard/wizard_view.xml | 13 +- addons/wiki/wizard/wizard_wiki.py | 142 ------------------ addons/wiki/wizard/wizard_wiki.xml | 105 ------------- 13 files changed, 49 insertions(+), 328 deletions(-) delete mode 100644 addons/wiki/wizard/wizard_wiki.py delete mode 100644 addons/wiki/wizard/wizard_wiki.xml diff --git a/addons/wiki/wiki_view.xml b/addons/wiki/wiki_view.xml index e6feae5eeba..ec738a5a91f 100644 --- a/addons/wiki/wiki_view.xml +++ b/addons/wiki/wiki_view.xml @@ -6,18 +6,6 @@ - - - - wiki.groups.tree wiki.groups @@ -54,11 +42,6 @@ string="Create Menu" type="action" icon="gtk-justify-fill" /> -