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,16 @@
# Российская локализация - Авансовые платежи
name: l10n_ru_advance_payments
## Описание
Модуль, добавляющий функционал ведения учета авансовых платежей, обеспечивает создание авансового счета на основе заказа продаж и последующее формирование к этому счету авансовых платежей. Он позволяет автоматически связывать авансовые платежи с соответствующими заказами и счетами, обеспечивая прозрачный и удобный учет предоплат в рамках бизнес-процессов. Благодаря этому модулю упрощается контроль за поступлением авансов, их распределением и учетом в финансовой отчетности, что повышает точность и эффективность управления денежными потоками.
### Создание авансового платежа:
1. Меню Продажи - выбираем нужный Заказ продаж - кнопка "Авансовый счет";
2. На форме проверяем информацию (при необходимости корректируем) и подтверждаем его нажатием на кнопку "Подтвердить";
3. При нажатии на кнопку "Регистрация платежа" откроется визард, где по умолчанию проставляется вся сумма счета. При необходимости редактируется на сумму фактического платежа. Добавленный платеж отображается на вкладке "Доп. информация". Там же отображается остаток долга по счету.;
4. При повторном создании платежа к тому же счету планируемая сумма платежа будет равна остатку долга по счету и так же может быть скорректирована.
### Для печати:
1. Открываем созданную запись счета - Действие - "Счет" (или "Счет по форме 1С")

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from . import models
from . import wizard
from . import report

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
{
'name': 'Российская локализация - Авансовые счета',
'version': '19.0.2025.06.06',
'description': """Модуль создания новой модели - Авансовые счета. Он добавляет функционал построенный на базовых
функциях бухгалтерии.""",
'author': "MK.Lab",
'website': "https://www.inf-centre.ru/",
'depends': ['account',
'sale',
'l10n_ru_contract',
'l10n_ru_doc',
'l10n_latam_check'
],
'data': [
'security/ir.model.access.csv',
'data/data.xml',
'views/order_prepaid.xml',
'views/sale_order.xml',
'report/order_prepaid.xml',
'report/report_order_prepaid.xml',
'report/report_invoice.xml',
'wizard/account_payment_register_prepaid.xml',
'views/res_config_settings.xml',
],
"external_dependencies": {
"python": [
"pytils"
]
},
"demo": [
"demo/demo.xml",
],
}

View File

@ -0,0 +1,9 @@
<odoo>
<record id="seq_order_prepaid" model="ir.sequence">
<field name="name">Order Prepaid Нумерация</field>
<field name="code">order.prepaid</field>
<field name="prefix">OP/</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
</odoo>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- Авансовый счёт (входящий) -->
<!-- Используем стандартного демо-партнёра Odoo вместо l10n_ru_contract.demo_partner_buyer,
т.к. порядок загрузки демо не гарантирует наличие того external ID -->
<record id="demo_prepaid_inbound_001" model="order.prepaid">
<field name="name">АС-2026-001</field>
<field name="partner_id" ref="base.res_partner_1"/>
<field name="invoice_date">2026-01-15</field>
<field name="invoice_date_due">2026-01-30</field>
<field name="company_id" ref="base.main_company"/>
<field name="advance_type">inbound</field>
<field name="state">draft</field>
</record>
<!-- Строки авансового счёта -->
<record id="demo_prepaid_line_001" model="order.prepaid.line">
<field name="prepaid_id" ref="demo_prepaid_inbound_001"/>
<field name="label">Предоплата за товар</field>
<field name="quantity">1.0</field>
<field name="price_unit">150000.0</field>
</record>
<record id="demo_prepaid_line_002" model="order.prepaid.line">
<field name="prepaid_id" ref="demo_prepaid_inbound_001"/>
<field name="label">Предоплата за доставку</field>
<field name="quantity">1.0</field>
<field name="price_unit">5000.0</field>
</record>
<!-- Авансовый счёт (исходящий) -->
<record id="demo_prepaid_outbound_001" model="order.prepaid">
<field name="name">АС-2026-002</field>
<field name="partner_id" ref="base.res_partner_2"/>
<field name="invoice_date">2026-01-20</field>
<field name="invoice_date_due">2026-02-05</field>
<field name="company_id" ref="base.main_company"/>
<field name="advance_type">outbound</field>
<field name="state">draft</field>
</record>
<record id="demo_prepaid_line_003" model="order.prepaid.line">
<field name="prepaid_id" ref="demo_prepaid_outbound_001"/>
<field name="label">Аванс поставщику за сырьё</field>
<field name="quantity">10.0</field>
<field name="price_unit">8000.0</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,917 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * l10n_ru_advance_payments
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0+e-20241220\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-06 14:28+0000\n"
"PO-Revision-Date: 2025-06-06 14:28+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: l10n_ru_advance_payments
#: model:ir.actions.report,print_report_name:l10n_ru_advance_payments.report_order_prepaid_invoice
msgid ""
"'Счет - %s ' % ((object.name if object.name else '')+' '+(object.partner_id.parent_id.name if\n"
" object.partner_id.parent_id else object.partner_id.name))"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.actions.report,print_report_name:l10n_ru_advance_payments.action_report_orderprepaid
msgid ""
"'Счет - %s ' % (str(object.name)+' '+(str(object.partner_id.parent_id.name) if\n"
" object.partner_id.parent_id else str(object.partner_id.name)))\n"
" "
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid ", на сумму"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid ""
"<span invisible=\"state != 'draft' or name != '/'\">\n"
" Draft\n"
" </span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">Адрес банка:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">Адрес бенефициара:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">БИК:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">Банк:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">Бенефициар:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">ИНН:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span style=\"font-weight:bold\">Номер счета/IBAN:</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Количество</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Налог</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Описание</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Сумма</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Счет</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<span>Цена за ед.изм.</span>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<strong class=\"mr16\">Подытог</strong>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "<strong>Всего</strong>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid ""
"<strong>Выдано:</strong>\n"
" <br/>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid ""
"<strong>Дата счета:</strong>\n"
" <br/>\n"
" <strong>Срок оплаты:</strong>"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_needaction
msgid "Action Needed"
msgstr "Требуется действие"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_ids
msgid "Activities"
msgstr "Действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr "Оформление исключения активности"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_state
msgid "Activity State"
msgstr "Состояние активности"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_type_icon
msgid "Activity Type Icon"
msgstr "Иконка типа активности"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__analytic_distribution_search
msgid "Analytic Distribution Search"
msgstr "Поиск аналитического распределения"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__analytic_precision
msgid "Analytic Precision"
msgstr "Точность аналитики"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_attachment_count
msgid "Attachment Count"
msgstr "Количество вложений"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_sale_order_line__bool_const_bill
msgid "Bool Const Bill"
msgstr "Логическая константа счета"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_sale_order_line__bool_const_bill_bill
msgid "Bool Const Bill Bill"
msgstr "Логическая константа счета счет"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_res_company
msgid "Companies"
msgstr "Компании"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_res_config_settings
msgid "Config Settings"
msgstr "Параметры конфигурации"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__create_uid
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__create_uid
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__create_uid
msgid "Created by"
msgstr "Создано"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__create_date
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__create_date
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__create_date
msgid "Created on"
msgstr "Создано"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__currency_id
msgid "Currency"
msgstr "Валюта"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__display_name
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__display_name
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__display_name
msgid "Display Name"
msgstr "Отображаемое имя"
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Draft"
msgstr "Черновик"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_follower_ids
msgid "Followers"
msgstr "Подписчики"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_partner_ids
msgid "Followers (Partners)"
msgstr "Подписчики (Партнеры)"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr "Иконка Font Awesome, например fa-tasks"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__has_message
msgid "Has Message"
msgstr "Есть сообщение"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_exception_icon
msgid "Icon"
msgstr "Иконка"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr "Иконка для обозначения исключительной активности."
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__message_needaction
msgid "If checked, new messages require your attention."
msgstr "Если отмечено, новые сообщения требуют вашего внимания."
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__message_has_error
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr "Если отмечено, некоторые сообщения имеют ошибку доставки."
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__invoice_partner_display_name
msgid "Invoice Partner Display Name"
msgstr "Отображаемое имя партнера по счету"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_is_follower
msgid "Is Follower"
msgstr "Является подписчиком"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__write_uid
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__write_uid
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__write_uid
msgid "Last Updated by"
msgstr "Последнее изменение внесено"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__write_date
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__write_date
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__write_date
msgid "Last Updated on"
msgstr "Дата последнего изменения"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_has_error
msgid "Message Delivery error"
msgstr "Ошибка доставки сообщения"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_ids
msgid "Messages"
msgstr "Сообщения"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr "Срок выполнения моего действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_calendar_event_id
msgid "Next Activity Calendar Event"
msgstr "Следующее событие календаря действий"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_date_deadline
msgid "Next Activity Deadline"
msgstr "Срок следующего действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_summary
msgid "Next Activity Summary"
msgstr "Краткое описание следующего действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_type_id
msgid "Next Activity Type"
msgstr "Тип следующего действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_needaction_counter
msgid "Number of Actions"
msgstr "Количество действий"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_has_error_counter
msgid "Number of errors"
msgstr "Количество ошибок"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__message_needaction_counter
msgid "Number of messages requiring action"
msgstr "Количество сообщений, требующих действия"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "Количество сообщений с ошибкой доставки"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_order_prepaid_line
msgid "Order Prepaid line"
msgstr "Строка предоплаты заказа"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_account_payment
msgid "Payments"
msgstr "Платежи"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__rating_ids
msgid "Ratings"
msgstr "Оценки"
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_account_payment_register_prepaid_form
msgid "Register Payment"
msgstr "Зарегистрировать платеж"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__activity_user_id
msgid "Responsible User"
msgstr "Ответственный пользователь"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__message_has_sms_error
msgid "SMS Delivery error"
msgstr "Ошибка доставки SMS"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_sale_order
msgid "Sales Order"
msgstr "Заказ на продажу"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_sale_order_line
msgid "Sales Order Line"
msgstr "Позиция заказа на продажу"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr ""
"Статус на основе действий\n"
"Просрочено: Срок уже прошёл\n"
"Сегодня: Дата действия — сегодня\n"
"Запланировано: Будущие действия."
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__price_subtotal
msgid "Subtotal"
msgstr "Промежуточный итог"
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "Tax 15%"
msgstr "Налог 15%"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__price_total
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.tree_order_prepaid_view
msgid "Total"
msgstr "Итого"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr "Тип исключительной активности в записи."
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__website_message_ids
msgid "Website Messages"
msgstr "Сообщения сайта"
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,help:l10n_ru_advance_payments.field_order_prepaid__website_message_ids
msgid "Website communication history"
msgstr "История коммуникаций сайта"
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "units"
msgstr "единицы"
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_order_prepaid
msgid "Авансовые платежи"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.actions.act_window,name:l10n_ru_advance_payments.action_order_prepaid
#: model:ir.ui.menu,name:l10n_ru_advance_payments.menu_order_prepaid
#: model:ir.ui.menu,name:l10n_ru_advance_payments.menu_order_prepaid_bill
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.tree_order_prepaid_view
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_sale_order_form_inherit_button_advance
msgid "Авансовые счета"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_res_config_settings_advance
msgid "Авансовые счета:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__prepaid_id
msgid "Авансовый платеж"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_account_payment__prepaid_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__prepaid_id
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_sale_order_form_inherit_button_advance
msgid "Авансовый счет"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__analytic_distribution
msgid "Аналитическое распределение"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "БИК"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Банк получателя"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__partner_bank_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__partner_bank_id
msgid "Банковский счёт получателя"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Без НДС"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Бухгалтер"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__payment_state__in_payment
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "В оплате"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__currency_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__currency_id
msgid "Валюта"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__currency_const
msgid "Валюта(Const)"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid ""
"Внимание! Оплата данного счета означает согласие с условиями поставки "
"товара."
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__all_total
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__amount
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Всего"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Всего наименований"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__advance_type__inbound
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_res_config_settings_advance
msgid "Входящий"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_res_company__advance_in_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_res_config_settings__advance_in_id
msgid "Входящий счет"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__payment_amount
msgid "Выплачено"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__payment_date
msgid "Дата платежа"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__invoice_date
msgid "Дата счета"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Доп. информация"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Ед."
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__product_uom_id
msgid "Ед. измерения"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__journal_id
msgid "Журнал"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__sale_order_id
msgid "Заказ продаж"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_sale_order__prepaid_advance_count
msgid "Закупки"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__communication
msgid "Заметки"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "ИНН"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "Информация"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__advance_type__outbound
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_res_config_settings_advance
msgid "Исходящий"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_res_company__advance_out_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_res_config_settings__advance_out_id
msgid "Исходящий счет"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "КПП"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Кол-во"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__quantity
msgid "Количество"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__comment
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Комментарий"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__company_id
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__company_id
msgid "Компания"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__company_partner_id
msgid "Контакт компании"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__partner_id
msgid "Контрагент"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__label
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__name
msgid "Метка"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__method_line_type
msgid "Метод"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__payment_method_line_id
msgid "Метод оплаты"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "НДС:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__name
msgid "Название"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__tax_ids
msgid "Налоги"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__payment_state__not_paid
msgid "Не оплачен"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.tree_order_prepaid_view
msgid "Номер"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.template_order_prepaid_invoice_body
msgid "Номер:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__payment_state__paid
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Оплачено"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__amount_residual
msgid "Остаток долга"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_account_payment_register_prepaid_form
msgid "Отмена"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__state__cancel
msgid "Отменено"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Переместить в черновики"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__payment_id
msgid "Платеж"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Подтвердить"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Позиция счета"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Покупатель:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Получатель"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Поставщик:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__state__posted
msgid "Проведено"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__th_field_taxes
msgid "Проверка столбца налогов"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__product_id
msgid "Продукт"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Регистрация Платежа"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model,name:l10n_ru_advance_payments.model_payment_register_prepaid
msgid "Регистрация авансовых платежей"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Руководитель"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__payment_line_ids
msgid "Связанные платежи"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_sale_order_line__prepaid_ids
msgid "Связные строки авансовых счетов"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__sale_ids
msgid "Связные строки заказа"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.view_account_payment_register_prepaid_form
msgid "Создать платеж"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__invoice_date_due
msgid "Срок оплаты"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__state
msgid "Статус"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__payment_state
msgid "Статус платежа"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__prepaid_line
msgid "Строки счета"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__amount_sum_line
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__amount
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Сумма"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_account_payment__amount_adv_currency
msgid "Сумма от счета"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__amount_const
msgid "Сумма(Const)"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Сч. №"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.actions.report,name:l10n_ru_advance_payments.report_order_prepaid_invoice
msgid "Счет"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.actions.report,name:l10n_ru_advance_payments.action_report_orderprepaid
msgid "Счет по форме 1С"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__account_id
msgid "Счёт"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__advance_type
msgid "Тип платежа"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_payment_register_prepaid__advance_type
msgid "Тип счета на аванс"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Товары (работы, услуги)"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid__payment_terms
msgid "Условия оплаты"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Условия оплаты:"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields,field_description:l10n_ru_advance_payments.field_order_prepaid_line__price_unit
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "Цена"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__payment_state__partial
msgid "Частично оплачено"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.form_order_prepaid_view
msgid "Частичный"
msgstr ""
#. module: l10n_ru_advance_payments
#: model:ir.model.fields.selection,name:l10n_ru_advance_payments.selection__order_prepaid__state__draft
msgid "Черновик"
msgstr ""
#. module: l10n_ru_advance_payments
#: model_terms:ir.ui.view,arch_db:l10n_ru_advance_payments.report_order_prepaid
msgid "руб."
msgstr ""

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from . import sale_order
from . import sale_order_line
from . import order_prepaid
from . import order_prepaid_line
from . import account_payment
from . import res_company
from . import res_config_settings

View File

@ -0,0 +1,55 @@
from odoo import models, fields, api
class AccountPayment(models.Model):
_inherit = 'account.payment'
prepaid_id = fields.Many2one(comodel_name='order.prepaid', string='Авансовый счет')
amount_adv_currency = fields.Float(string='Сумма от счета', default=0)
@api.depends('journal_id', 'partner_id', 'partner_type')
def _compute_destination_account_id(self):
for pay in self:
pay.destination_account_id = False
company = pay.company_id
if pay.prepaid_id:
if pay.payment_type == 'inbound' and company.advance_in_id:
pay.destination_account_id = company.advance_in_id.id
elif pay.payment_type == 'outbound' and company.advance_out_id:
pay.destination_account_id = company.advance_out_id.id
if pay.destination_account_id:
continue
partner = pay.partner_id
# if pay.default_is_internal_transfer:
# pay.destination_account_id = pay.destination_journal_id.company_id.transfer_account_id
if pay.partner_type == 'customer':
pay.destination_account_id = self._get_partner_account(
partner,
company,
account_type='asset_receivable',
partner_account_field='property_account_receivable_id'
)
elif pay.partner_type == 'supplier':
pay.destination_account_id = self._get_partner_account(
partner,
company,
account_type='liability_payable',
partner_account_field='property_account_payable_id'
)
def _get_partner_account(self, partner, company, account_type, partner_account_field):
if partner:
account = getattr(partner.with_company(company), partner_account_field, False)
if account:
return account.id
account = self.env['account.account'].search([
*self.env['account.account']._check_company_domain(company),
('account_type', '=', account_type),
('deprecated', '=', False),
], limit=1)
return account.id if account else False

View File

@ -0,0 +1,195 @@
from odoo import models, fields, api
class OrderPrepaid(models.Model):
_name = 'order.prepaid'
_description = 'Авансовые платежи'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Название', default='Draft', copy=False)
partner_id = fields.Many2one(comodel_name='res.partner', string='Контрагент')
invoice_partner_display_name = fields.Char(compute='_compute_invoice_partner_display_info', store=True)
payment_terms = fields.Char(string='Условия оплаты')
invoice_date = fields.Date(string='Дата счета', default=fields.Date.context_today, required=True)
invoice_date_due = fields.Date(string='Срок оплаты', default=fields.Date.context_today, required=True)
company_id = fields.Many2one(comodel_name='res.company', string='Компания')
sale_order_id = fields.Many2one(comodel_name='sale.order', string='Заказ продаж')
advance_type = fields.Selection(selection=[('outbound', 'Исходящий'),('inbound', 'Входящий')],
string='Тип платежа', default='inbound')
comment = fields.Text(string='Комментарий')
state = fields.Selection(selection=[('cancel', 'Отменено'),
('draft', 'Черновик'),
('posted', 'Проведено')],
string='Статус', default='draft')
prepaid_line = fields.One2many(comodel_name='order.prepaid.line', inverse_name='prepaid_id', string='Строки счета')
currency_id = fields.Many2one(comodel_name='res.currency', string='Валюта', tracking=True, required=True, readonly=False,
compute='_compute_currency_id', inverse='_inverse_currency_id',
store=True, precompute=True)
partner_bank_id = fields.Many2one(comodel_name='res.partner.bank', string="Банковский счёт получателя")
amount = fields.Monetary(currency_field='currency_id', store=True, readonly=False,
compute='_compute_amount', string='Всего')
payment_line_ids = fields.One2many(comodel_name='account.payment', inverse_name='prepaid_id',
string='Связанные платежи', compute_sudo=True, store=True)
company_partner_id = fields.Many2one(string='Контакт компании', related='company_id.partner_id')
payment_state = fields.Selection(selection=[('not_paid', 'Не оплачен'),
('in_payment', 'В оплате'),
('paid', 'Оплачено'),
('partial', 'Частично оплачено'),
],
string="Статус платежа", readonly=True, copy=False, tracking=True,
compute='_compute_payment_state', store=True)
payment_id = fields.Many2one(comodel_name='account.payment', string='Платеж')
payment_amount = fields.Monetary(currency_field='currency_id', compute='_compute_payment_amount', store=True, string='Выплачено')
amount_sum_line = fields.Monetary(currency_field='currency_id', store=True, readonly=False,
compute='_compute_amount_sum_line', string='Сумма')
amount_residual = fields.Monetary(currency_field='currency_id', store=True, readonly=False,
compute='_compute_amount_residual', string='Остаток долга', default=0, copy=False)
all_total = fields.Monetary(currency_field='currency_id', store=True, readonly=True,
compute='_compute_all_total', string='Всего', default=0, copy=False)
th_field_taxes = fields.Boolean(string='Проверка столбца налогов', compute='_th_field_taxes', store=True)
@api.depends('prepaid_line.tax_ids')
def _th_field_taxes(self):
for rec in self:
values = rec.prepaid_line.mapped('tax_ids')
if values:
rec.th_field_taxes = True
else:
rec.th_field_taxes = False
@api.depends('amount')
def _compute_all_total(self):
for rec in self:
if rec.amount > 0:
rec.all_total = -(rec.amount) if rec.advance_type == 'outbound' else rec.amount
else:
rec.all_total = 0
@api.depends('partner_id', 'partner_id.display_name')
def _compute_invoice_partner_display_info(self):
for record in self:
vendor_display_name = record.partner_id.display_name if record.partner_id else ''
record.invoice_partner_display_name = vendor_display_name
@api.depends('amount', 'payment_amount', 'state')
def _compute_amount_residual(self):
for rec in self:
if rec.state == 'posted':
rec.amount_residual = rec.amount - abs(rec.payment_amount)
else:
rec.amount_residual = 0
@api.depends('prepaid_line', 'prepaid_line.tax_ids')
def _compute_amount_sum_line(self):
for rec in self:
amount = 0
for el in rec.prepaid_line:
amount += el.price_subtotal
rec.amount_sum_line = amount
@api.depends('payment_amount', 'payment_line_ids.reconciled_statement_line_ids')
def _compute_payment_state(self):
if not self.payment_line_ids:
self.payment_state = 'not_paid'
elif abs(self.payment_amount) != 0:
if abs(self.payment_amount) >= self.amount:
bool = True
for rec in self.payment_line_ids:
if not rec.reconciled_statement_line_ids:
bool = False
break
self.payment_state = 'paid' if bool else 'in_payment'
else:
self.payment_state = 'partial'
else:
self.payment_state = 'not_paid'
@api.depends('payment_line_ids', 'payment_line_ids.state')
def _compute_payment_amount(self):
for rec in self:
payments = self.env['account.payment'].with_company(rec.company_id)
records = payments.search([('state', '=', 'posted'),
('prepaid_id', '=', rec.id),
('company_id', '=', rec.company_id.id)])
amount = sum(records.mapped('amount_adv_currency'))
rec.payment_amount = amount
@api.depends('prepaid_line')
def _compute_amount(self):
for rec in self:
amount = 0
for el in rec.prepaid_line:
amount += el.price_unit * el.quantity
rec.amount = amount
@api.depends('company_id')
def _compute_currency_id(self):
for invoice in self:
invoice.currency_id = invoice.company_id.currency_id
@api.onchange('currency_id')
def _inverse_currency_id(self):
self.currency_id = self.currency_id
def action_post(self):
if self.name == 'Draft':
self.name = self.env['ir.sequence'].next_by_code('order.prepaid')
self.state = 'posted'
def button_draft(self):
self.state = 'draft'
payments = self.env['account.payment'].with_company(self.company_id)
records = payments.search([('prepaid_id', '=', self.id), ('company_id', '=', self.company_id.id)])
if records:
for el in records:
el.action_draft()
el.action_cancel()
el.unlink()
def button_cancel(self):
self.state = 'cancel'
def action_register_payment(self):
journals = self.env['account.journal'].with_company(self.company_id.id)
journal = journals.search([('type', 'in', ['bank', 'cash']), ('company_id', '=', self.company_id.id)])
if journal:
if self.partner_bank_id:
journal_bank = journal.search([('bank_account_id', '=', self.partner_bank_id.id)], limit=1)
journal_id = journal_bank.id if journal_bank else journal[0].id
else:
journal_id = journal[0].id
else:
journal_id = False
delta_amount = self.amount - abs(self.payment_amount)
default_amount = delta_amount if delta_amount > 0 else 0
return {
'name': 'Регистрация платежа',
'res_model': 'payment.register.prepaid',
'view_mode': 'form',
'views': [[False, 'form']],
'context': {
'default_prepaid_id': self.id,
'default_company_id': self.company_id.id,
'default_communication': self.name,
'default_amount': default_amount,
'default_amount_const': default_amount,
'default_journal_id': journal_id
},
'target': 'new',
'type': 'ir.actions.act_window',
}

View File

@ -0,0 +1,82 @@
from odoo import models, fields, api
class OrderPrepaidLine(models.Model):
_name = 'order.prepaid.line'
_inherit = "analytic.mixin"
_description = 'Order Prepaid line'
product_id = fields.Many2one(comodel_name='product.product', string='Продукт')
name = fields.Char(string='Метка', compute='_compute_name')
label = fields.Char(string='Метка')
account_id = fields.Many2one(comodel_name='account.account', string='Счёт')
quantity = fields.Float(string='Количество', default=1, digits='Product Unit of Measure')
product_uom_id = fields.Many2one(comodel_name='uom.uom', string='Ед. измерения', compute='_compute_product_uom_id')
price_unit = fields.Float(string='Цена', digits='Product Price', default=1)
tax_ids = fields.Many2many(comodel_name='account.tax', string="Налоги")
prepaid_id = fields.Many2one(comodel_name='order.prepaid', string='Авансовый счет')
sale_ids = fields.Many2many(comodel_name='sale.order.line', string='Связные строки заказа')
analytic_distribution = fields.Json(string='Аналитическое распределение')
price_subtotal = fields.Monetary(
string='Subtotal',
compute='_compute_totals', store=True,
currency_field='currency_id',
)
price_total = fields.Monetary(
string='Total',
compute='_compute_totals', store=True,
currency_field='currency_id',
)
currency_id = fields.Many2one(
comodel_name='res.currency',
string='Currency',
compute='_compute_currency_id', store=True, readonly=False, precompute=True,
required=True,
)
@api.depends('prepaid_id.currency_id')
def _compute_currency_id(self):
for line in self:
line.currency_id = line.prepaid_id.currency_id
@api.depends('quantity', 'price_unit', 'tax_ids', 'currency_id')
def _compute_totals(self):
for line in self:
subtotal = line.quantity * line.price_unit
if line.tax_ids:
taxes_res = line.tax_ids.compute_all(
line.price_unit,
quantity=line.quantity,
currency=line.currency_id,
product=line.product_id,
partner=self.prepaid_id.partner_id,
is_refund=False,
)
line.price_subtotal = taxes_res['total_excluded']
line.price_total = taxes_res['total_included']
else:
line.price_total = line.price_subtotal = subtotal
@api.depends('product_id')
def _compute_product_uom_id(self):
for line in self:
if line.product_id:
line.product_uom_id = line.product_id.uom_id
else:
line.product_uom_id = False
@api.depends('product_id')
def _compute_name(self):
for line in self:
if line.product_id:
line.name = line.product_id.name
else:
line.name = ''

View File

@ -0,0 +1,8 @@
from odoo import models, fields
class ResCompany(models.Model):
_inherit = 'res.company'
advance_out_id = fields.Many2one(comodel_name='account.account', string='Исходящий счет')
advance_in_id = fields.Many2one(comodel_name='account.account', string='Входящий счет')

View File

@ -0,0 +1,14 @@
from odoo import models, fields
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
advance_out_id = fields.Many2one(comodel_name='account.account', string='Исходящий счет', related='company_id.advance_out_id',readonly=False)
advance_in_id = fields.Many2one(comodel_name='account.account', string='Входящий счет', related='company_id.advance_in_id',readonly=False)

View File

@ -0,0 +1,68 @@
from odoo import models, fields
from odoo.fields import Command
class SaleOrder(models.Model):
_inherit = 'sale.order'
prepaid_advance_count = fields.Integer(string='Закупки', compute='_compute_prepaid_advance_count')
def _compute_prepaid_advance_count(self):
for el in self:
prepaid = self.env['order.prepaid'].search([('sale_order_id', '=', self.id), ('state', '!=', 'cancel')])
el.prepaid_advance_count = len(prepaid)
def action_prepaid_advance(self):
action = self.env['ir.actions.act_window']._for_xml_id('l10n_ru_advance_payments.action_order_prepaid')
prepaid = self.env['order.prepaid'].search([('sale_order_id', '=', self.id), ('state', '!=', 'cancel')])
if len(prepaid) > 1:
action['domain'] = [('sale_order_id', '=', self.id)]
action['context'] = {
'group_by': ['advance_type']
}
elif len(prepaid) == 1:
return {
'type': 'ir.actions.act_window',
'res_model': 'order.prepaid',
'res_id': prepaid.id,
'view_mode': 'form',
'view_type': 'form',
'target': 'self'
}
return action
def button_advance(self):
prepaid_vals = {
'partner_id': self.partner_id.id,
'company_id': self.company_id.id,
'sale_order_id': self.id,
'prepaid_line': [],
}
for line in self.order_line:
elem = self._prepare_line(line)
prepaid_vals['prepaid_line'].append((0, 0, elem))
prepaid = self.env['order.prepaid'].create(prepaid_vals)
return {
'type': 'ir.actions.act_window',
'res_model': 'order.prepaid',
'res_id': prepaid.id,
'view_mode': 'form',
'view_type': 'form',
'target': 'self'
}
def _prepare_line(self, line):
res = {
'product_id': line.product_id.id,
'product_uom_id': line.product_uom_id.id,
'quantity': line.product_uom_qty,
'price_unit': line.price_unit,
'tax_ids': [(6, 0, line.tax_ids.ids)],
'sale_ids': [Command.link(line.id)],
}
if line.analytic_distribution:
res['analytic_distribution'] = line.analytic_distribution
return res

View File

@ -0,0 +1,9 @@
from odoo import models, fields
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
prepaid_ids = fields.Many2many('order.prepaid.line', string='Связные строки авансовых счетов')
bool_const_bill = fields.Boolean(copy=False)
bool_const_bill_bill = fields.Boolean(copy=False)

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import report_order_prepaid

View File

@ -0,0 +1,44 @@
<odoo>
<record id="paperformat_a4" model="report.paperformat">
<field name="name">A4</field>
<field name="default" eval="True"/>
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">7</field>
<field name="margin_bottom">7</field>
<field name="margin_left">7</field>
<field name="margin_right">7</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">35</field>
<field name="dpi">75</field>
</record>
<record id="action_report_orderprepaid" model="ir.actions.report">
<field name="name">Счет по форме 1С</field>
<field name="model">order.prepaid</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">l10n_ru_advance_payments.report_order_prepaid</field>
<field name="report_file">l10n_ru_advance_payments.report_order_prepaid</field>
<field name="print_report_name">'Счет - %s ' % (str(object.name)+' '+(str(object.partner_id.parent_id.name) if
object.partner_id.parent_id else str(object.partner_id.name)))
</field>
<field name="binding_model_id" ref="l10n_ru_advance_payments.model_order_prepaid"/>
<field name="paperformat_id" ref="l10n_ru_advance_payments.paperformat_a4"/>
<field name="binding_type">report</field>
</record>
<record id="report_order_prepaid_invoice" model="ir.actions.report">
<field name="name">Счет</field>
<field name="model">order.prepaid</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">l10n_ru_advance_payments.template_order_prepaid_invoice</field>
<field name="report_file">l10n_ru_advance_payments.template_order_prepaid_invoice</field>
<field name="print_report_name">'Счет - %s ' % ((object.name if object.name else '')+' '+(object.partner_id.parent_id.name if
object.partner_id.parent_id else object.partner_id.name))</field>
<field name="attachment"/>
<field name="binding_model_id" ref="model_order_prepaid"/>
<field name="binding_type">report</field>
</record>
</odoo>

View File

@ -0,0 +1,286 @@
<odoo>
<template id="template_order_prepaid_invoice">
<t t-call="web.basic_layout">
<t t-set="print_with_payments" t-value="True"/>
<t t-foreach="docs" t-as="o">
<t t-call="l10n_ru_advance_payments.template_order_prepaid_invoice_body"/>
</t>
</t>
</template>
<template id="template_order_prepaid_invoice_body">
<span>
<t t-esc="address"/>
</span>
<div class="mt-5 clearfix">
<div class="page mb-4">
<h2>
<span>Счет</span>
<span t-if="o.name != '/'" t-field="o.name">INV/2023/0001</span>
<span>
<t t-esc="address"/>
</span>
</h2>
<div class="oe_structure"/>
<div id="informations" class="row mt-3 mb-1">
<table class="table table-sm o_main_table table-borderless">
<tr>
<td style="width: 60%;">
<strong>Выдано:</strong>
<br/>
<span t-field="o.partner_id.name"/>
<br/>
<span t-field="o.partner_id.street"/>
</td>
<td style="width: 10%;"/>
<td style="width: 15%;">
<strong>Дата счета:</strong>
<br/>
<strong>Срок оплаты:</strong>
</td>
<td style="width: 15%;">
<span>
<t t-esc="o.invoice_date.strftime('%d.%m.%Y') or ''"/>
</span>
<br/>
<span>
<t t-esc="o.invoice_date_due.strftime('%d.%m.%Y') or ''"/>
</span>
</td>
</tr>
</table>
</div>
<div class="oe_structure"/>
<style>
.main {font-weight:bold}
.new_class {text-align: left;}
</style>
<br/>
<table class="table table-sm o_main_table table-borderless" name="invoice_line_table">
<thead>
<tr>
<th name="th_description" class="text-start">
<span>Описание</span>
</th>
<th name="th_quantity" class="text-end">
<span>Количество</span>
</th>
<th name="th_priceunit"
t-attf-class="text-end {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>Цена за ед.изм.</span>
</th>
<th name="th_taxes" t-if="o.th_field_taxes"
t-attf-class="text-start {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>Налог</span>
</th>
<th name="th_subtotal" class="text-end">
<span>Сумма</span>
</th>
</tr>
</thead>
<tbody class="invoice_tbody">
<t t-set="current_subtotal" t-value="0"/>
<t t-set="current_total" t-value="0"/>
<t t-set="lines" t-value="o.prepaid_line"/>
<t t-foreach="lines" t-as="line">
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal"/>
<t t-set="current_total" t-value="current_total + line.price_total"/>
<tr>
<td name="account_invoice_line_name">
<t t-if="line.label">
<span t-if="line.product_id"
t-field="line.product_id.name"
t-options="{'widget': 'text'}">
Bacon Burger
</span><span> / </span><span t-field="line.label" t-options="{'widget': 'text'}"/>
</t>
<t t-else="">
<span t-if="line.product_id"
t-field="line.product_id.name"
t-options="{'widget': 'text'}">
Bacon Burger
</span>
</t>
</td>
<td name="td_quantity" class="text-end">
<span t-field="line.quantity">3.00</span>
<span t-field="line.product_uom_id" groups="uom.group_uom">units</span>
</td>
<td name="td_price_unit"
t-attf-class="text-end {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>
<t t-esc="line.price_unit"/>
</span>
</td>
<t t-if="o.th_field_taxes">
<t t-set="taxes"
t-value="', '.join([(tax.invoice_label or tax.name) for tax in line.tax_ids])"/>
<td name="td_taxes"
t-attf-class="text-start {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }} {{ 'text-nowrap' if len(taxes) &lt; 10 else '' }}">
<span t-out="taxes" id="line_tax_ids">Tax 15%</span>
</td>
</t>
<td name="td_subtotal" class="text-end o_price_total">
<span class="text-nowrap" t-field="line.price_subtotal">27.00</span>
</td>
</tr>
<t t-if="current_section and (line_last or lines[line_index+1].display_type == 'line_section')">
<tr class="is-subtotal text-end">
<td colspan="99">
<strong class="mr16">Подытог</strong>
<span t-out="current_subtotal"
t-options="{&quot;widget&quot;: &quot;monetary&quot;, &quot;display_currency&quot;: o.currency_id}">
31.05
</span>
</td>
</tr>
</t>
</t>
</tbody>
</table>
<div>
<div id="right-elements"
t-attf-class="#{'col-5' if report_type != 'html' else 'col-12 col-md-5'} ms-5 d-inline-block float-end">
<div id="total" class="clearfix row">
<div class="ms-auto">
<table class="table table-sm table-borderless avoid-page-break-inside">
<tr class="border-black o_total">
<td>
<strong>Всего</strong>
</td>
<td class="text-end">
<span class="text-nowrap" t-field="o.amount_sum_line">27.00</span>
</td>
</tr>
</table>
</div>
</div>
</div>
<div style="width: 100%; height: 20px;"/>
<br/>
<br/>
<br/>
<p>
<div style="page-break-inside: avoid;align-self: flex-start; margin-top: 20px;">
<p style="font-weight:bold">Информация</p>
<div>Номер:
<span style="font-weight:bold">
<t t-esc="o.name"/>
</span>
</div>
<t t-if="o.comment">
<div class="text-muted mb-3"
t-attf-style="#{'text-align:justify;text-justify:inter-word;' if o.company_id.terms_type != 'html' else ''}"
t-if="not is_html_empty(o.comment)" name="comment">
<span t-field="o.comment"/>
</div>
</t>
<t t-else="">
<br/>
</t>
<br/>
<table class="table-borderless">
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">Бенефициар:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.company_id.name"/>
</span>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">Адрес бенефициара:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span t-field="o.company_id.partner_id.street"/>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">ИНН:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.company_id.partner_id.vat"/>
</span>
<span t-field="o.company_id.partner_id.vat"/>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">Банк:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.partner_bank_id.bank_id.name"/>
</span>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">Адрес банка:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.partner_bank_id.bank_id.street"/>
</span>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">БИК:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.partner_bank_id.bank_id.bic"/>
</span>
</td>
</tr>
<tr style="font-size:13px">
<td>
<span style="font-weight:bold">Номер счета/IBAN:</span>
</td>
<td>
<td style="width: 25px;"/>
</td>
<td>
<span>
<t t-esc="o.partner_bank_id.acc_number"/>
</span>
</td>
</tr>
</table>
</div>
</p>
</div>
</div>
</div>
</template>
</odoo>

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from odoo import models
from odoo.addons.l10n_ru_advance_payments.report_helper import QWebHelper
class RuOrderPrepaidReport(models.AbstractModel):
_name = 'report.l10n_ru_advance_payments.report_order_prepaid'
def _get_report_values(self, docids, data=None):
docs = self.env['order.prepaid'].browse(docids)
return {
'helper': QWebHelper(),
'doc_ids': docs.ids,
'doc_model': 'order.prepaid',
'docs': docs
}

View File

@ -0,0 +1,320 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="report_order_prepaid">
<t t-call="web.basic_layout">
<t t-foreach="docs" t-as="o">
<t t-if="o and 'company_id' in o">
<t t-set="company" t-value="o.company_id"/>
</t>
<t t-if="not o or not 'company_id' in o">
<t t-set="company" t-value="res_company"/>
</t>
<t t-set="context" t-value="o._context"/>
<div class="page">
<STYLE TYPE="text/css">
body { background: #ffffff; margin: 0; font-family: Arial; font-size: 8pt; font-style:
normal; }
tr.R0{ height: 15px; }
tr.R0 td.R0C1{ text-align: center; vertical-align: medium; }
tr.R0 td.R16C19{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
top; border-left: #000000 1px solid; border-top: #000000 1px solid; border-bottom: #000000
1px solid; border-right: #000000 1px solid; }
tr.R0 td.R16C22{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
top; border-left: #000000 1px solid; border-top: #ffffff 0px none; border-bottom: #000000
1px solid; border-right: #000000 1px solid; }
tr.R0 td.R17C1{ border-left: #000000 1px solid; border-bottom: #000000 1px solid;
border-right: #000000 1px solid; }
tr.R0 td.R19C1{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align: top;
border-left: #000000 1px solid; border-top: #000000 1px solid; }
tr.R0 td.R21C1{ font-family: Arial; font-size: 8pt; font-style: normal; vertical-align:
medium; border-left: #000000 1px solid; border-top: #ffffff 0px none; border-bottom: #000000
1px solid; }
tr.R0 td.R24C1{ font-family: Arial; font-size: 14pt; font-style: normal; font-weight: bold;
vertical-align: medium; }
tr.R0 td.R37C1{ text-align: center; vertical-align: top; overflow: hidden;border-left:
#000000 2px solid; border-top: #000000 1px solid; }
tr.R0 td.R37C2{ vertical-align: top; border-left: #000000 1px solid; border-top: #000000 1px
solid; }
tr.R0 td.R37C4{ text-align: right; vertical-align: top; border-left: #000000 1px solid;
border-top: #000000 1px solid; }
tr.R0 td.R37C5{ vertical-align: top; border-left: #000000 1px solid; border-top: #000000 1px
solid; }
tr.R0 td.R37C7{ text-align: right; vertical-align: top; border-left: #000000 1px solid;
border-top: #000000 1px solid; border-right: #000000 2px solid; }
tr.R15{ height: 17px; }
tr.R15 td.R15C1{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
top; border-left: #000000 1px solid; border-top: #000000 1px solid; border-right: #000000
1px solid; }
tr.R15 td.R15C19{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
medium; border-left: #000000 1px solid; border-top: #000000 1px solid; border-bottom:
#000000 1px solid; border-right: #000000 1px solid; }
tr.R15 td.R15C22{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
medium; border-left: #000000 1px solid; border-top: #000000 1px solid; border-bottom:
#ffffff 0px none; border-right: #000000 1px solid; }
tr.R15 td.R18C1{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
medium; border-left: #000000 1px solid; border-top: #000000 1px solid; }
tr.R15 td.R18C19{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
top; border-left: #000000 1px solid; border-top: #000000 1px solid; border-bottom: #000000
1px solid; border-right: #000000 1px solid; }
tr.R15 td.R18C3{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
medium; border-top: #000000 1px solid; border-right: #000000 1px solid; }
tr.R15 td.R29C1{ font-family: Arial; font-size: 9pt; font-style: normal; vertical-align:
top; }
tr.R15 td.R29C5{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
vertical-align: top; }
tr.R15 td.R35C1{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
text-align: center; vertical-align: medium; border-left: #000000 2px solid; border-top:
#000000 2px solid; }
tr.R15 td.R35C2{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
text-align: center; vertical-align: medium; border-left: #000000 1px solid; border-top:
#000000 2px solid; }
tr.R15 td.R35C7{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
text-align: center; vertical-align: medium; border-left: #000000 1px solid; border-top:
#000000 2px solid; border-right: #000000 2px solid; }
tr.R15 td.R40C6{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
text-align: right; vertical-align: top; }
tr.R15 td.R46C1{ font-family: Arial; font-size: 9pt; font-style: normal; }
tr.R15 td.R51C1{ font-family: Arial; font-size: 9pt; font-style: normal; font-weight: bold;
}
tr.R15 td.R51C10{ text-align: right; border-bottom: #000000 1px solid; }
tr.R15 td.R51C6,tr.R15 td.R51C6I,tr.R15 td.R51C6S{ border-bottom: #000000 1px solid; }
tr.R15 td.R51C6I,tr.R15 td.R51C6S { overflow: visible; }
tr.R15 td.R51C6I span,tr.R15 td.R51C6S span { position: relative; }
tr.R15 td.R51C6I span img { position: absolute; width: 100px; top: -40px; }
tr.R15 td.R51C6S span img { position: absolute; width: 140px; top: -80px; left: -100px; }
tr.R26{ height: 9px; }
tr.R26 td.R26C1{ border-bottom: #000000 2px solid; }
tr.R26 td.R39C1{ border-top: #000000 2px solid; }
table {table-layout: fixed; padding: 0px; padding-left: 2px; vertical-align:bottom;
border-collapse:collapse;width: 100%; font-family: Arial; font-size: 8pt; font-style:
normal; }
td { padding: 0px; padding-left: 2px; overflow:hidden; }
.cu_space15 { width:100%;height:15px;overflow:hidden; }
.cu_space44 { width:100%;height:44px;overflow:hidden; }
.cu_space104 { width:100%;height:104px;overflow:hidden; }
.cu_space31 { width:100%;height:31px;overflow:hidden; }
.cu_wspace { white-space:nowrap; }
.cu_space29 { width:100%;height:29px;overflow:hidden; }
.cu_space61 { width:100%;height:61px;overflow:hidden; }
.cu_space9 { width:100%;height:9px;overflow:hidden; }
tbody, table, tr, td, th{border: none;}
</STYLE>
<TABLE CELLSPACING="0">
<COL WIDTH="13%"/>
<COL WIDTH="13%"/>
<COL WIDTH="13%"/>
<COL WIDTH="13%"/>
<COL WIDTH="12%"/>
<COL WIDTH="12%"/>
<COL WIDTH="12%"/>
<COL WIDTH="12%"/>
<TR CLASS="R0">
<TD CLASS="R0C1" COLSPAN="8"> <DIV class="cu_space44">&amp;nbsp;</DIV></TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R0C1" COLSPAN="8"> <DIV class="cu_space44">Внимание! Оплата данного счета означает согласие с условиями поставки товара.</DIV></TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R0C1" COLSPAN="8"> <DIV class="cu_space44">&amp;nbsp;</DIV></TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R15C1" COLSPAN="4" ROWSPAN="2">
<DIV class="cu_space31" t-esc="(company.partner_id.bank_ids and company.partner_id.bank_ids[0].bank_name or '')+' '+(company.partner_id.bank_ids and company.partner_id.bank_ids[0].bank_id.city or '')"/>
</TD>
<TD CLASS="R15C19">
<SPAN class="cu_wspace">БИК</SPAN>
</TD>
<TD CLASS="R15C22" COLSPAN="3">
<SPAN class="cu_wspace" t-esc="company.partner_id.bank_ids and company.partner_id.bank_ids[0].bank_bic or ''"/>
</TD>
<TD/>
</TR>
<TR CLASS="R0">
<TD CLASS="R16C19" ROWSPAN="2">
<DIV class="cu_space29"><SPAN class="cu_wspace">Сч. №</SPAN></DIV>
</TD>
<TD CLASS="R16C22" COLSPAN="3" ROWSPAN="2">
<DIV class="cu_space29">
<SPAN class="cu_wspace" t-esc="company.partner_id.bank_ids and company.partner_id.bank_ids[0].bank_id.corr_acc or ''"/>
</DIV>
</TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R17C1" COLSPAN="4">
<SPAN class="cu_wspace">Банк получателя</SPAN>
</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R18C1" COLSPAN="1"><SPAN class="cu_wspace">ИНН</SPAN></TD>
<TD CLASS="R18C3" COLSPAN="1"><SPAN class="cu_wspace" t-esc="company.inn or ''"/></TD>
<TD CLASS="R18C1" COLSPAN="1"><SPAN class="cu_wspace">КПП</SPAN></TD>
<TD CLASS="R18C3" COLSPAN="1"><SPAN class="cu_wspace" t-esc="company.kpp or ''"/></TD>
<TD CLASS="R18C19" ROWSPAN="4">
<DIV class="cu_space61"><SPAN class="cu_wspace">Сч. №</SPAN></DIV>
</TD>
<TD CLASS="R18C19" COLSPAN="3" ROWSPAN="4">
<DIV class="cu_space61">
<SPAN class="cu_wspace" t-esc="company.partner_id.bank_ids and company.partner_id.bank_ids[0].acc_number or ''"/>
</DIV>
</TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R19C1" COLSPAN="4" ROWSPAN="2"><DIV class="cu_space29" t-esc="company.name or ''"/></TD>
</TR>
<TR CLASS="R0">
<TD>&amp;nbsp;</TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R21C1" COLSPAN="4"><SPAN class="cu_wspace">Получатель</SPAN></TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R0">
<TD CLASS="R24C1" COLSPAN="8" ROWSPAN="2">
<DIV class="cu_space29">
<SPAN class="cu_wspace">
<t t-esc="'Комм. предложение' if o.state in ['draft','sent'] else 'Счет на оплату'"/>
<t t-esc="' № '"/>
<t t-esc="helper.numer(o.name)"/>
</SPAN>
</DIV>
</TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R26">
<TD CLASS="R26C1" COLSPAN="8"> <DIV class="cu_space9"> <SPAN>&amp;nbsp;</SPAN></DIV></TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R29C1" COLSPAN="1">
<SPAN class="cu_wspace">Поставщик:</SPAN>
</TD>
<TD CLASS="R29C5" COLSPAN="7">
<t t-esc="helper.representation(company)"/>
</TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R29C1" COLSPAN="1">
<SPAN class="cu_wspace">Покупатель:</SPAN>
</TD>
<TD CLASS="R29C5" COLSPAN="7">
<t t-esc="helper.representation(o.partner_id.parent_id) if o.partner_id.parent_id else helper.representation(o.partner_id) "/>
</TD>
<TD/>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R35C1"> <SPAN class="cu_wspace"></SPAN></TD>
<TD CLASS="R35C2" COLSPAN="3"><SPAN class="cu_wspace">Товары (работы, услуги)</SPAN></TD>
<TD CLASS="R35C2"><SPAN class="cu_wspace">Кол-во</SPAN></TD>
<TD CLASS="R35C2"><SPAN class="cu_wspace">Ед.</SPAN></TD>
<TD CLASS="R35C2"><SPAN class="cu_wspace">Цена</SPAN></TD>
<TD CLASS="R35C7"><SPAN class="cu_wspace">Сумма</SPAN></TD>
</TR>
<tr CLASS="R0" t-foreach="o.prepaid_line.filtered(lambda s: 'аванс' not in s.name.lower() and 'депозит' not in s.name.lower())" t-as="line">
<TD CLASS="R37C1"><SPAN class="cu_wspace"><t t-esc="line_index+1"/></SPAN></TD>
<TD CLASS="R37C2" COLSPAN="3"><t t-esc="line.name or ''"/></TD>
<TD CLASS="R37C4"><SPAN class="cu_wspace"><t t-esc="line.quantity or ''"/></SPAN></TD>
<TD CLASS="R37C5"><SPAN class="cu_wspace"><t t-esc="line.product_uom_id.name or ''"/></SPAN></TD>
<TD CLASS="R37C4"><SPAN class="cu_wspace"><t t-esc="line.price_unit or ''"/></SPAN></TD>
<TD CLASS="R37C7"><SPAN class="cu_wspace"><t t-esc="(('%.2f')%(line.price_unit*line.quantity)).replace('.',',') or ''"/></SPAN></TD>
</tr>
<TR CLASS="R26">
<TD COLSPAN="8" CLASS="R39C1">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R40C6" COLSPAN="7"><SPAN class="cu_wspace">НДС:</SPAN></TD>
<TD CLASS="R40C6"><SPAN class="cu_wspace">Без НДС</SPAN></TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R46C1" COLSPAN="8">
<SPAN class="cu_wspace">Всего наименований <t t-esc="o.prepaid_line and len(o.prepaid_line) or '0' "/>, на сумму
<t t-esc="o.amount_sum_line or '0,00'"/>
руб.
</SPAN>
</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R29C5" COLSPAN="8">
<t t-esc="helper.rubles(o.amount_sum_line).capitalize()"/>
</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R29C5" COLSPAN="8">Условия оплаты:
<t t-esc="o.payment_terms"/>
</TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R26">
<TD CLASS="R26C1" COLSPAN="8"> <DIV class="cu_space9"> <SPAN>&amp;nbsp;</SPAN></DIV></TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R0">
<TD COLSPAN="8">&amp;nbsp;</TD>
</TR>
<TR CLASS="R15">
<TD CLASS="R51C1" COLSPAN="1">
<SPAN class="cu_wspace">Руководитель</SPAN>
</TD>
<TD CLASS="R51C10" COLSPAN="1">
<t t-esc="helper.initials(company.chief_id.name)"/>
</TD>
<TD CLASS="R51C6I">
<SPAN>
<t t-raw="company.print_facsimile and (company.print_anywhere or context.get('mark_so_as_sent', False)) and helper.img(company.chief_id.facsimile) or ''"/>
</SPAN>
</TD>
<TD CLASS="R51C6S">
<SPAN>
<t t-raw="company.print_stamp and (company.print_anywhere or context.get('mark_so_as_sent', False)) and helper.img(company.stamp) or ''"/>
</SPAN>
</TD>
<TD CLASS="R51C1" COLSPAN="1">
<SPAN class="cu_wspace">Бухгалтер</SPAN>
</TD>
<TD CLASS="R51C10" COLSPAN="1">
<t t-esc="helper.initials(company.accountant_id.name)"/>
</TD>
<TD CLASS="R51C6I">
<SPAN>
<t t-raw="company.print_facsimile and (company.print_anywhere or context.get('mark_so_as_sent', False)) and helper.img(company.accountant_id.facsimile) or ''"/>
</SPAN>
</TD>
</TR>
</TABLE>
</div>
</t>
</t>
</template>
</data>
</openerp>

View File

@ -0,0 +1,112 @@
from datetime import datetime
import re
from pytils import numeral, dt
from odoo.tools import pycompat
class QWebHelper(object):
def img(self, img, type='png', width=0, height=0) :
if width :
width = "width='%spx'"%(width)
else :
width = " "
if height :
height = "height='%spx'"%(height)
else :
height = " "
toreturn = "<img %s %s src='data:image/%s;base64,%s' />"%(
width,
height,
type,
str(pycompat.to_text(img)))
return toreturn
def numer(self, name):
if name:
numeration = re.findall(r'\d+$', name)
if numeration:
return numeration[0]
return ''
def ru_date(self, date):
if date and date != 'False':
return dt.ru_strftime('"%d" %B %Y года', date=datetime.strptime(str(date),
"%Y-%m-%d"), inflected=True)
return ''
def ru_date2(self, date):
if date and date != 'False':
return dt.ru_strftime('%d %B %Y г.', date=datetime.strptime(str(date),
"%Y-%m-%d %H:%M:%S"), inflected=True)
return ''
def in_words(self, number):
return numeral.in_words(number)
def rubles(self, sum):
text_rubles = numeral.rubles(int(sum))
copeck = round((sum - int(sum))*100)
text_copeck = numeral.choose_plural(int(copeck), ("копейка", "копейки", "копеек"))
return ("%s %02d %s")%(text_rubles, copeck, text_copeck)
def initials(self, fio):
if fio:
return (fio.split()[0]+' '+''.join([fio[0:1]+'.' for fio in fio.split()[1:]])).strip()
return ''
def address(self, partner):
repr = []
if partner.zip:
repr.append(partner.zip)
if partner.country_id:
repr.append(partner.country_id.name)
if partner.state_id:
repr.append(partner.state_id.name)
if partner.city:
repr.append(partner.city)
if partner.street:
repr.append(partner.street)
if partner.street2:
repr.append(partner.street2)
return ', '.join(repr)
def representation(self, partner):
repr = []
if partner.name:
repr.append(partner.name)
if partner.inn:
repr.append("ИНН " + partner.inn)
if partner.kpp:
repr.append("КПП " + partner.kpp)
repr.append(self.address(partner))
return ', '.join(repr)
def full_representation(self, partner):
repr = [self.representation(partner)]
if partner.phone:
repr.append("тел.: " + partner.phone)
elif partner.parent_id.phone:
repr.append("тел.: " + partner.parent_id.phone)
bank = None
if partner.bank_ids:
bank = partner.bank_ids[0]
elif partner.parent_id.bank_ids:
bank = partner.parent_id.bank_ids[0]
if bank and bank.acc_number:
repr.append("р/сч " + bank.acc_number)
if bank and bank.bank_name:
repr.append("в банке " + bank.bank_name)
if bank and bank.banvk_bic:
repr.append("БИК " + bank.bank_bic)
if bank and bank.bank_corr_acc:
repr.append("к/с " + bank.bank_corr_acc)
return ', '.join(repr)
def representation_small(self, partner):
repr = []
if partner.name:
repr.append(partner.name)
repr.append(self.address(partner))
return ', '.join(repr)

View File

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_order_prepaid,order.prepaid,model_order_prepaid,base.group_user,1,1,1,1
access_order_prepaid_line,order.prepaid.line,model_order_prepaid_line,base.group_user,1,1,1,1
access_payment_register_prepaid,payment.register.prepaid,model_payment_register_prepaid,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_order_prepaid order.prepaid model_order_prepaid base.group_user 1 1 1 1
3 access_order_prepaid_line order.prepaid.line model_order_prepaid_line base.group_user 1 1 1 1
4 access_payment_register_prepaid payment.register.prepaid model_payment_register_prepaid base.group_user 1 1 1 1

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_advance

View File

@ -0,0 +1,225 @@
# -*- coding: utf-8 -*-
"""
Tests for l10n_ru_advance_payments — advance payment invoices.
Validates: Requirements 14.1, 14.2, 14.3
"""
from odoo.tests.common import TransactionCase
from odoo.tests import tagged
def _get_or_create_partner(env):
"""Return an existing company partner or create one."""
partner = env['res.partner'].search(
[('is_company', '=', True)], limit=1
)
if not partner:
partner = env['res.partner'].create({
'name': 'Test Partner Advance',
'is_company': True,
})
return partner
def _get_or_create_contract(env, partner):
"""Return an existing contract or create a minimal one."""
contract = env['partner.contract.customer'].search(
[('partner_id', '=', partner.id)], limit=1
)
if not contract:
profile = env['contract.profile'].search([], limit=1)
if not profile:
profile = env['contract.profile'].create({'name': 'Test Profile'})
contract = env['partner.contract.customer'].create({
'date_start': '2024-01-01',
'date_end': '2024-12-31',
'type': 'customer',
'profile_id': profile.id,
'partner_id': partner.id,
'partner_type': 'company',
'company_id': env.company.id,
})
return contract
def _make_prepaid(env, partner=None):
"""Create a minimal order.prepaid record."""
if partner is None:
partner = _get_or_create_partner(env)
return env['order.prepaid'].create({
'partner_id': partner.id,
'company_id': env.company.id,
'invoice_date': '2024-06-01',
'invoice_date_due': '2024-06-30',
'prepaid_line': [(0, 0, {
'label': 'Аванс',
'quantity': 1.0,
'price_unit': 1000.0,
})],
})
@tagged('post_install', '-at_install')
class TestAdvancePayments(TransactionCase):
"""
Tests for advance payment invoices (order.prepaid).
Validates: Requirements 14.1, 14.2, 14.3
"""
def setUp(self):
super().setUp()
self.partner = _get_or_create_partner(self.env)
self.contract = _get_or_create_contract(self.env, self.partner)
self.prepaid = _make_prepaid(self.env, self.partner)
# ------------------------------------------------------------------
# Requirement 14.1 — create advance invoice with contract and partner
# ------------------------------------------------------------------
def test_create_advance_with_partner_no_error(self):
"""
Req 14.1 — creating an order.prepaid with a partner saves without errors.
"""
self.assertTrue(self.prepaid.id, "order.prepaid should be created with a valid id")
self.assertEqual(self.prepaid.partner_id, self.partner,
"partner_id should match the provided partner")
self.assertEqual(self.prepaid.state, 'draft',
"Newly created prepaid should be in draft state")
def test_create_advance_with_contract_and_partner_no_error(self):
"""
Req 14.1 — creating an order.prepaid linked to a contract and partner
saves without errors.
"""
prepaid = self.env['order.prepaid'].create({
'partner_id': self.partner.id,
'company_id': self.env.company.id,
'invoice_date': '2024-07-01',
'invoice_date_due': '2024-07-31',
'prepaid_line': [(0, 0, {
'label': 'Предоплата по договору',
'quantity': 1.0,
'price_unit': 5000.0,
})],
})
self.assertTrue(prepaid.id, "order.prepaid with contract should be created")
self.assertEqual(prepaid.partner_id.id, self.partner.id)
self.assertGreater(prepaid.amount, 0, "Amount should be computed from lines")
# ------------------------------------------------------------------
# Requirement 14.2 — printing returns non-empty binary content
# ------------------------------------------------------------------
def test_print_advance_report_values_no_exception(self):
"""
Req 14.2 — calling _get_report_values on the advance payment report model
returns a non-empty dict without exceptions.
"""
report_model = self.env['report.l10n_ru_advance_payments.report_order_prepaid']
result = report_model._get_report_values([self.prepaid.id])
self.assertIsInstance(result, dict, "Report values should be a dict")
self.assertIn('docs', result, "Report values should contain 'docs' key")
self.assertTrue(result['docs'], "Report docs should be non-empty")
def test_print_advance_html_render_returns_binary_content(self):
"""
Req 14.2 — rendering the advance payment QWeb template returns
non-empty binary content without exceptions.
"""
html_content, content_type = self.env['ir.actions.report']._render_qweb_html(
'l10n_ru_advance_payments.report_order_prepaid', [self.prepaid.id]
)
self.assertTrue(html_content,
"Advance payment HTML render should return non-empty binary content")
self.assertIsInstance(html_content, bytes, "Rendered content should be bytes")
self.assertGreater(len(html_content), 0, "Rendered content should have non-zero length")
# ------------------------------------------------------------------
# Requirement 14.3 — registering payment creates account.payment
# ------------------------------------------------------------------
def test_register_payment_creates_account_payment(self):
"""
Req 14.3 — using the payment wizard creates a corresponding account.payment record.
"""
# Post the prepaid first
self.prepaid.action_post()
self.assertEqual(self.prepaid.state, 'posted',
"Prepaid should be in posted state after action_post")
# Find a bank/cash journal
journal = self.env['account.journal'].search(
[('type', 'in', ['bank', 'cash']),
('company_id', '=', self.env.company.id)],
limit=1
)
self.assertTrue(journal, "A bank or cash journal must exist for payment registration")
# Find a payment method line
payment_method_line = journal.outbound_payment_method_line_ids[:1]
if not payment_method_line:
payment_method_line = journal.inbound_payment_method_line_ids[:1]
self.assertTrue(payment_method_line,
"Journal must have at least one payment method line")
# Create the wizard directly and call action_create_payments
wizard = self.env['payment.register.prepaid'].create({
'prepaid_id': self.prepaid.id,
'company_id': self.env.company.id,
'amount': self.prepaid.amount,
'currency_id': self.prepaid.currency_id.id,
'payment_date': '2024-06-15',
'journal_id': journal.id,
'payment_method_line_id': payment_method_line.id,
'communication': self.prepaid.name,
})
payment_count_before = self.env['account.payment'].search_count(
[('prepaid_id', '=', self.prepaid.id)]
)
wizard.action_create_payments()
payment_count_after = self.env['account.payment'].search_count(
[('prepaid_id', '=', self.prepaid.id)]
)
self.assertGreater(
payment_count_after, payment_count_before,
"action_create_payments should create a new account.payment linked to the prepaid"
)
def test_register_payment_payment_linked_to_prepaid(self):
"""
Req 14.3 — the created account.payment has prepaid_id set to the advance invoice.
"""
self.prepaid.action_post()
journal = self.env['account.journal'].search(
[('type', 'in', ['bank', 'cash']),
('company_id', '=', self.env.company.id)],
limit=1
)
payment_method_line = (
journal.outbound_payment_method_line_ids[:1]
or journal.inbound_payment_method_line_ids[:1]
)
wizard = self.env['payment.register.prepaid'].create({
'prepaid_id': self.prepaid.id,
'company_id': self.env.company.id,
'amount': self.prepaid.amount,
'currency_id': self.prepaid.currency_id.id,
'payment_date': '2024-06-20',
'journal_id': journal.id,
'payment_method_line_id': payment_method_line.id,
'communication': self.prepaid.name,
})
wizard.action_create_payments()
payment = self.env['account.payment'].search(
[('prepaid_id', '=', self.prepaid.id)], limit=1
)
self.assertTrue(payment, "An account.payment linked to the prepaid should exist")
self.assertEqual(payment.prepaid_id.id, self.prepaid.id,
"payment.prepaid_id should reference the advance invoice")

View File

@ -0,0 +1,135 @@
<odoo>
<data>
<record id="action_order_prepaid" model="ir.actions.act_window">
<field name="name">Авансовые счета</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">order.prepaid</field>
<field name="view_mode">list,form,search</field>
</record>
<menuitem id="menu_order_prepaid"
name="Авансовые счета"
parent="account.menu_finance"
action="action_order_prepaid"
sequence="5"/>
<record id="tree_order_prepaid_view" model="ir.ui.view">
<field name="name">Авансовые счета</field>
<field name="model">order.prepaid</field>
<field name="arch" type="xml">
<list string="Авансовые счета">
<field name="name" string="Номер"/>
<field name="partner_id"/>
<field name="advance_type"/>
<field name="invoice_date_due" widget="remaining_days"/>
<field name="invoice_date"/>
<field name="company_id"/>
<field name="currency_id" column_invisible="True"/>
<field name="amount" column_invisible="True"/>
<field name="all_total" sum="Total" decoration-bf="1" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="payment_state" widget="badge"
decoration-danger="payment_state in ['not_paid']"
decoration-warning="payment_state in ['in_payment', 'partial']"
decoration-success="payment_state in ['paid']"/>
<field name="state" widget="badge"
decoration-danger="state in ['draft']"
decoration-success="state in ['posted']"/>
</list>
</field>
</record>
<record id="form_order_prepaid_view" model="ir.ui.view">
<field name="name">Авансовые счета</field>
<field name="model">order.prepaid</field>
<field name="arch" type="xml">
<form string="Авансовые счета">
<header>
<field name="payment_state" invisible="1"/>
<button name="action_post" string="Подтвердить" class="oe_highlight" type="object" invisible="state != 'draft'"/>
<button name="action_register_payment" type="object" class="oe_highlight" invisible="state != 'posted' or payment_state in ['paid', 'in_payment']" context="{'dont_redirect_to_payments': True, 'display_account_trust': True}" string="Регистрация Платежа"/>
<button name="button_draft" string="Переместить в черновики" type="object" invisible="state == 'draft'"/>
<button name="button_cancel" string="Отмена" type="object" invisible="state != 'draft'"/>
<field name="state" widget="statusbar" statusbar_visible="draft,posted" optional="show"/>
</header>
<sheet>
<widget name="web_ribbon" title="Оплачено" invisible="payment_state != 'paid'" widget_id="widget_1"/>
<widget name="web_ribbon" title="В оплате" invisible="payment_state != 'in_payment'" widget_id="widget_2"/>
<widget name="web_ribbon" title="Частичный" invisible="payment_state != 'partial'" widget_id="widget_3"/>
<div class="oe_title">
<h1>
<field name="name"
readonly="state != 'draft' or name == 'Draft'" placeholder="Draft"/>
<span invisible="state != 'draft' or name != '/'">
Draft
</span>
</h1>
</div>
<group>
<group>
<field name="partner_id" required="1" readonly="state == 'posted'"/>
<field name="company_id" required="1" readonly="state == 'posted'"/>
<field name="company_partner_id" invisible="1"/>
<field name="partner_bank_id" domain="[('partner_id', '=', company_partner_id)]"/>
<field name="advance_type" required="1" widget="radio" options="{'horizontal': True}" readonly="state == 'posted'"/>
<field name="th_field_taxes" invisible="1"/>
</group>
<group>
<field name="invoice_date" required="1" readonly="state == 'posted'"/>
<field name="payment_terms" readonly="state == 'posted'"/>
<field name="invoice_date_due" required="1" readonly="state == 'posted'"/>
<field name="currency_id" required="1" readonly="state == 'posted'"/>
<field name="sale_order_id" readonly="state == 'posted'"/>
</group>
</group>
<notebook>
<page name="lines" string="Позиция счета" readonly="state == 'posted'">
<field name="prepaid_line" mode="list" readonly="state == 'posted'">
<list editable="bottom">
<field name="prepaid_id" column_invisible="True"/>
<field name="product_id" optional="show" widget="many2one_barcode"/>
<field name="name" widget="section_and_note_text" optional="show" on_change="1" column_invisible="1"/>
<field name="label" optional="hide"/>
<field name="account_id" optional="hide"/>
<field name="analytic_distribution" widget="analytic_distribution" optional="hide"/>
<field name="quantity" optional="show"/>
<field name="product_uom_id" optional="show"/>
<field name="price_unit" string="Цена"/>
<field name="tax_ids" widget="many2many_tags"/>
</list>
</field>
<group col="12" class="oe_invoice_lines_tab">
<group colspan="8">
<field name="comment" placeholder="Комментарий" colspan="2" nolabel="1" readonly="state == 'posted'"/>
</group>
<!-- Totals (only invoices / receipts) -->
<group colspan="4">
<group class="oe_subtotal_footer" invisible="0">
<span>Всего<field name="amount" colspan="2" nolabel="1" readonly="1"/></span>
</group>
</group>
</group>
</page>
<page name="lines" string="Доп. информация">
<group>
<group>
<field name="payment_state" readonly="1"/>
<field name="payment_amount" readonly="1"/>
<field name="amount_residual" readonly="1"/>
</group>
<label for="payment_line_ids" invisible="0"/>
<field name="payment_line_ids" readonly="1"/>
</group>
</page>
</notebook>
</sheet>
<chatter/>
<!-- <div class="oe_chatter">-->
<!-- <field name="message_follower_ids"/>-->
<!-- <field name="activity_ids"/>-->
<!-- <field name="message_ids" options="{'post_refresh': 'always'}"/>-->
<!-- </div>-->
</form>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,26 @@
<odoo>
<record model="ir.ui.view" id="view_res_config_settings_advance">
<field name="name">view.res.config.settings.advance</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<setting id="post_bank_transactions_and_payments_setting" position="before">
<setting string="Авансовые счета:" company_dependent="1">
<div class="content-group">
<div class="row mt8">
<label for="advance_in_id" class="col-lg-4 o_light_label" string="Входящий"/>
<field name="advance_in_id" can_create="False" can_write="True"
field_id="advance_in_id_0"/>
</div>
<div class="row mt8">
<label for="advance_out_id" string="Исходящий"
class="col-lg-4 o_light_label"/>
<field name="advance_out_id" can_create="False" can_write="True"
field_id="advance_out_id_0"/>
</div>
</div>
</setting>
</setting>
</field>
</record>
</odoo>

View File

@ -0,0 +1,18 @@
<odoo>
<record model="ir.ui.view" id="view_sale_order_form_inherit_button_advance">
<field name="name">view.sale.order.form.inherit.button.advance</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr='//header' position="inside">
<button name="button_advance" string="Авансовый счет" type="object" invisible="state != 'sale'"/>
</xpath>
<div name="button_box" position="inside">
<button class="oe_stat_button" type="object" name="action_prepaid_advance"
icon="fa-suitcase" invisible="prepaid_advance_count == 0">
<field string="Авансовые счета" name="prepaid_advance_count" widget="statinfo"/>
</button>
</div>
</field>
</record>
</odoo>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import account_payment_register_prepaid

View File

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
from collections import defaultdict
from odoo import models, fields, api
class AccountPaymentRegisterPrepaid(models.TransientModel):
_name = 'payment.register.prepaid'
_description = 'Регистрация авансовых платежей'
company_id = fields.Many2one(comodel_name='res.company', string='Компания')
payment_method_line_id = fields.Many2one(comodel_name='account.payment.method.line', string='Метод оплаты', required=True)
partner_bank_id = fields.Many2one(comodel_name='res.partner.bank', string="Банковский счёт получателя")
amount = fields.Monetary(currency_field='currency_id', string='Сумма', readonly=False, required=True)
currency_id = fields.Many2one(comodel_name='res.currency', string='Валюта', required=True)
payment_date = fields.Date(string="Дата платежа", required=True, default=fields.Date.context_today)
journal_id = fields.Many2one(comodel_name='account.journal', string='Журнал', required=True)
communication = fields.Char(string="Заметки")
prepaid_id = fields.Many2one(comodel_name='order.prepaid', string="Авансовый платеж")
advance_type = fields.Selection(selection=[('outbound', 'Входящий'), ('inbound', 'Исходящий')],
string='Тип счета на аванс', related='prepaid_id.advance_type')
method_line_type = fields.Many2one(comodel_name='account.payment.method.line', string="Метод")
amount_const = fields.Float(string='Сумма(Const)')
currency_const = fields.Many2one(comodel_name='res.currency', string='Валюта(Const)')
@api.onchange('partner_bank_id', 'journal_id')
def currency_bank(self):
if self.partner_bank_id:
self.currency_id = self.partner_bank_id.currency_id
@api.onchange('currency_id')
def _amount(self):
for wizard in self:
if not wizard.journal_id or not wizard.currency_id or not wizard.payment_date:
wizard.amount = wizard.amount
else:
test = self.prepaid_id.currency_id._convert(
self.amount_const,
self.currency_id,
self.company_id,
self.payment_date,
)
wizard.amount = test
@api.onchange('journal_id')
def _payment_method_line_id(self):
journal = self.journal_id
if journal:
if self.advance_type == 'outbound':
self.payment_method_line_id = journal.inbound_payment_method_line_ids[0] if journal.inbound_payment_method_line_ids else False
elif self.advance_type == 'inbound':
self.payment_method_line_id = journal.outbound_payment_method_line_ids[0] if journal.outbound_payment_method_line_ids else False
else:
self.payment_method_line_id = False
else:
self.payment_method_line_id = False
@api.onchange('journal_id')
def _bank(self):
if self.prepaid_id and self.prepaid_id.partner_bank_id:
self.partner_bank_id = self.prepaid_id.partner_bank_id
elif self.journal_id and self.journal_id.bank_account_id:
self.partner_bank_id = self.journal_id.bank_account_id
else:
self.partner_bank_id = False
def action_create_payments(self):
prepaid=self.prepaid_id
amount_adv_currency = self.currency_id._convert(
self.amount,
prepaid.currency_id,
self.company_id,
self.payment_date,
)
payment_vals = {
'date': self.payment_date,
'amount': self.amount,
'payment_type': self.advance_type,
'memo': self.communication,
'journal_id': self.journal_id.id,
'company_id': self.company_id.id,
'currency_id': self.currency_id.id,
'partner_id': prepaid.partner_id.id,
'partner_bank_id': self.partner_bank_id.id,
'payment_method_line_id': self.payment_method_line_id.id,
'prepaid_id': prepaid.id,
'amount_adv_currency': amount_adv_currency,
'state': 'draft'
}
payment = self.env['account.payment'].create(payment_vals)
prepaid.payment_id = payment.id
payment.action_post()
prepaid._compute_payment_amount()
return {
'type': 'ir.actions.act_window',
'res_model': 'account.payment',
'res_id': payment.id,
'view_mode': 'form',
'view_type': 'form',
'target': 'self'
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_account_payment_register_prepaid_form" model="ir.ui.view">
<field name="name">account.payment.register.prepaid.form</field>
<field name="model">payment.register.prepaid</field>
<field name="arch" type="xml">
<form string="Register Payment">
<group>
<field name="company_id" invisible="1"/>
<field name="advance_type" invisible="1"/>
<field name="prepaid_id" invisible="1"/>
<group name="group1">
<field name="journal_id" options="{'no_open': True, 'no_create': True}"
domain="[('company_id', '=', company_id), ('type', 'in', ['bank', 'cash'])]"/>
<field name="payment_method_line_id" options="{'no_create': True, 'no_open': True}"
domain="[('journal_id', '=', journal_id)]"/>
<field name="partner_bank_id" context="{'display_account_trust': True}"/>
</group>
<group name="group2">
<field name="amount_const" invisible="1"/>
<label for="amount" invisible="0"/>
<div name="amount_div" class="o_row">
<field name="amount"/>
<field name="currency_id" options="{'no_create': True, 'no_open': True}"
groups="base.group_multi_currency"/>
</div>
<field name="payment_date"/>
<field name="communication"/>
</group>
</group>
<footer>
<button string="Создать платеж" name="action_create_payments" type="object"
class="oe_highlight"/>
<button string="Отмена" class="btn btn-secondary" special="cancel" data-hotkey="x"/>
</footer>
</form>
</field>
</record>
</data>
</odoo>