Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC

This commit is contained in:
CI Publish Bot
2026-11-01 22:54:30 +00:00
commit 26250aa580
2492 changed files with 664277 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,193 @@
from odoo import Command
from odoo.tests import tagged, HttpCase
from odoo.addons.sale.tests.common import TestSaleCommon
@tagged('post_install', '-at_install')
class TestCommissionTours(TestSaleCommon, HttpCase):
"""Сквозной UI-тест модуля комиссий через web_tour.
Данные готовятся через ORM (R1), действия пользователя выполняются
в интерфейсе турами, результат каждого этапа проверяется по БД.
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
company = cls.company_data['company']
cls.purchase_journal = cls.company_data['default_journal_purchase']
cls.expense_account = cls.company_data['default_account_expense']
# --- Клиент ---
cls.customer = cls.env['res.partner'].create({
'name': 'Tour Customer',
'company_id': False,
})
# --- Товар: складируемый/потребляемый, цена 100, без налогов ---
cls.tour_product = cls.env['product.product'].create({
'name': 'Tour Product',
'type': 'consu',
'list_price': 100.0,
'taxes_id': [Command.clear()],
})
# --- Партнёры-получатели комиссий ---
cls.agent_10 = cls.env['res.partner'].create({'name': 'Tour Agent Ten'})
cls.agent_5 = cls.env['res.partner'].create({'name': 'Tour Agent Five'})
Commission = cls.env['commission.commission']
cls.commission_10 = Commission.create({
'name': 'Tour Commission 10',
'calc_type': 'percentage',
'percentage': 10.0,
'partner_id': cls.agent_10.id,
'journal_id': cls.purchase_journal.id,
'account_id': cls.expense_account.id,
'company_id': company.id,
})
cls.commission_5 = Commission.create({
'name': 'Tour Commission 5',
'calc_type': 'percentage',
'percentage': 5.0,
'partner_id': cls.agent_5.id,
'journal_id': cls.purchase_journal.id,
'account_id': cls.expense_account.id,
'company_id': company.id,
})
# --- Пользователь: продавец + менеджер комиссий ---
# group_commission_manager включает group_commission_viewer.
cls.tour_user = cls.env['res.users'].create({
'name': 'Tour Commission Manager',
'login': 'tour_commission',
'password': 'tour_commission',
'company_id': company.id,
'company_ids': [Command.set([company.id])],
'group_ids': [Command.set([
cls.env.ref('sales_team.group_sale_salesman_all_leads').id,
cls.env.ref('ruodoo_commission.group_commission_manager').id,
# Право просматривать счета поставщика (открытие по смарт-кнопке).
cls.env.ref('account.group_account_invoice').id,
])],
})
# ------------------------------------------------------------------
def _get_order(self):
return self.env['sale.order'].search(
[('partner_id', '=', self.customer.id)], limit=1,
)
def test_commission_full_flow(self):
# =============== Этап 1: заказ + комиссии + начисление ===============
self.start_tour(
'/odoo', 'ruodoo_commission_order_tour', login='tour_commission',
)
order = self._get_order()
self.assertTrue(order, msg="Этап 1: заказ должен быть создан")
self.assertEqual(
order.state, 'sale',
msg="Этап 1: заказ должен быть подтверждён (state='sale')",
)
self.assertEqual(
len(order.order_line), 1,
msg="Этап 1: в заказе должна быть одна строка",
)
line = order.order_line
self.assertEqual(
line.product_id, self.tour_product,
msg="Этап 1: товар строки — Tour Product",
)
self.assertEqual(
line.product_uom_qty, 10.0,
msg="Этап 1: количество должно быть 10",
)
self.assertEqual(
line.commission_ids, self.commission_10 | self.commission_5,
msg="Этап 1: к строке должны быть привязаны обе комиссии",
)
# Суммы комиссий: 10 шт × 100 = 1000; 10% = 100; 5% = 50; итог 150.
self.assertAlmostEqual(
line.commission_amount, 150.0,
msg="Этап 1: сумма комиссий строки должна быть 150",
)
self.assertAlmostEqual(
order.amount_commission, 150.0,
msg="Этап 1: «ИТОГО КОМИССИЙ» заказа должно быть 150",
)
# Комиссии не входят в итог заказа.
self.assertAlmostEqual(
order.amount_total, 1000.0,
msg="Этап 1: итог заказа не должен включать комиссии (1000)",
)
# Начислены счета комиссий: два партнёра-получателя → два билла.
bills = order.commission_bill_ids
self.assertEqual(
len(bills), 2,
msg="Этап 1: должно быть два счёта комиссий (по получателям)",
)
self.assertEqual(
set(bills.mapped('move_type')), {'in_invoice'},
msg="Этап 1: счета комиссий — счета поставщика (in_invoice)",
)
self.assertEqual(
set(bills.mapped('state')), {'posted'},
msg="Этап 1: счета комиссий должны быть проведены",
)
# Суммы в биллах совпадают с суммами комиссий заказа.
bill_10 = bills.filtered(lambda m: m.partner_id == self.agent_10)
bill_5 = bills.filtered(lambda m: m.partner_id == self.agent_5)
self.assertAlmostEqual(
bill_10.amount_total, 100.0,
msg="Этап 1: счёт агенту 10% должен быть на 100",
)
self.assertAlmostEqual(
bill_5.amount_total, 50.0,
msg="Этап 1: счёт агенту 5% должен быть на 50",
)
self.assertAlmostEqual(
sum(bills.mapped('amount_total')), order.amount_commission,
msg="Этап 1: сумма счетов должна совпадать с итогом комиссий заказа",
)
# Счета подставляются правильно: журнал и счёт расходов из карточки.
self.assertEqual(
set(bills.mapped('journal_id')), {self.purchase_journal},
msg="Этап 1: журнал счетов — из настроек комиссии",
)
self.assertEqual(
set(bills.invoice_line_ids.mapped('account_id')),
{self.expense_account},
msg="Этап 1: счёт расходов строк — из настроек комиссии",
)
# =============== Этап 2: смарт-кнопка «Комиссии» ===============
self.assertEqual(
order.commission_bill_count, 2,
msg="Этап 2: счётчик смарт-кнопки должен быть 2",
)
self.start_tour(
'/odoo', 'ruodoo_commission_smart_button_tour',
login='tour_commission',
)
# =============== Этап 3: отмена заказа ===============
bill_ids = bills.ids
self.start_tour(
'/odoo', 'ruodoo_commission_cancel_tour', login='tour_commission',
)
order.invalidate_recordset()
self.assertEqual(
order.state, 'cancel',
msg="Этап 3: заказ должен быть отменён",
)
remaining = self.env['account.move'].search([('id', 'in', bill_ids)])
self.assertFalse(
remaining,
msg="Этап 3: счета комиссий должны быть удалены при отмене заказа",
)