Beispiel #1
0
 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()
Beispiel #2
0
    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)
Beispiel #4
0
Datei: report.py Projekt: 0k/odoo
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
Beispiel #5
0
    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,
        }
Beispiel #6
0
 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
Beispiel #7
0
 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()
Beispiel #8
0
    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
Beispiel #11
0
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.'):])
Beispiel #12
0
 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
Beispiel #13
0
    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
Beispiel #15
0
    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,
        }
Beispiel #16
0
 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
Beispiel #17
0
 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
Beispiel #18
0
 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]
Beispiel #19
0
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
Beispiel #21
0
    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 {}
Beispiel #22
0
 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()
Beispiel #23
0
 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()
Beispiel #24
0
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()
Beispiel #25
0
 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
Beispiel #26
0
 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
Beispiel #27
0
 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()
Beispiel #28
0
 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)
Beispiel #29
0
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
Beispiel #30
0
 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 = {}
Beispiel #31
0
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)
Beispiel #32
0
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)
Beispiel #33
0
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()
Beispiel #34
0
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
Beispiel #35
0
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
Beispiel #36
0
    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 {}
Beispiel #37
0
                                      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
Beispiel #38
0
    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
Beispiel #39
0
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
Beispiel #40
0
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)
Beispiel #42
0
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()
Beispiel #43
0
    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
Beispiel #44
0
    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
Beispiel #45
0
    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 {}
Beispiel #46
0
    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)
Beispiel #47
0
    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
Beispiel #48
0
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)
Beispiel #49
0
    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
Beispiel #50
0
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)
Beispiel #51
0
    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'
Beispiel #52
0
    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 {}
Beispiel #53
0
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()
Beispiel #54
0
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)
Beispiel #55
0
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,
    }
Beispiel #57
0
    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 {}
Beispiel #58
0
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
Beispiel #59
0
    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])
Beispiel #60
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