Public release from ruodoo-project: 19.0 - 2026-05-31 21:19:12 UTC

This commit is contained in:
CI Publish Bot
2026-05-31 21:19:21 +00:00
commit aa4214c195
1213 changed files with 183945 additions and 0 deletions

View File

@ -0,0 +1 @@
from . import premium_order_wizard

View File

@ -0,0 +1,174 @@
# -*- 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)