示例#1
0
    def get_technical_translations(self, model_name):
        """ Find the translations for the fields of `model_name`

        Find the technical translations for the fields of the model, including
        string, tooltip and available selections.

        :return: action definition to open the list of available translations
        """
        fields = self.env['ir.model.fields'].search([('model', '=', model_name)
                                                     ])
        selection_ids = tools.flatten([
            field.selection_ids.ids for field in fields
            if field.ttype == 'selection'
        ])
        view = self.env.ref("base.view_translation_tree",
                            False) or self.env['ir.ui.view']
        return {
            'name':
            _("Technical Translations"),
            'view_mode':
            'tree',
            'views': [(view.id, "list")],
            'res_model':
            'ir.translation',
            'type':
            'ir.actions.act_window',
            'domain': [
                '&', ('type', '=', 'model'), '|', '&',
                ('res_id', 'in', fields.ids),
                ('name', 'like', 'ir.model.fields,'), '&',
                ('res_id', 'in', selection_ids),
                ('name', 'like', 'ir.model.fields.selection,')
            ],
        }
示例#2
0
    def get_form_vals(
        self,
        dynamic_fields,
        domains,
        cfg_val_ids=None,
        product_tmpl_id=None,
        config_session_id=None,
    ):
        """Generate a dictionary to return new values via onchange method.
        Domains hold the values available, this method enforces these values
        if a selection exists in the view that is not available anymore.

        :param dynamic_fields: Dictionary with the current {dynamic_field: val}
        :param domains: Odoo domains restricting attribute values

        :returns vals: Dictionary passed to {'value': vals} by onchange method
        """
        vals = {}
        dynamic_fields = {k: v for k, v in dynamic_fields.items() if v}
        for k, v in dynamic_fields.items():
            if not v:
                continue
            available_val_ids = domains[k][0][2]
            if isinstance(v, list):
                if any(type(el) != int for el in v):
                    v = v[0][2]
                value_ids = list(set(v) & set(available_val_ids))
                dynamic_fields.update({k: value_ids})
                vals[k] = [[6, 0, value_ids]]
            elif v not in available_val_ids:
                dynamic_fields.update({k: None})
                vals[k] = None
            else:
                vals[k] = v

        final_cfg_val_ids = list(dynamic_fields.values())

        vals.update(
            self.get_onchange_vals(final_cfg_val_ids, config_session_id))
        # To solve the Multi selection problem removing extra []
        if "value_ids" in vals:
            val_ids = vals["value_ids"][0]
            vals["value_ids"] = [[
                val_ids[0], val_ids[1],
                tools.flatten(val_ids[2])
            ]]

        return vals
示例#3
0
def send_email(message, smtp):
    smtp_from = message['Return-Path'] or message['From']

    # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
    from_rfc2822 = extract_rfc2822_addresses(smtp_from)
    assert from_rfc2822, (
        "Malformed 'Return-Path' or 'From' address: %r - "
        "It should contain one valid plain ASCII email") % smtp_from
    # use last extracted email, to support rarities like 'Support@MyComp <*****@*****.**>'
    smtp_from = from_rfc2822[-1]
    email_to = message['To']
    email_cc = message['Cc']
    email_bcc = message['Bcc']

    smtp_to_list = filter(
        None,
        tools.flatten(
            map(extract_rfc2822_addresses, [email_to, email_cc, email_bcc])))

    x_forge_to = message['X-Forge-To']
    if x_forge_to:
        # `To:` header forged, e.g. for posting on mail.channels, to avoid confusion
        del message['X-Forge-To']
        del message['To']  # avoid multiple To: headers!
        message['To'] = x_forge_to

    try:
        message_id = message['Message-Id']
        # Add email in Maildir if smtp_server contains maildir.
        try:
            smtp.sendmail(smtp_from, smtp_to_list, message.as_string())
        finally:
            pass
    except Exception as e:
        msg = "Mail delivery failed via SMTP server"
        _logger.info(msg)
        return message_id
示例#4
0
    def send_email(self,
                   message,
                   mail_server_id=None,
                   smtp_server=None,
                   smtp_port=None,
                   smtp_user=None,
                   smtp_password=None,
                   smtp_encryption=None,
                   smtp_debug=False,
                   smtp_session=None):
        """Sends an email directly (no queuing).

        No retries are done, the caller should handle MailDeliveryException in order to ensure that
        the mail is never lost.

        If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments.
        If mail_server_id is None and smtp_server is None, use the default mail server (highest priority).
        If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments.
        If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config,
        and fails if not found.

        :param message: the email.message.Message to send. The envelope sender will be extracted from the
                        ``Return-Path`` (if present), or will be set to the default bounce address.
                        The envelope recipients will be extracted from the combined list of ``To``,
                        ``CC`` and ``BCC`` headers.
        :param smtp_session: optional pre-established SMTP session. When provided,
                             overrides `mail_server_id` and all the `smtp_*` parameters.
                             Passing the matching `mail_server_id` may yield better debugging/log
                             messages. The caller is in charge of disconnecting the session.
        :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments.
        :param smtp_server: optional hostname of SMTP server to use
        :param smtp_encryption: optional TLS mode, one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation)
        :param smtp_port: optional SMTP port, if mail_server_id is not passed
        :param smtp_user: optional SMTP user, if mail_server_id is not passed
        :param smtp_password: optional SMTP password to use, if mail_server_id is not passed
        :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed
        :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
                 MailDeliveryException and logs root cause.
        """
        # Use the default bounce address **only if** no Return-Path was
        # provided by caller.  Caller may be using Variable Envelope Return
        # Path (VERP) to detect no-longer valid email addresses.
        smtp_from = message['Return-Path'] or self._get_default_bounce_address(
        ) or message['From']
        assert smtp_from, "The Return-Path or From header is required for any outbound email"

        # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
        from_rfc2822 = extract_rfc2822_addresses(smtp_from)
        assert from_rfc2822, (
            "Malformed 'Return-Path' or 'From' address: %r - "
            "It should contain one valid plain ASCII email") % smtp_from
        # use last extracted email, to support rarities like 'Support@MyComp <*****@*****.**>'
        smtp_from = from_rfc2822[-1]
        email_to = message['To']
        email_cc = message['Cc']
        email_bcc = message['Bcc']

        smtp_to_list = filter(
            None,
            tools.flatten(
                map(extract_rfc2822_addresses,
                    [email_to, email_cc, email_bcc])))
        assert smtp_to_list, self.NO_VALID_RECIPIENT

        x_forge_to = message['X-Forge-To']
        if x_forge_to:
            # `To:` header forged, e.g. for posting on mail.channels, to avoid confusion
            del message['X-Forge-To']
            del message['To']  # avoid multiple To: headers!
            message['To'] = x_forge_to

        # Do not actually send emails in testing mode!
        if getattr(threading.currentThread(), 'testing', False):
            _test_logger.info("skip sending email in test mode")
            return message['Message-Id']

        try:
            message_id = message['Message-Id']
            smtp = smtp_session
            try:
                smtp = smtp or self.connect(smtp_server,
                                            smtp_port,
                                            smtp_user,
                                            smtp_password,
                                            smtp_encryption,
                                            smtp_debug,
                                            mail_server_id=mail_server_id)
                smtp.sendmail(smtp_from, smtp_to_list, message.as_string())
            finally:
                # do not quit() a pre-established smtp_session
                if smtp is not None and not smtp_session:
                    smtp.quit()
        except Exception as e:
            params = (ustr(smtp_server), e.__class__.__name__, ustr(e))
            msg = _(
                "Mail delivery failed via SMTP server '%s'.\n%s: %s") % params
            _logger.info(msg)
            raise MailDeliveryException(_("Mail Delivery Failed"), msg)
        return message_id
示例#5
0
    def send_email(self,
                   message,
                   mail_server_id=None,
                   smtp_server=None,
                   smtp_port=None,
                   smtp_user=None,
                   smtp_password=None,
                   smtp_encryption=None,
                   smtp_debug=False):
        """Sends an email directly (no queuing).

        No retries are done, the caller should handle MailDeliveryException in order to ensure that
        the mail is never lost.

        If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments.
        If mail_server_id is None and smtp_server is None, use the default mail server (highest priority).
        If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments.
        If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config,
        and fails if not found.

        :param message: the email.message.Message to send. The envelope sender will be extracted from the
                        ``Return-Path`` (if present), or will be set to the default bounce address.
                        The envelope recipients will be extracted from the combined list of ``To``,
                        ``CC`` and ``BCC`` headers.
        :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments.
        :param smtp_server: optional hostname of SMTP server to use
        :param smtp_encryption: optional TLS mode, one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation)
        :param smtp_port: optional SMTP port, if mail_server_id is not passed
        :param smtp_user: optional SMTP user, if mail_server_id is not passed
        :param smtp_password: optional SMTP password to use, if mail_server_id is not passed
        :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed
        :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
                 MailDeliveryException and logs root cause.
        """
        # Use the default bounce address **only if** no Return-Path was
        # provided by caller.  Caller may be using Variable Envelope Return
        # Path (VERP) to detect no-longer valid email addresses.
        smtp_from = message['Return-Path'] or self._get_default_bounce_address(
        ) or message['From']
        assert smtp_from, "The Return-Path or From header is required for any outbound email"

        # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
        from_rfc2822 = extract_rfc2822_addresses(smtp_from)
        assert from_rfc2822, (
            "Malformed 'Return-Path' or 'From' address: %r - "
            "It should contain one valid plain ASCII email") % smtp_from
        # use last extracted email, to support rarities like 'Support@MyComp <*****@*****.**>'
        smtp_from = from_rfc2822[-1]
        email_to = message['To']
        email_cc = message['Cc']
        email_bcc = message['Bcc']

        smtp_to_list = filter(
            None,
            tools.flatten(
                map(extract_rfc2822_addresses,
                    [email_to, email_cc, email_bcc])))
        assert smtp_to_list, self.NO_VALID_RECIPIENT

        x_forge_to = message['X-Forge-To']
        if x_forge_to:
            # `To:` header forged, e.g. for posting on mail.channels, to avoid confusion
            del message['X-Forge-To']
            del message['To']  # avoid multiple To: headers!
            message['To'] = x_forge_to

        # Do not actually send emails in testing mode!
        if getattr(threading.currentThread(), 'testing', False):
            _test_logger.info("skip sending email in test mode")
            return message['Message-Id']

        # Get SMTP Server Details from Mail Server
        mail_server = None
        if mail_server_id:
            mail_server = self.sudo().browse(mail_server_id)
        elif not smtp_server:
            mail_server = self.sudo().search([], order='sequence', limit=1)

        if mail_server:
            smtp_server = mail_server.smtp_host
            smtp_user = mail_server.smtp_user
            smtp_password = mail_server.smtp_pass
            smtp_port = mail_server.smtp_port
            smtp_encryption = mail_server.smtp_encryption
            smtp_debug = smtp_debug or mail_server.smtp_debug
        else:
            # we were passed an explicit smtp_server or nothing at all
            smtp_server = smtp_server or tools.config.get('smtp_server')
            smtp_port = tools.config.get(
                'smtp_port', 25) if smtp_port is None else smtp_port

            smtp_user = smtp_user or tools.config.get('smtp_user')
            smtp_password = smtp_password or tools.config.get('smtp_password')
            if smtp_encryption is None and tools.config.get('smtp_ssl'):
                smtp_encryption = 'starttls'  # STARTTLS is the new meaning of the smtp_ssl flag as of v7.0

        if not smtp_server:
            raise UserError(
                _("Missing SMTP Server") + "\n" +
                _("Please define at least one SMTP server, or provide the SMTP parameters explicitly."
                  ))

        #mod by Yuri
        message.replace_header('From',
                               '%s <%s>' % (message['From'], smtp_user))
        if message.has_key('return-path'):
            message.replace_header('return-path', '%s' % (smtp_user, ))
        else:
            message.add_header('return-path', '%s' % (smtp_user, ))

        try:
            message_id = message['Message-Id']

            # Add email in Maildir if smtp_server contains maildir.
            if smtp_server.startswith('maildir:/'):
                from mailbox import Maildir
                maildir_path = smtp_server[8:]
                mdir = Maildir(maildir_path, factory=None, create=True)
                mdir.add(message.as_string(True))
                return message_id

            smtp = None

            try:
                smtp = self.connect(smtp_server, smtp_port, smtp_user,
                                    smtp_password, smtp_encryption or False,
                                    smtp_debug)
                smtp.sendmail(smtp_user, smtp_to_list, message.as_string())
            finally:
                if smtp is not None:
                    smtp.quit()
        except Exception as e:
            params = (ustr(smtp_server), e.__class__.__name__, ustr(e))
            msg = _(
                "Mail delivery failed via SMTP server '%s'.\n%s: %s") % params
            _logger.info(msg)
            raise MailDeliveryException(_("Mail Delivery Failed"), msg)

        return message_id
示例#6
0
    def send_email(self, message, mail_server_id=None, smtp_server=None, smtp_port=None,
                   smtp_user=None, smtp_password=None, smtp_encryption=None, smtp_debug=False,
                   smtp_session=None):
        """Sends an email directly (no queuing).

        No retries are done, the caller should handle MailDeliveryException in order to ensure that
        the mail is never lost.

        If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments.
        If mail_server_id is None and smtp_server is None, use the default mail server (highest priority).
        If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments.
        If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config,
        and fails if not found.

        :param message: the email.message.Message to send. The envelope sender will be extracted from the
                        ``Return-Path`` (if present), or will be set to the default bounce address.
                        The envelope recipients will be extracted from the combined list of ``To``,
                        ``CC`` and ``BCC`` headers.
        :param smtp_session: optional pre-established SMTP session. When provided,
                             overrides `mail_server_id` and all the `smtp_*` parameters.
                             Passing the matching `mail_server_id` may yield better debugging/log
                             messages. The caller is in charge of disconnecting the session.
        :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments.
        :param smtp_server: optional hostname of SMTP server to use
        :param smtp_encryption: optional TLS mode, one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation)
        :param smtp_port: optional SMTP port, if mail_server_id is not passed
        :param smtp_user: optional SMTP user, if mail_server_id is not passed
        :param smtp_password: optional SMTP password to use, if mail_server_id is not passed
        :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed
        :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
                 MailDeliveryException and logs root cause.
        """
        # Use the default bounce address **only if** no Return-Path was
        # provided by caller.  Caller may be using Variable Envelope Return
        # Path (VERP) to detect no-longer valid email addresses.
        smtp_from = message['Return-Path'] or self._get_default_bounce_address() or message['From']
        assert smtp_from, "The Return-Path or From header is required for any outbound email"

        # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
        from_rfc2822 = extract_rfc2822_addresses(smtp_from)
        assert from_rfc2822, ("Malformed 'Return-Path' or 'From' address: %r - "
                              "It should contain one valid plain ASCII email") % smtp_from
        # use last extracted email, to support rarities like 'Support@MyComp <*****@*****.**>'
        smtp_from = from_rfc2822[-1]
        email_to = message['To']
        email_cc = message['Cc']
        email_bcc = message['Bcc']

        smtp_to_list = filter(None, tools.flatten(map(extract_rfc2822_addresses, [email_to, email_cc, email_bcc])))
        assert smtp_to_list, self.NO_VALID_RECIPIENT

        x_forge_to = message['X-Forge-To']
        if x_forge_to:
            # `To:` header forged, e.g. for posting on mail.channels, to avoid confusion
            del message['X-Forge-To']
            del message['To']           # avoid multiple To: headers!
            message['To'] = x_forge_to

        # Do not actually send emails in testing mode!
        if getattr(threading.currentThread(), 'testing', False):
            _test_logger.info("skip sending email in test mode")
            return message['Message-Id']

        try:
            message_id = message['Message-Id']
            smtp = smtp_session
            try:
                smtp = smtp or self.connect(
                    smtp_server, smtp_port, smtp_user, smtp_password,
                    smtp_encryption, smtp_debug, mail_server_id=mail_server_id)
                smtp.sendmail(smtp_from, smtp_to_list, message.as_string())
            finally:
                # do not quit() a pre-established smtp_session
                if smtp is not None and not smtp_session:
                    smtp.quit()
        except Exception as e:
            params = (ustr(smtp_server), e.__class__.__name__, ustr(e))
            msg = _("Mail delivery failed via SMTP server '%s'.\n%s: %s") % params
            _logger.info(msg)
            raise MailDeliveryException(_("Mail Delivery Failed"), msg)
        return message_id
示例#7
0
    def send_email(self, message, mail_server_id=None, smtp_server=None, smtp_port=None,
                   smtp_user=None, smtp_password=None, smtp_encryption=None, smtp_debug=False):
        """Sends an email directly (no queuing).

        No retries are done, the caller should handle MailDeliveryException in order to ensure that
        the mail is never lost.

        If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments.
        If mail_server_id is None and smtp_server is None, use the default mail server (highest priority).
        If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments.
        If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config,
        and fails if not found.

        :param message: the email.message.Message to send. The envelope sender will be extracted from the
                        ``Return-Path`` (if present), or will be set to the default bounce address.
                        The envelope recipients will be extracted from the combined list of ``To``,
                        ``CC`` and ``BCC`` headers.
        :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments.
        :param smtp_server: optional hostname of SMTP server to use
        :param smtp_encryption: optional TLS mode, one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation)
        :param smtp_port: optional SMTP port, if mail_server_id is not passed
        :param smtp_user: optional SMTP user, if mail_server_id is not passed
        :param smtp_password: optional SMTP password to use, if mail_server_id is not passed
        :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed
        :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
                 MailDeliveryException and logs root cause.
        """
        # Use the default bounce address **only if** no Return-Path was
        # provided by caller.  Caller may be using Variable Envelope Return
        # Path (VERP) to detect no-longer valid email addresses.
        smtp_from = message['Return-Path'] or self._get_default_bounce_address() or message['From']
        assert smtp_from, "The Return-Path or From header is required for any outbound email"

        # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
        from_rfc2822 = extract_rfc2822_addresses(smtp_from)
        assert from_rfc2822, ("Malformed 'Return-Path' or 'From' address: %r - "
                              "It should contain one valid plain ASCII email") % smtp_from
        # use last extracted email, to support rarities like 'Support@MyComp <*****@*****.**>'
        smtp_from = from_rfc2822[-1]
        email_to = message['To']
        email_cc = message['Cc']
        email_bcc = message['Bcc']

        smtp_to_list = filter(None, tools.flatten(map(extract_rfc2822_addresses, [email_to, email_cc, email_bcc])))
        assert smtp_to_list, self.NO_VALID_RECIPIENT

        x_forge_to = message['X-Forge-To']
        if x_forge_to:
            # `To:` header forged, e.g. for posting on mail.channels, to avoid confusion
            del message['X-Forge-To']
            del message['To']           # avoid multiple To: headers!
            message['To'] = x_forge_to

        # Do not actually send emails in testing mode!
        if getattr(threading.currentThread(), 'testing', False):
            _test_logger.info("skip sending email in test mode")
            return message['Message-Id']

        # Get SMTP Server Details from Mail Server
        mail_server = None
        if mail_server_id:
            mail_server = self.sudo().browse(mail_server_id)
        elif not smtp_server:
            mail_server = self.sudo().search([], order='sequence', limit=1)

        if mail_server:
            smtp_server = mail_server.smtp_host
            smtp_user = mail_server.smtp_user
            smtp_password = mail_server.smtp_pass
            smtp_port = mail_server.smtp_port
            smtp_encryption = mail_server.smtp_encryption
            smtp_debug = smtp_debug or mail_server.smtp_debug
        else:
            # we were passed an explicit smtp_server or nothing at all
            smtp_server = smtp_server or tools.config.get('smtp_server')
            smtp_port = tools.config.get('smtp_port', 25) if smtp_port is None else smtp_port
            smtp_user = smtp_user or tools.config.get('smtp_user')
            smtp_password = smtp_password or tools.config.get('smtp_password')
            if smtp_encryption is None and tools.config.get('smtp_ssl'):
                smtp_encryption = 'starttls' # STARTTLS is the new meaning of the smtp_ssl flag as of v7.0

        if not smtp_server:
            raise UserError(_("Missing SMTP Server") + "\n" + _("Please define at least one SMTP server, or provide the SMTP parameters explicitly."))

        try:
            message_id = message['Message-Id']

            # Add email in Maildir if smtp_server contains maildir.
            if smtp_server.startswith('maildir:/'):
                from mailbox import Maildir
                maildir_path = smtp_server[8:]
                mdir = Maildir(maildir_path, factory=None, create=True)
                mdir.add(message.as_string(True))
                return message_id

            smtp = None
            try:
                smtp = self.connect(smtp_server, smtp_port, smtp_user, smtp_password, smtp_encryption or False, smtp_debug)
                smtp.sendmail(smtp_from, smtp_to_list, message.as_string())
            finally:
                if smtp is not None:
                    smtp.quit()
        except Exception as e:
            params = (ustr(smtp_server), e.__class__.__name__, ustr(e))
            msg = _("Mail delivery failed via SMTP server '%s'.\n%s: %s") % params
            _logger.info(msg)
            raise MailDeliveryException(_("Mail Delivery Failed"), msg)
        return message_id
示例#8
0
    def default_get(self, cr, uid, fields, context=None):
        print "default_get........"
        #cr.execute('insert into relation_name (self_id,module_name_id) values(%s,%s)',(first_value,second_value)
        res = {}
        if context is None: context = {}
        res = super(assign_interpreter, self).default_get(cr,
                                                          uid,
                                                          fields,
                                                          context=context)
        event_ids = context.get('active_ids', [])
        print "event_ids........", event_ids
        #active_model = context.get('active_model')
        if not event_ids or len(event_ids) != 1:
            # Partial Picking Processing may only be done for one picking at a time
            return res
        event_id, = event_ids
        if 'event_id' in fields:
            res.update(event_id=event_id)
        event = self.pool.get('event').browse(cr,
                                              uid,
                                              event_id,
                                              context=context)
        state = event.state
        if 'language_id' in fields:
            res.update({
                'language_id':
                event.language_id and event.language_id.id or False
            })
        #print "default_get..........",res

        event_ids = context.get('active_ids', [])
        #print "event_ids.......",event_ids
        obj = self.pool.get('hr.employee')
        select_obj = self.pool.get('select.interpreter')
        interpreter_ids = new_ids = select_ids = []
        if event_ids:
            lang = self.pool.get('event').browse(cr, uid,
                                                 event_ids[0]).language_id
            partner = self.pool.get('event').browse(cr, uid,
                                                    event_ids[0]).partner_id
            #            print "lang....",lang
            #            lang = self.browse(cr, uid, ids, context=context)
            #            sql = "select  interpreter_id from interpreter_language where name = %d"%(lang.id)
            int_lang_ids = self.pool.get('interpreter.language').search(
                cr, uid, [('name', '=', lang.id)])
            #            print "int_lang_ids........",int_lang_ids

            if int_lang_ids:
                for int_lang_id in int_lang_ids:
                    lang_browse = self.pool.get('interpreter.language').browse(
                        cr, uid, int_lang_id)
                    interpreter_ids.append(lang_browse.interpreter_id.id)
            new_ids = interpreter_ids
            if interpreter_ids:
                print "interpreter_ids........", interpreter_ids
                zip = partner.zip
                #print "zip...........",zip
                if zip:
                    #                    gibberish = urllib.urlopen('http://www.uszip.com/zip/' + '203150')
                    #                    less_gib = gibberish.read().decode('utf-8')
                    #                    query = "select id from hr_employee where zip = %s and id in %s"%( str(zip) + '' , tuple(interpreter_ids))
                    #                    cr.execute(query )
                    #                    i_ids = map(lambda x: x[0], cr.fetchall())
                    min_zip = int(zip) - 10
                    max_zip = int(zip) + 10
                    print "min_zip...max_zip......", min_zip, max_zip
                    visit_ids = []
                    for history in partner.interpreter_history:
                        if history.name.id in interpreter_ids:
                            visit_ids.append(history.name.id)
                    if visit_ids:
                        visit_ids = flatten(visit_ids)
                        visit_ids = list(set(visit_ids))

                    print "visit_ids........", visit_ids
                    for visit_id in visit_ids:
                        if visit_id in interpreter_ids:
                            interpreter_ids.remove(visit_id)
#                    print "visit_ids........",visit_ids
#                    print "interpreter_ids......",interpreter_ids
                    i_ids = obj.search(cr,
                                       uid,
                                       [('zip', '=', zip),
                                        ('id', 'in', tuple(interpreter_ids))],
                                       order="rate")
                    #                    print "i_ids.......",i_ids
                    #                    i_ids1 = obj.search(cr ,uid ,[('zip','!=',zip),('zip','!=',zip),('zip','!=',zip),('id','in',tuple(interpreter_ids))])
                    #                    query = "select id from hr_employee where zip::integer != %s and zip::integer <= %s and zip::integer >= %s and id in %s  order by rate "%( str(zip), str(max_zip) ,str(min_zip)  , tuple(interpreter_ids))
                    #                    cr.execute(query )
                    #                    i_ids1 = map(lambda x: x[0], cr.fetchall())
                    i_ids1 = obj.search(cr,
                                        uid,
                                        [('zip', '!=', zip),
                                         ('zip', '<=', max_zip),
                                         ('zip', '>=', min_zip),
                                         ('id', 'in', tuple(interpreter_ids))],
                                        order="rate")
                    print "i_ids1.......", i_ids1
                    new_ids = i_ids + i_ids1
                    #                    print "new_ids...........",new_ids
                    #                    select_ids = select_obj.search(cr ,uid ,[])
                    #                    print "select_ids........",select_ids
                    #                    for select_id in select_ids:
                    #                        select_obj.unlink(cr ,uid , select_id)
                    #                    query1 = "delete from select_assign_rel "
                    #                    cr.execute(query1 )
                    select_ids = []
                    for visit_id in visit_ids:
                        query = "select max(event_date) from interpreter_alloc_history where partner_id = %s and name = %s " % (
                            partner.id, visit_id)
                        cr.execute(query)
                        last_visit_date = map(lambda x: x[0], cr.fetchall())
                        #                        print "last_visit_date........",last_visit_date
                        history_ids = self.pool.get(
                            'interpreter.history').search(
                                cr,
                                uid, [(
                                    'name',
                                    '=',
                                    visit_id,
                                ), ('event_id', '=', event_ids[0]),
                                      ('state', '=', 'voicemailsent')],
                                order="event_date desc")
                        #voicemail_msg = self.pool.get('hr.employee').browse(cr ,uid , visit_id).voicemail_msg
                        voicemail_msg = ''
                        if history_ids:
                            voicemail_msg = self.pool.get(
                                'interpreter.history').browse(
                                    cr, uid, history_ids[0]).voicemail_msg
                        if last_visit_date and last_visit_date[0]:
                            select_ids.append(
                                select_obj.create(
                                    cr, uid, {
                                        'interpreter_id': visit_id,
                                        'event_id': event_ids[0],
                                        'visited': True,
                                        'visited_date': last_visit_date,
                                        'state': state,
                                        'voicemail_msg': voicemail_msg
                                    }))
                        else:
                            select_ids.append(
                                select_obj.create(
                                    cr, uid, {
                                        'interpreter_id': visit_id,
                                        'event_id': event_ids[0],
                                        'visited': True,
                                        'state': state,
                                        'voicemail_msg': voicemail_msg
                                    }))
                    for new_id in new_ids:
                        history_ids = self.pool.get(
                            'interpreter.history').search(
                                cr,
                                uid, [(
                                    'name',
                                    '=',
                                    new_id,
                                ), ('event_id', '=', event_ids[0]),
                                      ('state', '=', 'voicemailsent')],
                                order="event_date desc")
                        voicemail_msg = ''
                        if history_ids:
                            voicemail_msg = self.pool.get(
                                'interpreter.history').browse(
                                    cr, uid, history_ids[0]).voicemail_msg
                        select_ids.append(
                            select_obj.create(
                                cr, uid, {
                                    'interpreter_id': new_id,
                                    'event_id': event_ids[0],
                                    'state': state,
                                    'voicemail_msg': voicemail_msg
                                }))
#                    new_ids = tuple(new_ids)
#                    print "new_ids.....",new_ids
#                    print "list(new_ids).....",list(new_ids)
#                    print "select_ids........",select_ids

        res['interpreter_ids'] = select_ids  #[(6, 0, select_ids)]
        return res
class invoice_import_excel(models.TransientModel):
    """ Import Account Invoice Excel sheet and pay Account invoices """
    _name = "invoice.import.excel"
    _description = "Import Order"

    excel_file=fields.Binary('Excel file', required=True , filters='*.xls,*.xlsx')
    state=fields.Selection([('init','init'),('done','done')], 'state', readonly=True,default='init')
    check_number=fields.Char('Check Number', size=16)
    amount=fields.Float('Amount', digits=dp.get_precision('Account'))
    date_checkprint=fields.Date('Date',default=fields.Date.context_today)
    journal_id=fields.Many2one('account.journal','Payment Method')
    company_id=fields.Many2one('res.company', 'Company', required=True,default=lambda self: self.env['res.company']._company_default_get('invoice.import.excel'))
    reference=fields.Char('Payment Ref', size=64)
    file_name = fields.Char('Attachment Name', size=64)

    @api.multi
    def pay_invoices(self,inv_ids, invoice_amount):
        ''' Function to create customer wise vouchers and pay them from xls '''
        cust_inv, payment_ids, check_count = {}, [], 0
        invoice_obj = self.env['account.invoice']
        account_payment = self.env['account.payment']
        curr_pool = self.env['res.currency']
        customer_grouped, customer_invoice_grouped = [], [] 
        for payment_obj in self:
            journal = payment_obj.journal_id
            company_id = payment_obj.company_id.id or False
            reference = payment_obj.reference
            self=self.with_context(company_id=company_id)
            for invoice in invoice_obj.browse(inv_ids):
                if invoice.partner_id.id not in customer_grouped:
                    customer_grouped.append(invoice.partner_id.id)
                    customer_invoice_grouped.append(invoice.id)
                if not cust_inv.get(invoice.partner_id.id):
                    cust_inv[invoice.partner_id.id] = [invoice.id]
                else:
                    cust_inv[invoice.partner_id.id].append(invoice.id)
            for cust, invoices in cust_inv.iteritems():
                if not invoices or not cust:
                    return
                amount, inv_ids,line_ids= 0.0, [],[]
                for vals in invoice_obj.browse(invoices):
                    amount += invoice_amount.get(vals.id) or 0.0
                    inv_ids.append([(4, vals.id, None)])
                    ref = vals.origin or ''
                    original_amount = vals.amount_total
                    balance_amount = vals.residual
                    allocation = vals.residual
                    # if vals.currency_id.id != self.currency_id.id:
                    #     currency_id = self.currency_id.with_context(date=self.payment_date)
                    #     original_amount = curr_pool._compute(vals.currency_id, currency_id, original_amount, round=True)
                    #     balance_amount = curr_pool._compute(vals.currency_id, currency_id, balance_amount, round=True)
                    #     allocation = curr_pool._compute(vals.currency_id, currency_id, allocation, round=True)
                    event_id = vals.event_id and vals.event_id.id or False
                    patient_id = vals.patient_id and vals.patient_id.id or False
                    invoice_old_number = vals.invoice_old_number or ''
                    line_ids.append((0, 0, {
                        'invoice_id': vals.id, 'account_id': vals.account_id.id,
                        'invoice_old_number': invoice_old_number,
                        'date': vals.date_invoice, 'due_date': vals.date_due, 'patient_id': patient_id,
                        'original_amount': original_amount, 'balance_amount': balance_amount, 'event_id': event_id,
                        'allocation': allocation, 'full_reconclle': True, 'reference': ref,
                    }))

                payment_vals={
                    'journal_id': payment_obj.journal_id.id,
                    'payment_method_id': payment_obj.journal_id.outbound_payment_method_ids[0].id or False,
                    'payment_date': payment_obj.date_checkprint,
                    'reference': payment_obj.reference,
                    'invoice_ids': inv_ids,
                    'payment_type': 'outbound',
                    'amount': amount,
                    'partner_id': cust,
                    'partner_type': 'customer',
                    'line_ids':line_ids
                }
                if payment_obj.check_number:
                    if check_count == 0:
                        payment_vals['check_number_string'] = payment_obj.check_number or ''
                    else:
                        payment_vals['check_number_string'] = str(payment_obj.check_number) + '_' + str(check_count) or ''
                account_payment_id = account_payment.create(payment_vals)
                payment_ids.append(account_payment_id.id)
                account_payment_id.post()
                check_count += 1
        return payment_ids

    @api.model
    def get_test_file_path(self):
        """Return the test file path"""
        proxy = self.env['ir.config_parameter']
        file_path = proxy.sudo().get_param('test_file_path')
        if not file_path:
            raise UserError(_('Please configure test_file_path as "/home/openerp/" in config parameters.'))
        if file_path.endswith('/'):
            file_path += 'test.xls'
        else:
            file_path += '/test.xls'
        return file_path
    
    def import_excel(self):
        '''Code to import excel and generate a Voucher ,confirm the Voucher , and Validate that.'''
        data = self
        if not data.excel_file:
            raise UserError(_('Please select a Excel file'))
        if data.file_name:
            if not data.file_name.lower().endswith(('.xls', '.xlsx')):
                raise UserError(_('Unsupported File Format.'))
        if not data.company_id:
            raise UserError(_('You must select Company First.'))
        file = base64.decodestring(data.excel_file)
        invoice_no, amount = 0, 1
        file_path = self.get_test_file_path()
        fp = open(file_path,'wb')
        fp.write(file)
        fp.close()
        book = xlrd.open_workbook(file_path)
        sh = book.sheet_by_index(0)
#        logger.info(' row count : %d',sh.nrows)
#        print "sh.nrows..........",sh.nrows
        inv_ids, total_amount, invoice_amount, inv_amount, invoice_num_list = [], 0.0, {}, {}, ['0']
        for line in range (1, sh.nrows):
            try:
                row = sh.row_values(line)
#                print "row............",row
                if row != '':
                    if not row[invoice_no]:
                        continue
                    amt = row[amount] or 0.0
                    if amt < 0.0:
                        continue
                    total_amount += float(amt)
                    inv_no = str(row[invoice_no]).strip().split('.')[0]
                    if row[invoice_no] in inv_amount:
                        inv_amount[inv_no] += amt or 0.0
                    else:
                        inv_amount[inv_no] = amt or 0.0
                        invoice_num_list.append(inv_no)
            except Exception , e:
                logger.info(' Exception : %s',e.args)
        if round(total_amount,6) != round(data.amount,6):
            raise UserError(_('Total Invoice amount and paid amount is mismatching!'))
        if invoice_num_list:
            self._cr.execute("select id, number from account_invoice where state = 'open' and company_id = %d and  number in %s"%(data.company_id.id, tuple(invoice_num_list)))
            result = self._cr.fetchall()
            if result:
                for rs in result:
                    if len(rs) == 2:
                        inv_ids.append(rs[0])
                        if rs[0] in invoice_amount:
                            invoice_amount[rs[0]] += inv_amount[str(rs[1])] or 0.0
                        else:
                            invoice_amount[rs[0]] = inv_amount[str(rs[1])] or 0.0

#        print "inv_ids.............",len(inv_ids)
#        inv_ids = list(set(flatten(inv_ids)))
        payment_ids = self.pay_invoices(list(set(flatten(inv_ids))), invoice_amount)
        view_ref = self.env['ir.model.data'].sudo().get_object_reference('account', 'view_account_payment_tree')
        view_id = view_ref[1] if view_ref else False

        return {
            'name': _("Customer Payments"),
            'view_mode': 'tree,form',
            'view_type': 'form',
            'res_model': 'account.payment',
            'type': 'ir.actions.act_window',
            'domain': "[('id','in',["+','.join(map(str, payment_ids))+"])]",
        }