def go(id, uid, ids, datas, context): with openerp.api.Environment.manage(): cr = openerp.registry(db).cursor() try: result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]["exception"] = openerp.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"] = openerp.exceptions.DeferredException( tools.ustr(exception.name), tools.ustr(exception.value) ) else: tb = sys.exc_info() self_reports[id]["exception"] = openerp.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) openerp.modules.registry.RegistryManager.check_registry_signaling(cr.dbname) registry = openerp.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)) openerp.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 __init__(self, cr, name, table, rml=False, parser=False, header=True, store=False): super(Aeroo_report, self).__init__(name, table, rml, parser, header, store) self.logger("registering %s (%s)" % (name, table), logging.INFO) self.active_prints = {} pool = registry(cr.dbname) ir_obj = pool.get('ir.actions.report.xml') name = name.startswith('report.') and name[7:] or name try: report_xml_ids = ir_obj.search(cr, 1, [('report_name', '=', name)]) if report_xml_ids: report_xml = ir_obj.browse(cr, 1, report_xml_ids[0]) else: report_xml = False #TODO v8 remove, preload_mode is deprecated, as reports themselves are not preloaded #if report_xml and report_xml.preload_mode == 'preload': # file_data = report_xml.report_sxw_content # if not file_data: # self.logger("template is not defined in %s (%s) !" % (name, table), logging.WARNING) # template_io = None # else: # template_io = StringIO() # template_io.write(base64.decodestring(file_data)) # style_io=self.get_styles_file(cr, 1, report_xml) # if template_io: # self.serializer = OOSerializer(template_io, oo_styles=style_io) except Exception, e: logger.error("Error while registering report '%s' (%s)", name, table, exc_info=True)
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 = openerp.registry(db).cursor() try: result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = openerp.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'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: tb = sys.exc_info() self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb) self_reports[id]['state'] = True
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 = openerp.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, "act_window": self._tag_act_window, "assert": self._tag_assert, }
def on_disconnect(self, notice): super(TwitterStream, self).on_disconnect(notice) with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: self.env = api.Environment(new_cr, self.env.uid, self.env.context) self.state = 'stop' return False
def load_test(module_name, idref, mode): cr.commit() try: _load_data(cr, module_name, idref, mode, 'test') return True except Exception: _test_logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: if tools.config.options['test_commit']: cr.commit() else: cr.rollback() # avoid keeping stale xml_id, etc. in cache openerp.registry(cr.dbname).clear_caches()
def action_text_input(self,cr,content,original,fromUser): if content.startswith("shell:"): r = os.popen(content[6:]) res = r.readlines() return str(res) if content.startswith("odoo:"): content = eval(content[5:] or '') model_name = content[0] method_name = content[1] args = content[2] openerp.modules.registry.RegistryManager.check_registry_signaling(cr.dbname) registry = openerp.registry(cr.dbname) if model_name in registry: model = registry[model_name] if hasattr(model, method_name): try: msg =getattr(model, method_name)(cr, SUPERUSER_ID, *args) except Exception,e: msg = e.message() openerp.modules.registry.RegistryManager.signal_caches_change(cr.dbname) else: msg = "Method `%s.%s` does not exist." % (model_name, method_name) else: msg = "Model `%s` does not exist." % model_name return str(msg)
def process(location_id, level): registry = openerp.registry(cr.dbname) xml = '<row>' location_name = registry['stock.location'].read(cr, uid, [location_id], ['name']) xml += "<col para='yes' tree='yes' space='" + str(3*level) + "mm'>" xml += location_name[0]['name'] + '</col>' prod_info = registry['stock.location']._product_get(cr, uid, location_id) xml += "<col>" for prod_id in prod_info.keys(): if prod_info[prod_id] != 0.0: prod_name = registry['product.product'].read(cr, uid, [prod_id], ['name']) xml += prod_name[0]['name'] + '\n' xml += '</col>' xml += "<col>" for prod_id in prod_info.keys(): if prod_info[prod_id] != 0.0: xml += str(prod_info[prod_id]) + '\n' xml += '</col></row>' location_child = registry['stock.location'].read(cr, uid, [location_id], ['child_ids']) for child_id in location_child[0]['child_ids']: xml += process(child_id, level+1) return xml
def poll(self, dbname, channels, last, options=None, timeout=TIMEOUT): if options is None: options = {} if not openerp.evented: current = threading.current_thread() current._Thread__daemonic = True # rename the thread to avoid tests waiting for a longpolling current.setName("openerp.longpolling.request.%s" % current.ident) registry = openerp.registry(dbname) with registry.cursor() as cr: with openerp.api.Environment.manage(): notifications = registry['telegram.bus'].poll(cr, openerp.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['telegram.bus'].poll(cr, openerp.SUPERUSER_ID, channels, last, options, force_status=True) except Exception: # timeout pass return notifications
def LocalService(name): """ The openerp.netsvc.LocalService() function is deprecated. It still works in two cases: workflows and reports. For workflows, instead of using LocalService('workflow'), openerp.workflow should be used (better yet, methods on openerp.osv.orm.Model should be used). For reports, openerp.report.render_report() should be used (methods on the Model should be provided too in the future). """ assert openerp.conf.deprecation.allow_local_service _logger.warning("LocalService() is deprecated since march 2013 (it was called with '%s')." % name) if name == 'workflow': return openerp.workflow if name.startswith('report.'): report = openerp.report.interface.report_int._reports.get(name) if report: return report else: dbname = getattr(threading.currentThread(), 'dbname', None) if dbname: registry = openerp.registry(dbname) with registry.cursor() as cr: return registry['ir.actions.report.xml']._lookup_report(cr, name[len('report.'):])
def __init__(self, cursor, uid, report_id, context): "constructor" self.cursor = cursor self.uid = uid self.pool = openerp.registry(self.cursor.dbname) self.report_id = report_id self.context = context
def poll(self, dbname, channels, last, timeout=TIMEOUT): # 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 openerp.evented: current = threading.current_thread() current._Thread__daemonic = True # rename the thread to avoid tests waiting for a longpolling current.setName("openerp.longpolling.request.%s" % current.ident) registry = openerp.registry(dbname) # immediatly returns if past notifications exist with registry.cursor() as cr: notifications = registry['bus.bus'].poll(cr, openerp.SUPERUSER_ID, channels, last) # 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, openerp.SUPERUSER_ID, channels, last) except Exception: # timeout pass return notifications
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 = openerp.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) report_xml.report_rml = None report_xml.report_rml_content = None report_xml.report_sxw_content_data = None report_xml.report_sxw_content = None report_xml.report_sxw = None else: return super(WebKitParser, self).create(cursor, uid, ids, data, context) 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, 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 = openerp.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 __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 = openerp.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 on_connect(self): super(TwitterStream, self).on_connect() with api.Environment.manage(): with registry(self.env.cr.dbname).cursor() as new_cr: self.env = api.Environment(new_cr, self.env.uid, self.env.context) self.state = 'start' pass
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 = openerp.registry(self.cr.dbname)[self.model]
def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw): """ Logging function: This function is performing the logging operation @param model: Object whose values are being changed @param method: method to log: create, read, write, unlink, action or workflow action @param fct_src: execute method of Object proxy @return: Returns result as per method of Object proxy """ pool = openerp.registry(cr.dbname) resource_pool = pool[model] model_pool = pool.get('ir.model') model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)]) model_id = model_ids and model_ids[0] or False assert model_id, _("'%s' Model does not exist..." %(model)) model = model_pool.browse(cr, SUPERUSER_ID, model_id) # fields to log. currently only used by log on read() field_list = [] old_values = new_values = {} if method == 'create': res = fct_src(cr, uid_orig, model.model, method, *args, **kw) if res: res_ids = [res] new_values = get_data(cr, uid_orig, pool, res_ids, model, method) elif method == 'read': res = fct_src(cr, uid_orig, model.model, method, *args, **kw) # build the res_ids and the old_values dict. Here we don't use get_data() to # avoid performing an additional read() res_ids = [] for record in res: res_ids.append(record['id']) old_values[(model.id, record['id'])] = {'value': record, 'text': record} # log only the fields read field_list = args[1] elif method == 'unlink': res_ids = args[0] old_values = get_data(cr, uid_orig, pool, res_ids, model, method) res = fct_src(cr, uid_orig, model.model, method, *args, **kw) else: # method is write, action or workflow action res_ids = [] if args: res_ids = args[0] if isinstance(res_ids, (long, int)): res_ids = [res_ids] if res_ids: # store the old values into a dictionary old_values = get_data(cr, uid_orig, pool, res_ids, model, method) # process the original function, workflow trigger... res = fct_src(cr, uid_orig, model.model, method, *args, **kw) if method == 'copy': res_ids = [res] if res_ids: # check the new values and store them into a dictionary new_values = get_data(cr, uid_orig, pool, res_ids, model, method) # compare the old and new values and create audittrail log if needed process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) return res
def emp_create_xml(self, cr, uid, dept, row_id, empid, name, som, eom): start_date = str(som).split()[0] end_date = str(eom).split()[0] difference_date = eom - som display={} if dept==0: count=0 registry = openerp.registry(cr.dbname) attendance_ids = registry['hr_attendance.record.report'].search(cr, uid, [('employee_id','in',[empid,False]),('name','>=',start_date),('name','<=',end_date)],order='name ASC') ids_date_attendance = registry['hr_attendance.record.report'].read(cr, uid, attendance_ids, ['name','sign_in']) public_holidays = registry['company.public.holidays'].search(cr, uid, [('record_year','=',str(som.year))]) employee_leaves = registry['hr.holidays'].search(cr,uid,[('employee_id','in',[empid,False]), ('type', '=', 'remove')]) ids_date_leaves = registry['hr.holidays'].read(cr, uid, employee_leaves, ['date_from','date_to','state']) for index in range(1,difference_date.days +2 ): diff=index-1 current=som+datetime.timedelta(diff) display[index] = '' #### Checking Present for item in ids_date_attendance: if str(current).split()[0] == item['name']: display[index]=5 count=count +1 if display[index] != '': break ### Checking Public Holidays if display[index] == '': for pholiday in registry['company.public.holidays'].browse(cr,uid,public_holidays): if pholiday.holiday_day == str(current).split()[0]: display[index]=4 if display[index] != '': break ### Checking Leave Request if display[index] == '': for item in ids_date_leaves: date_from = datetime.datetime.strptime(item['date_from'].split()[0], '%Y-%m-%d') date_to = datetime.datetime.strptime(item['date_to'].split()[0], '%Y-%m-%d') current_update = current.strftime("%Y-%m-%d %H:%M:%S") datetime_current = datetime.datetime.strptime(current_update.split()[0], '%Y-%m-%d') if datetime_current >= date_from and datetime_current <= date_to: display[index]= 1 if display[index] != '': break ### Cheking Absent if display[index] == '': if current.strftime('%a') not in ['Sat','Sun']: display[index] = 2 data_xml=['<info id="%d" number="%d" val="%s" />' % (row_id,x,display[x]) for x in range(1,len(display)+1) ] # Computing the xml xml = ''' %s <employee row="%d" id="%d" name="%s" sum="%s"> </employee> ''' % (data_xml,row_id,dept, ustr(toxml(name)),count) return xml
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 = openerp.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 __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 = openerp.registry(self.cr.dbname)[self.model] self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def _auth_method_user(self): super(IrHttp, self)._auth_method_user() if random.random() < 0.01: with openerp.registry(request.cr.dbname).cursor() as cr: cr.autocommit(True) env = api.Environment(cr, request.uid, request.context) env['ir.sessions'].update_last_activity(request.session.sid) cr.commit()
def environment(): """ Return an environment with a new cursor for the current database; the cursor is committed and closed after the context block. """ reg = registry(common.get_db_name()) with reg.cursor() as cr: yield api.Environment(cr, SUPERUSER_ID, {}) cr.commit()
def aeroo_docs_enabled(self, cr): ''' Check if Aeroo DOCS connection is enabled ''' pool = registry(cr.dbname) icp = pool['ir.config_parameter'] enabled = icp.get_param(cr, 1, 'aeroo.docs_enabled') return enabled == 'True' and True or False
def get_other_template(self, cr, uid, model, rec_id, parser): if hasattr(parser, 'get_template'): pool = registry(cr.dbname) record = pool.get(model).browse(cr, uid, rec_id, {}) template = parser.get_template(cr, uid, record) return template else: return False
def __init__(self, cr, uid, model, id): self.cr = cr self.uid = uid self.model = model self.id = id self.ids = [id] self.obj = openerp.registry(cr.dbname)[model] self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def __getattr__(self, name): cr = self._cursor if cr is None: from openerp import registry cr = self._cursor = registry(self.dbname).cursor() for _ in xrange(self._depth): cr.__enter__() return getattr(cr, name)
def execute(db, uid, obj, method, *args, **kw): threading.currentThread().dbname = db with openerp.registry(db).cursor() as cr: check_method_name(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 __init__(self, cr, uid, datas, func=False): # create a new document self.cr = cr self.pool = openerp.registry(cr.dbname) self.func = func or {} self.datas = datas self.uid = uid self.bin_datas = {}
def trans_generate(lang, modules, cr): dbname = cr.dbname registry = openerp.registry(dbname) trans_obj = registry['ir.translation'] model_data_obj = registry['ir.model.data'] uid = 1 query = 'SELECT name, model, res_id, module' \ ' FROM ir_model_data' query_models = """SELECT m.id, m.model, imd.module FROM ir_model AS m, ir_model_data AS imd WHERE m.id = imd.res_id AND imd.model = 'ir.model' """ if 'all_installed' in modules: query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') ' query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') " query_param = None if 'all' not in modules: query += ' WHERE module IN %s' query_models += ' AND imd.module in %s' query_param = (tuple(modules),) query += ' ORDER BY module, model, name' query_models += ' ORDER BY module, model' cr.execute(query, query_param) _to_translate = set() def push_translation(module, type, name, id, source, comments=None): # empty and one-letter terms are ignored, they probably are not meant to be # translated, and would be very hard to translate anyway. if not source or len(source.strip()) <= 1: return tnx = (module, source, name, id, type, tuple(comments or ())) _to_translate.add(tnx) def push(mod, type, name, res_id, term): term = (term or '').strip() if len(term) > 2 or term in ENGLISH_SMALL_WORDS: push_translation(mod, type, name, res_id, term) def get_root_view(xml_id): view = model_data_obj.xmlid_to_object(cr, uid, xml_id) if view: while view.mode != 'primary': view = view.inherit_id xml_id = view.get_external_id(cr, uid).get(view.id, xml_id) return xml_id for (xml_name,model,res_id,module) in cr.fetchall(): module = encode(module) model = encode(model) xml_name = "%s.%s" % (module, encode(xml_name)) if model not in registry: _logger.error("Unable to find object %r", model) continue Model = registry[model] if not Model._translate: # explicitly disabled continue obj = Model.browse(cr, uid, res_id) if not obj.exists(): _logger.warning("Unable to find object %r with id %d", model, res_id) continue if model=='ir.model.fields': try: field_name = encode(obj.name) except AttributeError, exc: _logger.error("name error in %s: %s", xml_name, str(exc)) continue field_model = registry.get(obj.model) if (field_model is None or not field_model._translate or field_name not in field_model._fields): continue field_def = field_model._fields[field_name] if hasattr(field_def, 'selection') and isinstance(field_def.selection, (list, tuple)): name = "%s,%s" % (encode(obj.model), field_name) for dummy, val in field_def.selection: push_translation(module, 'selection', name, 0, encode(val)) elif model=='ir.actions.report.xml': name = encode(obj.report_name) fname = "" if obj.report_rml: fname = obj.report_rml parse_func = trans_parse_rml report_type = "report" elif obj.report_xsl: continue if fname and obj.report_type in ('pdf', 'xsl'): try: report_file = misc.file_open(fname) try: d = etree.parse(report_file) for t in parse_func(d.iter()): push_translation(module, report_type, name, 0, t) finally: report_file.close() except (IOError, etree.XMLSyntaxError): _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
def execute_cr(cr, uid, obj, method, *args, **kw): object = openerp.registry(cr.dbname).get(obj) if object is None: raise except_orm('Object Error', "Object %s doesn't exist" % obj) return getattr(object, method)(cr, uid, *args, **kw)
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 = openerp.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 load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None, upg_registry=None): """Migrates+Updates or Installs all module nodes from ``graph`` :param graph: graph of module nodes to load :param status: status dictionary for keeping track of progress :param perform_checks: whether module descriptors should be checked for validity (prints warnings for same cases) :param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped :return: list of modules that were installed or updated """ def load_test(module_name, idref, mode): cr.commit() try: _load_data(cr, module_name, idref, mode, 'test') return True except Exception: _test_logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: if tools.config.options['test_commit']: cr.commit() else: cr.rollback() # avoid keeping stale xml_id, etc. in cache openerp.modules.registry.RegistryManager.clear_caches( cr.dbname) def _get_files_of_kind(kind): if kind == 'demo': kind = ['demo_xml', 'demo'] elif kind == 'data': kind = ['init_xml', 'update_xml', 'data'] if isinstance(kind, str): kind = [kind] files = [] for k in kind: for f in package.data[k]: files.append(f) if k.endswith('_xml') and not (k == 'init_xml' and not f.endswith('.xml')): # init_xml, update_xml and demo_xml are deprecated except # for the case of init_xml with yaml, csv and sql files as # we can't specify noupdate for those file. correct_key = 'demo' if k.count('demo') else 'data' _logger.warning( "module %s: key '%s' is deprecated in favor of '%s' for file '%s'.", package.name, k, correct_key, f) return files def _load_data(cr, module_name, idref, mode, kind): """ kind: data, demo, test, init_xml, update_xml, demo_xml. noupdate is False, unless it is demo data or it is csv data in init mode. """ try: if kind in ('demo', 'test'): threading.currentThread().testing = True for filename in _get_files_of_kind(kind): _logger.info("module %s: loading %s", module_name, filename) noupdate = False if kind in ('demo', 'demo_xml') or (filename.endswith('.csv') and kind in ('init', 'init_xml')): noupdate = True tools.convert_file(cr, module_name, filename, idref, mode, noupdate, kind, report) finally: if kind in ('demo', 'test'): threading.currentThread().testing = False if status is None: status = {} if skip_modules is None: skip_modules = [] processed_modules = [] loaded_modules = [] registry = openerp.registry(cr.dbname) migrations = openerp.modules.migration.MigrationManager(cr, graph) _logger.info('loading %d modules...', len(graph)) # Query manual fields for all models at once and save them on the registry # so the initialization code for each model does not have to do it # one model at a time. registry.fields_by_model = {} cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual', )) for field in cr.dictfetchall(): registry.fields_by_model.setdefault(field['model'], []).append(field) # suppress commits to have the upgrade of one module in just one transaction cr.commit_org = cr.commit cr.commit = lambda *args: None cr.rollback_org = cr.rollback cr.rollback = lambda *args: None # register, instantiate and initialize models for each modules for index, package in enumerate(graph): module_name = package.name module_id = package.id if module_name in skip_modules or module_name in loaded_modules: continue _logger.debug('module %s: loading objects', package.name) migrations.migrate_module(package, 'pre') load_openerp_module(package.name) models = registry.load(cr, package) loaded_modules.append(package.name) if hasattr(package, 'init') or hasattr( package, 'update') or package.state in ('to install', 'to upgrade'): # OpenUpgrade: add this module's models to the registry local_registry = {} for model in models: if not model._auto: continue openupgrade_loading.log_model(model, local_registry) openupgrade_loading.compare_registries(cr, package.name, upg_registry, local_registry) init_module_models(cr, package.name, models) status['progress'] = float(index) / len(graph) # Can't put this line out of the loop: ir.module.module will be # registered by init_module_models() above. modobj = registry['ir.module.module'] if perform_checks: modobj.check(cr, SUPERUSER_ID, [module_id]) idref = {} mode = 'update' if hasattr(package, 'init') or package.state == 'to install': mode = 'init' if hasattr(package, 'init') or hasattr( package, 'update') or package.state in ('to install', 'to upgrade'): if package.state == 'to upgrade': # upgrading the module information modobj.write(cr, SUPERUSER_ID, [module_id], modobj.get_values_from_terp(package.data)) _load_data(cr, module_name, idref, mode, kind='data') has_demo = hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed') if has_demo: status['progress'] = (index + 0.75) / len(graph) _load_data(cr, module_name, idref, mode, kind='demo') cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id)) # OpenUpgrade: add 'try' block for logging exceptions # as errors in post scripts seem to be dropped try: migrations.migrate_module(package, 'post') except Exception as exc: _logger.error( 'Error executing post migration script for module %s: %s', package, exc) raise registry._init_modules.add(package.name) # validate all the views at a whole registry['ir.ui.view']._validate_module_views( cr, SUPERUSER_ID, module_name) if has_demo: # launch tests only in demo mode, allowing tests to use demo data. if tools.config.options['test_enable']: # Yamel test report.record_result(load_test(module_name, idref, mode)) # Python tests ir_http = registry['ir.http'] if hasattr(ir_http, '_routing_map'): # Force routing map to be rebuilt between each module test suite del (ir_http._routing_map) report.record_result( openerp.modules.module.run_unit_tests( module_name, cr.dbname)) processed_modules.append(package.name) ver = adapt_version(package.data['version']) # Set new modules and dependencies modobj.write(cr, SUPERUSER_ID, [module_id], { 'state': 'installed', 'latest_version': ver }) # Update translations for all installed languages modobj.update_translations(cr, SUPERUSER_ID, [module_id], None) package.state = 'installed' for kind in ('init', 'demo', 'update'): if hasattr(package, kind): delattr(package, kind) registry._init_modules.add(package.name) cr.commit_org() # The query won't be valid for models created later (i.e. custom model # created after the registry has been loaded), so empty its result. registry.fields_by_model = None cr.commit = cr.commit_org cr.commit() return loaded_modules, processed_modules
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 OpenERP 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 = openerp.registry(db_name).cursor() else: raise Exception( "No database cursor found, please pass one explicitly") # Send Email try: mail_server_pool = openerp.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 _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 = openerp.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 {}
AND nextcall <= (now() at time zone 'UTC') AND id=%s FOR UPDATE NOWAIT""", (job['id'], ), log_exceptions=False) locked_job = lock_cr.fetchone() if not locked_job: _logger.debug( "Job `%s` already executed by another process/thread. skipping it", job['name']) continue # Got the lock on the job row, run its code _logger.debug('Starting job `%s`.', job['name']) job_cr = db.cursor() try: registry = openerp.registry(db_name) registry[cls._name]._process_job(job_cr, job, lock_cr) except Exception: _logger.exception( 'Unexpected exception while processing cron job %r', job) finally: job_cr.close() except psycopg2.OperationalError, e: if e.pgcode == '55P03': # Class 55: Object not in prerequisite state; 55P03: lock_not_available _logger.debug( 'Another process/thread is already busy executing job `%s`, skipping it.', job['name']) continue
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 = openerp.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 create_log_line(cr, uid, log_id, model, lines=None): """ Creates lines for changed fields with its old and new values @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param model: Object which values are being changed @param lines: List of values for line is to be created """ if lines is None: lines = [] pool = openerp.registry(cr.dbname) obj_pool = pool[model.model] model_pool = pool.get('ir.model') field_pool = pool.get('ir.model.fields') log_line_pool = pool.get('audittrail.log.line') for line in lines: field_obj = obj_pool._all_columns.get(line['name']) assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) field_obj = field_obj.column old_value = line.get('old_value', '') new_value = line.get('new_value', '') search_models = [model.id] if obj_pool._inherits: search_models += model_pool.search(cr, uid, [('model', 'in', obj_pool._inherits.keys())]) field_id = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', search_models)]) if field_obj._type == 'many2one': old_value = old_value and old_value[0] or old_value new_value = new_value and new_value[0] or new_value #Tuannh3 fix text boolean and list elif field_obj._type == 'boolean': value_bool = 'False' if str(line.get('new_value_text', '')) != '': value_bool = str(line.get('new_value_text', '')) line.update({'new_value_text' : value_bool}) value_bool = 'False' if str(line.get('old_value_text', '')) != '': value_bool = str(line.get('old_value_text', '')) line.update({'old_value_text' : value_bool}) elif field_obj._type == 'many2many' or field_obj._type == 'one2many': old_value_text = line.get('old_value_text', '') new_value_text = line.get('new_value_text', '') res = '' if isinstance(old_value_text, list): for item in old_value_text: if not res: res = '%s' % (item) else: res = '%s, %s' % (res, item) line.update({'old_value_text' : res}) res = '' if isinstance(new_value_text, list): for item in new_value_text: if not res: res = '%s' % (item) else: res = '%s, %s' % (res, item) line.update({'new_value_text' : res}) vals = { "log_id": log_id, "field_id": field_id and field_id[0] or False, "old_value": old_value, "new_value": new_value, "old_value_text": line.get('old_value_text', ''), "new_value_text": line.get('new_value_text', ''), "field_description": field_obj.string } line_id = log_line_pool.create(cr, uid, vals) return True
def exec_workflow(db, uid, obj, signal, *args): with openerp.registry(db).cursor() as cr: return exec_workflow_cr(cr, uid, obj, signal, *args)
def change_digit(cr): decimal_precision = openerp.registry(cr.dbname)['decimal.precision'] res = decimal_precision.precision_get(cr, SUPERUSER_ID, application) return (16, res)
def load_modules(db, force_demo=False, status=None, update_module=False): initialize_sys_path() force = [] if force_demo: force.append('demo') cr = db.cursor() try: if not openerp.modules.db.is_initialized(cr): _logger.info("init db") openerp.modules.db.initialize(cr) update_module = True # process auto-installed modules tools.config["init"]["all"] = 1 tools.config['update']['all'] = 1 if not tools.config['without_demo']: tools.config["demo"]['all'] = 1 # This is a brand new registry, just created in # openerp.modules.registry.RegistryManager.new(). registry = openerp.registry(cr.dbname) if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute( "update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) graph = openerp.modules.graph.Graph() graph.add_module(cr, 'base', force) if not graph: _logger.critical( 'module base cannot be loaded! (hint: verify addons-path)') raise ImportError( 'Module `base` cannot be loaded! (hint: verify addons-path)') # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading report = registry._assertion_report loaded_modules, processed_modules = load_module_graph( cr, graph, status, perform_checks=update_module, report=report) load_lang = tools.config.pop('load_language') if load_lang or update_module: # some base models are used below, so make sure they are set up registry.setup_models(cr, partial=True) if load_lang: for lang in load_lang.split(','): tools.load_language(cr, lang) # STEP 2: Mark other modules to be loaded/updated if update_module: modobj = registry['ir.module.module'] _logger.info('updating modules list') modobj.update_list(cr, SUPERUSER_ID) _check_module_names( cr, itertools.chain(tools.config['init'].keys(), tools.config['update'].keys())) mods = [k for k in tools.config['init'] if tools.config['init'][k]] if mods: ids = modobj.search( cr, SUPERUSER_ID, ['&', ('state', '=', 'uninstalled'), ('name', 'in', mods)]) if ids: modobj.button_install(cr, SUPERUSER_ID, ids) mods = [ k for k in tools.config['update'] if tools.config['update'][k] ] if mods: ids = modobj.search( cr, SUPERUSER_ID, ['&', ('state', '=', 'installed'), ('name', 'in', mods)]) if ids: modobj.button_upgrade(cr, SUPERUSER_ID, ids) cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base')) modobj.invalidate_cache(cr, SUPERUSER_ID, ['state']) # STEP 3: Load marked modules (skipping base which was done in STEP 1) # IMPORTANT: this is done in two parts, first loading all installed or # partially installed modules (i.e. installed/to upgrade), to # offer a consistent system to the second part: installing # newly selected modules. # We include the modules 'to remove' in the first step, because # they are part of the "currently installed" modules. They will # be dropped in STEP 6 later, before restarting the loading # process. # IMPORTANT 2: We have to loop here until all relevant modules have been # processed, because in some rare cases the dependencies have # changed, and modules that depend on an uninstalled module # will not be processed on the first pass. # It's especially useful for migrations. previously_processed = -1 while previously_processed < len(processed_modules): previously_processed = len(processed_modules) processed_modules += load_marked_modules( cr, graph, ['installed', 'to upgrade', 'to remove'], force, status, report, loaded_modules, update_module) if update_module: processed_modules += load_marked_modules( cr, graph, ['to install'], force, status, report, loaded_modules, update_module) registry.setup_models(cr) # STEP 3.5: execute migration end-scripts migrations = openerp.modules.migration.MigrationManager(cr, graph) for package in graph: migrations.migrate_module(package, 'end') # STEP 4: Finish and cleanup installations if processed_modules: cr.execute( """select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""" ) for (model, name) in cr.fetchall(): if model in registry and not registry[model].is_transient( ) and not isinstance(registry[model], openerp.osv.orm.AbstractModel): _logger.warning( 'The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,0,0,0', model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_')) # Temporary warning while we remove access rights on osv_memory objects, as they have # been replaced by owner-only access rights cr.execute( """select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""" ) for (model, name) in cr.fetchall(): if model in registry and registry[model].is_transient(): _logger.warning( 'The transient model %s (%s) should not have explicit access rules!', model, name) cr.execute("SELECT model from ir_model") for (model, ) in cr.fetchall(): if model in registry: registry[model]._check_removed_columns(cr, log=True) elif _logger.isEnabledFor( logging.INFO): # more an info that a warning... _logger.warning( "Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model) # Cleanup orphan records registry['ir.model.data']._process_end(cr, SUPERUSER_ID, processed_modules) for kind in ('init', 'demo', 'update'): tools.config[kind] = {} cr.commit() # STEP 5: Uninstall modules to remove if update_module: # Remove records referenced from ir_model_data for modules to be # removed (and removed the references from ir_model_data). cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove', )) modules_to_remove = dict(cr.fetchall()) if modules_to_remove: pkgs = reversed( [p for p in graph if p.name in modules_to_remove]) for pkg in pkgs: uninstall_hook = pkg.info.get('uninstall_hook') if uninstall_hook: py_module = sys.modules['openerp.addons.%s' % (pkg.name, )] getattr(py_module, uninstall_hook)(cr, registry) registry['ir.module.module'].module_uninstall( cr, SUPERUSER_ID, modules_to_remove.values()) # Recursive reload, should only happen once, because there should be no # modules to remove next time cr.commit() _logger.info( 'Reloading registry once more after uninstalling modules') openerp.api.Environment.reset() return openerp.modules.registry.RegistryManager.new( cr.dbname, force_demo, status, update_module) # STEP 6: verify custom views on every model if update_module: Views = registry['ir.ui.view'] for model in registry.models.keys(): if not Views._validate_custom_views(cr, SUPERUSER_ID, model): _logger.warning('Invalid custom view(s) for model %s', model) if report.failures: _logger.error('At least one test failed when loading the modules.') else: _logger.info('Modules loaded.') # STEP 8: call _register_hook on every model for model in registry.models.values(): model._register_hook(cr) # STEP 9: Run the post-install tests cr.commit() t0 = time.time() t0_sql = openerp.sql_db.sql_counter if openerp.tools.config['test_enable']: if update_module: cr.execute( "SELECT name FROM ir_module_module WHERE state='installed' and name = ANY(%s)", (processed_modules, )) else: cr.execute( "SELECT name FROM ir_module_module WHERE state='installed'" ) for module_name in cr.fetchall(): report.record_result( openerp.modules.module.run_unit_tests( module_name[0], cr.dbname, position=runs_post_install)) _logger.log(25, "All post-tested in %.2fs, %s queries", time.time() - t0, openerp.sql_db.sql_counter - t0_sql) finally: cr.close()
def _callback(self, model_name, method_name, args): args = str2tuple(args) registry = openerp.registry(self._cr.dbname) res = {} if model_name in registry: model = registry[model_name] if hasattr(model, method_name): if len(args) > 9: raise UserError( _('Method with more than 9 arguments ' 'is not allowed!')) if len(args) == 0: res = getattr(model, method_name)(self._cr, self._uid) if len(args) == 1: res = getattr(model, method_name)(self._cr, self._uid, args[0]) if len(args) == 2: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1]) if len(args) == 3: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2]) if len(args) == 4: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3]) if len(args) == 5: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3], args[4]) if len(args) == 6: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3], args[4], args[5]) if len(args) == 7: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3], args[4], args[5], args[6]) if len(args) == 8: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]) if len(args) == 9: res = getattr(model, method_name)(self._cr, self._uid, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]) else: raise UserError( _("Method '%s.%s' does not exist.") % (model_name, method_name)) else: raise UserError("Model '%s' does not exist." % model_name) return res
def create_xml(self, cr, uid, ids, datas, context=None): number = (datas.get('form', False) and datas['form']['number']) or 1 registry = openerp.registry(cr.dbname) product_pool = registry.get('product.product') product_uom_pool = registry.get('product.uom') workcenter_pool = registry.get('mrp.workcenter') user_pool = registry.get('res.users') bom_pool = registry.get('mrp.bom') pricelist_pool = registry.get('product.pricelist') rml_obj=report_sxw.rml_parse(cr, uid, product_pool._name,context) rml_obj.localcontext.update({'lang':context.get('lang',False)}) company_currency = user_pool.browse(cr, uid, uid).company_id.currency_id company_currency_symbol = company_currency.symbol or company_currency.name def process_bom(bom, currency_id, factor=1): xml = '<row>' sum = 0 sum_strd = 0 prod = product_pool.browse(cr, uid, bom['product_id']) prod_name = to_xml(bom['name']) prod_qtty = factor * bom['product_qty'] product_uom = product_uom_pool.browse(cr, uid, bom['product_uom'], context=context) product_uom_name = to_xml(product_uom.name) main_sp_price, main_sp_name , main_strd_price = '','','' sellers, sellers_price = '','' if prod.seller_id: main_sp_name = '- <b>'+ to_xml(prod.seller_id.name) +'</b>\r\n' pricelist = prod.seller_id.property_product_pricelist_purchase price = pricelist_pool.price_get(cr,uid,[pricelist.id], prod.id, number*prod_qtty or 1.0, prod.seller_id.id, { 'uom': prod.uom_po_id.id, 'date': time.strftime('%Y-%m-%d'), })[pricelist.id] main_sp_price = """<b>"""+rml_obj.formatLang(price)+' '+ (company_currency_symbol)+"""</b>\r\n""" sum += prod_qtty*price std_price = product_uom_pool._compute_price(cr, uid, prod.uom_id.id, prod.standard_price, to_uom_id=product_uom.id) main_strd_price = str(std_price) + '\r\n' sum_strd = prod_qtty*std_price for seller_id in prod.seller_ids: if seller_id.name.id == prod.seller_id.id: continue sellers += '- <i>'+ to_xml(seller_id.name.name) +'</i>\r\n' pricelist = seller_id.name.property_product_pricelist_purchase price = pricelist_pool.price_get(cr,uid,[pricelist.id], prod.id, number*prod_qtty or 1.0, seller_id.name.id, { 'uom': prod.uom_po_id.id, 'date': time.strftime('%Y-%m-%d'), })[pricelist.id] sellers_price += """<i>"""+rml_obj.formatLang(price) +' '+ (company_currency_symbol) +"""</i>\r\n""" xml += """<col para='yes'> """+ prod_name +""" </col> <col para='yes'> """+ main_sp_name + sellers + """ </col> <col f='yes'>"""+ rml_obj.formatLang(prod_qtty) +' '+ product_uom_name +"""</col> <col f='yes'>"""+ rml_obj.formatLang(float(main_strd_price)) +' '+ (company_currency_symbol) +"""</col> <col f='yes'>""" + main_sp_price + sellers_price + """</col>'""" xml += '</row>' return xml, sum, sum_strd def process_workcenter(wrk): workcenter = workcenter_pool.browse(cr, uid, wrk['workcenter_id']) cost_cycle = wrk['cycle']*workcenter.costs_cycle cost_hour = wrk['hour']*workcenter.costs_hour total = cost_cycle + cost_hour xml = '<row>' xml += "<col para='yes'>" + to_xml(workcenter.name) + '</col>' xml += "<col/>" xml += """<col f='yes'>"""+rml_obj.formatLang(cost_cycle)+' '+ (company_currency_symbol) + """</col>""" xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour)+' '+ (company_currency_symbol) + """</col>""" xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour + cost_cycle)+' '+ (company_currency_symbol) + """</col>""" xml += '</row>' return xml, total xml = '' config_start = """ <config> <date>""" + to_xml(rml_obj.formatLang(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),date_time=True)) + """</date> <company>%s</company> <PageSize>210.00mm,297.00mm</PageSize> <PageWidth>595.27</PageWidth> <PageHeight>841.88</PageHeight> <tableSize>55.00mm,58.00mm,29.00mm,29.00mm,29.00mm</tableSize> """ % to_xml(user_pool.browse(cr, uid, uid).company_id.name) config_stop = """ <report-footer>Generated by Odoo</report-footer> </config> """ workcenter_header = """ <lines style='header'> <row> <col>%s</col> <col t='yes'/> <col t='yes'>%s</col> <col t='yes'>%s</col> <col t='yes'>%s</col> </row> </lines> """ % (_('Work Center name'), _('Cycles Cost'), _('Hourly Cost'),_('Work Cost')) prod_header = """ <row> <col>%s</col> <col>%s</col> <col t='yes'>%s</col> <col t='yes'>%s</col> <col t='yes'>%s</col> </row> """ % (_('Components'), _('Components suppliers'), _('Quantity'),_('Cost Price per Unit of Measure'), _('Supplier Price per Unit of Measure')) purchase_price_digits = rml_obj.get_digits(dp='Product Price') for product in product_pool.browse(cr, uid, ids, context=context): product_uom_name = to_xml(product.uom_id.name) bom_id = bom_pool._bom_find(cr, uid, product_id=product.id, context=context) title = "<title>%s</title>" %(_("Cost Structure")) title += "<title>%s</title>" % (to_xml(product.name)) xml += "<lines style='header'>" + title + prod_header + "</lines>" if not bom_id: total_strd = number * product.standard_price total = number * product_pool.price_get(cr, uid, [product.id], 'standard_price')[product.id] xml += """<lines style='lines'><row> <col para='yes'>-</col> <col para='yes'>-</col> <col para='yes'>-</col> <col para='yes'>-</col> <col para='yes'>-</col> </row></lines>""" xml += """<lines style='total'> <row> <col> """ + _('Total Cost of %s %s') % (str(number), product_uom_name) + """: </col> <col/> <col f='yes'/> <col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col> <col t='yes'>"""+ rml_obj.formatLang(total, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col> </row></lines>'""" else: bom = bom_pool.browse(cr, uid, bom_id, context=context) factor = number * product.uom_id.factor / bom.product_uom.factor sub_boms = bom_pool._bom_explode(cr, uid, bom, product, factor / bom.product_qty, context=context) total = 0 total_strd = 0 parent_bom = { 'product_qty': bom.product_qty, 'name': bom.product_id.name, 'product_uom': bom.product_uom.id, 'product_id': bom.product_id.id } xml_tmp = '' for sub_bom in (sub_boms and sub_boms[0]) or [parent_bom]: txt, sum, sum_strd = process_bom(sub_bom, company_currency.id) xml_tmp += txt total += sum total_strd += sum_strd xml += "<lines style='lines'>" + xml_tmp + '</lines>' xml += """<lines style='sub_total'> <row> <col> """ + _('Components Cost of %s %s') % (str(number), product_uom_name) + """: </col> <col/> <col t='yes'/> <col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col> <col t='yes'></col> </row></lines>'""" total2 = 0 xml_tmp = '' for wrk in (sub_boms and sub_boms[1]): txt, sum = process_workcenter(wrk) xml_tmp += txt total2 += sum if xml_tmp: xml += workcenter_header xml += "<lines style='lines'>" + xml_tmp + '</lines>' xml += """<lines style='sub_total'> <row> <col> """ + _('Work Cost of %s %s') % (str(number), product_uom_name) +""": </col> <col/> <col/> <col/> <col t='yes'>"""+ rml_obj.formatLang(total2, digits=purchase_price_digits) +' '+ (company_currency_symbol) +"""</col> </row></lines>'""" xml += """<lines style='total'> <row> <col> """ + _('Total Cost of %s %s') % (str(number), product_uom_name) + """: </col> <col/> <col t='yes'/> <col t='yes'>"""+ rml_obj.formatLang(total_strd+total2, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col> <col t='yes'></col> </row></lines>'""" xml = '<?xml version="1.0" ?><report>' + config_start + config_stop + xml + '</report>' return xml
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 = openerp.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 web_login(self, redirect=None, **kw): if request.httprequest.method == 'POST': ensure_db() remote = request.httprequest.remote_addr # Get registry and cursor config_obj = registry(request.session.db)['ir.config_parameter'] attempt_obj = registry( request.session.db)['res.authentication.attempt'] banned_remote_obj = registry( request.session.db)['res.banned.remote'] cursor = attempt_obj.pool.cursor() # Get Settings max_attempts_qty = int(config_obj.search_read( cursor, SUPERUSER_ID, [('key', '=', 'auth_brute_force.max_attempt_qty')], ['value'])[0]['value']) environ_log = config_obj.search_read( cursor, SUPERUSER_ID, [('key', '=', 'auth_brute_force.environ_log')], ['value']) # Test if remote user is banned banned = banned_remote_obj.search(cursor, SUPERUSER_ID, [ ('remote', '=', remote)]) if banned: _logger.warning( "Authentication tried from remote '%s'. The request has" " been ignored because the remote has been banned after" " %d attempts without success. Login tried : '%s'." % ( remote, max_attempts_qty, request.params['login'])) request.params['password'] = '' else: # Try to authenticate result = request.session.authenticate( request.session.db, request.params['login'], request.params['password']) # Log attempt cursor.commit() environ = '' if environ_log: filter_value = environ_log[0]['value'] filter_keys = [k.strip() for k in filter_value.split(',')] for key, value in request.httprequest.environ.items(): if key in filter_keys or filter_value == '*': environ += '%s=%s\n' % (key, value) attempt_obj.create(cursor, SUPERUSER_ID, { 'attempt_date': fields.Datetime.now(), 'login': request.params['login'], 'remote': remote, 'environ': environ, 'result': banned and 'banned' or ( result and 'successfull' or 'failed'), }) cursor.commit() if not banned and not result: # Get last bad attempts quantity attempts_qty = len(attempt_obj.search_last_failed( cursor, SUPERUSER_ID, remote)) if max_attempts_qty <= attempts_qty: # We ban the remote _logger.warning( "Authentication failed from remote '%s'. " "The remote has been banned. Login tried : '%s'." % ( remote, request.params['login'])) banned_remote_obj.create(cursor, SUPERUSER_ID, { 'remote': remote, 'ban_date': fields.Datetime.now(), }) cursor.commit() else: _logger.warning( "Authentication failed from remote '%s'." " Login tried : '%s'. Attempt %d / %d." % ( remote, request.params['login'], attempts_qty, max_attempts_qty)) cursor.close() return super(LoginController, self).web_login(redirect=redirect, **kw)
def create_xml(self, cr, uid, ids, datas, context={}): def _thousand_separator(decimal, amount): if not amount: amount = 0.0 if type(amount) is float: amount = str(decimal % amount) else: amount = str(amount) if (amount == '0'): return ' ' orig = amount new = re.sub("^(-?\d+)(\d{3})", "\g<1>.\g<2>", amount) if orig == new: return new else: return _thousand_separator(decimal, new) pool = openerp.registry(cr.dbname) order_obj = pool.get('sale.order') wh_obj = pool.get('stock.warehouse') session_obj = pool.get('pos.session') user_obj = pool.get('res.users') users = user_obj.browse(cr, uid, uid) warehouse_ids = datas['form']['warehouse_ids'] or wh_obj.search( cr, uid, []) company = users.company_id rml_parser = report_sxw.rml_parse(cr, uid, 'edukits_total_retail', context=context) rml = """ <document filename="test.pdf"> <template pageSize="(21.0cm,29.7cm)" title="Total Retail Report" author="SGEEDE" allowSplitting="20"> <pageTemplate id="first"> <frame id="first" x1="50.0" y1="0.0" width="500" height="830"/> </pageTemplate> </template> <stylesheet> <blockTableStyle id="Table1"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="-1,-1"/> </blockTableStyle> <blockTableStyle id="parent_table"> <blockAlignment value="LEFT"/> <blockLeftPadding start="0,0" length="0.1cm"/> <blockRightPadding start="0,0" length="0.1cm"/> <blockTopPadding start="0,0" length="0.15cm"/> <blockBottomPadding start="0,0" length="0.15cm"/> </blockTableStyle> <blockTableStyle id="Table2"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="-1,-1"/> </blockTableStyle> <blockTableStyle id="Table3"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> </blockTableStyle> <blockTableStyle id="Table3_Normal"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <blockTopPadding start="0,0" length="-0.15cm"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,1" stop="0,1"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="-1,-1"/> </blockTableStyle> <blockTableStyle id="Table3_PARENT"> <blockAlignment value="CENTER"/> <blockValign value="TOP"/> </blockTableStyle> """ for warehouse in wh_obj.browse(cr, uid, warehouse_ids): if warehouse.color: rml += """ <blockTableStyle id="Table3""" + to_xml(str(warehouse.color.name)) + """"> <blockBackground colorName="#""" + to_xml(str( warehouse.color.color)) + """" start="0,0" stop="0,-1"/> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <blockTopPadding start="0,0" length="0.1cm"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,1" stop="0,1"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="-1,-1"/> </blockTableStyle> """ if not warehouse.color: rml += """ <blockTableStyle id="Table3False"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <blockTopPadding start="0,0" length="0.1cm"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="-1,-1"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,1" stop="0,1"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="-1,-1"/> </blockTableStyle> """ rml += """ <blockTableStyle id="Table3_LINE"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="2,0" stop="2,3"/> </blockTableStyle> <blockTableStyle id="Table3_LINE2"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> </blockTableStyle> <blockTableStyle id="Table3_LINE2W"> <blockBackground colorName="white"/> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> </blockTableStyle> <blockTableStyle id="Table1_line"> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="2,0"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="2,0"/> </blockTableStyle> <blockTableStyle id="Table1_lines"> <blockBackground colorName="white"/> <blockAlignment value="LEFT"/> <blockValign value="TOP"/> <lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="2,0"/> <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="2,0"/> <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="2,0"/> <lineStyle kind="LINEAFTER" colorName="#000000" start="0,0" stop="2,0"/> </blockTableStyle> <initialize> <paraStyle name="all" alignment="justify"/> </initialize> <paraStyle name="P1" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P2" fontName="Helvetica-Bold" fontSize="14.0" leading="17" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P3" fontName="Times-Roman" fontSize="11.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P4" fontName="Times-Roman" fontSize="11.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P5" fontName="Times-Roman" fontSize="11.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P6" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="P7" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="P8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="P9" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P10" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P11" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P12" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="P13" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P14" fontName="Helvetica-Bold" fontSize="12.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P15" textColor="black" fontName="Helvetica" fontSize="10.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P15_W" textColor="white" fontName="Helvetica" fontSize="10.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P15_RIGHT" textColor="black" fontName="Helvetica" fontSize="10.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P15_CENTER" textColor="black" fontName="Helvetica-Bold" fontSize="12.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P15_CENTER_2" textColor="black" fontName="Helvetica-Bold" fontSize="14.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P16" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P17" fontName="Times-Roman" fontSize="8.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="1.0"/> <paraStyle name="P19" rightIndent="0.0" leftIndent="0.0" fontName="Times-Roman" fontSize="10.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="P20" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="12.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="Standard" fontName="Times-Roman"/> <paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="List" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="Table Contents" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="Table Heading" fontName="Times-Roman" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/> <paraStyle name="Caption" fontName="Times-Roman" fontSize="10.0" leading="13" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="Index" fontName="Times-Roman"/> <paraStyle name="Heading" fontName="Helvetica" fontSize="15.0" leading="19" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="Footer" fontName="Times-Roman"/> <paraStyle name="Horizontal Line" fontName="Times-Roman" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="14.0"/> <paraStyle name="terp_header" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="Heading 9" fontName="Helvetica-Bold" fontSize="75%" leading="NaN" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="terp_tblheader_General" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_tblheader_Details" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="9.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Bold_8" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_tblheader_General_Right" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_tblheader_Details_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/> <paraStyle name="terp_default_Right_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_header_Right" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="terp_header_Centre2" fontName="Helvetica-Bold" fontSize="12.0" leading="19" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="terp_header_Centre3" fontName="Helvetica-Bold" fontSize="12.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/> <paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_12" fontName="Helvetica" fontSize="12.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Bold_9_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="Heading 1" fontName="Times-Bold" fontSize="24.0" leading="29" spaceBefore="0.0" spaceAfter="0.0"/> <paraStyle name="Heading 2" fontName="Times-Bold" fontSize="20.0" leading="29" spaceBefore="0.0" spaceAfter="0.0"/> <images/> </stylesheet> <story> """ no_total = 1 rml += """ <blockTable colWidths="250,250" style="Table3_PARENT"> """ # Day transaction for batamcentre center = False currency_amount = 0 currency_symbol = '' bank_ids = [] date_end = datetime.strptime(datas['form']['date_end'], "%Y-%m-%d") # Normal transaction for warehouse in wh_obj.browse(cr, uid, warehouse_ids): currency_amount = warehouse.currency_id.rate_silent location_id = warehouse.lot_stock_id.id results = [] total_bank = 0.0 if warehouse.is_split: date_start_day = datetime.strptime( datas['form']['date_end'] + ' 00:00:00', "%Y-%m-%d %H:%M:%S") date_stop_day = datetime.strptime( datas['form']['date_end'] + ' 17:59:59', "%Y-%m-%d %H:%M:%S") date_start = datetime.strptime( datas['form']['date_end'] + ' 18:00:00', "%Y-%m-%d %H:%M:%S") date_stop = datetime.strptime( datas['form']['date_end'] + ' 23:59:59', "%Y-%m-%d %H:%M:%S") sessions_ids = session_obj.search( cr, uid, [('stock_location_rel', '=', location_id), ('stop_at', '!=', False)]) session_night_ids = [] session_day_ids = [] for sessions in session_obj.browse(cr, uid, sessions_ids): stop_temp = datetime.strptime(sessions.stop_at, "%Y-%m-%d %H:%M:%S") tz_count = 0 hour_offset = "" minute_offset = "" for tz_offset in users.tz_offset: tz_count += 1 if tz_count <= 3: hour_offset += tz_offset elif tz_count <= 5: minute_offset += tz_offset stop_at = stop_temp + relativedelta(hours=int(hour_offset)) if (stop_at >= date_start) and (stop_at <= date_stop): session_night_ids.append(sessions.id) if (stop_at >= date_start_day) and (stop_at <= date_stop_day): session_day_ids.append(sessions.id) # if not warehouse.is_split: session_ids = session_obj.search( cr, uid, [('stop_at', '>=', datas['form']['date_end'] + ' 00:00:00'), ('stop_at', '<=', datas['form']['date_end'] + ' 23:59:59'), ('stock_location_rel', '=', location_id)]) if len(warehouse_ids) == 1: rml += """ <tr> <td> """ elif no_total % 2 == 0: rml += """<td>""" else: rml += """ <tr> <td> """ if warehouse.color: rml += """ <blockTable colWidths="210" style="Table3"> """ if not warehouse.color: rml += """ <blockTable colWidths="210" style="Table3_Normal"> """ rml += """ <tr> </tr> <tr> <td> <blockTable rowHeights="38" colWidths="198" style="Table3""" + to_xml( str(warehouse.color.name)) + """"> <tr> <td> <para style="P15_CENTER_2">""" + to_xml(str( warehouse.name)) + """</para> </td> </tr> </blockTable> <blockTable colWidths="198" style="Table1_lines"> <tr> <td> <para style="P15">TGL: """ + to_xml(str(format( date_end, '%d-%B-%y'))) + """</para> </td> </tr> </blockTable> <blockTable rowHeights="17" colWidths="198" style="Table3""" + to_xml( str(warehouse.color.name)) + """"> <tr> <td background="pink"> <para style="P15_CENTER">SETORAN</para> </td> </tr> </blockTable> <blockTable colWidths="198" style="Table1_lines"> <tr> <td> """ total_card = 0.0 # if not session_ids: # rml +=""" # <para style="P15">-</para> # """ total_amount = 0.0 total_amount_night = 0.0 #for day transaction if report is split if warehouse.is_split: for session in session_obj.browse(cr, uid, session_day_ids): for bank in session.statement_ids: if bank.journal_id.type == 'bank': total_card += bank.balance_end if session.cashier_deposit_ids: for cashier in session.cashier_deposit_ids: total_amount += cashier.amount_total else: for session in session_obj.browse(cr, uid, session_ids): for bank in session.statement_ids: if bank.journal_id.type == 'bank': total_card += bank.balance_end if session.cashier_deposit_ids: for cashier in session.cashier_deposit_ids: total_amount += cashier.amount_total rml += """ <para style="P15">""" + rml_parser.formatLang( total_amount + 0, currency_obj=company.currency_id) + """</para> """ # if warehouse.is_split: if session_ids: sessions = session_obj.browse(cr, uid, session_ids[0]) if warehouse.is_split: rml += """ </td> </tr> </blockTable> <blockTable rowHeights="17" colWidths="198" style="Table3""" + to_xml( str(warehouse.color.name)) + """"> <tr> <td background="pink"> <para style="P15_CENTER">SETORAN (Malam)</para> </td> </tr> </blockTable> <blockTable colWidths="198" style="Table1_lines"> <tr> <td> """ for session in session_obj.browse(cr, uid, session_night_ids): for bank in session.statement_ids: if bank.journal_id.type == 'bank': total_card += bank.balance_end if session.cashier_deposit_ids: for cashier in session.cashier_deposit_ids: total_amount_night += cashier.amount_total rml += """ <para style="P15">""" + rml_parser.formatLang( total_amount_night + 0, currency_obj=company.currency_id) + """</para> """ # if not session_night_ids: # rml +=""" # <para style="P15">-</para> # """ #normal transaction rml += """ </td> </tr> </blockTable> <blockTable rowHeights="17" colWidths="198" style="Table3""" + to_xml( str(warehouse.color.name)) + """"> <tr> <td background="pink"> <para style="P15_CENTER">CC and DC</para> </td> </tr> </blockTable> <blockTable colWidths="100,98" style="Table1_lines"> <tr> <td> """ if not session_ids: rml += """ <para style="P15">-</para> """ session_list = [] bank_ids = [] for session in session_obj.browse(cr, uid, session_ids): session_list.append(session.id) # for bank in session.statement_ids: # if bank.journal_id.type == 'bank': # rml +=""" # <para style="P15">""" + to_xml(str(bank.journal_id.name)) + """</para> # """ if len(session_list) == 1: cr.execute( """ SELECT sum(abs.balance_end), aj.name from account_bank_statement abs inner join account_journal aj on abs.journal_id = aj.id where pos_session_id = %s and aj.type != 'cash' group by aj.name; """ % (tuple(session_list)[0], )) bank_ids = cr.fetchall() if len(session_list) > 1: cr.execute( """ SELECT sum(abs.balance_end), aj.name from account_bank_statement abs inner join account_journal aj on abs.journal_id = aj.id where pos_session_id in %s and aj.type != 'cash' group by aj.name; """ % (tuple(session_list), )) bank_ids = cr.fetchall() if bank_ids: for edukits_bank in bank_ids: rml += """ <para style="P15">""" + to_xml(str(edukits_bank[1])) + """</para> """ rml += """ </td> <td> """ if not session_ids: rml += """ <para style="P15">-</para> """ if bank_ids: for edukits_bank in bank_ids: total_bank_amount = 0 if edukits_bank[0]: total_bank_amount = edukits_bank[0] total_bank += edukits_bank[0] rml += """ <para style="P15">""" + rml_parser.formatLang( total_bank_amount + 0, currency_obj=company.currency_id) + """</para> """ rml += """ </td> </tr> </blockTable> <blockTable rowHeights="17" colWidths="198" style="Table3""" + to_xml( str(warehouse.color.name)) + """"> <tr> <td background="pink"> <para style="P15_CENTER">PENGELUARAN</para> </td> </tr> </blockTable> <blockTable colWidths="198" style="Table1_lines"> <tr> <td background="pink"> <para style="P15_W">Table</para> </td> </tr> </blockTable> <blockTable colWidths="198" style="Table1_lines"> <tr> <td background="pink"> <para style="P15_W">Table</para> </td> </tr> </blockTable> <blockTable colWidths="80,118" style="Table1_lines"> <tr> <td> <para style="P15">MAITRI</para> </td> <td> <para style="P15_RIGHT"></para> <para style="P15_RIGHT">""" + rml_parser.formatLang( total_amount + total_amount_night + total_bank + 0, currency_obj=company.currency_id) + """</para> </td> </tr> </blockTable> <blockTable colWidths="80,118" style="Table1_lines"> <tr> <td> <para style="P15">KURS :""" + rml_parser.formatLang( currency_amount, ) + """</para> </td> <td> <para style="P15_RIGHT">""" + rml_parser.formatLang( (total_amount + total_amount_night) * currency_amount, currency_obj=warehouse.currency_id) + """</para> </td> </tr> </blockTable> <blockTable colWidths="80,5,110" style="Table3_LINE2"> <tr> <td> <para style="P15"></para> </td> <td> <para style="P15"></para> </td> <td> <para style="P15_CENTER"></para> </td> </tr> </blockTable> </td> </tr> </blockTable> <spacer length="0.5cm"/>""" rml += """ </td> """ if center: if len(warehouse_ids) == 1: rml += """<td></td>""" rml += """ </tr> """ elif ((no_total % 2 == 1) and (len(warehouse_ids) + 1 == no_total)): rml += """<td></td>""" rml += """ </tr> """ elif no_total % 2 == 0: rml += """ </tr> """ else: if len(warehouse_ids) + 1 == no_total: rml += """ </tr> """ else: if len(warehouse_ids) == 1: rml += """<td></td>""" rml += """ </tr> """ elif ((no_total % 2 == 1) and (len(warehouse_ids) == no_total)): rml += """<td></td>""" rml += """ </tr> """ elif no_total % 2 == 0: rml += """ </tr> """ else: if len(warehouse_ids) == no_total: rml += """ </tr> """ no_total += 1 rml += """ </blockTable> </story> </document>""" date_cur = time.strftime('%Y-%m-%d %H:%M:%S') return rml
def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None): """Populates the ir_translation table.""" if verbose: _logger.info('loading translation file for language %s', lang) if context is None: context = {} db_name = cr.dbname registry = openerp.registry(db_name) lang_obj = registry.get('res.lang') trans_obj = registry.get('ir.translation') iso_lang = misc.get_iso_codes(lang) try: ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)]) if not ids: # lets create the language with locale information lang_obj.load_lang(cr, SUPERUSER_ID, lang=lang, lang_name=lang_name) # Parse also the POT: it will possibly provide additional targets. # (Because the POT comments are correct on Launchpad but not the # PO comments due to a Launchpad limitation. See LP bug 933496.) pot_reader = [] # now, the serious things: we read the language file fileobj.seek(0) if fileformat == 'csv': reader = csv.reader(fileobj, quotechar='"', delimiter=',') # read the first line of the file (it contains columns titles) for row in reader: fields = row break elif fileformat == 'po': reader = TinyPoFile(fileobj) fields = ['type', 'name', 'res_id', 'src', 'value', 'comments'] # Make a reader for the POT file and be somewhat defensive for the # stable branch. if fileobj.name.endswith('.po'): try: # Normally the path looks like /path/to/xxx/i18n/lang.po # and we try to find the corresponding # /path/to/xxx/i18n/xxx.pot file. # (Sometimes we have 'i18n_extra' instead of just 'i18n') addons_module_i18n, _ = os.path.split(fileobj.name) addons_module, i18n_dir = os.path.split(addons_module_i18n) addons, module = os.path.split(addons_module) pot_handle = misc.file_open(os.path.join( addons, module, i18n_dir, module + '.pot')) pot_reader = TinyPoFile(pot_handle) except: pass else: _logger.info('Bad file format: %s', fileformat) raise Exception(_('Bad file format')) # Read the POT references, and keep them indexed by source string. class Target(object): def __init__(self): self.value = None self.targets = set() # set of (type, name, res_id) self.comments = None pot_targets = defaultdict(Target) for type, name, res_id, src, _, comments in pot_reader: if type is not None: target = pot_targets[src] target.targets.add((type, name, res_id)) target.comments = comments # read the rest of the file irt_cursor = trans_obj._get_import_cursor(cr, SUPERUSER_ID, context=context) def process_row(row): """Process a single PO (or POT) entry.""" # dictionary which holds values for this line of the csv file # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ..., # 'src': ..., 'value': ..., 'module':...} dic = dict.fromkeys(('type', 'name', 'res_id', 'src', 'value', 'comments', 'imd_model', 'imd_name', 'module')) dic['lang'] = lang dic.update(zip(fields, row)) # discard the target from the POT targets. src = dic['src'] if src in pot_targets: target = pot_targets[src] target.value = dic['value'] target.targets.discard((dic['type'], dic['name'], dic['res_id'])) # This would skip terms that fail to specify a res_id res_id = dic['res_id'] if not res_id: return if isinstance(res_id, (int, long)) or \ (isinstance(res_id, basestring) and res_id.isdigit()): dic['res_id'] = int(res_id) dic['module'] = module_name else: # res_id is an xml id dic['res_id'] = None dic['imd_model'] = dic['name'].split(',')[0] if '.' in res_id: dic['module'], dic['imd_name'] = res_id.split('.', 1) else: dic['module'], dic['imd_name'] = False, res_id irt_cursor.push(dic) # First process the entries from the PO file (doing so also fills/removes # the entries from the POT file). for row in reader: process_row(row) # Then process the entries implied by the POT file (which is more # correct w.r.t. the targets) if some of them remain. pot_rows = [] for src, target in pot_targets.iteritems(): if target.value: for type, name, res_id in target.targets: pot_rows.append((type, name, res_id, src, target.value, target.comments)) pot_targets.clear() for row in pot_rows: process_row(row) irt_cursor.finish() trans_obj.clear_caches() if verbose: _logger.info("translation file loaded succesfully") except IOError: filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat) _logger.exception("couldn't read translation file %s", filename)
def _create_bars(self, cr, uid, ids, report, fields, results, context): pool = openerp.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 execute_cr(cr, uid, obj, method, *args, **kw): object = openerp.registry(cr.dbname).get(obj) if object is None: raise UserError(_("Object %s doesn't exist") % obj) return getattr(object, method)(cr, uid, *args, **kw)
def create(self, cr, uid, ids, datas, context=None): if not context: context = {} self.pool = openerp.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'
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 = openerp.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 load_modules(db, force_demo=False, status=None, update_module=False): # TODO status['progress'] reporting is broken: used twice (and reset each # time to zero) in load_module_graph, not fine-grained enough. # It should be a method exposed by the registry. initialize_sys_path() force = [] if force_demo: force.append('demo') upg_registry = {} cr = db.cursor() try: if not openerp.modules.db.is_initialized(cr): _logger.info("init db") openerp.modules.db.initialize(cr) tools.config["init"]["all"] = 1 tools.config['update']['all'] = 1 if not tools.config['without_demo']: tools.config["demo"]['all'] = 1 # This is a brand new registry, just created in # openerp.modules.registry.RegistryManager.new(). registry = openerp.registry(cr.dbname) if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute( "update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) graph = openerp.modules.graph.Graph() graph.add_module(cr, 'base', force) if not graph: _logger.critical( 'module base cannot be loaded! (hint: verify addons-path)') raise osv.osv.except_osv( _('Could not load base module'), _('module base cannot be loaded! (hint: verify addons-path)')) # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading report = registry._assertion_report loaded_modules, processed_modules = load_module_graph( cr, graph, status, perform_checks=update_module, report=report, upg_registry=upg_registry) if tools.config['load_language']: for lang in tools.config['load_language'].split(','): tools.load_language(cr, lang) # STEP 2: Mark other modules to be loaded/updated if update_module: modobj = registry['ir.module.module'] if ('base' in tools.config['init']) or ('base' in tools.config['update']): _logger.info('updating modules list') modobj.update_list(cr, SUPERUSER_ID) _check_module_names( cr, itertools.chain(tools.config['init'].keys(), tools.config['update'].keys())) mods = [k for k in tools.config['init'] if tools.config['init'][k]] if mods: ids = modobj.search( cr, SUPERUSER_ID, ['&', ('state', '=', 'uninstalled'), ('name', 'in', mods)]) if ids: modobj.button_install(cr, SUPERUSER_ID, ids) mods = [ k for k in tools.config['update'] if tools.config['update'][k] ] if mods: ids = modobj.search( cr, SUPERUSER_ID, ['&', ('state', '=', 'installed'), ('name', 'in', mods)]) if ids: modobj.button_upgrade(cr, SUPERUSER_ID, ids) cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base')) # STEP 3: Load marked modules (skipping base which was done in STEP 1) # IMPORTANT: this is done in two parts, first loading all installed or # partially installed modules (i.e. installed/to upgrade), to # offer a consistent system to the second part: installing # newly selected modules. # We include the modules 'to remove' in the first step, because # they are part of the "currently installed" modules. They will # be dropped in STEP 6 later, before restarting the loading # process. # IMPORTANT 2: We have to loop here until all relevant modules have been # processed, because in some rare cases the dependencies have # changed, and modules that depend on an uninstalled module # will not be processed on the first pass. # It's especially useful for migrations. previously_processed = -1 while previously_processed < len(processed_modules): previously_processed = len(processed_modules) processed_modules += load_marked_modules( cr, graph, ['installed', 'to upgrade', 'to remove'], force, status, report, loaded_modules, update_module, upg_registry) if update_module: processed_modules += load_marked_modules( cr, graph, ['to install'], force, status, report, loaded_modules, update_module, upg_registry) # load custom models cr.execute('select model from ir_model where state=%s', ('manual', )) for model in cr.dictfetchall(): registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {}) # STEP 4: Finish and cleanup installations if processed_modules: cr.execute( """select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""" ) for (model, name) in cr.fetchall(): if model in registry and not registry[model].is_transient( ) and not isinstance(registry[model], openerp.osv.orm.AbstractModel): _logger.warning( 'The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,1,1,1', model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_')) # Temporary warning while we remove access rights on osv_memory objects, as they have # been replaced by owner-only access rights cr.execute( """select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""" ) for (model, name) in cr.fetchall(): if model in registry and registry[model].is_transient(): _logger.warning( 'The transient model %s (%s) should not have explicit access rules!', model, name) cr.execute("SELECT model from ir_model") for (model, ) in cr.fetchall(): if model in registry: registry[model]._check_removed_columns(cr, log=True) else: _logger.warning( "Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model) # Cleanup orphan records registry['ir.model.data']._process_end(cr, SUPERUSER_ID, processed_modules) # OpenUpgrade: call deferred migration steps if update_module: deferred_80.migrate_deferred(cr, registry) for kind in ('init', 'demo', 'update'): tools.config[kind] = {} cr.commit() # STEP 5: Cleanup menus # Remove menu items that are not referenced by any of other # (child) menu item, ir_values, or ir_model_data. # TODO: This code could be a method of ir_ui_menu. Remove menu without actions of children if update_module: while True: cr.execute('''delete from ir_ui_menu where (id not IN (select parent_id from ir_ui_menu where parent_id is not null)) and (id not IN (select res_id from ir_values where model='ir.ui.menu')) and (id not IN (select res_id from ir_model_data where model='ir.ui.menu'))''' ) cr.commit() if not cr.rowcount: break else: _logger.info('removed %d unused menus', cr.rowcount) # STEP 6: Uninstall modules to remove if update_module: # Remove records referenced from ir_model_data for modules to be # removed (and removed the references from ir_model_data). cr.execute("SELECT id FROM ir_module_module WHERE state=%s", ('to remove', )) mod_ids_to_remove = [x[0] for x in cr.fetchall()] if mod_ids_to_remove: registry['ir.module.module'].module_uninstall( cr, SUPERUSER_ID, mod_ids_to_remove) # Recursive reload, should only happen once, because there should be no # modules to remove next time cr.commit() _logger.info( 'Reloading registry once more after uninstalling modules') return openerp.modules.registry.RegistryManager.new( cr.dbname, force_demo, status, update_module) # STEP 7: verify custom views on every model if update_module: Views = registry['ir.ui.view'] custom_view_test = True for model in registry.models.keys(): if not Views._validate_custom_views(cr, SUPERUSER_ID, model): custom_view_test = False _logger.error('invalid custom view(s) for model %s', model) report.record_result(custom_view_test) if report.failures: _logger.error('At least one test failed when loading the modules.') else: _logger.info('Modules loaded.') # STEP 8: call _register_hook on every model for model in registry.models.values(): model._register_hook(cr) # STEP 9: Run the post-install tests cr.commit() if openerp.tools.config['test_enable']: cr.execute( "SELECT name FROM ir_module_module WHERE state='installed'") for module_name in cr.fetchall(): report.record_result( openerp.modules.module.run_unit_tests( module_name[0], cr.dbname, position=runs_post_install)) finally: cr.close()
def extend_trans_generate(lang, modules, cr): dbname = cr.dbname registry = openerp.registry(dbname) trans_obj = registry['ir.translation'] model_data_obj = registry['ir.model.data'] uid = 1 query = 'SELECT name, model, res_id, module' \ ' FROM ir_model_data' query_models = """SELECT m.id, m.model, imd.module FROM ir_model AS m, ir_model_data AS imd WHERE m.id = imd.res_id AND imd.model = 'ir.model' """ if 'all_installed' in modules: query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') ' query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') " query_param = None if 'all' not in modules: query += ' WHERE module IN %s' query_models += ' AND imd.module in %s' query_param = (tuple(modules), ) query += ' ORDER BY module, model, name' query_models += ' ORDER BY module, model' cr.execute(query, query_param) _to_translate = set() def push_translation(module, type, name, id, source, comments=None): # empty and one-letter terms are ignored, they probably are not meant to be # translated, and would be very hard to translate anyway. if not source or len(source.strip()) <= 1: return tnx = (module, source, name, id, type, tuple(comments or ())) _to_translate.add(tnx) def encode(s): if isinstance(s, unicode): return s.encode('utf8') return s def push(mod, type, name, res_id, term): term = (term or '').strip() if len(term) > 2 or term in ENGLISH_SMALL_WORDS: push_translation(mod, type, name, res_id, term) def get_root_view(xml_id): view = model_data_obj.xmlid_to_object(cr, uid, xml_id) if view: while view.mode != 'primary': view = view.inherit_id xml_id = view.get_external_id(cr, uid).get(view.id, xml_id) return xml_id for (xml_name, model, res_id, module) in cr.fetchall(): module = encode(module) model = encode(model) xml_name = "%s.%s" % (module, encode(xml_name)) if model not in registry: _logger.error("Unable to find object %r", model) continue Model = registry[model] if not Model._translate: # explicitly disabled continue obj = Model.browse(cr, uid, res_id) if not obj.exists(): _logger.warning("Unable to find object %r with id %d", model, res_id) continue if model == 'ir.ui.view': d = etree.XML(encode(obj.arch)) if obj.type == 'qweb': view_id = get_root_view(xml_name) push_qweb = lambda t, l: push(module, 'view', 'website', view_id, t) _extract_translatable_qweb_terms(d, push_qweb) else: push_view = lambda t, l: push(module, 'view', obj.model, xml_name, t) trans_parse_view(d, push_view) elif model == 'ir.actions.wizard': pass # TODO Can model really be 'ir.actions.wizard' ? elif model == 'ir.model.fields': try: field_name = encode(obj.name) except AttributeError, exc: _logger.error("name error in %s: %s", xml_name, str(exc)) continue objmodel = registry.get(obj.model) if (objmodel is None or field_name not in objmodel._columns or not objmodel._translate): continue field_def = objmodel._columns[field_name] name = "%s,%s" % (encode(obj.model), field_name) push_translation(module, 'field', name, 0, encode(field_def.string)) if field_def.help: push_translation(module, 'help', name, 0, encode(field_def.help)) if field_def.translate: ids = objmodel.search(cr, uid, []) obj_values = objmodel.read(cr, uid, ids, [field_name]) for obj_value in obj_values: res_id = obj_value['id'] if obj.name in ('ir.model', 'ir.ui.menu'): res_id = 0 model_data_ids = model_data_obj.search( cr, uid, [ ('model', '=', model), ('res_id', '=', res_id), ]) if not model_data_ids: push_translation(module, 'model', name, 0, encode(obj_value[field_name])) if hasattr(field_def, 'selection') and isinstance( field_def.selection, (list, tuple)): for dummy, val in field_def.selection: push_translation(module, 'selection', name, 0, encode(val)) elif model == 'ir.actions.report.xml': name = encode(obj.report_name) fname = "" ##### Changes for Aeroo ###### if obj.report_type == 'aeroo': trans_ids = trans_obj.search(cr, uid, [('type', '=', 'report'), ('res_id', '=', obj.id)]) for t in trans_obj.read(cr, uid, trans_ids, ['name', 'src']): push_translation(module, "report", t['name'], xml_name, t['src'].encode('UTF-8')) ############################## else: if obj.report_rml: fname = obj.report_rml parse_func = trans_parse_rml report_type = "report" elif obj.report_xsl: fname = obj.report_xsl parse_func = trans_parse_xsl report_type = "xsl" if fname and obj.report_type in ('pdf', 'xsl'): try: report_file = misc.file_open(fname) try: d = etree.parse(report_file) for t in parse_func(d.iter()): push_translation(module, report_type, name, 0, t) finally: report_file.close() except (IOError, etree.XMLSyntaxError): _logger.exception( "couldn't export translation for report %s %s %s", name, report_type, fname)
def delete_old_report(cr, uid, ids, table, context): pool = openerp.registry(cr.dbname) aids = pool.get('ir.attachment').search(cr, uid, [('res_id', 'in', ids), ('res_model', '=', table)]) pool.get('ir.attachment').unlink(cr, uid, aids, context)
def parser(cr, uid, ids, data, context): parameters = {} name = '' model = 'stock.picking' data_source = 'model' uom_obj = registry(cr.dbname).get('product.uom') picking_obj = registry(cr.dbname).get('stock.picking') pickings = picking_obj.browse(cr, uid, ids, context) picking_ref_ids = {} picking_lines_ids = {} out_report_lines = pickings.compute_out_report_lines() for picking in pickings: language = picking.partner_id.lang or 'es_ES' picking_ref_ids[str( picking.id )] = picking.partner_id.ref or picking.partner_id.commercial_partner_id.ref or '' shop_id = picking.supplier_id and picking.sale_id and picking.sale_id.shop_id or False if shop_id: partner_shop_ids = picking.partner_id.shop_ref_ids.filtered( lambda r: r.shop_id.id == shop_id.id) picking_ref_ids[str( picking.id )] = partner_shop_ids and partner_shop_ids.ref or picking_ref_ids[ str(picking.id)] picking_lines_ids[str(picking.id)] = [] for line in out_report_lines[picking.id]: product_id = line['product_id'].with_context(lang=language) lot_id = line['lot_id'] move_id = line['move_id'].with_context(lang=language) use_date = lot_id.use_date and datetime.strptime( lot_id.use_date[:10], "%Y-%m-%d").strftime('%d/%m/%Y') or '' uom_qty = line['product_qty'] uos_qty = uom_obj._compute_qty(cr, uid, product_id.uom_id.id, uom_qty, move_id.product_uos.id) vals = { 'picking_id': picking.id, 'prod_code': product_id.default_code or '', 'prod_ean13': product_id.ean13 or '', 'prod_name': move_id.name or product_id.name or '', 'lot_name': lot_id.name or '', 'lot_date': use_date, 'uom_qty': uom_qty, 'uos_qty': uos_qty, 'uom_name': product_id.uom_id.name or '', 'uos_name': move_id.product_uos.name or product_id.uom_id.name or '', 'price_unit': move_id.procurement_id.sale_line_id.price_unit or 0.0, 'discount': move_id.procurement_id.sale_line_id.discount or 0.0, 'price_subtotal': line['total'], 'taxes': line['tax_str'], 'valued_picking': picking.valued_picking, } picking_lines_ids[str(picking.id)].append(vals) parameters['picking_ref_ids'] = picking_ref_ids parameters['picking_lines_ids'] = picking_lines_ids return { 'ids': ids, 'name': name, 'model': model, 'records': [], 'data_source': data_source, 'parameters': parameters, }
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 = openerp.registry(cr.dbname).cursor() orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') procurement_obj = self.pool.get('procurement.order') dom = company_id and [('company_id', '=', company_id)] or [] orderpoint_ids = orderpoint_obj.search(cr, uid, dom) prev_ids = [] while orderpoint_ids: ids = orderpoint_ids[:100] del orderpoint_ids[:100] for op in orderpoint_obj.browse(cr, uid, ids, context=context): try: prods = self._product_virtual_get(cr, uid, op) 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 -= orderpoint_obj.subtract_procurements( cr, uid, op, context=context) 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) self.check(cr, uid, [proc_id]) # self.run can raise and that would destroy this # procurement, commit at this point if use_new_cursor: cr.commit() self.run(cr, uid, [proc_id]) if use_new_cursor: cr.commit() except Exception as e: _logger.exception("Orderpoint processing failed") if use_new_cursor: # is retryable? if isinstance(e, OperationalError): orderpoint_ids.append(op.id) 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 load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None): """Migrates+Updates or Installs all module nodes from ``graph`` :param graph: graph of module nodes to load :param status: deprecated parameter, unused, left to avoid changing signature in 8.0 :param perform_checks: whether module descriptors should be checked for validity (prints warnings for same cases) :param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped :return: list of modules that were installed or updated """ def load_test(module_name, idref, mode): cr.commit() try: _load_data(cr, module_name, idref, mode, 'test') return True except Exception: _test_logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: if tools.config.options['test_commit']: cr.commit() else: cr.rollback() # avoid keeping stale xml_id, etc. in cache openerp.modules.registry.RegistryManager.clear_caches( cr.dbname) def _get_files_of_kind(kind): if kind == 'demo': kind = ['demo_xml', 'demo'] elif kind == 'data': kind = ['init_xml', 'update_xml', 'data'] if isinstance(kind, str): kind = [kind] files = [] for k in kind: for f in package.data[k]: files.append(f) if k.endswith('_xml') and not (k == 'init_xml' and not f.endswith('.xml')): # init_xml, update_xml and demo_xml are deprecated except # for the case of init_xml with yaml, csv and sql files as # we can't specify noupdate for those file. correct_key = 'demo' if k.count('demo') else 'data' _logger.warning( "module %s: key '%s' is deprecated in favor of '%s' for file '%s'.", package.name, k, correct_key, f) return files def _load_data(cr, module_name, idref, mode, kind): """ kind: data, demo, test, init_xml, update_xml, demo_xml. noupdate is False, unless it is demo data or it is csv data in init mode. """ try: if kind in ('demo', 'test'): threading.currentThread().testing = True for filename in _get_files_of_kind(kind): _logger.info("loading %s/%s", module_name, filename) noupdate = False if kind in ('demo', 'demo_xml') or (filename.endswith('.csv') and kind in ('init', 'init_xml')): noupdate = True tools.convert_file(cr, module_name, filename, idref, mode, noupdate, kind, report) finally: if kind in ('demo', 'test'): threading.currentThread().testing = False processed_modules = [] loaded_modules = [] registry = openerp.registry(cr.dbname) migrations = openerp.modules.migration.MigrationManager(cr, graph) _logger.info('loading %d modules...', len(graph)) registry.clear_manual_fields() # register, instantiate and initialize models for each modules t0 = time.time() t0_sql = openerp.sql_db.sql_counter for index, package in enumerate(graph): module_name = package.name module_id = package.id if skip_modules and module_name in skip_modules: continue migrations.migrate_module(package, 'pre') load_openerp_module(package.name) new_install = package.state == 'to install' if new_install: py_module = sys.modules['openerp.addons.%s' % (module_name, )] pre_init = package.info.get('pre_init_hook') if pre_init: getattr(py_module, pre_init)(cr) models = registry.load(cr, package) loaded_modules.append(package.name) if hasattr(package, 'init') or hasattr( package, 'update') or package.state in ('to install', 'to upgrade'): registry.setup_models(cr, partial=True) init_module_models(cr, package.name, models) idref = {} mode = 'update' if hasattr(package, 'init') or package.state == 'to install': mode = 'init' if hasattr(package, 'init') or hasattr( package, 'update') or package.state in ('to install', 'to upgrade'): # Can't put this line out of the loop: ir.module.module will be # registered by init_module_models() above. modobj = registry['ir.module.module'] if perform_checks: modobj.check(cr, SUPERUSER_ID, [module_id]) if package.state == 'to upgrade': # upgrading the module information modobj.write(cr, SUPERUSER_ID, [module_id], modobj.get_values_from_terp(package.data)) _load_data(cr, module_name, idref, mode, kind='data') has_demo = hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed') if has_demo: _load_data(cr, module_name, idref, mode, kind='demo') cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id)) modobj.invalidate_cache(cr, SUPERUSER_ID, ['demo'], [module_id]) migrations.migrate_module(package, 'post') # Update translations for all installed languages modobj.update_translations( cr, SUPERUSER_ID, [module_id], None, { 'overwrite': openerp.tools.config["overwrite_existing_translations"] }) registry._init_modules.add(package.name) if new_install: post_init = package.info.get('post_init_hook') if post_init: getattr(py_module, post_init)(cr, registry) # validate all the views at a whole registry['ir.ui.view']._validate_module_views( cr, SUPERUSER_ID, module_name) if has_demo: # launch tests only in demo mode, allowing tests to use demo data. if tools.config.options['test_enable']: # Yamel test report.record_result(load_test(module_name, idref, mode)) # Python tests ir_http = registry['ir.http'] if hasattr(ir_http, '_routing_map'): # Force routing map to be rebuilt between each module test suite del (ir_http._routing_map) report.record_result( openerp.modules.module.run_unit_tests( module_name, cr.dbname)) processed_modules.append(package.name) ver = adapt_version(package.data['version']) # Set new modules and dependencies modobj.write(cr, SUPERUSER_ID, [module_id], { 'state': 'installed', 'latest_version': ver }) package.load_state = package.state package.load_version = package.installed_version package.state = 'installed' for kind in ('init', 'demo', 'update'): if hasattr(package, kind): delattr(package, kind) registry._init_modules.add(package.name) cr.commit() _logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, openerp.sql_db.sql_counter - t0_sql) registry.clear_manual_fields() cr.commit() return loaded_modules, processed_modules
def wrapper(___dbname, *args, **kwargs): """ Wraps around OSV functions and normalises a few exceptions """ dbname = ___dbname # NOTE: this forbid to use "___dbname" as arguments in http routes def tr(src, ttype): # We try to do the same as the _(), but without the frame # inspection, since we aready are wrapping an osv function # trans_obj = self.get('ir.translation') cannot work yet :( ctx = {} if not kwargs: if args and isinstance(args[-1], dict): ctx = args[-1] elif isinstance(kwargs, dict): if 'context' in kwargs: ctx = kwargs['context'] elif 'kwargs' in kwargs: # http entry points such as call_kw() ctx = kwargs['kwargs'].get('context') uid = 1 if args and isinstance(args[0], (long, int)): uid = args[0] lang = ctx and ctx.get('lang') if not (lang or hasattr(src, '__call__')): return src # We open a *new* cursor here, one reason is that failed SQL # queries (as in IntegrityError) will invalidate the current one. cr = False if hasattr(src, '__call__'): # callable. We need to find the right parameters to call # the orm._sql_message(self, cr, uid, ids, context) function, # or we skip.. # our signature is f(registry, dbname [,uid, obj, method, args]) try: if args and len(args) > 1: # TODO self doesn't exist, but was already wrong before (it was not a registry but just the object_service. obj = self.get(args[1]) if len(args) > 3 and isinstance( args[3], (long, int, list)): ids = args[3] else: ids = [] cr = openerp.sql_db.db_connect(dbname).cursor() return src(obj, cr, uid, ids, context=(ctx or {})) except Exception: pass finally: if cr: cr.close() return False # so that the original SQL error will # be returned, it is the best we have. try: cr = openerp.sql_db.db_connect(dbname).cursor() res = translate(cr, name=False, source_type=ttype, lang=lang, source=src) if res: return res else: return src finally: if cr: cr.close() def _(src): return tr(src, 'code') tries = 0 while True: try: if openerp.registry(dbname)._init and not openerp.tools.config[ 'test_enable']: raise openerp.exceptions.Warning( 'Currently, this database is not fully loaded and can not be used.' ) return f(dbname, *args, **kwargs) except (OperationalError, QWebException) as e: if isinstance(e, QWebException): cause = e.qweb.get('cause') if isinstance(cause, OperationalError): e = cause else: raise # Automatically retry the typical transaction serialization errors if e.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY: raise if tries >= MAX_TRIES_ON_CONCURRENCY_FAILURE: _logger.info("%s, maximum number of tries reached" % errorcodes.lookup(e.pgcode)) raise wait_time = random.uniform(0.0, 2**tries) tries += 1 _logger.info("%s, retry %d/%d in %.04f sec..." % (errorcodes.lookup(e.pgcode), tries, MAX_TRIES_ON_CONCURRENCY_FAILURE, wait_time)) time.sleep(wait_time) except IntegrityError, inst: registry = openerp.registry(dbname) for key in registry._sql_error.keys(): if key in inst[0]: raise ValidationError( tr(registry._sql_error[key], 'sql_constraint') or inst[0]) if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): msg = _( 'The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set' ) _logger.debug("IntegrityError", exc_info=True) try: errortxt = inst.pgerror.replace('«', '"').replace('»', '"') if '"public".' in errortxt: context = errortxt.split('"public".')[1] model_name = table = context.split('"')[1] else: last_quote_end = errortxt.rfind('"') last_quote_begin = errortxt.rfind( '"', 0, last_quote_end) model_name = table = errortxt[ last_quote_begin + 1:last_quote_end].strip() model = table.replace("_", ".") if model in registry: model_class = registry[model] model_name = model_class._description or model_class._name msg += _('\n\n[object with reference: %s - %s]') % ( model_name, model) except Exception: pass raise ValidationError(msg) else: raise ValidationError(inst[0])
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, str): 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 = openerp.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, str): 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, 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, str): 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 list(view_res.get('fields',{}).keys()): view_data = registry[datas['res_model']].default_get(cr, uid, list(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 list(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 as 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 else: raise Exception("Cannot handle action of type %s" % act_model) log_test("will be using %s action %s #%d", act_model, act_xmlid, act_id) action = registry[act_model].read(cr, uid, [act_id], context=context)[0] assert action, "Could not read action %s[%s]" %(act_model, act_id) loop = 0 while action: loop += 1 # This part tries to emulate the loop of the Gtk client if loop > 100: _logger.error("Passed %d loops, giving up", loop) raise Exception("Too many loops at action") log_test("it is an %s action at loop #%d", action.get('type', 'unknown'), loop) result = _exec_action(action, datas, context) if not isinstance(result, dict): break datas = result.get('datas', {}) if datas: del result['datas'] action = result return True