Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC
This commit is contained in:
117
ruodoo_commission_test_tours/README.rst
Normal file
117
ruodoo_commission_test_tours/README.rst
Normal file
@@ -0,0 +1,117 @@
|
||||
==========================================
|
||||
РуОду — Комиссии агентам: сценарные тесты
|
||||
==========================================
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
||||
:alt: License: LGPL-3
|
||||
|
||||
|badge1| |badge2|
|
||||
|
||||
Сквозной функциональный тест модуля ``ruodoo_commission`` на штатном
|
||||
механизме туров Odoo (``web_tour`` + ``HttpCase.start_tour``, headless
|
||||
Chrome). Тест имитирует работу пользователя через интерфейс и после
|
||||
каждого этапа проверяет результат по данным в БД (ORM), а не только по
|
||||
экрану. Предназначен для запуска перед релизом: падает, если бизнес-
|
||||
процесс комиссий сломан.
|
||||
|
||||
Только для тестирования — модуль не несёт бизнес-логики.
|
||||
|
||||
**Содержание**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Что проверяется
|
||||
===============
|
||||
|
||||
Один тестовый метод (``test_commission_full_flow``) последовательно
|
||||
запускает три тура под пользователем «продавец + начисляет комиссии»:
|
||||
|
||||
#. **Заказ и начисление** (``ruodoo_commission_order_tour``):
|
||||
создать заказ, выбрать клиента, добавить строку (товар, количество),
|
||||
выбрать две комиссии в колонке «Комиссии», сохранить, подтвердить,
|
||||
нажать «Начислить комиссию».
|
||||
#. **Смарт-кнопка** (``ruodoo_commission_smart_button_tour``):
|
||||
открыть заказ, нажать смарт-кнопку «Комиссии», увидеть список
|
||||
сформированных счетов поставщика.
|
||||
#. **Отмена** (``ruodoo_commission_cancel_tour``): отменить заказ через
|
||||
интерфейс.
|
||||
|
||||
Проверки по БД между турами:
|
||||
|
||||
* заказ подтверждён; в строке один товар, количество 10, две комиссии;
|
||||
* сумма комиссий строки и «ИТОГО КОМИССИЙ» заказа совпадают (150);
|
||||
* комиссии не входят в итог заказа (``amount_total`` = 1000);
|
||||
* сформированы два счёта поставщика (по числу получателей), оба
|
||||
проведены; суммы (100 и 50) совпадают с суммами комиссий;
|
||||
* журнал и счёт расходов в счетах — из настроек комиссии;
|
||||
* счётчик смарт-кнопки равен 2;
|
||||
* после отмены заказ в состоянии «Отменён», счета комиссий удалены.
|
||||
|
||||
Зависимости
|
||||
===========
|
||||
|
||||
* ``ruodoo_commission`` — тестируемый модуль
|
||||
* ``sale_management`` — заказы на продажу (UI-сценарий)
|
||||
* ``account`` — счета поставщика
|
||||
|
||||
Требования окружения
|
||||
====================
|
||||
|
||||
Туры выполняются в headless-браузере, поэтому в окружении нужны:
|
||||
|
||||
* **Chrome/Chromium** (Odoo ищет ``google-chrome`` / ``chromium`` в
|
||||
``PATH``; путь можно задать переменной ``ODOO_BROWSER_BIN``);
|
||||
* Python-пакет **websocket-client** (иначе тур-тест будет пропущен).
|
||||
|
||||
.. note::
|
||||
|
||||
Если браузер или ``websocket-client`` недоступны, Odoo помечает
|
||||
тест как *skipped*. Пропуск не является успехом — для достоверного
|
||||
прогона перед релизом обеспечьте оба компонента (например, в
|
||||
``Dockerfile`` образа Odoo).
|
||||
|
||||
Запуск
|
||||
======
|
||||
|
||||
::
|
||||
|
||||
odoo -d <test_db> -i ruodoo_commission_test_tours \
|
||||
--test-enable --test-tags=/ruodoo_commission_test_tours \
|
||||
--stop-after-init
|
||||
|
||||
Полезные опции: ``--screenshots=/tmp/commission_tours`` для скриншотов
|
||||
при падении; ``ODOO_BROWSER_BIN=/path/to/chrome`` — явный путь к браузеру.
|
||||
|
||||
Как это устроено
|
||||
================
|
||||
|
||||
* Туры (``static/tests/tours/*.js``) подключены как ассеты в
|
||||
``web.assets_tests`` и зарегистрированы в
|
||||
``registry.category("web_tour.tours")``.
|
||||
* Селекторы — стабильные: по ``name`` полей/кнопок
|
||||
(``button[name=action_accrue_commission]``,
|
||||
``.o_field_many2many_tags[name=commission_ids]``), семантическим
|
||||
классам Odoo и ``:contains`` только для данных, созданных тестом
|
||||
(«Tour Customer», «Tour Commission …»).
|
||||
* Данные (клиент, товар без налогов, два вида комиссий с журналом,
|
||||
счётом расходов и партнёрами-получателями, пользователь с группами)
|
||||
создаются в ``setUpClass`` через ORM. ORM используется только для
|
||||
подготовки и проверок; действия сценария выполняются в UI.
|
||||
|
||||
Авторы
|
||||
======
|
||||
|
||||
* MK.Lab, RuOdoo
|
||||
|
||||
Модуль сопровождается MK.Lab, RuOdoo.
|
||||
|
||||
.. image:: https://ruodoo.ru/logo.png
|
||||
:alt: MK.Lab, RuOdoo
|
||||
:target: https://ruodoo.ru
|
||||
|
||||
Модуль является частью решения РуОду.
|
||||
0
ruodoo_commission_test_tours/__init__.py
Normal file
0
ruodoo_commission_test_tours/__init__.py
Normal file
48
ruodoo_commission_test_tours/__manifest__.py
Normal file
48
ruodoo_commission_test_tours/__manifest__.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'РуОду — Комиссии агентам: сценарные тесты (туры)',
|
||||
'version': '19.0.2026.09.27',
|
||||
'summary': 'Сквозной UI-тест модуля комиссий через web_tour',
|
||||
'description': """
|
||||
РуОду — Комиссии агентам: сценарные тесты
|
||||
=========================================
|
||||
|
||||
Сквозной функциональный тест модуля ``ruodoo_commission`` на штатном
|
||||
механизме туров Odoo (``web_tour`` + ``HttpCase.start_tour``, headless
|
||||
Chrome).
|
||||
|
||||
Сценарий имитирует работу пользователя через интерфейс:
|
||||
|
||||
* создание заказа продаж, выбор клиента, заполнение строки (товар,
|
||||
количество), выбор нескольких комиссий в колонке «Комиссии»;
|
||||
* сохранение и подтверждение заказа;
|
||||
* начисление комиссии (кнопка «Начислить комиссию») — формирование
|
||||
счетов поставщика;
|
||||
* переход по смарт-кнопке «Комиссии» к сформированным счетам;
|
||||
* отмена заказа.
|
||||
|
||||
После каждого этапа результат проверяется по данным в БД (ORM):
|
||||
совпадение сумм комиссий в строке/заказе и в счетах, корректность
|
||||
подставленных журнала/счёта расходов/партнёра, а также штатная отмена
|
||||
с удалением счетов комиссий.
|
||||
|
||||
Только для тестирования: модуль не несёт бизнес-логики.
|
||||
""",
|
||||
'author': 'MK.Lab, RuOdoo',
|
||||
'website': 'https://ruodoo.ru',
|
||||
'category': 'Accounting',
|
||||
'depends': [
|
||||
'ruodoo_commission',
|
||||
'sale_management',
|
||||
'account',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_tests': [
|
||||
'ruodoo_commission_test_tours/static/tests/tours/*.js',
|
||||
],
|
||||
},
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'license': 'LGPL-3',
|
||||
'maintainers': ['mklab', 'ruodoo'],
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_utils";
|
||||
|
||||
/**
|
||||
* Этап 3: отменить заказ через интерфейс и убедиться, что отмена
|
||||
* отрабатывает штатно (заказ переходит в состояние «Cancelled»).
|
||||
* Каскадное удаление счетов комиссий проверяется в Python после тура.
|
||||
*
|
||||
* Кнопка «Отмена» в Odoo 19 может находиться в выпадающем меню
|
||||
* действий строки состояния — используем statusbarButtonsSteps.
|
||||
*/
|
||||
registry.category("web_tour.tours").add("ruodoo_commission_cancel_tour", {
|
||||
url: "/odoo",
|
||||
steps: () => [
|
||||
...stepUtils.goToAppSteps("sale.sale_menu_root", "Открыть приложение «Продажи»"),
|
||||
{
|
||||
content: "Открыть заказ Tour Customer из списка",
|
||||
trigger: '.o_list_view td.o_data_cell:contains("Tour Customer")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Форма заказа открыта",
|
||||
trigger: ".o_form_view .o_statusbar_status",
|
||||
},
|
||||
// Нажать «Отмена» (может быть в дропдауне действий).
|
||||
...stepUtils.statusbarButtonsSteps("Cancel", "Нажать «Отмена»"),
|
||||
// Базовый sale.action_cancel не открывает визард — состояние сразу
|
||||
// меняется. На случай подтверждающего модального окна закроем его.
|
||||
{
|
||||
content: "Подтвердить отмену, если появилось модальное окно",
|
||||
trigger: "body",
|
||||
run: function () {
|
||||
const btn = document.querySelector(
|
||||
".modal-dialog footer button.btn-primary"
|
||||
);
|
||||
if (btn) {
|
||||
btn.click();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
content: "Заказ отменён",
|
||||
trigger: ".o_statusbar_status .o_arrow_button_current:contains(Cancelled)",
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_utils";
|
||||
import saleUtils from "@sale/js/tours/tour_utils";
|
||||
|
||||
/**
|
||||
* Этап 1: создание заказа, выбор клиента, заполнение строки,
|
||||
* выбор двух комиссий в колонке «Комиссии», сохранение, подтверждение,
|
||||
* затем начисление комиссии (кнопка «Начислить комиссию»).
|
||||
*
|
||||
* Данные (клиент «Tour Customer», товар «Tour Product», комиссии
|
||||
* «Tour Commission 10» и «Tour Commission 5») создаёт Python-тест.
|
||||
* Тур ничего не делает через ORM — только UI.
|
||||
*/
|
||||
registry.category("web_tour.tours").add("ruodoo_commission_order_tour", {
|
||||
url: "/odoo",
|
||||
steps: () => [
|
||||
...stepUtils.goToAppSteps("sale.sale_menu_root", "Открыть приложение «Продажи»"),
|
||||
...saleUtils.createNewSalesOrder(),
|
||||
...saleUtils.selectCustomer("Tour Customer"),
|
||||
|
||||
// --- Строка заказа: товар ---
|
||||
...saleUtils.addProduct("Tour Product"),
|
||||
|
||||
// Количество = 10
|
||||
{
|
||||
content: "Указать количество",
|
||||
trigger: ".o_selected_row div[name=product_uom_qty] input",
|
||||
run: "edit 10",
|
||||
},
|
||||
|
||||
// --- Комиссии строки: выбрать две ---
|
||||
{
|
||||
content: "Открыть поле «Комиссии» в строке",
|
||||
trigger: ".o_selected_row .o_field_many2many_tags[name=commission_ids] input",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ввести первую комиссию",
|
||||
trigger: ".o_selected_row .o_field_many2many_tags[name=commission_ids] input",
|
||||
run: "edit Tour Commission 10",
|
||||
},
|
||||
{
|
||||
content: "Выбрать комиссию 10%",
|
||||
trigger: 'ul.ui-autocomplete a:contains("Tour Commission 10")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Убедиться, что тег комиссии 10% добавлен",
|
||||
trigger: '.o_selected_row .o_field_many2many_tags[name=commission_ids] .o_tag:contains("Tour Commission 10")',
|
||||
},
|
||||
{
|
||||
content: "Ввести вторую комиссию",
|
||||
trigger: ".o_selected_row .o_field_many2many_tags[name=commission_ids] input",
|
||||
run: "edit Tour Commission 5",
|
||||
},
|
||||
{
|
||||
content: "Выбрать комиссию 5%",
|
||||
trigger: 'ul.ui-autocomplete a:contains("Tour Commission 5")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Убедиться, что тег комиссии 5% добавлен",
|
||||
trigger: '.o_selected_row .o_field_many2many_tags[name=commission_ids] .o_tag:contains("Tour Commission 5")',
|
||||
},
|
||||
|
||||
// --- Сохранить заказ ---
|
||||
...stepUtils.saveForm(),
|
||||
|
||||
// Проверить, что «ИТОГО КОМИССИЙ» отобразилось (поле видно группе)
|
||||
{
|
||||
content: "Итог комиссий присутствует на форме",
|
||||
trigger: ".o_field_widget[name=amount_commission]",
|
||||
},
|
||||
|
||||
// --- Подтвердить заказ ---
|
||||
{
|
||||
content: "Подтвердить заказ",
|
||||
trigger: "button[name=action_confirm]",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Заказ перешёл в состояние «Заказ продаж»",
|
||||
trigger: ".o_statusbar_status .o_arrow_button_current:contains(Sales Order)",
|
||||
},
|
||||
|
||||
// --- Начислить комиссию ---
|
||||
{
|
||||
content: "Нажать «Начислить комиссию»",
|
||||
trigger: "button[name=action_accrue_commission]",
|
||||
run: "click",
|
||||
},
|
||||
// После начисления открывается список/форма счетов комиссий.
|
||||
{
|
||||
content: "Открылись счета комиссий (вендор-биллы)",
|
||||
trigger: ".o_list_view .o_data_row, .o_form_view .o_breadcrumb",
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_utils";
|
||||
|
||||
/**
|
||||
* Этап 2: открыть заказ и проверить смарт-кнопку «Комиссии»:
|
||||
* она нажимается и выводит связанные счета поставщика.
|
||||
*
|
||||
* Заказ уже подтверждён и по нему начислены комиссии (этап 1).
|
||||
*/
|
||||
registry.category("web_tour.tours").add("ruodoo_commission_smart_button_tour", {
|
||||
url: "/odoo",
|
||||
steps: () => [
|
||||
...stepUtils.goToAppSteps("sale.sale_menu_root", "Открыть приложение «Продажи»"),
|
||||
{
|
||||
content: "Открыть заказ Tour Customer из списка",
|
||||
trigger: '.o_list_view td.o_data_cell:contains("Tour Customer")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Форма заказа открыта",
|
||||
trigger: ".o_form_view .o_statusbar_status",
|
||||
},
|
||||
// Смарт-кнопка «Комиссии» видна и содержит счётчик > 0
|
||||
{
|
||||
content: "Смарт-кнопка «Комиссии» присутствует",
|
||||
trigger: "button[name=action_view_commission_bills]",
|
||||
},
|
||||
{
|
||||
content: "Нажать смарт-кнопку «Комиссии»",
|
||||
trigger: "button[name=action_view_commission_bills]",
|
||||
run: "click",
|
||||
},
|
||||
// Открывается список счетов поставщика по этому заказу.
|
||||
{
|
||||
content: "Открылся список счетов комиссий",
|
||||
trigger: ".o_list_view .o_data_row",
|
||||
},
|
||||
{
|
||||
content: "Это счета поставщика (тип «Bill»)",
|
||||
trigger: ".o_breadcrumb",
|
||||
},
|
||||
],
|
||||
});
|
||||
1
ruodoo_commission_test_tours/tests/__init__.py
Normal file
1
ruodoo_commission_test_tours/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import test_commission_tours
|
||||
193
ruodoo_commission_test_tours/tests/test_commission_tours.py
Normal file
193
ruodoo_commission_test_tours/tests/test_commission_tours.py
Normal 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: счета комиссий должны быть удалены при отмене заказа",
|
||||
)
|
||||
Reference in New Issue
Block a user