Пример #1
0
 def update_checksum(self):
     missing = []
     for record in self:
         file_path = record._build_path()
         with opened_w_error(file_path, "rb") as (file_handler, exception):
             if exception:
                 missing.append(file_path)
                 _logger.error("Failed to read the file (%s): %s" % (file_path, str(exception)))
             else:
                 file = file_handler.read()
                 record.checksum = record._compute_checksum(file)
     if missing:
         message = _("Something went wrong! Seems that some files are missing.\n")
         for path in missing:
             message += "\n - %s" % path
         raise MissingError(message)
    def get_property_fields(self, object, properties):
        """ This method must be redefined by modules that
        introduce property fields in the relevant models.
        It intends to be used to compute the value of property fields.
        The models that implement this method will define the the logic
        to obtain the value of the property field for a certain object.
        If it is not defined by the models, will raise an error message.
        @param object: actual object for which we intend to get the property
        values.
        @param properties: ir.property recordset, including in
        the context the company for which we intend to obtain the value
        for the given object.

        @returns: Does not expect to return anything
        """
        raise MissingError(_('It must be redefined'))
Пример #3
0
 def _document_check_access(self,
                            model_name,
                            document_id,
                            access_token=None):
     document = request.env[model_name].browse([document_id])
     document_sudo = document.with_user(SUPERUSER_ID).exists()
     if not document_sudo:
         raise MissingError(_("This document does not exist."))
     try:
         document.check_access_rights('read')
         document.check_access_rule('read')
     except AccessError:
         if not access_token or not document_sudo.access_token or not consteq(
                 document_sudo.access_token, access_token):
             raise
     return document_sudo
Пример #4
0
 def validate_invoice_header(self):
     # extract the data lines from the specified absolute path
     # print "##### FILE NAME ",self.invoice_file_path
     data = self.read_file(self.invoice_file_path)
     # read the header attributes
     file_header = self.sanitize_row(data[0]).split(';')
     # validate header attributes
     for key in self.invoice_header:
         # print("key ",key)
         # print("### HEADER ",file_header)
         if key not in file_header:
             raise MissingError("Missing attribute invoice_header %s" % key)
     # remove the header
     data.pop(0)
     # store the data in object attribute
     self.invoice_data = [self.sanitize_row(row).split(';') for row in data]
Пример #5
0
 def check_report(self):
     """."""
     query = self.offering
     church = ('church_id', '=', self.env.user.company_id.id)
     services = self.env['ng_church.offering'].search([('service_id', '=',
                                                        query.id), church])
     offering_line = self.env['ng_church.offering_line']
     for offering in services:
         offering_line += offering_line.search([('offering_id', '=',
                                                 offering.id), church])
     offerings = self._report_range(offering_line, self.date_from,
                                    self.date_to)
     if len(offerings) > 0:
         return self.env['report'].get_action(
             offerings, 'ng_church.church_offering_report')
     raise MissingError('Record not found')
Пример #6
0
 def _prepare_claim(self, params):
     categ = self.env['crm.case.categ'].search([('id', '=',
                                                 params['subject_id'])])
     claim_type = self.env.ref('crm_claim_type.crm_claim_type_customer').id
     backend_id = self.backend_record.id
     vals = {
         'categ_id': params['subject_id'],
         'name': categ.name,
         'description': params['message'],
         'partner_id': self.partner.id,
         'claim_type': claim_type,
         'shopinvader_backend_id': backend_id,
         'claim_line_ids': []
     }
     vals = self.env['crm.claim'].play_onchanges(vals, ['partner_id'])
     order = False
     for line in params['sale_order_line']:
         if not line['qty']:
             continue
         so_line = self.env['sale.order.line'].search([
             ('id', '=', line['id']),
             ('order_id.partner_id', '=', self.partner.id),
             ('order_id.shopinvader_backend_id', '=', backend_id)
         ])
         if not so_line:
             raise MissingError(
                 _('The sale order line %s does not exist') % line['id'])
         if not order:
             order = so_line.order_id
             vals['ref'] = 'sale.order,%s' % order.id
         elif order != so_line.order_id:
             raise UserError(
                 _('All sale order lines must'
                   'come from the same sale order'))
         if order.invoice_ids and not vals.get('invoice_id', False):
             vals['invoice_id'] = order.invoice_ids[0].id
         vals['claim_line_ids'].append((0, 0, {
             'product_id':
             so_line.product_id.id,
             'product_returned_quantity':
             line['qty'],
             'claim_origin':
             'none'
         }))
     if not vals['claim_line_ids']:
         raise UserError(_('You have to select an item'))
     return vals
Пример #7
0
    def _get_report_values(self, docids, data=None):
        partner_obj = self.env["res.partner"]
        student_ids = self.env.context.get("active_ids", [])
        students = partner_obj.browse(student_ids or docids)

        template = self.env.company.school_leaving_template
        if not template:
            raise MissingError("School Leaving Report Template is empty.")

        contents = {}
        for student in students:
            vals = {
                "date_today": fields.Date.context_today(self),
            }
            student_vals = student.read()[0]
            for key, value in student_vals.items():
                vals["student_" + key] = value
            parent = student.family_ids.member_ids.filtered(
                lambda m: m.person_type == "parent")
            if parent:
                parent_vals = parent[0].read()[0]
                for key, value in parent_vals.items():
                    vals["parent_" + key] = value
            if student.grade_level_id:
                grade_level_vals = student.grade_level_id.read()[0]
                for key, value in grade_level_vals.items():
                    vals["grade_level_" + key] = value
            for key, value in vals.items():
                new_value = str(value)
                if isinstance(value, date):
                    new_value = format_date(self.env, value)
                elif isinstance(value, datetime):
                    new_value = format_datetime(self.env, value)
                vals[key] = new_value
            try:
                contents[student.id] = template % vals
            except:
                raise ValidationError(
                    "An error has occurred while formatting the school leaving report template."
                )

        return {
            "doc_ids": student_ids,
            "doc_model": "res.partner",
            "docs": students,
            "contents": contents,
        }
Пример #8
0
 def find(self, env, path, model=None):
     if model:
         return self._find(env, path, model)
     else:
         result = []
         try:
             result.append(self._find(env, path, 'muk_dms.directory'))
         except MissingError:
             pass
         try:
             result.append(self._find(env, path, 'muk_dms.file'))
         except MissingError:
             pass
         if result:
             return result
         else:
             raise MissingError(_("The record is missing!"))
Пример #9
0
 def _read_file(self, file_path):
     with opened_w_error(file_path, "rb") as (file_handler, exception):
         if exception:
             _logger.error("Failed to read the file (%s): %s" % (file_path, str(exception)))
             raise MissingError(
                 _("Something went wrong! Seems that the file (%s) is missing or broken.") %
                 os.path.basename(file_path))
         else:
             file = file_handler.read()
             encode_file = base64.b64encode(file)
             if self._check_file(file, self.checksum):
                 return encode_file
             else:
                 _logger.error(
                     "Failed to read the file (%s): The file has been altered outside of the system." %
                     os.path.basename(file_path))
                 raise ValidationError(_("The file (%s) is corrupted.") % os.path.basename(file_path))
Пример #10
0
 def _ticket_check_access(self, model_name, document_id, access_token=None):
     document_search = request.env[model_name].sudo().search([
         ('id', '=', document_id),
         ('partner_id.id', '=', request.env.user.partner_id.id)
     ])
     document = request.env[model_name].sudo().browse([document_id])
     document_sudo = document.sudo().exists()
     if not document_sudo or not document_search:
         raise MissingError("This document does not exist.")
     try:
         document.check_access_rights('read')
         document.check_access_rule('read')
     except AccessError:
         if not access_token or not consteq(document_sudo.access_token,
                                            access_token):
             raise
     return document_sudo
Пример #11
0
 def _document_check_access(self,
                            model_name,
                            document_id,
                            access_token=None):
     document = request.env[model_name].browse([document_id])
     _logger.info("document: " + str(document))
     document_sudo = document.sudo().exists()
     if not document_sudo:
         raise MissingError("This document does not exist.")
     try:
         document.check_access_rights('read')
         document.check_access_rule('read')
     except AccessError:
         if not access_token or not consteq(document_sudo.access_token,
                                            access_token):
             raise
     return document_sudo
Пример #12
0
    def _find_from_reference(self, reference):
        """Find a task from the given reference.

        :param reference: the task reference for which to find a task.
        :return: a project.task record if any found, otherwise None
        """
        if not reference.task_id:
            return None

        task = self.browse(reference.task_id)

        if not task.exists():
            raise MissingError(
                _('The task referenced by {ref} does not exist. '
                  'No task found for the database ID {id}.').format(
                      ref=reference, id=reference.task_id))

        return task
Пример #13
0
 def get(self, _id, size):
     """
     Get partner's image
     """
     field = 'image'
     if size == 'small':
         field = 'image_small'
     elif size == 'medium':
         field = 'image_medium'
     status, headers, content = self.env['ir.http'].binary_content(
         model='res.partner', id=_id, field=field, env=self.env)
     if not content:
         raise MissingError(_('No image found for partner %s') % _id)
     image_base64 = base64.b64decode(content)
     headers.append(('Content-Length', len(image_base64)))
     response = request.make_response(image_base64, headers)
     response.status_code = status
     return response
Пример #14
0
 def _prepare_second_account_move_line(self, move_id):
     if self.journal_id.default_debit_account_id.id == False:
         raise MissingError(
             '{} default debit and credit are not set.'.format(
                 self.journal_id.name))
     payload = {
         'name': self.description,
         'account_id': self.journal_id.default_debit_account_id.id,
         'move_id': move_id,
         'partner_id': parish(self),
         'quantity': 1,
         'debit': abs(self.amount),
         'credit': 0.0,
         'date': self.date,
     }
     account_move_line = self.env['account.move.line'].with_context(
         check_move_validity=False)
     account_move_line.create(payload)
Пример #15
0
 def get(self, _id, size):
     """
     Get partner's image
     """
     field = "image"
     if size == "small":
         field = "image_small"
     elif size == "medium":
         field = "image_medium"
     status, headers, content = self.env["ir.http"].binary_content(
         model="res.partner", id=_id, field=field, env=self.env)
     if not content:
         raise MissingError(_("No image found for partner %s") % _id)
     image_base64 = base64.b64decode(content)
     headers.append(("Content-Length", len(image_base64)))
     response = request.make_response(image_base64, headers)
     response.status_code = status
     return response
Пример #16
0
    def apply_discount(self):

        for order_id in self:
            write_lines = []
            partner_id = order_id.student_id if order_id.student_id else order_id.partner_id
            discount_ids = partner_id.discount_ids

            for order_line_id in order_id.order_line:

                # If there is a student, our priority is the student

                invoice_line_categories = get_parent_category(
                    order_line_id.product_id.categ_id)
                discount_applicable = discount_ids.filtered(
                    lambda discount: discount.category_id in
                    invoice_line_categories)

                for discount in discount_applicable:
                    percent = discount.percent
                    discount_count = -order_line_id.price_subtotal * (percent /
                                                                      100)

                    if not discount.product_id:
                        raise MissingError(
                            "There is no product set for the discount %s" %
                            discount.name)

                    order_line_create = {
                        "product_id":
                        discount.product_id.get_single_product_variant().get(
                            "product_id", False),
                        "price_unit":
                        discount_count,
                        # "analytic_account_id": discount.analytic_account_id.id,
                    }

                    if order_line_id.tax_id:
                        order_line_create.update(
                            {"tax_id": [(6, 0, order_line_id.tax_id.ids)]})

                    write_lines.append((0, 0, order_line_create))

            order_id.write({"order_line": write_lines})
Пример #17
0
    def aeroo_report(self, docids, data):

        self.name = self._context.get('report_name')
        report = self.env['ir.actions.report']._get_report_from_name(self.name)
        # TODO
        #_logger.info("Start Aeroo Reports %s (%s)" % (name, ctx.get('active_model')), logging.INFO) # debug mode

        if 'tz' not in self._context:
            self = self.with_context(tz=self.env.user.tz)

        # TODO we should propagate context in the proper way, just with self

        # agregamos el process_sep aca ya que necesitamos el doc convertido
        # para poder unirlos
        if report.process_sep and len(docids) > 1:
            # por ahora solo soportamos process_sep para pdf, en version
            # anterior tambien soportaba algun otro
            code = report.out_format.code
            if code != 'oo-pdf':
                raise MissingError(
                    _('Process_sep not compatible with selected output format')
                )

            results = []
            for docid in docids:
                results.append(
                    self.assemble_tasks([docid], data, report, self._context))
            output = PdfFileWriter()
            for r in results:
                reader = PdfFileReader(BytesIO(r[0]))
                for page in range(reader.getNumPages()):
                    output.addPage(reader.getPage(page))
            s = BytesIO()
            output.write(s)
            data = s.getvalue()
            res = self._context.get('return_filename') and\
                (data, results[0][1], results[0][2]) or (data, results[0][1])
        else:
            res = self.assemble_tasks(docids, data, report, self._context)
        # TODO
        #_logger.info("End Aeroo Reports %s (%s), total elapsed time: %s" % (name, model), time() - aeroo_print.start_total_time), logging.INFO) # debug mode

        return res
Пример #18
0
 def action_print_report_xlsx(self):
     self.create_report_view()
     self._cr.execute("SELECT * FROM hotel_report")
     docs = self._cr.fetchall()
     if not docs:
         raise MissingError("Record does not exist or has been deleted.")
     return {
         'type': 'ir.actions.report',
         'data': {
             'model':
             'report.hotel_management.report_xlsx',
             'options':
             json.dumps(self.get_data(), default=date_utils.json_default),
             'output_format':
             'xlsx',
             'report_name':
             'Hotel Management Report',
         },
         'report_type': 'xlsx',
     }
 def _get_commerce_partner(self):
     if self._jwt_payload:
         partner_email = self._jwt_payload.get("email")
         backend = self._get_backend()
         if partner_email:
             commerce_partner = self._find_partner(backend, partner_email)
             if len(commerce_partner) == 1:
                 self._validate_partner(backend, commerce_partner)
                 return commerce_partner
             else:
                 _logger.warning("Wrong email, jwt payload ignored")
                 if len(commerce_partner) > 1:
                     _logger.warning(
                         "More than one commerce.partner found for:"
                         " backend_id={} email={}".format(
                             backend.id, partner_email))
                 # Could be because the email is not related to a partner or
                 # because the partner is inactive
                 raise MissingError(_("The given partner is not found!"))
     return super()._get_commerce_partner()
Пример #20
0
 def _get_partner_from_headers(cls, headers):
     partner_model = request.env["shopinvader.partner"]
     partner_email = headers.get("HTTP_PARTNER_EMAIL")
     backend = cls._get_shopinvader_backend_from_request()
     if partner_email:
         partner = cls._find_partner(backend, partner_email)
         if len(partner) == 1:
             cls._validate_partner(backend, partner)
             return partner.record_id
         else:
             _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored")
             if len(partner) > 1:
                 _logger.warning(
                     "More than one shopinvader.partner found for:"
                     " backend_id={} email={}".format(
                         backend.id, partner_email))
             # Could be because the email is not related to a partner or
             # because the partner is inactive
             raise MissingError(_("The given partner is not found!"))
     return partner_model.browse([]).record_id
 def _get_commerce_partner(self):
     headers = self.request.httprequest.environ
     partner_model = self.env["commerce.partner"]
     partner_email = headers.get("HTTP_PARTNER_EMAIL")
     backend = self._get_backend()
     if partner_email:
         partner = self._find_partner(backend, partner_email)
         if len(partner) == 1:
             self._validate_partner(backend, partner)
             return partner
         else:
             _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored")
             if len(partner) > 1:
                 _logger.warning(
                     "More than one commerce.partner found for:"
                     " backend_id={} email={}".format(backend.id, partner_email)
                 )
             # Could be because the email is not related to a partner or
             # because the partner is inactive
             raise MissingError(_("The given partner is not found!"))
     return partner_model.browse([])
Пример #22
0
    def validate_counter_header(self):
        # extract the data lines from the specified absolute path
        data = self.read_file(self.counter_file_path)
        # read the header attributes
        file_header = self.sanitize_row(data[0]).split(';')
        # validate header attributes
        for key in self.counter_header:
            if key not in file_header:
                raise MissingError("Missing attribute counter_header %s" % key)
        # remove the header
        data.pop(0)
        # store the data in object attribute
        self.counter_data = [self.sanitize_row(row).split(';') for row in data]
        record_id = self.env['file.compteur'].search([])
        if record_id:
            record_id.unlink()

        for rec in self.counter_data:
            vals = {
                'CodeConcession':
                rec[self.counter_header.index('CodeConcession')],
                'NomConcession':
                rec[self.counter_header.index('NomConcession')],
                'CodeClient':
                rec[self.counter_header.index('CodeClient')],
                'NumeroSerie':
                rec[self.counter_header.index('NuméroSérie')],
                'DateLimite':
                rec[self.counter_header.index('DateLimite')],
                'CodeCompteur1':
                rec[self.counter_header.index('CodeCompteur1')],
                'CodeCompteur2':
                rec[self.counter_header.index('CodeCompteur2')],
                'DernierCompteur1':
                rec[self.counter_header.index('DernierCompteur1')],
                'DernierCompteur2':
                rec[self.counter_header.index('DernierCompteur2')],
            }
            self.env['file.compteur'].create(vals)
Пример #23
0
 def _get_deduction_lines(self):
     self.ensure_one()
     res = []
     if not self.employee_id.address_home_id:
         raise MissingError("Private address of {} is not set. Set the private address in the employee form.".format(employee.name))
     partner = self.employee_id.address_home_id
     results, total, amls = self.env["report.account.report_agedpartnerbalance"].with_context(
         partner_ids=partner)._get_partner_move_lines(
                 ["receivable"], fields.Date.context_today(self), "posted", 30)
     remaining_wage = self.net_wage
     for aml in amls.get(partner.id, []):
         if aml["amount"] <= 0 or (self.struct_id.type_id.invoice_payment_scope == "overdue" and aml["period"] >= 6):
             continue
         residual_amount = min(aml["amount"], remaining_wage)
         deduction_vals = {
             "move_line_id": aml["line"].id,
             "amount": residual_amount,
         }
         res.append(deduction_vals)
         remaining_wage -= residual_amount
         if not remaining_wage:
             break
     return res
Пример #24
0
    def get_facebook_access_token(self):
        self.execute()
        get_param = self.env['ir.config_parameter'].sudo().get_param

        base_url = 'http://localhost'  # get_param('web.base.url', 'http://localhost')
        https_url = base_url.replace("http://", "https://")
        canvas_url = https_url + "/config-save-token"

        perms = get_param('omi.fb_permission', '').split(',')

        app_id = self.fb_app_id

        if app_id and canvas_url and perms:
            graph = facebook.GraphAPI(version=3.1)
            auth_url = "%s&response_type=token" % graph.get_auth_url(
                app_id, canvas_url, perms)
            return {
                'type': 'ir.actions.act_url',
                'url': auth_url,
                'target': 'self',
                'target_type': 'public',
            }
        raise MissingError(_('Require "Facebook App ID" and "Permissions"'))
Пример #25
0
    def _find_record(
        self,
        xmlid=None,
        res_model='ir.attachment',
        res_id=None,
        access_token=None,
    ):
        """
        Find and return a record either using an xmlid either a model+id
        pair. This method is an helper for the ``/web/content`` and
        ``/web/image`` controllers and should not be used in other
        contextes.

        :param Optional[str] xmlid: xmlid of the record
        :param Optional[str] res_model: model of the record,
            ir.attachment by default.
        :param Optional[id] res_id: id of the record
        :param Optional[str] access_token: access token to use instead
            of the access rights and access rules.
        :returns: single record
        :raises MissingError: when no record was found.
        """
        record = None
        if xmlid:
            record = self.env.ref(xmlid, False)
        elif res_id is not None and res_model in self.env:
            record = self.env[res_model].browse(res_id).exists()
        if not record:
            raise MissingError(
                f"No record found for xmlid={xmlid}, res_model={res_model}, id={res_id}"
            )

        if record._name == 'ir.attachment':
            record = record.validate_access(access_token)

        return record
Пример #26
0
def init_postgis(cr):
    """ Initialize postgis
    Add PostGIS support to the database. PostGIS is a spatial database
    extender for PostgreSQL object-relational database. It adds support for
    geographic objects allowing location queries to be run in SQL.
    """
    cr.execute("""
        SELECT
            tablename
        FROM
            pg_tables
        WHERE
            tablename='spatial_ref_sys';
    """)
    check = cr.fetchone()
    if check:
        return {}
    try:
        cr.execute("""
        CREATE EXTENSION postgis;
        CREATE EXTENSION postgis_topology;
    """)
    except Exception:
        raise MissingError(
            _(
                "Error, can not automatically initialize spatial postgis"
                " support. Database user may have to be superuser and"
                " postgres/postgis extensions with their devel header have"
                " to be installed. If you do not want Odoo to connect with a"
                " super user you can manually prepare your database. To do"
                " this, open a client to your database using a super user and"
                " run:\n"
                "CREATE EXTENSION postgis;\n"
                "CREATE EXTENSION postgis_topology;\n"
            )
        )
    def _get_report_values(self, docids, data=None):
        payment_obj = self.env["pos_pr.invoice.payment"]
        pos_session_id = data["form"]["pos_session_id"][0]
        grouping = data["form"]["grouping"]
        payments = payment_obj.search([("pos_session_id", "=", pos_session_id)
                                       ])
        if not payments:
            raise MissingError(
                "There are no invoice payments related to this session.")

        if grouping == "method":
            groups = payments.mapped("payment_method_id")
        else:
            groups = payments.mapped("payment_group_id")

        return {
            "doc_ids": payments.ids,
            "doc_model": "pos_pr.invoice.payment",
            "docs": payments,
            "groups": groups,
            "grouping": grouping,
            "session": self.env["pos.session"].browse(pos_session_id),
            "getattr": getattr,
        }
Пример #28
0
    def validate_statement_header(self):
        # extract the data lines from the specified absolute path
        data = self.read_file(self.statement_file_path)
        # read the header attributes
        file_header = self.sanitize_row(data[0]).split(';')
        # validate header attributes
        for key in self.statement_header:
            if key not in file_header:
                raise MissingError("Missing attribute statement_header %s" %
                                   key)
        # remove the header
        data.pop(0)
        # store the data in object attribute
        self.statement_data = [
            self.sanitize_row(row).split(';') for row in data
        ]
        record_id = self.env['file.releve'].search([])
        if record_id:
            record_id.unlink()
        for rec in self.statement_data:
            vals = {
                'TypeReleve': rec[1],
                'TypeCompteur': rec[2],
                'NumeroSerie': rec[3],
                'NumContrat': rec[4],
                'NumeroFacture': rec[5],
                'NumeroReleve': rec[6],
                'DateReleve': rec[7],
                'DateDebutPeriode': rec[8],
                'DateFinPeriode': rec[9],
                'CompteurReleve': rec[10],
                'Consommation': rec[11],
                'VolumeDepassement': rec[12],
            }

            self.env['file.releve'].create(vals)
Пример #29
0
    def _check_name_within_range(self):
        for move in self.filtered(lambda m: m.journal_id.is_honduras_invoice and m.state == "posted" and m.type == "out_invoice"):
            if not all([move.journal_id.cai, move.journal_id.prefix, move.journal_id.authorized_range_from,
                        move.journal_id.authorized_range_to, move.journal_id.issue_limit_date]):
                raise MissingError("CAI, Prefix, Issue Limit Date, or Authorized Range fields are not set in Journal")

            if fields.Date.context_today(self) > move.journal_id.issue_limit_date:
                raise ValidationError("Invoice issue limit date of %s is exceeded!" % move.journal_id.issue_limit_date)

            prefix = move.journal_id.prefix
            padding = move.journal_id.sequence_id.padding
            lower_limit = prefix + str(move.journal_id.authorized_range_from).zfill(padding)
            upper_limit = prefix + str(move.journal_id.authorized_range_to).zfill(padding)
            current_number = int(move.name.replace(prefix, ""))
            if move.journal_id.authorized_range_from > current_number or current_number > move.journal_id.authorized_range_to:
               raise ValidationError("Invoice number %s is outside of range (%s, %s)" % (move.name, lower_limit, upper_limit))
            move.cai = move.journal_id.cai
            move.authorized_range_from = lower_limit
            move.authorized_range_to = upper_limit
            move.issue_limit_date = move.journal_id.issue_limit_date

            warning_limit = prefix + str(move.journal_id.authorized_range_warning).zfill(padding)
            if move.name == warning_limit:
                self.env.ref("honduras_invoices.account_journal_mail_template_authorized_range_warn").send_mail(move.journal_id.id)
Пример #30
0
 def _get_partner_from_headers(cls, headers):
     partner_model = request.env["shopinvader.partner"]
     partner_email = headers.get("HTTP_PARTNER_EMAIL")
     backend = cls._get_shopinvader_backend_from_request()
     if partner_email:
         partner_domain = [
             ("partner_email", "=", partner_email),
             ("backend_id", "=", backend.id),
         ]
         partner = partner_model.search(partner_domain)
         if len(partner) == 1:
             return partner.record_id
         else:
             _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored")
             if len(partner) > 1:
                 _logger.warning(
                     "More than one shopinvader.partner found for domain:"
                     " %s",
                     partner_domain,
                 )
             # Could be because the email is not related to a partner or
             # because the partner is inactive
             raise MissingError("The given partner is not found!")
     return partner_model.browse([]).record_id