def __init__(self, session, record): self.cr = session.cr self.uid = session.uid self.model = record.model self.id = record.id self.ids = [record.id] self.obj = ecore.registry(self.cr.dbname)[self.model]
def go(id, uid, ids, datas, context): with ecore.api.Environment.manage(): cr = ecore.registry(db).cursor() try: result, format = ecore.report.render_report( cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id][ 'exception'] = ecore.exceptions.DeferredException( 'RML is not available at specified location or not enough data to print!', tb) self_reports[id]['result'] = result self_reports[id]['format'] = format self_reports[id]['state'] = True except Exception, exception: _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self_reports[id][ 'exception'] = ecore.exceptions.DeferredException( tools.ustr(exception.name), tools.ustr(exception.value)) else: tb = sys.exc_info() self_reports[id][ 'exception'] = ecore.exceptions.DeferredException( tools.exception_to_unicode(exception), tb) self_reports[id]['state'] = True cr.commit() cr.close()
def _callback(self, cr, uid, model_name, method_name, args, job_id): """ Run the method associated to a given job It takes care of logging and exception handling. :param model_name: model name on which the job method is located. :param method_name: name of the method to call when this job is processed. :param args: arguments of the method (without the usual self, cr, uid). :param job_id: job id. """ try: args = str2tuple(args) ecore.modules.registry.RegistryManager.check_registry_signaling(cr.dbname) registry = ecore.registry(cr.dbname) if model_name in registry: model = registry[model_name] if hasattr(model, method_name): log_depth = (None if _logger.isEnabledFor(logging.DEBUG) else 1) netsvc.log(_logger, logging.DEBUG, 'cron.object.execute', (cr.dbname,uid,'*',model_name,method_name)+tuple(args), depth=log_depth) if _logger.isEnabledFor(logging.DEBUG): start_time = time.time() getattr(model, method_name)(cr, uid, *args) if _logger.isEnabledFor(logging.DEBUG): end_time = time.time() _logger.debug('%.3fs (%s, %s)' % (end_time - start_time, model_name, method_name)) ecore.modules.registry.RegistryManager.signal_caches_change(cr.dbname) else: msg = "Method `%s.%s` does not exist." % (model_name, method_name) _logger.warning(msg) else: msg = "Model `%s` does not exist." % model_name _logger.warning(msg) except Exception, e: self._handle_callback_exception(cr, uid, model_name, method_name, args, job_id, e)
def create(self, cursor, uid, ids, data, context=None): """We override the create function in order to handle generator Code taken from report openoffice. Thanks guys :) """ pool = ecore.registry(cursor.dbname) ir_obj = pool['ir.actions.report.xml'] report_xml_ids = ir_obj.search(cursor, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: report_xml = ir_obj.browse(cursor, uid, report_xml_ids[0], context=context) else: return super(WebKitParser, self).create(cursor, uid, ids, data, context) setattr(report_xml, 'use_global_header', self.header if report_xml.header else False) if report_xml.report_type != 'webkit': return super(WebKitParser, self).create(cursor, uid, ids, data, context) result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context) if not result: return (False, False) return result
def __init__(self, cursor, uid, report_id, context): "constructor" self.cursor = cursor self.uid = uid self.pool = ecore.registry(self.cursor.dbname) self.report_id = report_id self.context = context
def __call__(self, source): res = source cr = None is_new_cr = False try: frame = inspect.currentframe() if frame is None: return source frame = frame.f_back if not frame: return source lang = self._get_lang(frame) if lang: cr, is_new_cr = self._get_cr(frame) if cr: # Try to use ir.translation to benefit from global cache if possible registry = ecore.registry(cr.dbname) res = registry['ir.translation']._get_source( cr, SUPERUSER_ID, None, ('code', 'sql_constraint'), lang, source) else: _logger.debug( 'no context cursor detected, skipping translation for "%r"', source) else: _logger.debug( 'no translation language detected, skipping translation for "%r" ', source) except Exception: _logger.debug('translation went wrong for "%r", skipped', source) # if so, double-check the root/base translations filenames finally: if cr and is_new_cr: cr.close() return res
def poll(self, dbname, channels, last, options=None, timeout=TIMEOUT): if options is None: options = {} # Dont hang ctrl-c for a poll request, we need to bypass private # attribute access because we dont know before starting the thread that # it will handle a longpolling request if not ecore.evented: current = threading.current_thread() current._Thread__daemonic = True # rename the thread to avoid tests waiting for a longpolling current.setName("ecore.longpolling.request.%s" % current.ident) registry = ecore.registry(dbname) # immediatly returns if past notifications exist with registry.cursor() as cr: notifications = registry['bus.bus'].poll(cr, ecore.SUPERUSER_ID, channels, last, options) # or wait for future ones if not notifications: event = self.Event() for channel in channels: self.channels.setdefault(hashable(channel), []).append(event) try: event.wait(timeout=timeout) with registry.cursor() as cr: notifications = registry['bus.bus'].poll(cr, ecore.SUPERUSER_ID, channels, last, options, force_status=True) except Exception: # timeout pass return notifications
def __init__(self, cr, module, idref, mode, report=None, noupdate=False, xml_filename=None): self.mode = mode self.module = module self.cr = cr self.idref = idref self.pool = ecore.registry(cr.dbname) self.uid = 1 if report is None: report = assertion_report.assertion_report() self.assertion_report = report self.noupdate = noupdate self.xml_filename = xml_filename self._tags = { 'record': self._tag_record, 'delete': self._tag_delete, 'function': self._tag_function, 'menuitem': self._tag_menuitem, 'template': self._tag_template, 'workflow': self._tag_workflow, 'report': self._tag_report, 'ir_set': self._tag_ir_set, # deprecated:: 9.0 'act_window': self._tag_act_window, 'assert': self._tag_assert, }
def __init__(self, cr, module, id_map, mode, filename, report=None, noupdate=False, loglevel=logging.DEBUG): self.cr = cr self.module = module self.id_map = id_map self.mode = mode self.filename = filename if report is None: report = assertion_report.assertion_report() self.assertion_report = report self.noupdate = noupdate self.loglevel = loglevel self.pool = ecore.registry(cr.dbname) self.uid = 1 self.context = {} # opererp context self.eval_context = { 'ref': self._ref(), '_ref': self._ref(), # added '_ref' so that record['ref'] is possible 'time': time, 'datetime': datetime, 'timedelta': timedelta } self.env = ecore.api.Environment(self.cr, self.uid, self.context)
def __call__(self, source): res = source cr = None is_new_cr = False try: frame = inspect.currentframe() if frame is None: return source frame = frame.f_back if not frame: return source lang = self._get_lang(frame) if lang: cr, is_new_cr = self._get_cr(frame) if cr: # Try to use ir.translation to benefit from global cache if possible registry = ecore.registry(cr.dbname) res = registry['ir.translation']._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source) else: _logger.debug('no context cursor detected, skipping translation for "%r"', source) else: _logger.debug('no translation language detected, skipping translation for "%r" ', source) except Exception: _logger.debug('translation went wrong for "%r", skipped', source) # if so, double-check the root/base translations filenames finally: if cr and is_new_cr: cr.close() return res
def exp_render_report(db, uid, object, ids, datas=None, context=None): if not datas: datas={} if not context: context={} self_id_protect.acquire() global self_id self_id += 1 id = self_id self_id_protect.release() self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} cr = ecore.registry(db).cursor() try: result, format = ecore.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) self_reports[id]['result'] = result self_reports[id]['format'] = format self_reports[id]['state'] = True except Exception, exception: _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self_reports[id]['exception'] = ecore.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException(tools.exception_to_unicode(exception), tb) self_reports[id]['state'] = True
def run_scheduler(self, cr, uid, use_new_cursor=False, company_id = False, context=None): ''' Call the scheduler to check the procurement order. This is intented to be done for all existing companies at the same time, so we're running all the methods as SUPERUSER to avoid intercompany and access rights issues. @param self: The object pointer @param cr: The current row, from the database cursor, @param uid: The current user ID for security checks @param ids: List of selected IDs @param use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement. This is appropriate for batch jobs only. @param context: A standard dictionary for contextual values @return: Dictionary of values ''' if context is None: context = {} try: if use_new_cursor: cr = ecore.registry(cr.dbname).cursor() # Run confirmed procurements dom = [('state', '=', 'confirmed')] if company_id: dom += [('company_id', '=', company_id)] prev_ids = [] while True: ids = self.search(cr, SUPERUSER_ID, dom, context=context) if not ids or prev_ids == ids: break else: prev_ids = ids self.run(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context) if use_new_cursor: cr.commit() # Check if running procurements are done offset = 0 dom = [('state', '=', 'running')] if company_id: dom += [('company_id', '=', company_id)] prev_ids = [] while True: ids = self.search(cr, SUPERUSER_ID, dom, offset=offset, context=context) if not ids or prev_ids == ids: break else: prev_ids = ids self.check(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context) if use_new_cursor: cr.commit() finally: if use_new_cursor: try: cr.close() except Exception: pass return {}
def __getattr__(self, name): cr = self._cursor if cr is None: from ecore import registry cr = self._cursor = registry(self.dbname).cursor() for _ in xrange(self._depth): cr.__enter__() return getattr(cr, name)
def __init__(self, cr, uid, datas, func=False): # create a new document self.cr = cr self.pool = ecore.registry(cr.dbname) self.func = func or {} self.datas = datas self.uid = uid self.bin_datas = {}
def execute(db, uid, obj, method, *args, **kw): threading.currentThread().dbname = db with ecore.registry(db).cursor() as cr: if method.startswith('_'): raise UserError(_('Private methods (such as %s) cannot be called remotely.') % (method,)) res = execute_cr(cr, uid, obj, method, *args, **kw) if res is None: _logger.info('The method %s of the object %s can not return `None` !', method, obj) return res
def create(self, cr, uid, ids, datas, context=None): if not context: context={} self.cr=cr self.context = context self.groupby = context.get('group_by',[]) self.groupby_no_leaf = context.get('group_by_no_leaf',False) registry = ecore.registry(cr.dbname) model = registry[datas['model']] model_id = registry['ir.model'].search(cr, uid, [('model','=',model._name)]) model_desc = model._description if model_id: model_desc = registry['ir.model'].browse(cr, uid, model_id[0], context).name self.title = model_desc datas['ids'] = ids result = model.fields_view_get(cr, uid, view_type='tree', context=context) fields_order = self.groupby + self._parse_string(result['arch']) if self.groupby: rows = [] def get_groupby_data(groupby = [], domain = []): records = model.read_group(cr, uid, domain, fields_order, groupby , 0, None, context) for rec in records: rec['__group'] = True rec['__no_leaf'] = self.groupby_no_leaf rec['__grouped_by'] = groupby[0] if (isinstance(groupby, list) and groupby) else groupby for f in fields_order: if f not in rec: rec.update({f:False}) elif isinstance(rec[f], tuple): rec[f] = rec[f][1] rows.append(rec) inner_groupby = (rec.get('__context', {})).get('group_by',[]) inner_domain = rec.get('__domain', []) if inner_groupby: get_groupby_data(inner_groupby, inner_domain) else: if self.groupby_no_leaf: continue child_ids = model.search(cr, uid, inner_domain) res = model.read(cr, uid, child_ids, result['fields'].keys(), context) res.sort(lambda x,y: cmp(ids.index(x['id']), ids.index(y['id']))) rows.extend(res) dom = [('id','in',ids)] if self.groupby_no_leaf and len(ids) and not ids[0]: dom = datas.get('_domain',[]) get_groupby_data(self.groupby, dom) else: rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context) ids2 = map(itemgetter('id'), rows) # getting the ids from read result if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen rows_new = [] for id in datas['ids']: rows_new += [elem for elem in rows if elem['id'] == id] rows = rows_new res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc) return self.obj.get(), 'pdf'
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None): if not context: context={} registry = ecore.registry(cr.dbname) attach = report_xml.attachment if attach: objs = self.getObjects(cr, uid, ids, context) results = [] for obj in objs: aname = eval(attach, {'object':obj, 'time':time}) result = False if report_xml.attachment_use and aname and context.get('attachment_use', True): aids = registry['ir.attachment'].search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)]) if aids: brow_rec = registry['ir.attachment'].browse(cr, uid, aids[0]) if not brow_rec.datas: continue d = base64.decodestring(brow_rec.datas) results.append((d,'pdf')) continue result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context) if not result: return False if aname: try: name = aname+'.'+result[1] # Remove the default_type entry from the context: this # is for instance used on the account.account_invoices # and is thus not intended for the ir.attachment type # field. ctx = dict(context) ctx.pop('default_type', None) registry['ir.attachment'].create(cr, uid, { 'name': aname, 'datas': base64.encodestring(result[0]), 'datas_fname': name, 'res_model': self.table, 'res_id': obj.id, }, context=ctx ) except AccessError: #TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632 _logger.info('Could not create saved report attachment', exc_info=True) results.append(result) if results: if results[0][1]=='pdf': from pyPdf import PdfFileWriter, PdfFileReader output = PdfFileWriter() for r in results: reader = PdfFileReader(cStringIO.StringIO(r[0])) for page in range(reader.getNumPages()): output.addPage(reader.getPage(page)) s = cStringIO.StringIO() output.write(s) return s.getvalue(), results[0][1] return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
def get_config_warning(self, cr, msg, context=None): """ Helper: return a Warning exception with the given message where the %(field:xxx)s and/or %(menu:yyy)s are replaced by the human readable field's name and/or menuitem's full path. Usage: ------ Just include in your error message %(field:model_name.field_name)s to obtain the human readable field's name, and/or %(menu:module_name.menuitem_xml_id)s to obtain the menuitem's full path. Example of use: --------------- from ecore.addons.base.res.res_config import get_warning_config raise get_warning_config(cr, _("Error: this action is prohibited. You should check the field %(field:sale.config.settings.fetchmail_lead)s in %(menu:base.menu_sale_config)s."), context=context) This will return an exception containing the following message: Error: this action is prohibited. You should check the field Create leads from incoming mails in Settings/Configuration/Sales. What if there is another substitution in the message already? ------------------------------------------------------------- You could have a situation where the error message you want to upgrade already contains a substitution. Example: Cannot find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration\Journals\Journals. What you want to do here is simply to replace the path by %menu:account.menu_account_config)s, and leave the rest alone. In order to do that, you can use the double percent (%%) to escape your new substitution, like so: Cannot find any account journal of %s type for this company.\n\nYou can create one in the %%(menu:account.menu_account_config)s. """ res_config_obj = ecore.registry(cr.dbname)['res.config.settings'] regex_path = r'%\(((?:menu|field):[a-z_\.]*)\)s' # Process the message # 1/ find the menu and/or field references, put them in a list references = re.findall(regex_path, msg, flags=re.I) # 2/ fetch the menu and/or field replacement values (full path and # human readable field's name) and the action_id if any values = {} action_id = None for item in references: ref_type, ref = item.split(':') if ref_type == 'menu': values[item], action_id = res_config_obj.get_option_path( cr, SUPERUSER_ID, ref, context=context) elif ref_type == 'field': values[item] = res_config_obj.get_option_name(cr, SUPERUSER_ID, ref, context=context) # 3/ substitute and return the result if (action_id): return exceptions.RedirectWarning( msg % values, action_id, _('Go to the configuration panel')) return exceptions.UserError(msg % values)
def load_language(cr, lang): """Loads a translation terms for a language. Used mainly to automate language loading at db initialization. :param lang: language ISO code with optional _underscore_ and l10n flavor (ex: 'fr', 'fr_BE', but not 'fr-BE') :type lang: str """ registry = ecore.registry(cr.dbname) language_installer = registry['base.language.install'] oid = language_installer.create(cr, SUPERUSER_ID, {'lang': lang}) language_installer.lang_install(cr, SUPERUSER_ID, [oid], context=None)
def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init', noupdate=False): '''Import csv file : quote: " delimiter: , encoding: utf-8''' if not idref: idref={} model = ('.'.join(fname.split('.')[:-1]).split('-'))[0] #remove folder path from model head, model = os.path.split(model) input = cStringIO.StringIO(csvcontent) #FIXME reader = csv.reader(input, quotechar='"', delimiter=',') fields = reader.next() fname_partial = "" if config.get('import_partial'): fname_partial = module + '/'+ fname if not os.path.isfile(config.get('import_partial')): pickle.dump({}, file(config.get('import_partial'),'w+')) else: data = pickle.load(file(config.get('import_partial'))) if fname_partial in data: if not data[fname_partial]: return else: for i in range(data[fname_partial]): reader.next() if not (mode == 'init' or 'id' in fields): _logger.error("Import specification does not contain 'id' and we are in init mode, Cannot continue.") return uid = 1 datas = [] for line in reader: if not (line and any(line)): continue try: datas.append(map(misc.ustr, line)) except: _logger.error("Cannot import the line: %s", line) registry = ecore.registry(cr.dbname) result, rows, warning_msg, dummy = registry[model].import_data(cr, uid, fields, datas,mode, module, noupdate, filename=fname_partial) if result < 0: # Report failed import and abort module install raise Exception(_('Module loading %s failed: file %s could not be processed:\n %s') % (module, fname, warning_msg)) if config.get('import_partial'): data = pickle.load(file(config.get('import_partial'))) data[fname_partial] = 0 pickle.dump(data, file(config.get('import_partial'),'wb')) cr.commit()
def execute(db, uid, obj, method, *args, **kw): threading.currentThread().dbname = db with ecore.registry(db).cursor() as cr: if method.startswith('_'): raise UserError( _('Private methods (such as %s) cannot be called remotely.') % (method, )) res = execute_cr(cr, uid, obj, method, *args, **kw) if res is None: _logger.info( 'The method %s of the object %s can not return `None` !', method, obj) return res
def receive(self, req): """ End-point to receive mail from an external SMTP server. """ dbs = req.jsonrequest.get('databases') for db in dbs: message = dbs[db].decode('base64') try: registry = ecore.registry(db) with registry.cursor() as cr: mail_thread = registry['mail.thread'] mail_thread.message_process(cr, SUPERUSER_ID, None, message) except psycopg2.Error: pass return True
def get_config_warning(self, cr, msg, context=None): """ Helper: return a Warning exception with the given message where the %(field:xxx)s and/or %(menu:yyy)s are replaced by the human readable field's name and/or menuitem's full path. Usage: ------ Just include in your error message %(field:model_name.field_name)s to obtain the human readable field's name, and/or %(menu:module_name.menuitem_xml_id)s to obtain the menuitem's full path. Example of use: --------------- from ecore.addons.base.res.res_config import get_warning_config raise get_warning_config(cr, _("Error: this action is prohibited. You should check the field %(field:sale.config.settings.fetchmail_lead)s in %(menu:base.menu_sale_config)s."), context=context) This will return an exception containing the following message: Error: this action is prohibited. You should check the field Create leads from incoming mails in Settings/Configuration/Sales. What if there is another substitution in the message already? ------------------------------------------------------------- You could have a situation where the error message you want to upgrade already contains a substitution. Example: Cannot find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration\Journals\Journals. What you want to do here is simply to replace the path by %menu:account.menu_account_config)s, and leave the rest alone. In order to do that, you can use the double percent (%%) to escape your new substitution, like so: Cannot find any account journal of %s type for this company.\n\nYou can create one in the %%(menu:account.menu_account_config)s. """ res_config_obj = ecore.registry(cr.dbname)['res.config.settings'] regex_path = r'%\(((?:menu|field):[a-z_\.]*)\)s' # Process the message # 1/ find the menu and/or field references, put them in a list references = re.findall(regex_path, msg, flags=re.I) # 2/ fetch the menu and/or field replacement values (full path and # human readable field's name) and the action_id if any values = {} action_id = None for item in references: ref_type, ref = item.split(':') if ref_type == 'menu': values[item], action_id = res_config_obj.get_option_path(cr, SUPERUSER_ID, ref, context=context) elif ref_type == 'field': values[item] = res_config_obj.get_option_name(cr, SUPERUSER_ID, ref, context=context) # 3/ substitute and return the result if (action_id): return exceptions.RedirectWarning(msg % values, action_id, _('Go to the configuration panel')) return exceptions.UserError(msg % values)
def wkf_expr_execute_action(self, activity): """ Evaluate the ir.actions.server action specified in the activity. """ context = { 'active_model': self.record.model, 'active_id': self.record.id, 'active_ids': [self.record.id] } ir_actions_server = ecore.registry(self.session.cr.dbname)['ir.actions.server'] result = ir_actions_server.run(self.session.cr, self.session.uid, [activity['action_id']], context) return result
def create(self, cr, uid, ids, datas, context=None): if not context: context={} datas['ids'] = ids registry = ecore.registry(cr.dbname) model = registry[datas['model']] # title come from description of model which are specified in py file. self.title = model._description result = model.fields_view_get(cr, uid, view_type='form', context=context) fields_order = self._parse_string(result['arch']) rows = model.read(cr, uid, datas['ids'], result['fields'].keys() ) self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model._description) return self.obj.get(), 'pdf'
def create(self, cr, uid, ids, data, context=None): context = dict(context or {}) if self.internal_header: context.update(internal_header=self.internal_header) # skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases context.update(bin_raw=True) registry = ecore.registry(cr.dbname) ir_obj = registry['ir.actions.report.xml'] registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context) report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context) else: title = '' report_file = tools.file_open(self.tmpl, subdir=None) try: rml = report_file.read() report_type= data.get('report_type', 'pdf') class a(object): def __init__(self, *args, **argv): for key,arg in argv.items(): setattr(self, key, arg) report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header) finally: report_file.close() # We add an attribute on the ir.actions.report.xml instance. # This attribute 'use_global_header' will be used by # the create_single_XXX function of the report engine. # This change has been done to avoid a big change of the API. setattr(report_xml, 'use_global_header', self.header if report_xml.header else False) report_type = report_xml.report_type if report_type in ['sxw','odt']: fnct = self.create_source_odt elif report_type in ['pdf','raw','txt','html']: fnct = self.create_source_pdf elif report_type=='html2html': fnct = self.create_source_html2html elif report_type=='mako2html': fnct = self.create_source_mako2html else: raise NotImplementedError(_('Unknown report type: %s') % report_type) fnct_ret = fnct(cr, uid, ids, data, report_xml, context) if not fnct_ret: return False, False return fnct_ret
def calc_date(self, cr, uid, context=None): """Compute the limit date for a given date""" if context is None: context = {} if not context.get('product_id', False): date = False else: product = ecore.registry(cr.dbname)['product.product'].browse( cr, uid, context['product_id']) duration = getattr(product, dtype) # set date to False when no expiry time specified on the product date = duration and (datetime.datetime.today() + datetime.timedelta(days=duration)) return date and date.strftime('%Y-%m-%d %H:%M:%S') or False
def wkf_expr_execute_action(self, activity): """ Evaluate the ir.actions.server action specified in the activity. """ context = { 'active_model': self.record.model, 'active_id': self.record.id, 'active_ids': [self.record.id] } ir_actions_server = ecore.registry( self.session.cr.dbname)['ir.actions.server'] result = ir_actions_server.run(self.session.cr, self.session.uid, [activity['action_id']], context) return result
def create(self, cr, uid, ids, datas, context): registry = ecore.registry(cr.dbname) xml = self.create_xml(cr, uid, ids, datas, context) xml = tools.ustr(xml).encode('utf8') report_type = datas.get('report_type', 'pdf') if report_type == 'raw': return xml, report_type registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context) rml = self.create_rml(cr, xml, uid, context) ir_actions_report_xml_obj = registry['ir.actions.report.xml'] report_xml_ids = ir_actions_report_xml_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'eCore Report' create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) return pdf, report_type
def run_scheduler(self, cr, uid, use_new_cursor=False, company_id=False, context=None): ''' Call the scheduler in order to check the running procurements (super method), to check the minimum stock rules and the availability of moves. This function is intended to be run for all the companies at the same time, so we run functions as SUPERUSER to avoid intercompanies and access rights issues. @param self: The object pointer @param cr: The current row, from the database cursor, @param uid: The current user ID for security checks @param ids: List of selected IDs @param use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement. This is appropriate for batch jobs only. @param context: A standard dictionary for contextual values @return: Dictionary of values ''' super(procurement_order, self).run_scheduler(cr, uid, use_new_cursor=use_new_cursor, company_id=company_id, context=context) if context is None: context = {} try: if use_new_cursor: cr = ecore.registry(cr.dbname).cursor() move_obj = self.pool.get('stock.move') #Minimum stock rules self._procure_orderpoint_confirm(cr, SUPERUSER_ID, use_new_cursor=use_new_cursor, company_id=company_id, context=context) #Search all confirmed stock_moves and try to assign them confirmed_ids = move_obj.search(cr, uid, [('state', '=', 'confirmed')], limit=None, order='priority desc, date_expected asc', context=context) for x in xrange(0, len(confirmed_ids), 100): move_obj.action_assign(cr, uid, confirmed_ids[x:x + 100], context=context) if use_new_cursor: cr.commit() if use_new_cursor: cr.commit() finally: if use_new_cursor: try: cr.close() except Exception: pass return {}
def wkf_expr_check(self, transition, signal): """ Test if a transition can be taken. The transition can be taken if: - the signal name matches, - the uid is SUPERUSER_ID or the user groups contains the transition's group, - the condition evaluates to a truish value. """ if transition['signal'] and signal != transition['signal']: return False if self.session.uid != ecore.SUPERUSER_ID and transition['group_id']: registry = ecore.registry(self.session.cr.dbname) user_groups = registry['res.users'].read(self.session.cr, self.session.uid, [self.session.uid], ['groups_id'])[0]['groups_id'] if transition['group_id'] not in user_groups: return False return self.wkf_expr_eval_expr(transition['condition'])
def __init__(self, cr, uid, name, parents=rml_parents, tag=rml_tag, context=None): if not context: context = {} self.cr = cr self.uid = uid self.pool = ecore.registry(cr.dbname) user = self.pool['res.users'].browse(cr, uid, uid, context=context) self.localcontext = { 'user': user, 'setCompany': self.setCompany, 'repeatIn': self.repeatIn, 'setLang': self.setLang, 'setTag': self.setTag, 'removeParentNode': self.removeParentNode, 'format': self.format, 'formatLang': self.formatLang, 'lang': user.company_id.partner_id.lang, 'translate': self._translate, 'setHtmlImage': self.set_html_image, 'strip_name': self._strip_name, 'time': time, 'display_address': self.display_address, # more context members are setup in setCompany() below: # - company_id # - logo } self.setCompany(user.company_id) self.localcontext.update(context) self.name = name self._node = None self.parents = parents self.tag = tag self._lang_cache = {} self.lang_dict = {} self.default_lang = {} self.lang_dict_called = False self._transl_regex = re.compile('(\[\[.+?\]\])')
def exp_render_report(db, uid, object, ids, datas=None, context=None): if not datas: datas = {} if not context: context = {} self_id_protect.acquire() global self_id self_id += 1 id = self_id self_id_protect.release() self_reports[id] = { 'uid': uid, 'result': False, 'state': False, 'exception': None } cr = ecore.registry(db).cursor() try: result, format = ecore.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException( 'RML is not available at specified location or not enough data to print!', tb) self_reports[id]['result'] = result self_reports[id]['format'] = format self_reports[id]['state'] = True except Exception, exception: _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self_reports[id]['exception'] = ecore.exceptions.DeferredException( tools.ustr(exception.name), tools.ustr(exception.value)) else: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException( tools.exception_to_unicode(exception), tb) self_reports[id]['state'] = True
def __init__(self, cr, module, id_map, mode, filename, report=None, noupdate=False, loglevel=logging.DEBUG): self.cr = cr self.module = module self.id_map = id_map self.mode = mode self.filename = filename if report is None: report = assertion_report.assertion_report() self.assertion_report = report self.noupdate = noupdate self.loglevel = loglevel self.pool = ecore.registry(cr.dbname) self.uid = 1 self.context = {} # opererp context self.eval_context = {'ref': self._ref(), '_ref': self._ref(), # added '_ref' so that record['ref'] is possible 'time': time, 'datetime': datetime, 'timedelta': timedelta} self.env = ecore.api.Environment(self.cr, self.uid, self.context)
def create(self, cursor, uid, ids, data, context=None): """We override the create function in order to handle generator Code taken from report openoffice. Thanks guys :) """ pool = ecore.registry(cursor.dbname) ir_obj = pool['ir.actions.report.xml'] report_xml_ids = ir_obj.search(cursor, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: report_xml = ir_obj.browse(cursor, uid, report_xml_ids[0], context=context) else: return super(WebKitParser, self).create(cursor, uid, ids, data, context) setattr(report_xml, 'use_global_header', self.header if report_xml.header else False) if report_xml.report_type != 'webkit': return super(WebKitParser, self).create(cursor, uid, ids, data, context) result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context) if not result: return (False,False) return result
def go(id, uid, ids, datas, context): with ecore.api.Environment.manage(): cr = ecore.registry(db).cursor() try: result, format = ecore.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) self_reports[id]['result'] = result self_reports[id]['format'] = format self_reports[id]['state'] = True except Exception, exception: _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self_reports[id]['exception'] = ecore.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: tb = sys.exc_info() self_reports[id]['exception'] = ecore.exceptions.DeferredException(tools.exception_to_unicode(exception), tb) self_reports[id]['state'] = True cr.commit() cr.close()
def wkf_expr_check(self, transition, signal): """ Test if a transition can be taken. The transition can be taken if: - the signal name matches, - the uid is SUPERUSER_ID or the user groups contains the transition's group, - the condition evaluates to a truish value. """ if transition['signal'] and signal != transition['signal']: return False if self.session.uid != ecore.SUPERUSER_ID and transition['group_id']: registry = ecore.registry(self.session.cr.dbname) user_groups = registry['res.users'].read( self.session.cr, self.session.uid, [self.session.uid], ['groups_id'])[0]['groups_id'] if transition['group_id'] not in user_groups: return False return self.wkf_expr_eval_expr(transition['condition'])
def create(self, cr, uid, ids, datas, context): registry = ecore.registry(cr.dbname) xml = self.create_xml(cr, uid, ids, datas, context) xml = tools.ustr(xml).encode('utf8') report_type = datas.get('report_type', 'pdf') if report_type == 'raw': return xml, report_type registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context) rml = self.create_rml(cr, xml, uid, context) ir_actions_report_xml_obj = registry['ir.actions.report.xml'] report_xml_ids = ir_actions_report_xml_obj.search( cr, uid, [('report_name', '=', self.name[7:])], context=context) self.title = report_xml_ids and ir_actions_report_xml_obj.browse( cr, uid, report_xml_ids)[0].name or 'eCore Report' create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) return pdf, report_type
def __init__(self, cr, uid, name, parents=rml_parents, tag=rml_tag, context=None): if not context: context={} self.cr = cr self.uid = uid self.pool = ecore.registry(cr.dbname) user = self.pool['res.users'].browse(cr, uid, uid, context=context) self.localcontext = { 'user': user, 'setCompany': self.setCompany, 'repeatIn': self.repeatIn, 'setLang': self.setLang, 'setTag': self.setTag, 'removeParentNode': self.removeParentNode, 'format': self.format, 'formatLang': self.formatLang, 'lang' : user.company_id.partner_id.lang, 'translate' : self._translate, 'setHtmlImage' : self.set_html_image, 'strip_name' : self._strip_name, 'time' : time, 'display_address': self.display_address, # more context members are setup in setCompany() below: # - company_id # - logo } self.setCompany(user.company_id) self.localcontext.update(context) self.name = name self._node = None self.parents = parents self.tag = tag self._lang_cache = {} self.lang_dict = {} self.default_lang = {} self.lang_dict_called = False self._transl_regex = re.compile('(\[\[.+?\]\])')
def run_scheduler(self, cr, uid, use_new_cursor=False, company_id=False, context=None): ''' Call the scheduler in order to check the running procurements (super method), to check the minimum stock rules and the availability of moves. This function is intended to be run for all the companies at the same time, so we run functions as SUPERUSER to avoid intercompanies and access rights issues. @param self: The object pointer @param cr: The current row, from the database cursor, @param uid: The current user ID for security checks @param ids: List of selected IDs @param use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement. This is appropriate for batch jobs only. @param context: A standard dictionary for contextual values @return: Dictionary of values ''' super(procurement_order, self).run_scheduler(cr, uid, use_new_cursor=use_new_cursor, company_id=company_id, context=context) if context is None: context = {} try: if use_new_cursor: cr = ecore.registry(cr.dbname).cursor() move_obj = self.pool.get('stock.move') #Minimum stock rules self._procure_orderpoint_confirm(cr, SUPERUSER_ID, use_new_cursor=use_new_cursor, company_id=company_id, context=context) #Search all confirmed stock_moves and try to assign them confirmed_ids = move_obj.search( cr, uid, [('state', '=', 'confirmed')], limit=None, order='priority desc, date_expected asc', context=context) for x in xrange(0, len(confirmed_ids), 100): move_obj.action_assign(cr, uid, confirmed_ids[x:x + 100], context=context) if use_new_cursor: cr.commit() if use_new_cursor: cr.commit() finally: if use_new_cursor: try: cr.close() except Exception: pass return {}
def _procure_orderpoint_confirm(self, cr, uid, use_new_cursor=False, company_id=False, context=None): ''' Create procurement based on Orderpoint :param bool use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement. This is appropriate for batch jobs only. ''' if context is None: context = {} if use_new_cursor: cr = ecore.registry(cr.dbname).cursor() orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') procurement_obj = self.pool.get('procurement.order') product_obj = self.pool.get('product.product') dom = company_id and [('company_id', '=', company_id)] or [] orderpoint_ids = orderpoint_obj.search(cr, uid, dom, order="location_id") prev_ids = [] tot_procs = [] while orderpoint_ids: ids = orderpoint_ids[:1000] del orderpoint_ids[:1000] product_dict = {} ops_dict = {} ops = orderpoint_obj.browse(cr, uid, ids, context=context) #Calculate groups that can be executed together for op in ops: key = (op.location_id.id, ) if not product_dict.get(key): product_dict[key] = [op.product_id] ops_dict[key] = [op] else: product_dict[key] += [op.product_id] ops_dict[key] += [op] for key in product_dict.keys(): ctx = context.copy() ctx.update({'location': ops_dict[key][0].location_id.id}) prod_qty = product_obj._product_available( cr, uid, [x.id for x in product_dict[key]], context=ctx) subtract_qty = orderpoint_obj.subtract_procurements_from_orderpoints( cr, uid, [x.id for x in ops_dict[key]], context=context) for op in ops_dict[key]: try: prods = prod_qty[op.product_id.id]['virtual_available'] if prods is None: continue if float_compare(prods, op.product_min_qty, precision_rounding=op.product_uom. rounding) <= 0: qty = max(op.product_min_qty, op.product_max_qty) - prods reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0 if float_compare(reste, 0.0, precision_rounding=op.product_uom. rounding) > 0: qty += op.qty_multiple - reste if float_compare(qty, 0.0, precision_rounding=op.product_uom. rounding) < 0: continue qty -= subtract_qty[op.id] qty_rounded = float_round( qty, precision_rounding=op.product_uom.rounding) if qty_rounded > 0: proc_id = procurement_obj.create( cr, uid, self._prepare_orderpoint_procurement( cr, uid, op, qty_rounded, context=context), context=context) tot_procs.append(proc_id) if use_new_cursor: cr.commit() except OperationalError: if use_new_cursor: orderpoint_ids.append(op.id) cr.rollback() continue else: raise try: tot_procs.reverse() self.run(cr, uid, tot_procs, context=context) tot_procs = [] if use_new_cursor: cr.commit() except OperationalError: if use_new_cursor: cr.rollback() continue else: raise if use_new_cursor: cr.commit() if prev_ids == ids: break else: prev_ids = ids if use_new_cursor: cr.commit() cr.close() return {}
def create_rml(self, cr, xml, uid, context=None): if self.tmpl == '' and not self.internal_header: self.internal_header = True if not context: context = {} registry = ecore.registry(cr.dbname) ir_translation_obj = registry['ir.translation'] # In some case we might not use xsl ... if not self.xsl: return xml stylesheet_file = tools.file_open(self.xsl) try: stylesheet = etree.parse(stylesheet_file) xsl_path, _ = os.path.split(self.xsl) for import_child in stylesheet.findall('./import'): if 'href' in import_child.attrib: imp_file = import_child.get('href') _, imp_file = tools.file_open(imp_file, subdir=xsl_path, pathinfo=True) import_child.set('href', urllib.quote(str(imp_file))) imp_file.close() finally: stylesheet_file.close() #TODO: get all the translation in one query. That means we have to: # * build a list of items to translate, # * issue the query to translate them, # * (re)build/update the stylesheet with the translated items def translate(doc, lang): translate_aux(doc, lang, False) def translate_aux(doc, lang, t): for node in doc: t = t or node.get("t") if t: text = None tail = None if node.text: text = node.text.strip().replace('\n', ' ') if node.tail: tail = node.tail.strip().replace('\n', ' ') if text: translation1 = ir_translation_obj._get_source( cr, uid, self.name2, 'xsl', lang, text) if translation1: node.text = node.text.replace(text, translation1) if tail: translation2 = ir_translation_obj._get_source( cr, uid, self.name2, 'xsl', lang, tail) if translation2: node.tail = node.tail.replace(tail, translation2) translate_aux(node, lang, t) if context.get('lang', False): translate(stylesheet.iter(), context['lang']) transform = etree.XSLT(stylesheet) xml = etree.tostring(transform(etree.fromstring(xml))) return xml
def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, wiz_data=None, wiz_buttons=None, context=None, our_module=None): """Take an ir.action.act_window and follow it until a report is produced :param action_id: the integer id of an action, or a reference to xml id of the act_window (can search [our_module.]+xml_id :param active_model, active_ids: call the action as if it had been launched from that model+ids (tree/form view action) :param wiz_data: a dictionary of values to use in the wizard, if needed. They will override (or complete) the default values of the wizard form. :param wiz_buttons: a list of button names, or button icon strings, which should be preferred to press during the wizard. Eg. 'OK' or 'gtk-print' :param our_module: the name of the calling module (string), like 'account' """ if not our_module and isinstance(action_id, basestring): if '.' in action_id: our_module = action_id.split('.', 1)[0] if context is None: context = {} else: context = context.copy() # keep it local # TODO context fill-up registry = ecore.registry(cr.dbname) def log_test(msg, *args): _test_logger.info(" - " + msg, *args) datas = {} if active_model: datas['model'] = active_model if active_ids: datas['ids'] = active_ids if not wiz_buttons: wiz_buttons = [] if isinstance(action_id, basestring): if '.' in action_id: act_module, act_xmlid = action_id.split('.', 1) else: if not our_module: raise ValueError( 'You cannot only specify action_id "%s" without a module name' % action_id) act_module = our_module act_xmlid = action_id act_model, act_id = registry['ir.model.data'].get_object_reference( cr, uid, act_module, act_xmlid) else: assert isinstance(action_id, (long, int)) act_model = 'ir.action.act_window' # assume that act_id = action_id act_xmlid = '<%s>' % act_id def _exec_action(action, datas, context): # taken from client/modules/action/main.py:84 _exec_action() if isinstance(action, bool) or 'type' not in action: return # Updating the context : Adding the context of action in order to use it on Views called from buttons if datas.get('id', False): context.update({ 'active_id': datas.get('id', False), 'active_ids': datas.get('ids', []), 'active_model': datas.get('model', False) }) context1 = action.get('context', {}) if isinstance(context1, basestring): context1 = safe_eval(context1, context.copy()) context.update(context1) if action['type'] in ['ir.actions.act_window', 'ir.actions.submenu']: for key in ('res_id', 'res_model', 'view_type', 'view_mode', 'limit', 'auto_refresh', 'search_view', 'auto_search', 'search_view_id'): datas[key] = action.get(key, datas.get(key, None)) view_id = False if action.get('views', []): if isinstance(action['views'], list): view_id = action['views'][0][0] datas['view_mode'] = action['views'][0][1] else: if action.get('view_id', False): view_id = action['view_id'][0] elif action.get('view_id', False): view_id = action['view_id'][0] assert datas['res_model'], "Cannot use the view without a model" # Here, we have a view that we need to emulate log_test("will emulate a %s view: %s#%s", action['view_type'], datas['res_model'], view_id or '?') view_res = registry[datas['res_model']].fields_view_get( cr, uid, view_id, action['view_type'], context) assert view_res and view_res.get( 'arch'), "Did not return any arch for the view" view_data = {} if view_res.get('fields', {}).keys(): view_data = registry[datas['res_model']].default_get( cr, uid, view_res['fields'].keys(), context) if datas.get('form'): view_data.update(datas.get('form')) if wiz_data: view_data.update(wiz_data) _logger.debug("View data is: %r", view_data) for fk, field in view_res.get('fields', {}).items(): # Default fields returns list of int, while at create() # we need to send a [(6,0,[int,..])] if field['type'] in ('one2many', 'many2many') \ and view_data.get(fk, False) \ and isinstance(view_data[fk], list) \ and not isinstance(view_data[fk][0], tuple) : view_data[fk] = [(6, 0, view_data[fk])] action_name = action.get('name') try: from xml.dom import minidom cancel_found = False buttons = [] dom_doc = minidom.parseString(view_res['arch']) if not action_name: action_name = dom_doc.documentElement.getAttribute('name') for button in dom_doc.getElementsByTagName('button'): button_weight = 0 if button.getAttribute('special') == 'cancel': cancel_found = True continue if button.getAttribute('icon') == 'gtk-cancel': cancel_found = True continue if button.getAttribute('default_focus') == '1': button_weight += 20 if button.getAttribute('string') in wiz_buttons: button_weight += 30 elif button.getAttribute('icon') in wiz_buttons: button_weight += 10 string = button.getAttribute( 'string') or '?%s' % len(buttons) buttons.append({ 'name': button.getAttribute('name'), 'string': string, 'type': button.getAttribute('type'), 'weight': button_weight, }) except Exception, e: _logger.warning( "Cannot resolve the view arch and locate the buttons!", exc_info=True) raise AssertionError(e.args[0]) if not datas['res_id']: # it is probably an orm_memory object, we need to create # an instance datas['res_id'] = registry[datas['res_model']].create( cr, uid, view_data, context) if not buttons: raise AssertionError( "view form doesn't have any buttons to press!") buttons.sort(key=lambda b: b['weight']) _logger.debug( 'Buttons are: %s', ', '.join( ['%s: %d' % (b['string'], b['weight']) for b in buttons])) res = None while buttons and not res: b = buttons.pop() log_test("in the \"%s\" form, I will press the \"%s\" button.", action_name, b['string']) if not b['type']: log_test("the \"%s\" button has no type, cannot use it", b['string']) continue if b['type'] == 'object': #there we are! press the button! fn = getattr(registry[datas['res_model']], b['name']) if not fn: _logger.error( "The %s model doesn't have a %s attribute!", datas['res_model'], b['name']) continue res = fn(cr, uid, [ datas['res_id'], ], context) break else: _logger.warning( "in the \"%s\" form, the \"%s\" button has unknown type %s", action_name, b['string'], b['type']) return res elif action['type'] == 'ir.actions.report.xml': if 'window' in datas: del datas['window'] if not datas: datas = action.get('datas') if not datas: datas = action.get('data') datas = datas.copy() ids = datas.get('ids') if 'ids' in datas: del datas['ids'] res = try_report(cr, uid, 'report.' + action['report_name'], ids, datas, context, our_module=our_module) return res
def _create_bars(self, cr, uid, ids, report, fields, results, context): pool = ecore.registry(cr.dbname) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') can.show(80,380,'/16/H'+report['title']) process_date = { 'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]), 'M': lambda x: x.split('-')[1], 'Y': lambda x: x.split('-')[0] } order_date = { 'D': lambda x: time.mktime((2005, int(x.split('-')[0]), int(x.split('-')[1]), 0, 0, 0, 0, 0, 0)), 'M': lambda x: x, 'Y': lambda x: x } ar = area.T(size=(350,350), x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"), y_axis = axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:])))) idx = 0 date_idx = None fct = {} for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype']) if type[0]['ttype'] == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] else: fct[idx] = lambda x : x else: fct[idx] = lambda x : x idx+=1 # plot are usually displayed year by year # so we do so if the first field is a date data_by_year = {} if date_idx is not None: for r in results: key = process_date['Y'](r[date_idx]) if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) data_by_year[key].append(r) else: data_by_year[''] = results nb_bar = len(data_by_year)*(len(fields)-1) colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(nb_bar)) abscissa = {} for line in data_by_year.keys(): fields_bar = [] # sum data and save it in a list. An item for a fields for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] data_cum = [] prev = 0.0 keys = data.keys() keys.sort() # cumulate if necessary for k in keys: data_cum.append([k, float(data[k])+float(prev)]) if fields[idx+1]['cumulate']: prev += data[k] idx0 = 0 plot = bar_plot.T(label=fields[idx+1]['name']+' '+str(line), data = data_cum, cluster=(idx0*(len(fields)-1)+idx,nb_bar), fill_style=colors[idx0*(len(fields)-1)+idx]) ar.add_plot(plot) abscissa.update(fields_bar[idx]) idx0 += 1 abscissa = map(lambda x : [x, None], abscissa) abscissa.sort() ar.x_coord = category_coord.T(abscissa,0) ar.draw(can) can.close() self.obj = external_pdf(pdf_string.getvalue()) self.obj.render() pdf_string.close() return True
def login(db, login, password): res_users = ecore.registry(db)['res.users'] return res_users._login(db, login, password)
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None): """generate the PDF""" # just try to find an xml id for the report cr = cursor pool = ecore.registry(cr.dbname) found_xml_ids = pool["ir.model.data"].search(cr, uid, [["model", "=", "ir.actions.report.xml"], \ ["res_id", "=", report_xml.id]], context=context) xml_id = None if found_xml_ids: xml_id = pool["ir.model.data"].read(cr, uid, found_xml_ids[0], ["module", "name"]) xml_id = "%s.%s" % (xml_id["module"], xml_id["name"]) if context is None: context={} htmls = [] if report_xml.report_type != 'webkit': return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context) parser_instance = self.parser(cursor, uid, self.name2, context=context) self.pool = pool objs = self.getObjects(cursor, uid, ids, context) parser_instance.set_context(objs, data, ids, report_xml.report_type) template = False if report_xml.report_file : path = get_module_resource(*report_xml.report_file.split('/')) if path and os.path.exists(path) : template = file(path).read() if not template and report_xml.report_webkit_data : template = report_xml.report_webkit_data if not template : raise UserError(_('Webkit report template not found!')) header = report_xml.webkit_header.html footer = report_xml.webkit_header.footer_html if not header and report_xml.use_global_header: raise UserError(_('No header defined for this Webkit report!') + " " + _('Please set a header in company settings.')) if not report_xml.use_global_header : header = '' default_head = get_module_resource('report_webkit', 'default_header.html') with open(default_head,'r') as f: header = f.read() css = report_xml.webkit_header.css if not css : css = '' translate_call = partial(self.translate_call, parser_instance) body_mako_tpl = mako_template(template) helper = WebKitHelper(cursor, uid, report_xml.id, context) parser_instance.localcontext['helper'] = helper parser_instance.localcontext['css'] = css parser_instance.localcontext['_'] = translate_call # apply extender functions additional = {} if xml_id in _extender_functions: for fct in _extender_functions[xml_id]: fct(pool, cr, uid, parser_instance.localcontext, context) if report_xml.precise_mode: ctx = dict(parser_instance.localcontext) for obj in parser_instance.localcontext['objects']: ctx['objects'] = [obj] try : html = body_mako_tpl.render(dict(ctx)) htmls.append(html) except Exception, e: msg = u"%s" % e _logger.info(msg, exc_info=True) raise UserError(msg)
def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False, attachments=None, message_id=None, references=None, openobject_id=False, debug=False, subtype='plain', headers=None, smtp_server=None, smtp_port=None, ssl=False, smtp_user=None, smtp_password=None, cr=None, uid=None): """Low-level function for sending an email (deprecated). :deprecate: since eCore 6.1, please use ir.mail_server.send_email() instead. :param email_from: A string used to fill the `From` header, if falsy, config['email_from'] is used instead. Also used for the `Reply-To` header if `reply_to` is not provided :param email_to: a sequence of addresses to send the mail to. """ # If not cr, get cr from current thread database local_cr = None if not cr: db_name = getattr(threading.currentThread(), 'dbname', None) if db_name: local_cr = cr = ecore.registry(db_name).cursor() else: raise Exception( "No database cursor found, please pass one explicitly") # Send Email try: mail_server_pool = ecore.registry(cr.dbname)['ir.mail_server'] res = False # Pack Message into MIME Object email_msg = mail_server_pool.build_email(email_from, email_to, subject, body, email_cc, email_bcc, reply_to, attachments, message_id, references, openobject_id, subtype, headers=headers) res = mail_server_pool.send_email( cr, uid or 1, email_msg, mail_server_id=None, smtp_server=smtp_server, smtp_port=smtp_port, smtp_user=smtp_user, smtp_password=smtp_password, smtp_encryption=('ssl' if ssl else None), smtp_debug=debug) except Exception: _logger.exception("tools.email_send failed to deliver email") return False finally: if local_cr: cr.close() return res
def run_scheduler(self, cr, uid, use_new_cursor=False, company_id=False, context=None): ''' Call the scheduler to check the procurement order. This is intented to be done for all existing companies at the same time, so we're running all the methods as SUPERUSER to avoid intercompany and access rights issues. @param self: The object pointer @param cr: The current row, from the database cursor, @param uid: The current user ID for security checks @param ids: List of selected IDs @param use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement. This is appropriate for batch jobs only. @param context: A standard dictionary for contextual values @return: Dictionary of values ''' if context is None: context = {} try: if use_new_cursor: cr = ecore.registry(cr.dbname).cursor() # Run confirmed procurements dom = [('state', '=', 'confirmed')] if company_id: dom += [('company_id', '=', company_id)] prev_ids = [] while True: ids = self.search(cr, SUPERUSER_ID, dom, context=context) if not ids or prev_ids == ids: break else: prev_ids = ids self.run(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context) if use_new_cursor: cr.commit() # Check if running procurements are done offset = 0 dom = [('state', '=', 'running')] if company_id: dom += [('company_id', '=', company_id)] prev_ids = [] while True: ids = self.search(cr, SUPERUSER_ID, dom, offset=offset, context=context) if not ids or prev_ids == ids: break else: prev_ids = ids self.check(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context) if use_new_cursor: cr.commit() finally: if use_new_cursor: try: cr.close() except Exception: pass return {}
def create(self, cr, uid, ids, datas, context=None): if not context: context={} self.pool = ecore.registry(cr.dbname) report = self.pool['ir.report.custom'].browse(cr, uid, [datas['report_id']])[0] datas['model'] = report.model_id.model if report.menu_id: ids = self.pool[report.model_id.model].search(cr, uid, []) datas['ids'] = ids report_id = datas['report_id'] report = self.pool['ir.report.custom'].read(cr, uid, [report_id], context=context)[0] fields = self.pool['ir.report.custom.fields'].read(cr, uid, report['fields_child0'], context=context) fields.sort(lambda x,y : x['sequence'] - y['sequence']) if report['field_parent']: parent_field = self.pool['ir.model.fields'].read(cr, uid, [report['field_parent'][0]], ['model']) model_name = self.pool['ir.model'].read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model'] fct = { 'id': lambda x: x, 'gety': lambda x: x.split('-')[0], 'in': lambda x: x.split(',') } new_fields = [] new_cond = [] for f in fields: row = [] cond = [] for i in range(4): field_child = f['field_child'+str(i)] if field_child: row.append( self.pool['ir.model.fields'].read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name'] ) if f['fc'+str(i)+'_operande']: fct_name = 'id' cond_op = f['fc'+str(i)+'_op'] if len(f['fc'+str(i)+'_op'].split(',')) == 2: cond_op = f['fc'+str(i)+'_op'].split(',')[1] fct_name = f['fc'+str(i)+'_op'].split(',')[0] cond.append((fct[fct_name], f['fc'+str(i)+'_operande'][1], cond_op, f['fc'+str(i)+'_condition'])) else: cond.append(None) new_fields.append(row) new_cond.append(cond) objs = self.pool[model_name].browse(cr, uid, ids) # Group by groupby = None idx = 0 for f in fields: if f['groupby']: groupby = idx idx += 1 results = [] if report['field_parent']: level = [] def build_tree(obj, level, depth): res = self._row_get(cr, uid,[obj], new_fields, new_cond) level.append(depth) new_obj = eval('obj.'+report['field_parent'][1],{'obj': obj}) if not isinstance(new_obj, list) : new_obj = [new_obj] for o in new_obj: if o: res += build_tree(o, level, depth+1) return res for obj in objs: results += build_tree(obj, level, 0) else: results = self._row_get(cr, uid,objs, new_fields, new_cond, group_by=groupby) fct = { 'calc_sum': lambda l: reduce(lambda x,y: float(x)+float(y), filter(None, l), 0), 'calc_avg': lambda l: reduce(lambda x,y: float(x)+float(y), filter(None, l), 0) / (len(filter(None, l)) or 1.0), 'calc_max': lambda l: reduce(lambda x,y: max(x,y), [(i or 0.0) for i in l], 0), 'calc_min': lambda l: reduce(lambda x,y: min(x,y), [(i or 0.0) for i in l], 0), 'calc_count': lambda l: len(filter(None, l)), 'False': lambda l: '\r\n'.join(filter(None, l)), 'groupby': lambda l: reduce(lambda x,y: x or y, l) } new_res = [] prev = None if groupby is not None: res_dic = {} for line in results: if not line[groupby] and prev in res_dic: res_dic[prev].append(line) else: prev = line[groupby] res_dic.setdefault(line[groupby], []) res_dic[line[groupby]].append(line) #we use the keys in results since they are ordered, whereas in res_dic.heys() they aren't for key in filter(None, [x[groupby] for x in results]): row = [] for col in range(len(fields)): if col == groupby: row.append(fct['groupby'](map(lambda x: x[col], res_dic[key]))) else: row.append(fct[str(fields[col]['operation'])](map(lambda x: x[col], res_dic[key]))) new_res.append(row) results = new_res if report['type']=='table': if report['field_parent']: res = self._create_tree(uid, ids, report, fields, level, results, context) else: sort_idx = 0 for idx in range(len(fields)): if fields[idx]['name'] == report['sortby']: sort_idx = idx break try : results.sort(lambda x,y : cmp(float(x[sort_idx]),float(y[sort_idx]))) except : results.sort(lambda x,y : cmp(x[sort_idx],y[sort_idx])) if report['limitt']: results = results[:int(report['limitt'])] res = self._create_table(uid, ids, report, fields, None, results, context) elif report['type'] in ('pie','bar', 'line'): results2 = [] prev = False for r in results: row = [] for j in range(len(r)): if j == 0 and not r[j]: row.append(prev) elif j == 0 and r[j]: prev = r[j] row.append(r[j]) else: try: row.append(float(r[j])) except Exception: row.append(r[j]) results2.append(row) if report['type']=='pie': res = self._create_pie(cr,uid, ids, report, fields, results2, context) elif report['type']=='bar': res = self._create_bars(cr,uid, ids, report, fields, results2, context) elif report['type']=='line': res = self._create_lines(cr,uid, ids, report, fields, results2, context) return self.obj.get(), 'pdf'