Files
public/premium_client/wizard/premium_order_wizard.py

174 lines
7.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import json
import logging
import re
import time
from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
_logger = logging.getLogger(__name__)
try:
import requests
except Exception: # pragma: no cover
requests = None
class PremiumOrderWizard(models.TransientModel):
_name = "premium.order.wizard"
_description = "Премиум: заявка на сервис"
service_id = fields.Many2one("premium.service", string="Сервис", required=True)
company_name = fields.Char(string="Название компании", required=True)
inn = fields.Char(string="ИНН") # будет браться из VAT
email = fields.Char(string="Email", required=True)
phone_telegram = fields.Char(string="Телефон/Телеграм")
contact_person = fields.Char(string="Контактное лицо")
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
company = self.env.company
res.setdefault("company_name", company.name)
res.setdefault("inn", company.vat)
res.setdefault("email", company.email or self.env.user.email)
res.setdefault("phone_telegram", company.phone or company.mobile)
res.setdefault("contact_person", self.env.user.name)
_logger.info("Premium order wizard default values: %s", res)
return res
@api.constrains("email")
def _check_email(self):
email_regex = r"^[\w\.-]+@[\w\.-]+\.\w+$"
for rec in self:
if rec.email and not re.match(email_regex, rec.email):
raise ValidationError(_("Некорректный формат email."))
@api.constrains("inn")
def _check_inn(self):
for rec in self:
if rec.inn and (not rec.inn.isdigit() or len(rec.inn) not in (10, 12)):
raise ValidationError(_("ИНН должен содержать 10 или 12 цифр."))
@api.onchange("email")
def _onchange_email(self):
if self.email and not re.match(r"^[\w\.-]+@[\w\.-]+\.\w+$", self.email):
return {
"warning": {
"title": _("Предупреждение"),
"message": _("Некорректный формат email."),
}
}
@api.onchange("inn")
def _onchange_inn(self):
if self.inn and (not self.inn.isdigit() or len(self.inn) not in (10, 12)):
return {
"warning": {
"title": _("Предупреждение"),
"message": _("ИНН должен содержать 10 или 12 цифр."),
}
}
def _build_payload(self):
self.ensure_one()
service = self.service_id
payload = {
"service_id": service.id,
"service_name": service.name,
"service_category": service.category,
"service_author_url": service.author_url,
"service_description": (service.description or ""),
"company_name": self.company_name,
"inn": self.inn,
"email": self.email,
"phone": self.phone_telegram,
"contact_name": self.contact_person,
"source_db": self.env.cr.dbname,
}
_logger.info("Premium order payload built: %s", payload)
return payload
def action_submit(self):
self.ensure_one()
if not self.email or not self.company_name:
raise UserError(_("Заполните обязательные поля: Email и Название компании."))
if requests is None:
raise UserError(_("Библиотека requests недоступна на сервере Odoo."))
icp = self.env["ir.config_parameter"].sudo()
base_url = (icp.get_param("premium.project_api_url") or "").strip()
token = (icp.get_param("premium.project_api_token") or "").strip()
_logger.info("Premium API configuration - URL: %s, Token present: %s", base_url, bool(token))
if not base_url:
raise UserError(
_("Не настроен адрес Project API (Settings → Technical → Parameters → System Parameters).")
)
if base_url.endswith("/newlead/"):
url = base_url
else:
url = base_url.rstrip("/") + "/newlead/"
_logger.info("Premium API final URL: %s", url)
headers = {"Content-Type": "application/json"}
if token:
headers["X-API-Key"] = token
payload = self._build_payload()
_logger.info("Attempting to send payload to %s: %s", url, payload)
retries = 3
for attempt in range(1, retries + 1):
try:
_logger.info("Premium order attempt %s of %s", attempt, retries)
resp = requests.post(url, json=payload, headers=headers, timeout=15)
_logger.info("Response status: %s, headers: %s", resp.status_code, dict(resp.headers))
ok = resp.status_code in (200, 201)
try:
body = resp.json()
_logger.info("Response body: %s", body)
except Exception as e:
body = {}
_logger.warning("Failed to parse response JSON: %s", e)
_logger.info("Response text: %s", resp.text)
if ok and (body.get("ok") is True):
_logger.info("Premium order successful, lead_id: %s", body.get("lead_id"))
return {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {
"title": _("Заявка успешно отправлена"),
"type": "success",
"sticky": False,
},
}
else:
_logger.error("Premium order failed: %s %s", resp.status_code, body)
if attempt == retries:
raise UserError(
_("Сервис временно недоступен, пожалуйста, отправьте заявку на info@inf-centre.ru")
)
except requests.exceptions.ConnectionError as e:
_logger.warning("Connection error on attempt %s: %s", attempt, e)
if attempt == retries:
_logger.exception("Premium order connection exception: %s", e)
raise UserError(
_("Не удалось подключиться к серверу Project. Проверьте настройки подключения или отправьте заявку на info@inf-centre.ru")
)
time.sleep(3)
except Exception as e:
_logger.warning("Attempt %s failed: %s", attempt, e)
if attempt == retries:
_logger.exception("Premium order exception: %s", e)
raise UserError(
_("Сервис временно недоступен, пожалуйста, отправьте заявку на info@inf-centre.ru")
)
time.sleep(3)