From 2c894fe74be920449e8c6ea0ec27128bd74b88ba Mon Sep 17 00:00:00 2001 From: Sergey Korobkov Date: Fri, 17 Jan 2025 20:45:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=D1=8F=20=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20v18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_ru_act_rev/README.md | 14 + l10n_ru_act_rev/__init__.py | 4 + l10n_ru_act_rev/__manifest__.py | 45 + l10n_ru_act_rev/controllers/__init__.py | 3 + l10n_ru_act_rev/controllers/controllers.py | 98 ++ l10n_ru_act_rev/demo/demo.xml | 30 + l10n_ru_act_rev/models/__init__.py | 2 + l10n_ru_act_rev/models/account_account.py | 7 + l10n_ru_act_rev/models/ir_actions_report.py | 10 + l10n_ru_act_rev/report/__init__.py | 2 + l10n_ru_act_rev/report/general_ledger.py | 1060 +++++++++++++++ l10n_ru_act_rev/report/general_ledger.xml | 286 ++++ l10n_ru_act_rev/report/layouts.xml | 34 + l10n_ru_act_rev/security/ir.model.access.csv | 3 + .../views/account_account_views.xml | 14 + l10n_ru_act_rev/views/portal_templates.xml | 12 + .../views/report_general_ledger.xml | 9 + l10n_ru_act_rev/wizard/__init__.py | 2 + l10n_ru_act_rev/wizard/abstract_wizard.py | 38 + .../wizard/general_ledger_wizard.py | 897 +++++++++++++ .../wizard/general_ledger_wizard_view.xml | 164 +++ l10n_ru_attorney/README.md | 21 + l10n_ru_attorney/__init__.py | 3 + l10n_ru_attorney/__manifest__.py | 42 + l10n_ru_attorney/models/__init__.py | 5 + l10n_ru_attorney/models/__init__.pyc | Bin 0 -> 202 bytes l10n_ru_attorney/models/base_consent.py | 46 + l10n_ru_attorney/models/hr_employee.py | 19 + l10n_ru_attorney/models/purchase_order.py | 9 + l10n_ru_attorney/report/consent_report.xml | 303 +++++ l10n_ru_attorney/security/ir.model.access.csv | 2 + l10n_ru_attorney/views/base_consent_views.xml | 66 + l10n_ru_attorney/views/hr_employee_views.xml | 19 + .../views/purchase_order_views.xml | 16 + l10n_ru_base/README.md | 16 + l10n_ru_base/__init__.py | 2 + l10n_ru_base/__manifest__.py | 28 + l10n_ru_base/i18n/ru_RU.po | 117 ++ l10n_ru_base/models/__init__.py | 4 + l10n_ru_base/models/res_config_settings.py | 46 + l10n_ru_base/static/description/icon.png | Bin 0 -> 4308 bytes .../views/res_config_settings_views.xml | 42 + l10n_ru_contract/README.md | 30 + l10n_ru_contract/__init__.py | 3 + l10n_ru_contract/__manifest__.py | 52 + l10n_ru_contract/data/data.xml | 21 + l10n_ru_contract/models/__init__.py | 9 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 269 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 342 bytes .../__pycache__/__init__.cpython-35.pyc | Bin 0 -> 174 bytes .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 235 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 274 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 247 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 226 bytes .../contract_customer.cpython-310.pyc | Bin 0 -> 12914 bytes .../contract_customer.cpython-311.pyc | Bin 0 -> 21777 bytes .../contract_customer.cpython-35.pyc | Bin 0 -> 2418 bytes .../contract_customer.cpython-36.pyc | Bin 0 -> 8580 bytes .../contract_customer.cpython-37.pyc | Bin 0 -> 12975 bytes .../contract_customer.cpython-38.pyc | Bin 0 -> 11924 bytes .../contract_customer.cpython-39.pyc | Bin 0 -> 11865 bytes .../crutch_fields_header.cpython-310.pyc | Bin 0 -> 2798 bytes .../crutch_fields_header.cpython-311.pyc | Bin 0 -> 2855 bytes .../crutch_fields_header.cpython-37.pyc | Bin 0 -> 2656 bytes .../__pycache__/dop_field.cpython-310.pyc | Bin 0 -> 12211 bytes .../__pycache__/dop_field.cpython-311.pyc | Bin 0 -> 20499 bytes .../__pycache__/dop_field.cpython-36.pyc | Bin 0 -> 12033 bytes .../__pycache__/dop_field.cpython-37.pyc | Bin 0 -> 12498 bytes .../__pycache__/dop_field.cpython-38.pyc | Bin 0 -> 12100 bytes .../__pycache__/dop_field.cpython-39.pyc | Bin 0 -> 12023 bytes .../__pycache__/report_helper.cpython-36.pyc | Bin 0 -> 4891 bytes l10n_ru_contract/models/account_move.py | 50 + l10n_ru_contract/models/contract_customer.py | 334 +++++ .../models/crutch_fields_header.py | 33 + l10n_ru_contract/models/dop_field.py | 353 +++++ l10n_ru_contract/models/purchase_order.py | 13 + .../models/sale_make_invoice_advance.py | 18 + l10n_ru_contract/models/sale_order.py | 62 + l10n_ru_contract/report/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 253 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 320 bytes .../__pycache__/__init__.cpython-35.pyc | Bin 0 -> 172 bytes .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 250 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 258 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 262 bytes ...report_barite_specification.cpython-36.pyc | Bin 0 -> 706 bytes .../report_contract.cpython-310.pyc | Bin 0 -> 711 bytes .../report_contract.cpython-311.pyc | Bin 0 -> 982 bytes .../report_contract.cpython-35.pyc | Bin 0 -> 741 bytes .../report_contract.cpython-36.pyc | Bin 0 -> 696 bytes .../report_contract.cpython-37.pyc | Bin 0 -> 704 bytes .../report_contract.cpython-38.pyc | Bin 0 -> 718 bytes .../report_contract_order.cpython-310.pyc | Bin 0 -> 718 bytes .../report_contract_order.cpython-311.pyc | Bin 0 -> 988 bytes .../report_contract_order.cpython-36.pyc | Bin 0 -> 703 bytes .../report_contract_order.cpython-37.pyc | Bin 0 -> 711 bytes .../report_contract_order.cpython-38.pyc | Bin 0 -> 725 bytes .../report_contract_sto.cpython-35.pyc | Bin 0 -> 885 bytes .../report_contract_sto.cpython-36.pyc | Bin 0 -> 860 bytes .../__pycache__/report_helper.cpython-36.pyc | Bin 0 -> 4881 bytes l10n_ru_contract/report/report_contract.py | 14 + l10n_ru_contract/report/report_contract.xml | 398 ++++++ .../report/report_contract_invoice.py | 15 + .../report/report_contract_invoice.xml | 592 +++++++++ .../report/report_contract_order.py | 18 + .../report/report_contract_order.xml | 594 +++++++++ .../report/report_contract_order1.xml | 406 ++++++ l10n_ru_contract/security/ir.model.access.csv | 6 + .../views/contract_customer_view.xml | 357 +++++ l10n_ru_contract/views/mail_template.xml | 37 + l10n_ru_doc/README.md | 38 + l10n_ru_doc/__init__.py | 5 + l10n_ru_doc/__manifest__.py | 75 ++ l10n_ru_doc/demo/l10n_ru_doc_demo.xml | 63 + l10n_ru_doc/i18n/ru.po | 116 ++ l10n_ru_doc/models/__init__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 471 bytes .../account_invoice.cpython-310.pyc | Bin 0 -> 5013 bytes .../account_move_line.cpython-310.pyc | Bin 0 -> 1437 bytes .../__pycache__/product.cpython-310.pyc | Bin 0 -> 461 bytes .../__pycache__/res_bank.cpython-310.pyc | Bin 0 -> 980 bytes .../__pycache__/res_company.cpython-310.pyc | Bin 0 -> 1075 bytes .../__pycache__/res_partner.cpython-310.pyc | Bin 0 -> 767 bytes .../__pycache__/res_users.cpython-310.pyc | Bin 0 -> 507 bytes .../models/__pycache__/sale.cpython-310.pyc | Bin 0 -> 773 bytes .../models/__pycache__/tax.cpython-310.pyc | Bin 0 -> 462 bytes .../models/__pycache__/uom.cpython-310.pyc | Bin 0 -> 464 bytes l10n_ru_doc/models/account_invoice.py | 150 +++ l10n_ru_doc/models/account_move_line.py | 29 + l10n_ru_doc/models/product.py | 5 + l10n_ru_doc/models/res_bank.py | 19 + l10n_ru_doc/models/res_company.py | 18 + l10n_ru_doc/models/res_partner.py | 11 + l10n_ru_doc/models/res_users.py | 7 + l10n_ru_doc/models/sale.py | 8 + l10n_ru_doc/models/tax.py | 6 + l10n_ru_doc/models/uom.py | 4 + l10n_ru_doc/report/__init__.py | 5 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 325 bytes .../__pycache__/report_act.cpython-310.pyc | Bin 0 -> 758 bytes .../__pycache__/report_bill.cpython-310.pyc | Bin 0 -> 762 bytes .../report_invoice.cpython-310.pyc | Bin 0 -> 774 bytes .../__pycache__/report_order.cpython-310.pyc | Bin 0 -> 772 bytes .../__pycache__/report_upd.cpython-310.pyc | Bin 0 -> 1018 bytes l10n_ru_doc/report/l10n_ru_doc_report.xml | 107 ++ l10n_ru_doc/report/report_act.py | 16 + l10n_ru_doc/report/report_act.xml | 203 +++ l10n_ru_doc/report/report_bill.py | 14 + l10n_ru_doc/report/report_bill.xml | 758 +++++++++++ l10n_ru_doc/report/report_invoice.py | 13 + l10n_ru_doc/report/report_invoice.xml | 329 +++++ l10n_ru_doc/report/report_order.py | 13 + l10n_ru_doc/report/report_order.xml | 330 +++++ l10n_ru_doc/report/report_upd.py | 24 + l10n_ru_doc/report/report_upd.xml | 1108 ++++++++++++++++ l10n_ru_doc/report/report_updn.xml | 1177 +++++++++++++++++ l10n_ru_doc/report_helper.py | 112 ++ l10n_ru_doc/static/description/docs.png | Bin 0 -> 16383 bytes l10n_ru_doc/static/description/icon.png | Bin 0 -> 12456 bytes l10n_ru_doc/static/description/index.html | 45 + l10n_ru_doc/static/description/support.png | Bin 0 -> 20040 bytes l10n_ru_doc/static/description/waybill.png | Bin 0 -> 16671 bytes l10n_ru_doc/static/src/css/l10n_ru_doc.css | 7 + l10n_ru_doc/views/account_invoice_view.xml | 36 + l10n_ru_doc/views/l10n_ru_doc_data.xml | 14 + l10n_ru_doc/views/product.xml | 16 + l10n_ru_doc/views/res_bank_view.xml | 18 + l10n_ru_doc/views/res_company_view.xml | 42 + l10n_ru_doc/views/res_partner_view.xml | 36 + l10n_ru_doc/views/res_users_view.xml | 33 + l10n_ru_doc/views/tax.xml | 17 + l10n_ru_doc/views/uom.xml | 28 + l10n_ru_upd_xml/README.md | 9 + l10n_ru_upd_xml/__init__.py | 3 + l10n_ru_upd_xml/__manifest__.py | 45 + l10n_ru_upd_xml/controllers/__init__.py | 3 + l10n_ru_upd_xml/controllers/main.py | 91 ++ l10n_ru_upd_xml/demo/demo.xml | 30 + l10n_ru_upd_xml/models/__init__.py | 7 + l10n_ru_upd_xml/models/account_move.py | 210 +++ l10n_ru_upd_xml/models/account_move_line.py | 7 + l10n_ru_upd_xml/models/ir_actions_report.py | 62 + l10n_ru_upd_xml/models/res_company.py | 11 + l10n_ru_upd_xml/models/res_partner.py | 36 + l10n_ru_upd_xml/models/res_users.py | 25 + l10n_ru_upd_xml/models/uom_uom.py | 7 + l10n_ru_upd_xml/reports/__init__.py | 3 + l10n_ru_upd_xml/reports/demo_report.xml | 76 ++ l10n_ru_upd_xml/reports/report.xml | 14 + .../reports/report_report_xml_abstract.py | 44 + l10n_ru_upd_xml/reports/upd_report.xml | 215 +++ l10n_ru_upd_xml/security/ir.model.access.csv | 2 + .../src/js/report/action_manager_report.js | 50 + .../views/ir_actions_report_view.xml | 24 + l10n_ru_upd_xml/views/res_company_view.xml | 23 + l10n_ru_upd_xml/views/res_partner_view.xml | 29 + l10n_ru_upd_xml/views/res_users_view.xml | 21 + l10n_ru_upd_xml/views/view_account_move.xml | 17 + l10n_ru_upd_xml/views/views_uom_okei.xml | 30 + l10n_ru_upd_xml/views/webclient_templates.xml | 11 + 200 files changed, 13131 insertions(+) create mode 100644 l10n_ru_act_rev/README.md create mode 100644 l10n_ru_act_rev/__init__.py create mode 100644 l10n_ru_act_rev/__manifest__.py create mode 100644 l10n_ru_act_rev/controllers/__init__.py create mode 100644 l10n_ru_act_rev/controllers/controllers.py create mode 100644 l10n_ru_act_rev/demo/demo.xml create mode 100644 l10n_ru_act_rev/models/__init__.py create mode 100644 l10n_ru_act_rev/models/account_account.py create mode 100644 l10n_ru_act_rev/models/ir_actions_report.py create mode 100644 l10n_ru_act_rev/report/__init__.py create mode 100644 l10n_ru_act_rev/report/general_ledger.py create mode 100644 l10n_ru_act_rev/report/general_ledger.xml create mode 100644 l10n_ru_act_rev/report/layouts.xml create mode 100644 l10n_ru_act_rev/security/ir.model.access.csv create mode 100644 l10n_ru_act_rev/views/account_account_views.xml create mode 100644 l10n_ru_act_rev/views/portal_templates.xml create mode 100644 l10n_ru_act_rev/views/report_general_ledger.xml create mode 100644 l10n_ru_act_rev/wizard/__init__.py create mode 100644 l10n_ru_act_rev/wizard/abstract_wizard.py create mode 100644 l10n_ru_act_rev/wizard/general_ledger_wizard.py create mode 100644 l10n_ru_act_rev/wizard/general_ledger_wizard_view.xml create mode 100644 l10n_ru_attorney/README.md create mode 100644 l10n_ru_attorney/__init__.py create mode 100644 l10n_ru_attorney/__manifest__.py create mode 100644 l10n_ru_attorney/models/__init__.py create mode 100644 l10n_ru_attorney/models/__init__.pyc create mode 100644 l10n_ru_attorney/models/base_consent.py create mode 100644 l10n_ru_attorney/models/hr_employee.py create mode 100644 l10n_ru_attorney/models/purchase_order.py create mode 100644 l10n_ru_attorney/report/consent_report.xml create mode 100644 l10n_ru_attorney/security/ir.model.access.csv create mode 100644 l10n_ru_attorney/views/base_consent_views.xml create mode 100644 l10n_ru_attorney/views/hr_employee_views.xml create mode 100644 l10n_ru_attorney/views/purchase_order_views.xml create mode 100644 l10n_ru_base/README.md create mode 100644 l10n_ru_base/__init__.py create mode 100644 l10n_ru_base/__manifest__.py create mode 100644 l10n_ru_base/i18n/ru_RU.po create mode 100644 l10n_ru_base/models/__init__.py create mode 100644 l10n_ru_base/models/res_config_settings.py create mode 100644 l10n_ru_base/static/description/icon.png create mode 100644 l10n_ru_base/views/res_config_settings_views.xml create mode 100644 l10n_ru_contract/README.md create mode 100644 l10n_ru_contract/__init__.py create mode 100644 l10n_ru_contract/__manifest__.py create mode 100644 l10n_ru_contract/data/data.xml create mode 100644 l10n_ru_contract/models/__init__.py create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-310.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-311.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-35.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-36.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-37.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-38.pyc create mode 100644 l10n_ru_contract/models/__pycache__/__init__.cpython-39.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-310.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-311.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-35.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-36.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-37.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-38.pyc create mode 100644 l10n_ru_contract/models/__pycache__/contract_customer.cpython-39.pyc create mode 100644 l10n_ru_contract/models/__pycache__/crutch_fields_header.cpython-310.pyc create mode 100644 l10n_ru_contract/models/__pycache__/crutch_fields_header.cpython-311.pyc create mode 100644 l10n_ru_contract/models/__pycache__/crutch_fields_header.cpython-37.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-310.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-311.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-36.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-37.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-38.pyc create mode 100644 l10n_ru_contract/models/__pycache__/dop_field.cpython-39.pyc create mode 100644 l10n_ru_contract/models/__pycache__/report_helper.cpython-36.pyc create mode 100644 l10n_ru_contract/models/account_move.py create mode 100644 l10n_ru_contract/models/contract_customer.py create mode 100644 l10n_ru_contract/models/crutch_fields_header.py create mode 100644 l10n_ru_contract/models/dop_field.py create mode 100644 l10n_ru_contract/models/purchase_order.py create mode 100644 l10n_ru_contract/models/sale_make_invoice_advance.py create mode 100644 l10n_ru_contract/models/sale_order.py create mode 100644 l10n_ru_contract/report/__init__.py create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-310.pyc create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-311.pyc create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-35.pyc create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-36.pyc create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-37.pyc create mode 100644 l10n_ru_contract/report/__pycache__/__init__.cpython-38.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_barite_specification.cpython-36.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-310.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-311.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-35.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-36.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-37.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract.cpython-38.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_order.cpython-310.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_order.cpython-311.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_order.cpython-36.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_order.cpython-37.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_order.cpython-38.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-35.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-36.pyc create mode 100644 l10n_ru_contract/report/__pycache__/report_helper.cpython-36.pyc create mode 100644 l10n_ru_contract/report/report_contract.py create mode 100644 l10n_ru_contract/report/report_contract.xml create mode 100644 l10n_ru_contract/report/report_contract_invoice.py create mode 100644 l10n_ru_contract/report/report_contract_invoice.xml create mode 100644 l10n_ru_contract/report/report_contract_order.py create mode 100644 l10n_ru_contract/report/report_contract_order.xml create mode 100644 l10n_ru_contract/report/report_contract_order1.xml create mode 100644 l10n_ru_contract/security/ir.model.access.csv create mode 100644 l10n_ru_contract/views/contract_customer_view.xml create mode 100644 l10n_ru_contract/views/mail_template.xml create mode 100644 l10n_ru_doc/README.md create mode 100644 l10n_ru_doc/__init__.py create mode 100644 l10n_ru_doc/__manifest__.py create mode 100644 l10n_ru_doc/demo/l10n_ru_doc_demo.xml create mode 100644 l10n_ru_doc/i18n/ru.po create mode 100644 l10n_ru_doc/models/__init__.py create mode 100644 l10n_ru_doc/models/__pycache__/__init__.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/account_invoice.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/account_move_line.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/product.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/res_bank.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/res_company.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/res_partner.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/res_users.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/sale.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/tax.cpython-310.pyc create mode 100644 l10n_ru_doc/models/__pycache__/uom.cpython-310.pyc create mode 100644 l10n_ru_doc/models/account_invoice.py create mode 100644 l10n_ru_doc/models/account_move_line.py create mode 100644 l10n_ru_doc/models/product.py create mode 100644 l10n_ru_doc/models/res_bank.py create mode 100644 l10n_ru_doc/models/res_company.py create mode 100644 l10n_ru_doc/models/res_partner.py create mode 100644 l10n_ru_doc/models/res_users.py create mode 100644 l10n_ru_doc/models/sale.py create mode 100644 l10n_ru_doc/models/tax.py create mode 100644 l10n_ru_doc/models/uom.py create mode 100644 l10n_ru_doc/report/__init__.py create mode 100644 l10n_ru_doc/report/__pycache__/__init__.cpython-310.pyc create mode 100644 l10n_ru_doc/report/__pycache__/report_act.cpython-310.pyc create mode 100644 l10n_ru_doc/report/__pycache__/report_bill.cpython-310.pyc create mode 100644 l10n_ru_doc/report/__pycache__/report_invoice.cpython-310.pyc create mode 100644 l10n_ru_doc/report/__pycache__/report_order.cpython-310.pyc create mode 100644 l10n_ru_doc/report/__pycache__/report_upd.cpython-310.pyc create mode 100644 l10n_ru_doc/report/l10n_ru_doc_report.xml create mode 100644 l10n_ru_doc/report/report_act.py create mode 100644 l10n_ru_doc/report/report_act.xml create mode 100644 l10n_ru_doc/report/report_bill.py create mode 100644 l10n_ru_doc/report/report_bill.xml create mode 100644 l10n_ru_doc/report/report_invoice.py create mode 100644 l10n_ru_doc/report/report_invoice.xml create mode 100644 l10n_ru_doc/report/report_order.py create mode 100644 l10n_ru_doc/report/report_order.xml create mode 100644 l10n_ru_doc/report/report_upd.py create mode 100644 l10n_ru_doc/report/report_upd.xml create mode 100644 l10n_ru_doc/report/report_updn.xml create mode 100644 l10n_ru_doc/report_helper.py create mode 100644 l10n_ru_doc/static/description/docs.png create mode 100644 l10n_ru_doc/static/description/icon.png create mode 100644 l10n_ru_doc/static/description/index.html create mode 100644 l10n_ru_doc/static/description/support.png create mode 100644 l10n_ru_doc/static/description/waybill.png create mode 100644 l10n_ru_doc/static/src/css/l10n_ru_doc.css create mode 100644 l10n_ru_doc/views/account_invoice_view.xml create mode 100644 l10n_ru_doc/views/l10n_ru_doc_data.xml create mode 100644 l10n_ru_doc/views/product.xml create mode 100644 l10n_ru_doc/views/res_bank_view.xml create mode 100644 l10n_ru_doc/views/res_company_view.xml create mode 100644 l10n_ru_doc/views/res_partner_view.xml create mode 100644 l10n_ru_doc/views/res_users_view.xml create mode 100644 l10n_ru_doc/views/tax.xml create mode 100644 l10n_ru_doc/views/uom.xml create mode 100644 l10n_ru_upd_xml/README.md create mode 100644 l10n_ru_upd_xml/__init__.py create mode 100644 l10n_ru_upd_xml/__manifest__.py create mode 100644 l10n_ru_upd_xml/controllers/__init__.py create mode 100644 l10n_ru_upd_xml/controllers/main.py create mode 100644 l10n_ru_upd_xml/demo/demo.xml create mode 100644 l10n_ru_upd_xml/models/__init__.py create mode 100644 l10n_ru_upd_xml/models/account_move.py create mode 100644 l10n_ru_upd_xml/models/account_move_line.py create mode 100644 l10n_ru_upd_xml/models/ir_actions_report.py create mode 100644 l10n_ru_upd_xml/models/res_company.py create mode 100644 l10n_ru_upd_xml/models/res_partner.py create mode 100644 l10n_ru_upd_xml/models/res_users.py create mode 100644 l10n_ru_upd_xml/models/uom_uom.py create mode 100644 l10n_ru_upd_xml/reports/__init__.py create mode 100644 l10n_ru_upd_xml/reports/demo_report.xml create mode 100644 l10n_ru_upd_xml/reports/report.xml create mode 100644 l10n_ru_upd_xml/reports/report_report_xml_abstract.py create mode 100644 l10n_ru_upd_xml/reports/upd_report.xml create mode 100644 l10n_ru_upd_xml/security/ir.model.access.csv create mode 100644 l10n_ru_upd_xml/static/src/js/report/action_manager_report.js create mode 100644 l10n_ru_upd_xml/views/ir_actions_report_view.xml create mode 100644 l10n_ru_upd_xml/views/res_company_view.xml create mode 100644 l10n_ru_upd_xml/views/res_partner_view.xml create mode 100644 l10n_ru_upd_xml/views/res_users_view.xml create mode 100644 l10n_ru_upd_xml/views/view_account_move.xml create mode 100644 l10n_ru_upd_xml/views/views_uom_okei.xml create mode 100644 l10n_ru_upd_xml/views/webclient_templates.xml diff --git a/l10n_ru_act_rev/README.md b/l10n_ru_act_rev/README.md new file mode 100644 index 0000000..101fe21 --- /dev/null +++ b/l10n_ru_act_rev/README.md @@ -0,0 +1,14 @@ +# Российская локализация - Акт сверки +name: l10n_ru_act_rev + + +## Описание +Добавление печатной формы акт сверки из контактов, с помощью которой можно легко отслеживать дебеторские и кредиторские проводки с клиентами. + +### Для печати: +1. Выбираем меню Контакты - карточку конкретного партнера - Действия - "Печать акт сверки"; +2. В визарде выбираем: + 2.1. Компанию (для которой нужна сверка с выбранным контактом); + 2.2. Период сверки; + 2.3. Цель (один из режимом: все проведенные проводки или все проводки, включая черновики); +3. Кнопка "Печать" \ No newline at end of file diff --git a/l10n_ru_act_rev/__init__.py b/l10n_ru_act_rev/__init__.py new file mode 100644 index 0000000..778f647 --- /dev/null +++ b/l10n_ru_act_rev/__init__.py @@ -0,0 +1,4 @@ +from . import models +from . import report +from . import wizard +from . import controllers diff --git a/l10n_ru_act_rev/__manifest__.py b/l10n_ru_act_rev/__manifest__.py new file mode 100644 index 0000000..840b9e8 --- /dev/null +++ b/l10n_ru_act_rev/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Российская локализация - Акт сверки", + + 'summary': """ + Добавление отчета акт сверки""", + + 'description': """ + Добавление формы акт сверки, находящегося в контактах, с помощью которого можно легко отслеживать дебеторские и кредиторские проводки с клиентами. + + Для печати: + 1. Выбираем меню Контакты - конкретного партнера - Действия - "Печать акт сверки"; + 2. В визарде выбираем: + 2.1. Компанию (для которой нужна сверка с выбранным контактом); + 2.2. Период сверки; + 2.3. Цель (один из режимом: все проведенные проводки или все проводки, включая черновики); + 3. Кнопка "Печать" + + """, + + 'author': "MK.Lab", + 'website': "https://www.inf-centre.ru/", + + 'category': 'Uncategorized', + 'version': '0.1', + + # any module necessary for this one to work correctly + "depends": ["account", "portal", "website", 'contacts', "l10n_ru_doc", 'l10n_ru_contract', 'l10n_ru_base'], + "data": [ + "security/ir.model.access.csv", + "wizard/general_ledger_wizard_view.xml", + "report/layouts.xml", + "report/general_ledger.xml", + "views/account_account_views.xml", + "views/report_general_ledger.xml", + "views/portal_templates.xml", + ], + "installable": True, + "application": True, + "auto_install": False, + # only loaded in demonstration mode + 'demo': [ + 'demo/demo.xml', + ], +} diff --git a/l10n_ru_act_rev/controllers/__init__.py b/l10n_ru_act_rev/controllers/__init__.py new file mode 100644 index 0000000..457bae2 --- /dev/null +++ b/l10n_ru_act_rev/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/l10n_ru_act_rev/controllers/controllers.py b/l10n_ru_act_rev/controllers/controllers.py new file mode 100644 index 0000000..e053c1f --- /dev/null +++ b/l10n_ru_act_rev/controllers/controllers.py @@ -0,0 +1,98 @@ +from odoo import http +from odoo.http import request +from datetime import datetime, date +import werkzeug + + +class ActRevise(http.Controller): + + @http.route(['/my/act_revise/'], type='http', auth="public", website=True) + def print_report(self): + partner = request.env.user.partner_id.parent_id.id + partner_name = request.env.user.partner_id.parent_id.name + if not partner: + partner = request.env.user.partner_id.id + partner_name = request.env.user.partner_id.name + company = request.env.user.company_id.id + # company_name = request.env.user.company_id.name + # today = date.today() + # d1 = today.strftime("%d.%m.%y") + # + # new_url=str('AC ' + company +' - ' + partner + ' ' + d1) + # if request.httprequest.full_path == '/my/act_revise/a?': + # return werkzeug.utils.redirect('/my/act_revise/%s' % new_url) + + wizard_data = { + "target_move": "posted", + "hide_account_at_0": True, + "foreign_currency": True, + "company_id": company, + "partner_ids": [partner], + "show_cost_center": True, + "centralize": True + } + wizard_record = request.env['general.ledger.act_revise.wizard'].sudo().create(wizard_data) + + action_read = request.env.ref('l10n_ru_act_rev.action_general_ledger_wizard').sudo().read() + if action_read: + action = action_read[0] + action['res_id'] = wizard_record.id + action['context'] = dict(request.env.context) + return request.redirect('/web#action=' + str(action['id']) + '&id=' + str(wizard_record.id) + '&view_type=form') + else: + return request.make_response("Error: Action not found.",[('Content-Type', 'text/plain')],400) + + # @http.route(['/my/act_revise/'], type='http', auth="public", website=True) + # def print_report(self): + # partner = request.env.user.partner_id.parent_id.id + # partner_name = request.env.user.partner_id.parent_id.name + # if not partner: + # partner = request.env.user.partner_id.id + # partner_name = request.env.user.partner_id.name + # company = request.env.user.company_id.id + # company_name = request.env.user.company_id.name + # today = date.today() + # d1 = today.strftime("%d.%m.%y") + # # new_url = str('Акт Сверки ' + d1 + ' ' + company_name + '_' + partner_name) + # # new_url=str('AC ' + company +' - ' + partner + ' ' + d1) + # # if request.httprequest.full_path == '/my/act_revise/a?': + # # return werkzeug.utils.redirect('/my/act_revise/%s' % new_url) + # wizard_data = {"target_move": "posted", + # "hide_account_at_0": True, + # "foreign_currency": True, + # #"show_analytic_tags": True, + # "company_id": company, + # "partner_ids": [partner], + # #"show_partner_details": True, + # "show_cost_center": True, + # "centralize": True} + # t = request.env['general.ledger.act_revise.wizard'].sudo().create(wizard_data) + # data = t._prepare_report_general_ledger() + # name = t.get_report_filename() + # report_name = name.encode('cp1251') + # pdf, _ = request.env['ir.actions.report']._render_qweb_pdf( + # 'act_revise.action_print_report_general_ledger_qweb', res_ids=t.id, data=data) + # pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)), ] + # return request.make_response(pdf, headers=pdfhttpheaders) + + @http.route(['/my/act_revise_contact/'], type='http', auth="public", website=True) + def print_report_contact(self, date_to, date_from, target_move, company, partner): + partner_id = int(partner) or 'default_partner_value' + company_id = int(company) + wizard_data = {"date_to": date_to, + "date_from": date_from, + "target_move": target_move, + "hide_account_at_0": True, + "foreign_currency": True, + #"show_analytic_tags": True, + "company_id": company_id, + "partner_ids": [partner_id], + #"show_partner_details": True, + "show_cost_center": True, + "centralize": True} + t = request.env['general.ledger.act_revise.wizard'].sudo().create(wizard_data) + data = t._prepare_report_general_ledger() + pdf, _ = request.env['ir.actions.report']._render_qweb_pdf( + 'l10n_ru_act_rev.action_print_report_general_ledger_qweb', res_ids=t.id, data=data) + pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)), ] + return request.make_response(pdf, headers=pdfhttpheaders) \ No newline at end of file diff --git a/l10n_ru_act_rev/demo/demo.xml b/l10n_ru_act_rev/demo/demo.xml new file mode 100644 index 0000000..340fdd0 --- /dev/null +++ b/l10n_ru_act_rev/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/l10n_ru_act_rev/models/__init__.py b/l10n_ru_act_rev/models/__init__.py new file mode 100644 index 0000000..f75a803 --- /dev/null +++ b/l10n_ru_act_rev/models/__init__.py @@ -0,0 +1,2 @@ +from . import account_account +from . import ir_actions_report \ No newline at end of file diff --git a/l10n_ru_act_rev/models/account_account.py b/l10n_ru_act_rev/models/account_account.py new file mode 100644 index 0000000..3e251fe --- /dev/null +++ b/l10n_ru_act_rev/models/account_account.py @@ -0,0 +1,7 @@ +from odoo import fields, models, _ + + +class AccountAccount(models.Model): + _inherit = "account.account" + + centralized = fields.Boolean(_("Централизованно")) diff --git a/l10n_ru_act_rev/models/ir_actions_report.py b/l10n_ru_act_rev/models/ir_actions_report.py new file mode 100644 index 0000000..b0f8377 --- /dev/null +++ b/l10n_ru_act_rev/models/ir_actions_report.py @@ -0,0 +1,10 @@ +from odoo import api, models + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + @api.model + def _prepare_account_financial_report_context(self, data): + lang = data and data.get("account_financial_report_lang") or "" + return dict(self.env.context or {}, lang=lang) if lang else False diff --git a/l10n_ru_act_rev/report/__init__.py b/l10n_ru_act_rev/report/__init__.py new file mode 100644 index 0000000..f7ccab0 --- /dev/null +++ b/l10n_ru_act_rev/report/__init__.py @@ -0,0 +1,2 @@ +from . import general_ledger + diff --git a/l10n_ru_act_rev/report/general_ledger.py b/l10n_ru_act_rev/report/general_ledger.py new file mode 100644 index 0000000..6e54de7 --- /dev/null +++ b/l10n_ru_act_rev/report/general_ledger.py @@ -0,0 +1,1060 @@ +import calendar +import datetime +import operator + +from odoo.exceptions import UserError +from odoo import _, api, models +from odoo.tools import float_is_zero +import logging + +class GeneralLedgerReport(models.AbstractModel): + _name = "report.l10n_ru_act_rev.general_ledger" + _description = "General Ledger Report" + + COMMON_ML_FIELDS = [ + "account_id", + "partner_id", + "journal_id", + "move_type", + "date", + "ref", + "id", + "move_id", + "name", + ] + + @api.model + def _get_move_lines_domain_not_reconciled( + self, company_id, account_ids, partner_ids, only_posted_moves, date_from + ): + domain = [ + ("account_id", "in", account_ids), + ("company_id", "=", company_id), + ("reconciled", "=", False), + ] + if partner_ids: + domain += [("partner_id", "in", partner_ids)] + if only_posted_moves: + domain += [("move_id.state", "=", "posted")] + else: + domain += [("move_id.state", "in", ["posted", "draft"])] + if date_from: + domain += [("date", ">", date_from)] + return domain + + @api.model + def _get_new_move_lines_domain( + self, new_ml_ids, account_ids, company_id, partner_ids, only_posted_moves + ): + domain = [ + ("account_id", "in", account_ids), + ("company_id", "=", company_id), + ("id", "in", new_ml_ids), + ] + if partner_ids: + domain += [("partner_id", "in", partner_ids)] + if only_posted_moves: + domain += [("move_id.state", "=", "posted")] + else: + domain += [("move_id.state", "in", ["posted", "draft"])] + return domain + + def _recalculate_move_lines( + self, + move_lines, + move_type, + debit_ids, + credit_ids, + debit_amount, + credit_amount, + ml_ids, + account_ids, + company_id, + partner_ids, + only_posted_moves, + debit_amount_currency, + credit_amount_currency, + ): + debit_ids = set(debit_ids) + credit_ids = set(credit_ids) + in_credit_but_not_in_debit = credit_ids - debit_ids + reconciled_ids = list(debit_ids) + list(in_credit_but_not_in_debit) + reconciled_ids = set(reconciled_ids) + ml_ids = set(ml_ids) + new_ml_ids = reconciled_ids - ml_ids + new_ml_ids = list(new_ml_ids) + new_domain = self._get_new_move_lines_domain( + new_ml_ids, account_ids, company_id, partner_ids, only_posted_moves + ) + company_currency = self.env["res.company"].browse(company_id).currency_id + ml_fields = self._get_ml_fields() + new_move_lines = self.env["account.move.line"].search_read( + domain=new_domain, fields=ml_fields + ) + move_lines = move_lines + new_move_lines + for move_line in move_lines: + ml_id = move_line["id"] + if ml_id in debit_ids: + if move_line.get("amount_residual", False): + move_line["amount_residual"] += debit_amount[ml_id] + else: + move_line["amount_residual"] = debit_amount[ml_id] + if move_line.get("amount_residual_currency", False): + move_line["amount_residual_currency"] += debit_amount_currency[ + ml_id + ] + else: + move_line["amount_residual_currency"] = debit_amount_currency[ml_id] + if ml_id in credit_ids: + if move_line.get("amount_residual", False): + move_line["amount_residual"] -= credit_amount[ml_id] + else: + move_line["amount_residual"] = -credit_amount[ml_id] + if move_line.get("amount_residual_currency", False): + move_line["amount_residual_currency"] -= credit_amount_currency[ + ml_id + ] + else: + move_line["amount_residual_currency"] = -credit_amount_currency[ + ml_id + ] + # Set amount_currency=0 to keep the same behaviour as in v13 + # Conditions: if there is no curency_id defined or it is equal + # to the company's curency_id + if "amount_currency" in move_line and ( + "currency_id" not in move_line + or move_line["currency_id"] == company_currency.id + ): + move_line["amount_currency"] = 0 + return move_lines + + def _get_accounts_data(self, accounts_ids): + accounts = self.env["account.account"].browse(accounts_ids) + accounts_data = {} + for account in accounts: + accounts_data.update( + { + account.id: { + "id": account.id, + "code": account.code, + "name": account.name, + "hide_account": False, + "group_id": account.group_id.id, + "currency_id": account.currency_id.id, + "currency_name": account.currency_id.name, + "centralized": account.centralized, + } + } + ) + return accounts_data + + def _get_journals_data(self, journals_ids): + journals = self.env["account.journal"].browse(journals_ids) + journals_data = {} + for journal in journals: + journals_data.update({journal.id: {"id": journal.id, "code": journal.code}}) + return journals_data + + def _get_analytic_data(self, account_ids): + analytic_accounts = self.env["account.analytic.account"].browse(account_ids) + analytic_data = {} + for account in analytic_accounts: + analytic_data.update({account.id: {"name": account.name}}) + return analytic_data + + def _get_taxes_data(self, taxes_ids): + taxes = self.env["account.tax"].browse(taxes_ids) + taxes_data = {} + for tax in taxes: + taxes_data.update( + { + tax.id: { + "id": tax.id, + "amount": tax.amount, + "amount_type": tax.amount_type, + "display_name": tax.display_name, + } + } + ) + if tax.amount_type == "percent" or tax.amount_type == "division": + taxes_data[tax.id]["string"] = "%" + else: + taxes_data[tax.id]["string"] = "" + taxes_data[tax.id]["tax_name"] = ( + tax.display_name + + " (" + + str(tax.amount) + + taxes_data[tax.id]["string"] + + ")" + ) + return taxes_data + + def _get_account_type_domain(self, grouped_by): + """To avoid set all possible types, set in or not in as operator of the types + we are interested in. In v15 we used the internal_type field (type of + account.account.type).""" + at_op = "in" if grouped_by != "taxes" else "not in" + return [ + ("account_type", at_op, ["asset_receivable", "liability_payable"]), + ] + + def _get_acc_prt_accounts_ids(self, company_id, grouped_by): + accounts_domain = [ + ("company_ids", "=", company_id), + ] + self._get_account_type_domain(grouped_by) + acc_prt_accounts = self.env["account.account"].search(accounts_domain) + return acc_prt_accounts.ids + + def _get_initial_balances_bs_ml_domain( + self, account_ids, company_id, date_from, base_domain, grouped_by, acc_prt=False + ): + accounts_domain = [ + ("company_ids", "=", company_id), + ("include_initial_balance", "=", True), + ] + if account_ids: + accounts_domain += [("id", "in", account_ids)] + domain = [] + domain += base_domain + domain += [("date", "<", date_from)] + accounts = self.env["account.account"].search(accounts_domain) + domain += [("account_id", "in", accounts.ids)] + if acc_prt: + domain += self._get_account_type_domain(grouped_by) + return domain + + def _get_initial_balances_pl_ml_domain( + self, account_ids, company_id, date_from, fy_start_date, base_domain + ): + accounts_domain = [ + ("company_ids", "=", company_id), + ("include_initial_balance", "=", False), + ] + if account_ids: + accounts_domain += [("id", "in", account_ids)] + domain = [] + domain += base_domain + domain += [("date", "<", date_from), ("date", ">=", fy_start_date)] + accounts = self.env["account.account"].search(accounts_domain) + domain += [("account_id", "in", accounts.ids)] + return domain + + def _get_accounts_initial_balance(self, initial_domain_bs, initial_domain_pl): + gl_initial_acc_bs = self.env["account.move.line"].read_group( + domain=initial_domain_bs, + fields=["account_id", "debit", "credit", "balance", "amount_currency:sum"], + groupby=["account_id"], + ) + gl_initial_acc_pl = self.env["account.move.line"].read_group( + domain=initial_domain_pl, + fields=["account_id", "debit", "credit", "balance", "amount_currency:sum"], + groupby=["account_id"], + ) + gl_initial_acc = gl_initial_acc_bs + gl_initial_acc_pl + return gl_initial_acc + + def _get_initial_balance_fy_pl_ml_domain( + self, account_ids, company_id, fy_start_date, base_domain + ): + accounts_domain = [ + ("company_ids", "=", company_id), + ("include_initial_balance", "=", False), + ] + if account_ids: + accounts_domain += [("id", "in", account_ids)] + domain = [] + domain += base_domain + domain += [("date", "<", fy_start_date)] + accounts = self.env["account.account"].search(accounts_domain) + domain += [("account_id", "in", accounts.ids)] + return domain + + def _get_pl_initial_balance( + self, account_ids, company_id, fy_start_date, foreign_currency, base_domain + ): + domain = self._get_initial_balance_fy_pl_ml_domain( + account_ids, company_id, fy_start_date, base_domain + ) + initial_balances = self.env["account.move.line"].read_group( + domain=domain, + fields=["account_id", "debit", "credit", "balance", "amount_currency:sum"], + groupby=["account_id"], + ) + pl_initial_balance = { + "debit": 0.0, + "credit": 0.0, + "balance": 0.0, + "bal_curr": 0.0, + } + for initial_balance in initial_balances: + pl_initial_balance["debit"] += initial_balance["debit"] + pl_initial_balance["credit"] += initial_balance["credit"] + pl_initial_balance["balance"] += initial_balance["balance"] + pl_initial_balance["bal_curr"] += initial_balance["amount_currency"] + return pl_initial_balance + + def _get_gl_initial_acc( + self, account_ids, company_id, date_from, fy_start_date, base_domain, grouped_by + ): + initial_domain_bs = self._get_initial_balances_bs_ml_domain( + account_ids, company_id, date_from, base_domain, grouped_by + ) + initial_domain_pl = self._get_initial_balances_pl_ml_domain( + account_ids, company_id, date_from, fy_start_date, base_domain + ) + return self._get_accounts_initial_balance(initial_domain_bs, initial_domain_pl) + + def _prepare_gen_ld_data_item(self, gl): + res = {} + for key_bal in ["init_bal", "fin_bal"]: + res[key_bal] = {} + for key_field in ["credit", "debit", "balance", "bal_curr"]: + field_name = key_field if key_field != "bal_curr" else "amount_currency" + res[key_bal][key_field] = gl[field_name] + return res + + def _prepare_gen_ld_data(self, gl_initial_acc, domain, grouped_by): + data = {} + for gl in gl_initial_acc: + acc_id = gl["account_id"][0] + data[acc_id] = self._prepare_gen_ld_data_item(gl) + data[acc_id]["id"] = acc_id + if grouped_by: + data[acc_id][grouped_by] = False + method = "_prepare_gen_ld_data_group_%s" % grouped_by + if not hasattr(self, method): + return data + return getattr(self, method)(data, domain, grouped_by) + + def _prepare_gen_ld_data_group_partners(self, data, domain, grouped_by): + gl_initial_acc_prt = self.env["account.move.line"].read_group( + domain=domain, + fields=[ + "account_id", + "partner_id", + "debit", + "credit", + "balance", + "amount_currency:sum", + ], + groupby=["account_id", "partner_id"], + lazy=False, + ) + if gl_initial_acc_prt: + for gl in gl_initial_acc_prt: + if not gl["partner_id"]: + prt_id = 0 + prt_name = _("Missing Partner") + else: + prt_id = gl["partner_id"][0] + prt_name = gl["partner_id"][1] + prt_name = prt_name._value + acc_id = gl["account_id"][0] + data[acc_id][prt_id] = self._prepare_gen_ld_data_item(gl) + data[acc_id][prt_id]["id"] = prt_id + data[acc_id][prt_id]["name"] = prt_name + data[acc_id][grouped_by] = True + return data + + def _prepare_gen_ld_data_group_taxes(self, data, domain, grouped_by): + gl_initial_acc_prt = self.env["account.move.line"].read_group( + domain=domain, + fields=[ + "account_id", + "debit", + "credit", + "balance", + "amount_currency:sum", + "tax_line_id", + ], + groupby=["account_id"], + lazy=False, + ) + if gl_initial_acc_prt: + for gl in gl_initial_acc_prt: + if "tax_line_id" in gl and gl["tax_line_id"]: + tax_id = gl["tax_line_id"][0] + tax_name = gl["tax_line_id"][1] + tax_name = tax_name._value + else: + tax_id = 0 + tax_name = "Missing Tax" + acc_id = gl["account_id"][0] + data[acc_id][tax_id] = self._prepare_gen_ld_data_item(gl) + data[acc_id][tax_id]["id"] = tax_id + data[acc_id][tax_id]["name"] = tax_name + data[acc_id][grouped_by] = True + return data + + def _get_initial_balance_data( + self, + account_ids, + partner_ids, + company_id, + date_from, + foreign_currency, + only_posted_moves, + unaffected_earnings_account, + fy_start_date, + cost_center_ids, + extra_domain, + grouped_by, + ): + # If explicit list of accounts is provided, + # don't include unaffected earnings account + if account_ids: + unaffected_earnings_account = False + base_domain = [] + if company_id: + base_domain += [("company_id", "=", company_id)] + if partner_ids: + base_domain += [("partner_id", "in", partner_ids)] + if only_posted_moves: + base_domain += [("move_id.state", "=", "posted")] + else: + base_domain += [("move_id.state", "in", ["posted", "draft"])] + if cost_center_ids: + base_domain += [("analytic_account_ids", "in", cost_center_ids)] + if extra_domain: + base_domain += extra_domain + gl_initial_acc = self._get_gl_initial_acc( + account_ids, company_id, date_from, fy_start_date, base_domain, grouped_by + ) + domain = self._get_initial_balances_bs_ml_domain( + account_ids, company_id, date_from, base_domain, grouped_by, acc_prt=True + ) + data = self._prepare_gen_ld_data(gl_initial_acc, domain, grouped_by) + accounts_ids = list(data.keys()) + unaffected_id = unaffected_earnings_account + if unaffected_id: + if unaffected_id not in accounts_ids: + accounts_ids.append(unaffected_id) + data[unaffected_id] = self._initialize_data(foreign_currency) + data[unaffected_id]["id"] = unaffected_id + data[unaffected_id]["mame"] = "" + data[unaffected_id][grouped_by] = False + pl_initial_balance = self._get_pl_initial_balance( + account_ids, company_id, fy_start_date, foreign_currency, base_domain + ) + for key_bal in ["init_bal", "fin_bal"]: + fields_balance = ["credit", "debit", "balance"] + if foreign_currency: + fields_balance.append("bal_curr") + for field_name in fields_balance: + data[unaffected_id][key_bal][field_name] += pl_initial_balance[ + field_name + ] + return data + + @api.model + def _get_move_line_data(self, move_line): + move_type = move_line.get("move_type", "") + inscription = "" + account = self.env['account.account'].browse(move_line['account_id'][0]) + accounttype = account.account_type + if move_type == "entry": + if accounttype == "liability_payable": + inscription = "Платеж поставщику" + elif accounttype == "asset_receivable": + inscription = "Оплата покупателя" + # elif accounttype == "asset_current": + # inscription = "Оплата покупателя" + # else: + # inscription = "" + elif move_type == "out_invoice": + inscription = "Продажа товаров и услуг" + # elif move_type == "out_refund": + # inscription = "Сторно клиента " + elif move_type == "in_invoice": + inscription = "Покупка товаров и услуг " + # elif move_type == "in_refund": + # inscription = "Кредитное обязательство поставщика " + # elif move_type == "out_receipt": + # inscription = "Квитанция продаж" + # elif move_type == "in_receipt": + # inscription = "Квитанция покупки" + + transformed_move_name = f"{inscription} No. {move_line['move_name']}" + move_line_data = { + "id": move_line["id"], + "date": move_line["date"], + "entry": transformed_move_name, + # "entry": move_line["move_name"], + "entry_id": move_line["move_id"][0], + "journal_id": move_line["journal_id"][0], + "account_id": move_line["account_id"][0], + "partner_id": move_line["partner_id"][0] + if move_line["partner_id"] + else False, + "partner_name": move_line["partner_id"][1] + if move_line["partner_id"] + else "", + "ref": "" if not move_line["ref"] else move_line["ref"], + "name": "" if not move_line["name"] else move_line["name"], + "tax_ids": move_line["tax_ids"], + "tax_line_id": move_line["tax_line_id"], + "debit": move_line["debit"], + "credit": move_line["credit"], + "balance": move_line["balance"], + "bal_curr": move_line["amount_currency"], + "rec_id": move_line["full_reconcile_id"][0] + if move_line["full_reconcile_id"] + else False, + "rec_name": move_line["full_reconcile_id"][1] + if move_line["full_reconcile_id"] + else "", + "currency_id": move_line["currency_id"], + "analytic_distribution": move_line["analytic_distribution"] or {}, + } + if ( + move_line_data["ref"] == move_line_data["name"] + or move_line_data["ref"] == "" + ): + ref_label = move_line_data["name"] + elif move_line_data["name"] == "": + ref_label = move_line_data["ref"] + else: + ref_label = move_line_data["ref"] + str(" - ") + move_line_data["name"] + move_line_data.update({"ref_label": ref_label}) + return move_line_data + + @api.model + def _get_period_domain( + self, + account_ids, + partner_ids, + company_id, + only_posted_moves, + date_to, + date_from, + cost_center_ids, + ): + domain = [ + ("display_type", "not in", ["line_note", "line_section"]), + ("date", ">=", date_from), + ("date", "<=", date_to), + ] + if account_ids: + domain += [("account_id", "in", account_ids)] + if company_id: + domain += [("company_id", "=", company_id)] + if partner_ids: + domain += [("partner_id", "in", partner_ids)] + if only_posted_moves: + domain += [("move_id.state", "=", "posted")] + else: + domain += [("move_id.state", "in", ["posted", "draft"])] + + if cost_center_ids: + domain += [("analytic_account_ids", "in", cost_center_ids)] + return domain + + def _initialize_data(self, foreign_currency): + res = {} + for key_bal in ["init_bal", "fin_bal"]: + res[key_bal] = {} + for key_field in ["balance", "credit", "debit"]: + res[key_bal][key_field] = 0.0 + if foreign_currency: + res[key_bal]["bal_curr"] = 0.0 + return res + + def _get_reconciled_after_date_to_ids(self, full_reconcile_ids, date_to): + full_reconcile_ids = list(full_reconcile_ids) + domain = [ + ("max_date", ">", date_to), + ("full_reconcile_id", "in", full_reconcile_ids), + ] + fields = ["full_reconcile_id"] + reconciled_after_date_to = self.env["account.partial.reconcile"].search_read( + domain=domain, fields=fields + ) + rec_after_date_to_ids = list( + map(operator.itemgetter("full_reconcile_id"), reconciled_after_date_to) + ) + rec_after_date_to_ids = [i[0] for i in rec_after_date_to_ids] + return rec_after_date_to_ids + + def _prepare_ml_items(self, move_line, grouped_by): + res = [] + if grouped_by == "partners": + item_id = move_line["partner_id"][0] if move_line["partner_id"] else 0 + item_name = ( + move_line["partner_id"][1] + if move_line["partner_id"] + else _("Missing Partner") + ) + res.append({"id": item_id, "name": item_name}) + elif grouped_by == "taxes": + if move_line["tax_line_id"]: + item_id = move_line["tax_line_id"][0] + item_name = move_line["tax_line_id"][1] + res.append({"id": item_id, "name": item_name}) + elif move_line["tax_ids"]: + for tax_id in move_line["tax_ids"]: + tax_item = self.env["account.tax"].browse(tax_id) + res.append({"id": tax_item.id, "name": tax_item.name}) + else: + res.append({"id": 0, "name": "Missing Tax"}) + else: + res.append({"id": 0, "name": ""}) + return res + + def _get_period_ml_data( + self, + account_ids, + partner_ids, + company_id, + foreign_currency, + only_posted_moves, + date_from, + date_to, + gen_ld_data, + cost_center_ids, + extra_domain, + grouped_by, + ): + domain = self._get_period_domain( + account_ids, + partner_ids, + company_id, + only_posted_moves, + date_to, + date_from, + cost_center_ids, + ) + if extra_domain: + domain += extra_domain + ml_fields = self._get_ml_fields() + move_lines = self.env["account.move.line"].search_read( + domain=domain, fields=ml_fields, order="date,move_name" + ) + journal_ids = set() + full_reconcile_ids = set() + taxes_ids = set() + analytic_ids = set() + full_reconcile_data = {} + acc_prt_account_ids = self._get_acc_prt_accounts_ids(company_id, grouped_by) + for move_line in move_lines: + journal_ids.add(move_line["journal_id"][0]) + for tax_id in move_line["tax_ids"]: + taxes_ids.add(tax_id) + for analytic_account in move_line["analytic_distribution"] or {}: + analytic_ids.add(int(analytic_account)) + if move_line["full_reconcile_id"]: + rec_id = move_line["full_reconcile_id"][0] + if rec_id not in full_reconcile_ids: + full_reconcile_data.update( + { + rec_id: { + "id": rec_id, + "name": move_line["full_reconcile_id"][1], + } + } + ) + full_reconcile_ids.add(rec_id) + acc_id = move_line["account_id"][0] + ml_id = move_line["id"] + if acc_id not in gen_ld_data.keys(): + gen_ld_data[acc_id] = self._initialize_data(foreign_currency) + gen_ld_data[acc_id]["id"] = acc_id + gen_ld_data[acc_id]["mame"] = move_line["account_id"][1] + if grouped_by: + gen_ld_data[acc_id][grouped_by] = False + if acc_id in acc_prt_account_ids: + item_ids = self._prepare_ml_items(move_line, grouped_by) + for item in item_ids: + item_id = item["id"] + if item_id not in gen_ld_data[acc_id]: + if grouped_by: + gen_ld_data[acc_id][grouped_by] = True + gen_ld_data[acc_id][item_id] = self._initialize_data( + foreign_currency + ) + gen_ld_data[acc_id][item_id]["id"] = item_id + gen_ld_data[acc_id][item_id]["name"] = item["name"] + gen_ld_data[acc_id][item_id][ml_id] = self._get_move_line_data( + move_line + ) + gen_ld_data[acc_id][item_id]["fin_bal"]["credit"] += move_line[ + "credit" + ] + gen_ld_data[acc_id][item_id]["fin_bal"]["debit"] += move_line[ + "debit" + ] + gen_ld_data[acc_id][item_id]["fin_bal"]["balance"] += move_line[ + "balance" + ] + if foreign_currency: + gen_ld_data[acc_id][item_id]["fin_bal"][ + "bal_curr" + ] += move_line["amount_currency"] + else: + gen_ld_data[acc_id][ml_id] = self._get_move_line_data(move_line) + gen_ld_data[acc_id]["fin_bal"]["credit"] += move_line["credit"] + gen_ld_data[acc_id]["fin_bal"]["debit"] += move_line["debit"] + gen_ld_data[acc_id]["fin_bal"]["balance"] += move_line["balance"] + if foreign_currency: + gen_ld_data[acc_id]["fin_bal"]["bal_curr"] += move_line[ + "amount_currency" + ] + journals_data = self._get_journals_data(list(journal_ids)) + accounts_data = self._get_accounts_data(gen_ld_data.keys()) + taxes_data = self._get_taxes_data(list(taxes_ids)) + analytic_data = self._get_analytic_data(list(analytic_ids)) + rec_after_date_to_ids = self._get_reconciled_after_date_to_ids( + full_reconcile_data.keys(), date_to + ) + return ( + gen_ld_data, + accounts_data, + journals_data, + full_reconcile_data, + taxes_data, + analytic_data, + rec_after_date_to_ids, + ) + + @api.model + def _recalculate_cumul_balance( + self, move_lines, last_cumul_balance, rec_after_date_to_ids + ): + for move_line in move_lines: + move_line["balance"] += last_cumul_balance + last_cumul_balance = move_line["balance"] + if move_line["rec_id"] in rec_after_date_to_ids: + move_line["rec_name"] = "(" + _("future") + ") " + move_line["rec_name"] + return move_lines + + def _create_account(self, account, acc_id, gen_led_data, rec_after_date_to_ids): + move_lines = [] + for ml_id in gen_led_data[acc_id].keys(): + if not isinstance(ml_id, int): + account.update({ml_id: gen_led_data[acc_id][ml_id]}) + else: + move_lines += [gen_led_data[acc_id][ml_id]] + move_lines = sorted(move_lines, key=lambda k: (k["date"])) + move_lines = self._recalculate_cumul_balance( + move_lines, + gen_led_data[acc_id]["init_bal"]["balance"], + rec_after_date_to_ids, + ) + account.update({"move_lines": move_lines}) + return account + + def _create_account_not_show_item( + self, account, acc_id, gen_led_data, rec_after_date_to_ids, grouped_by + ): + move_lines = [] + for prt_id in gen_led_data[acc_id].keys(): + if not isinstance(prt_id, int): + account.update({prt_id: gen_led_data[acc_id][prt_id]}) + elif isinstance(gen_led_data[acc_id][prt_id], dict): + for ml_id in gen_led_data[acc_id][prt_id].keys(): + if isinstance(ml_id, int): + move_lines += [gen_led_data[acc_id][prt_id][ml_id]] + move_lines = sorted(move_lines, key=lambda k: (k["date"])) + move_lines = self._recalculate_cumul_balance( + move_lines, + gen_led_data[acc_id]["init_bal"]["balance"], + rec_after_date_to_ids, + ) + account.update({"move_lines": move_lines, grouped_by: False}) + return account + + def _get_list_grouped_item( + self, data, account, rec_after_date_to_ids, hide_account_at_0, rounding + ): + list_grouped = [] + for data_id in data.keys(): + group_item = {} + move_lines = [] + if not isinstance(data_id, int): + account.update({data_id: data[data_id]}) + else: + for ml_id in data[data_id].keys(): + if not isinstance(ml_id, int): + group_item.update({ml_id: data[data_id][ml_id]}) + else: + move_lines += [data[data_id][ml_id]] + move_lines = sorted(move_lines, key=lambda k: (k["date"])) + move_lines = self._recalculate_cumul_balance( + move_lines, + data[data_id]["init_bal"]["balance"], + rec_after_date_to_ids, + ) + group_item.update({"move_lines": move_lines}) + if ( + hide_account_at_0 + and float_is_zero( + data[data_id]["init_bal"]["balance"], + precision_rounding=rounding, + ) + and group_item["move_lines"] == [] + ): + continue + list_grouped += [group_item] + return account, list_grouped + + def _create_general_ledger( + self, + gen_led_data, + accounts_data, + grouped_by, + rec_after_date_to_ids, + hide_account_at_0, + ): + general_ledger = [] + rounding = self.env.company.currency_id.rounding + for acc_id in gen_led_data.keys(): + account = {} + account.update( + { + "code": accounts_data[acc_id]["code"], + "name": accounts_data[acc_id]["name"], + "type": "account", + "currency_id": accounts_data[acc_id]["currency_id"], + "centralized": accounts_data[acc_id]["centralized"], + "grouped_by": grouped_by, + } + ) + if grouped_by and not gen_led_data[acc_id][grouped_by]: + account = self._create_account( + account, acc_id, gen_led_data, rec_after_date_to_ids + ) + if ( + hide_account_at_0 + and float_is_zero( + gen_led_data[acc_id]["init_bal"]["balance"], + precision_rounding=rounding, + ) + and account["move_lines"] == [] + ): + continue + else: + if grouped_by: + account, list_grouped = self._get_list_grouped_item( + gen_led_data[acc_id], + account, + rec_after_date_to_ids, + hide_account_at_0, + rounding, + ) + account.update({"list_grouped": list_grouped}) + if ( + hide_account_at_0 + and float_is_zero( + gen_led_data[acc_id]["init_bal"]["balance"], + precision_rounding=rounding, + ) + and account["list_grouped"] == [] + ): + continue + else: + account = self._create_account_not_show_item( + account, acc_id, gen_led_data, rec_after_date_to_ids, grouped_by + ) + if ( + hide_account_at_0 + and float_is_zero( + gen_led_data[acc_id]["init_bal"]["balance"], + precision_rounding=rounding, + ) + and account["move_lines"] == [] + ): + continue + general_ledger += [account] + return general_ledger + + @api.model + def _calculate_centralization(self, centralized_ml, move_line, date_to): + jnl_id = move_line["journal_id"] + month = move_line["date"].month + if jnl_id not in centralized_ml.keys(): + centralized_ml[jnl_id] = {} + if month not in centralized_ml[jnl_id].keys(): + centralized_ml[jnl_id][month] = {} + last_day_month = calendar.monthrange(move_line["date"].year, month) + date = datetime.date(move_line["date"].year, month, last_day_month[1]) + if date > date_to: + date = date_to + centralized_ml[jnl_id][month].update( + { + "journal_id": jnl_id, + "ref_label": "Centralized entries", + "date": date, + "debit": 0.0, + "credit": 0.0, + "balance": 0.0, + "bal_curr": 0.0, + "partner_id": False, + "rec_id": 0, + "entry_id": False, + "tax_ids": [], + "tax_line_id": False, + "full_reconcile_id": False, + "id": False, + "currency_id": False, + "analytic_distribution": {}, + } + ) + centralized_ml[jnl_id][month]["debit"] += move_line["debit"] + centralized_ml[jnl_id][month]["credit"] += move_line["credit"] + centralized_ml[jnl_id][month]["balance"] += ( + move_line["debit"] - move_line["credit"] + ) + centralized_ml[jnl_id][month]["bal_curr"] += move_line["bal_curr"] + return centralized_ml + + @api.model + def _get_centralized_ml(self, account, date_to, grouped_by): + centralized_ml = {} + if isinstance(date_to, str): + date_to = datetime.datetime.strptime(date_to, "%Y-%m-%d").date() + if grouped_by and account[grouped_by]: + for item in account["list_grouped"]: + for move_line in item["move_lines"]: + centralized_ml = self._calculate_centralization( + centralized_ml, + move_line, + date_to, + ) + else: + for move_line in account["move_lines"]: + centralized_ml = self._calculate_centralization( + centralized_ml, + move_line, + date_to, + ) + list_centralized_ml = [] + for jnl_id in centralized_ml.keys(): + list_centralized_ml += list(centralized_ml[jnl_id].values()) + return list_centralized_ml + + @api.model + def _get_report_values(self, docids, data): + logging.info(f'@@@@ general_ledger ') + logging.info(f'@@@@---------------------------------------------------------------------------------------------- _get_report_values ') + logging.info(f'@@@@----------------------------------------------------------------------------------------------' ) + logging.info(f'@@@@---------------------------------------------------------------------------------------------- ') + logging.info(f'@@@@----------------------------------------------------------------------------------------------' ) + logging.info(f'@@@@---------------------------------------------------------------------------------------------- ') + logging.info(f'@@@@---------------------------------------------------------------------------------------------- ') + + wizard_id = data["wizard_id"] + company = self.env["res.company"].browse(data["company_id"]) + company_id = data["company_id"] + date_to = data["date_to"] + date_from = data["date_from"] + partner_ids = data["partner_ids"] + account_ids = data["account_ids"] + cost_center_ids = data["cost_center_ids"] + grouped_by = data["grouped_by"] + hide_account_at_0 = data["hide_account_at_0"] + foreign_currency = data["foreign_currency"] + only_posted_moves = data["only_posted_moves"] + unaffected_earnings_account = data["unaffected_earnings_account"] + fy_start_date = data["fy_start_date"] + extra_domain = data["domain"] + gen_ld_data = self._get_initial_balance_data( + account_ids, + partner_ids, + company_id, + date_from, + foreign_currency, + only_posted_moves, + unaffected_earnings_account, + fy_start_date, + cost_center_ids, + extra_domain, + grouped_by, + ) + centralize = data["centralize"] + ( + gen_ld_data, + accounts_data, + journals_data, + full_reconcile_data, + taxes_data, + analytic_data, + rec_after_date_to_ids, + ) = self._get_period_ml_data( + account_ids, + partner_ids, + company_id, + foreign_currency, + only_posted_moves, + date_from, + date_to, + gen_ld_data, + cost_center_ids, + extra_domain, + grouped_by, + ) + general_ledger = self._create_general_ledger( + gen_ld_data, + accounts_data, + grouped_by, + rec_after_date_to_ids, + hide_account_at_0, + ) + if centralize: + for account in general_ledger: + if account["centralized"]: + centralized_ml = self._get_centralized_ml( + account, date_to, grouped_by + ) + account["move_lines"] = centralized_ml + account["move_lines"] = self._recalculate_cumul_balance( + account["move_lines"], + gen_ld_data[account["id"]]["init_bal"]["balance"], + rec_after_date_to_ids, + ) + if grouped_by and account[grouped_by]: + account[grouped_by] = False + del account["list_grouped"] + general_ledger = sorted(general_ledger, key=lambda k: k["code"]) + logging.info(f'@@@@ general_ledger ') + logging.info(f'@@@@ general_ledger ') + logging.info(f'@@@@ general_ledger {general_ledger}') + logging.info(f'@@@@ general_ledger ') + logging.info(f'@@@@ general_ledger ') + if not general_ledger: + raise UserError(f'Проводок для формирования акта по введенным условиям не найдено.') + return { + "doc_ids": [wizard_id], + "doc_model": "general.ledger.act_revise.wizard", + "docs": self.env["general.ledger.act_revise.wizard"].browse(wizard_id), + "foreign_currency": data["foreign_currency"], + "company_name": company.display_name, + "company_currency": company.currency_id, + "currency_name": company.currency_id.name, + "date_from": data["date_from"], + "date_to": data["date_to"], + "only_posted_moves": data["only_posted_moves"], + "hide_account_at_0": data["hide_account_at_0"], + "show_cost_center": data["show_cost_center"], + "general_ledger": general_ledger, + "accounts_data": accounts_data, + "journals_data": journals_data, + "full_reconcile_data": full_reconcile_data, + "taxes_data": taxes_data, + "centralize": centralize, + "analytic_data": analytic_data, + "filter_partner_ids": True if partner_ids else False, + "currency_model": self.env["res.currency"], + } + + def _get_ml_fields(self): + return self.COMMON_ML_FIELDS + [ + "analytic_distribution", + "full_reconcile_id", + "tax_line_id", + "currency_id", + "credit", + "debit", + "amount_currency", + "balance", + "tax_ids", + "move_name", + ] diff --git a/l10n_ru_act_rev/report/general_ledger.xml b/l10n_ru_act_rev/report/general_ledger.xml new file mode 100644 index 0000000..25f17b5 --- /dev/null +++ b/l10n_ru_act_rev/report/general_ledger.xml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + Акт сверки + general.ledger.act_revise.wizard + qweb-pdf + l10n_ru_act_rev.general_ledger + l10n_ru_act_rev.general_ledger + 'Акт сверки - %s' % (object.get_report_filename() or '') + + + + + Account financial report qweb paperformat + + custom + 297 + 210 + Landscape + 12 + 8 + 5 + 5 + + 10 + 110 + + + + + \ No newline at end of file diff --git a/l10n_ru_act_rev/report/layouts.xml b/l10n_ru_act_rev/report/layouts.xml new file mode 100644 index 0000000..e77d9c7 --- /dev/null +++ b/l10n_ru_act_rev/report/layouts.xml @@ -0,0 +1,34 @@ + + + + + diff --git a/l10n_ru_act_rev/security/ir.model.access.csv b/l10n_ru_act_rev/security/ir.model.access.csv new file mode 100644 index 0000000..166d819 --- /dev/null +++ b/l10n_ru_act_rev/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_general_ledger_act_revise_wizard,general.ledger.act_revise.wizard,model_general_ledger_act_revise_wizard,base.group_user,1,1,1,1 +access_general_ledger_act_revise_wizard_portal,general.ledger.act_revise.wizard.portal,model_general_ledger_act_revise_wizard,base.group_portal,1,1,1,1 diff --git a/l10n_ru_act_rev/views/account_account_views.xml b/l10n_ru_act_rev/views/account_account_views.xml new file mode 100644 index 0000000..38dce94 --- /dev/null +++ b/l10n_ru_act_rev/views/account_account_views.xml @@ -0,0 +1,14 @@ + + + + account.account.form.inherit + + account.account + form + + + + + + + diff --git a/l10n_ru_act_rev/views/portal_templates.xml b/l10n_ru_act_rev/views/portal_templates.xml new file mode 100644 index 0000000..b7a1ff2 --- /dev/null +++ b/l10n_ru_act_rev/views/portal_templates.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/l10n_ru_act_rev/views/report_general_ledger.xml b/l10n_ru_act_rev/views/report_general_ledger.xml new file mode 100644 index 0000000..9e6945e --- /dev/null +++ b/l10n_ru_act_rev/views/report_general_ledger.xml @@ -0,0 +1,9 @@ + + + + diff --git a/l10n_ru_act_rev/wizard/__init__.py b/l10n_ru_act_rev/wizard/__init__.py new file mode 100644 index 0000000..c0d813c --- /dev/null +++ b/l10n_ru_act_rev/wizard/__init__.py @@ -0,0 +1,2 @@ +from . import abstract_wizard +from . import general_ledger_wizard diff --git a/l10n_ru_act_rev/wizard/abstract_wizard.py b/l10n_ru_act_rev/wizard/abstract_wizard.py new file mode 100644 index 0000000..216bae7 --- /dev/null +++ b/l10n_ru_act_rev/wizard/abstract_wizard.py @@ -0,0 +1,38 @@ +from odoo import models, fields + + +class AbstractWizard(models.AbstractModel): + _name = "act_revise.abstract_wizard" + _description = "Abstract Wizard" + + def _get_partner_ids_domain(self): + return [ + "&", + "|", + ("company_id", "=", self.company_id.id), + ("company_id", "=", False), + "|", + ("parent_id", "=", False), + ("is_company", "=", True), + ] + + def _default_partners(self): + context = self.env.context + if context.get("active_ids") and context.get("active_model") == "res.partner": + partners = self.env["res.partner"].browse(context["active_ids"]) + corp_partners = partners.filtered("parent_id") + partners -= corp_partners + partners |= corp_partners.mapped("commercial_partner_id") + return partners.ids + + company_id = fields.Many2one( + comodel_name="res.company", + default=lambda self: self.env.company.id, + required=False, + string="Компания", + ) + + def button_export_pdf(self): + self.ensure_one() + report_type = "qweb-pdf" + return self._export(report_type) \ No newline at end of file diff --git a/l10n_ru_act_rev/wizard/general_ledger_wizard.py b/l10n_ru_act_rev/wizard/general_ledger_wizard.py new file mode 100644 index 0000000..dd1f716 --- /dev/null +++ b/l10n_ru_act_rev/wizard/general_ledger_wizard.py @@ -0,0 +1,897 @@ +import logging +import time +from ast import literal_eval +from odoo import _, api, fields, models +from odoo.tools import date_utils,pycompat +from pytils import dt,numeral +from datetime import datetime, date +import re +import urllib +from odoo.exceptions import UserError + +class GeneralLedgerReportWizard(models.TransientModel): + """General ledger report wizard.""" + + _name = "general.ledger.act_revise.wizard" + _description = "General Ledger Report Wizard" + _inherit = "act_revise.abstract_wizard" + + # date_range_id = fields.Many2one(comodel_name="date.range", string="Date range") + date_from = fields.Date(string="Начало даты", required=True, default=lambda self: self._init_date_from()) + date_to = fields.Date(string="Конец даты", required=True, default=fields.Date.context_today) + fy_start_date = fields.Date(compute="_compute_fy_start_date") + target_move = fields.Selection( + [("posted", "Все проведенные проводки"), ("all", "Все проводки")], + string="Цель операции", + required=True, + default="posted", + ) + account_ids = fields.Many2many( + comodel_name="account.account", string=_("Filter accounts") + ) + centralize = fields.Boolean(string=_("Activate centralization"), default=True) + hide_account_at_0 = fields.Boolean( + string=_("Hide account ending balance at 0"), + help=_("Use this filter to hide an account or a partner " + "with an ending balance at 0. " + "If partners are filtered, " + "debits and credits totals will not match the trial balance."), + ) + receivable_accounts_only = fields.Boolean() + payable_accounts_only = fields.Boolean() + partner_ids = fields.Many2many( + comodel_name="res.partner", + string=_("Filter partners"), + default=lambda self: self._default_partners(), + ) + account_journal_ids = fields.Many2many( + comodel_name="account.journal", string=_("Filter journals") + ) + cost_center_ids = fields.Many2many( + comodel_name="account.analytic.account", string=_("Filter cost centers") + ) + + not_only_one_unaffected_earnings_account = fields.Boolean(readonly=True) + foreign_currency = fields.Boolean( + string=_("Show foreign currency"), + help=_("Display foreign currency for move lines, unless " + "account currency is not setup through chart of accounts " + "will display initial and final balance in that currency."), + default=lambda self: self._default_foreign_currency(), + ) + account_code_from = fields.Many2one( + comodel_name="account.account", + help="Starting account in a range", + ) + account_code_to = fields.Many2one( + comodel_name="account.account", + help="Ending account in a range", + ) + grouped_by = fields.Selection( + selection=[("", "None"), ("partners", "Partners"), ("taxes", "Taxes")], + default="partners", + ) + show_cost_center = fields.Boolean( + string="Show Analytic Account", + default=True, + ) + domain = fields.Char( + string="Journal Items Domain", + default=[], + help="This domain will be used to select specific domain for Journal " "Items", + ) + + # def _print_report(self, report_type): + # self.ensure_one() + # data = self._prepare_report_general_ledger() + # report = self.env["ir.actions.report"].search( + # [("report_name", "=", "act_revise.general_ledger"), ("report_type", "=", report_type)], limit=1, ) + # if self.partner_ids[0].parent_id: + # partner = int(self.partner_ids[0].parent_id.id) + # else: + # partner = int(self.partner_ids[0].id) + # return { + # 'type': 'ir.actions.act_url', + # 'url': '/my/act_revise_contact/%s?date_to=%s&date_from=%s&target_move=%s&company=%s&partner=%s' % ( + # urllib.parse.quote(self.get_report_filename()), self.date_to, self.date_from, self.target_move, + # self.company_id.id, partner), + # 'target': 'new', + # } + + def _get_account_move_lines_domain(self): + domain = literal_eval(self.domain) if self.domain else [] + return domain + + @api.onchange("account_code_from", "account_code_to") + def on_change_account_range(self): + if ( + self.account_code_from + and self.account_code_from.code.isdigit() + and self.account_code_to + and self.account_code_to.code.isdigit() + ): + start_range = self.account_code_from.code + end_range = self.account_code_to.code + self.account_ids = self.env["account.account"].search( + [("code", ">=", start_range), ("code", "<=", end_range)] + ) + if self.company_id: + self.account_ids = self.account_ids.filtered( + lambda a: a.company_ids == self.company_id + ) + + def _init_date_from(self): + """set start date to begin of current year if fiscal year running""" + today = fields.Date.context_today(self) + company = self.company_id or self.env.company + last_fsc_month = company.fiscalyear_last_month + last_fsc_day = company.fiscalyear_last_day + + if ( + today.month < int(last_fsc_month) + or today.month == int(last_fsc_month) + and today.day <= last_fsc_day + ): + return time.strftime("%Y-01-01") + else: + return False + + def _default_foreign_currency(self): + return self.env.user.has_group("base.group_multi_currency") + + @api.depends("date_from") + def _compute_fy_start_date(self): + for wiz in self: + if wiz.date_from: + date_from, date_to = date_utils.get_fiscal_year( + wiz.date_from, + day=self.company_id.fiscalyear_last_day, + month=int(self.company_id.fiscalyear_last_month), + ) + wiz.fy_start_date = date_from + else: + wiz.fy_start_date = False + + @api.onchange("company_id") + def onchange_company_id(self): + """Handle company change.""" + count = self.env["account.account"].search_count( + [ + ("account_type", "=", "equity_unaffected"), + ("company_ids", "=", self.company_id.id), + ] + ) + self.not_only_one_unaffected_earnings_account = count != 1 + # if ( + # self.company_id + # and self.date_range_id.company_id + # and self.date_range_id.company_id != self.company_id + # ): + # self.date_range_id = False + if self.company_id and self.account_journal_ids: + self.account_journal_ids = self.account_journal_ids.filtered( + lambda p: p.company_id == self.company_id or not p.company_id + ) + if self.company_id and self.partner_ids: + self.partner_ids = self.partner_ids.filtered( + lambda p: p.company_id == self.company_id or not p.company_id + ) + if self.company_id and self.account_ids: + if self.receivable_accounts_only or self.payable_accounts_only: + self.onchange_type_accounts_only() + else: + self.account_ids = self.account_ids.filtered( + lambda a: a.company_ids == self.company_id + ) + if self.company_id and self.cost_center_ids: + self.cost_center_ids = self.cost_center_ids.filtered( + lambda c: c.company_id == self.company_id + ) + res = { + "domain": { + "account_ids": [], + "partner_ids": [], + "account_journal_ids": [], + "cost_center_ids": [], + # "date_range_id": [], + } + } + if not self.company_id: + return res + else: + res["domain"]["account_ids"] += [("company_ids", "=", self.company_id.id)] + res["domain"]["account_journal_ids"] += [ + ("company_ids", "=", self.company_id.id) + ] + res["domain"]["partner_ids"] += self._get_partner_ids_domain() + res["domain"]["cost_center_ids"] += [ + ("company_id", "=", self.company_id.id) + ] + # res["domain"]["date_range_id"] += [ + # "|", + # ("company_id", "=", self.company_id.id), + # ("company_id", "=", False), + # ] + return res + + # @api.onchange("date_range_id") + # def onchange_date_range_id(self): + # """Handle date range change.""" + # if self.date_range_id: + # self.date_from = self.date_range_id.date_start + # self.date_to = self.date_range_id.date_end + + # @api.constrains("company_id", "date_range_id") + # def _check_company_id_date_range_id(self): + # for rec in self.sudo(): + # if ( + # rec.company_id + # and rec.date_range_id.company_id + # and rec.company_id != rec.date_range_id.company_id + # ): + # raise ValidationError( + # _( + # "The Company in the General Ledger Report Wizard and in " + # "Date Range must be the same." + # ) + # ) + + @api.onchange("receivable_accounts_only", "payable_accounts_only") + def onchange_type_accounts_only(self): + """Handle receivable/payable accounts only change.""" + if self.receivable_accounts_only or self.payable_accounts_only: + domain = [("company_ids", "=", self.company_id.id)] + if self.receivable_accounts_only and self.payable_accounts_only: + domain += [ + ("account_type", "in", ("asset_receivable", "liability_payable")) + ] + elif self.receivable_accounts_only: + domain += [("account_type", "=", "asset_receivable")] + elif self.payable_accounts_only: + domain += [("account_type", "=", "liability_payable")] + self.account_ids = self.env["account.account"].search(domain) + else: + self.account_ids = None + + @api.onchange("partner_ids") + def onchange_partner_ids(self): + """Handle partners change.""" + if self.partner_ids: + self.receivable_accounts_only = self.payable_accounts_only = True + else: + self.receivable_accounts_only = self.payable_accounts_only = False + + @api.depends("company_id") + def _compute_unaffected_earnings_account(self): + for record in self: + record.unaffected_earnings_account = self.env["account.account"].search( + [ + ("account_type", "=", "equity_unaffected"), + ("company_ids", "=", record.company_id.id), + ] + ) + + unaffected_earnings_account = fields.Many2one( + comodel_name="account.account", + compute="_compute_unaffected_earnings_account", + store=True, + ) + + # def _print_report(self, report_type): + # self.ensure_one() + # data = self._prepare_report_general_ledger() + # report_name = "act_revise.general_ledger" + # return ( + # self.env["ir.actions.report"] + # .search( + # [("report_name", "=", report_name), ("report_type", "=", report_type)], + # limit=1, + # ) + # .report_action(self, data=data) + # ) + def _print_report(self, report_type): + self.ensure_one() + data = self._prepare_report_general_ledger() + report = self.env["ir.actions.report"].search( + [("report_name", "=", "l10n_ru_act_rev.general_ledger"), ("report_type", "=", report_type)], limit=1, ) + + if self.partner_ids[0].parent_id: + partner = int(self.partner_ids[0].parent_id.id) + else: + partner = int(self.partner_ids[0].id) + account_data = self.env['account.move.line'].sudo().search([ + ('partner_id', '=', partner), + ('account_id.account_type', 'in', ('liability_payable', 'asset_receivable')), + ('account_id.non_trade', '=', False), + ('date', '<=', self.date_to), + ('date', '>=', self.date_from) + ]) + if self.target_move == 'posted' and not account_data.filtered(lambda p: p.parent_state == 'posted') or not account_data: + raise UserError(f'Проводок для формирования акта по введенным условиям не найдено.') + return { + 'type': 'ir.actions.act_url', + 'url': '/my/act_revise_contact/%s?date_to=%s&date_from=%s&target_move=%s&company=%s&partner=%s' % ( + urllib.parse.quote(self.get_report_filename()), self.date_to, self.date_from, self.target_move, + self.company_id.id, partner), + 'target': 'new', + } + + def _prepare_report_general_ledger(self): + self.ensure_one() + return { + "wizard_id": self.id, + "date_from": self.date_from, + "date_to": self.date_to, + "only_posted_moves": self.target_move == "posted", + "hide_account_at_0": self.hide_account_at_0, + "foreign_currency": self.foreign_currency, + "company_id": self.company_id.id, + "account_ids": self.account_ids.ids, + "partner_ids": self.partner_ids.ids, + "grouped_by": self.grouped_by, + "cost_center_ids": self.cost_center_ids.ids, + "show_cost_center": self.show_cost_center, + "journal_ids": self.account_journal_ids.ids, + "centralize": self.centralize, + "fy_start_date": self.fy_start_date, + "unaffected_earnings_account": self.unaffected_earnings_account.id, + "account_financial_report_lang": self.env.lang, + "domain": self._get_account_move_lines_domain(), + } + + def _export(self, report_type): + """Default export is PDF.""" + return self._print_report(report_type) + + def _get_atr_from_dict(self, obj_id, data, key): + try: + return data[obj_id][key] + except KeyError: + return data[str(obj_id)][key] + + def numer(self, name): + if name: + numeration = re.findall('\d+$', name) + if numeration: return numeration[0] + return name + + def get_data_format(self, date): + if date and date != 'False': + return dt.ru_strftime(u'%d.%m.%Y г.', date=datetime.strptime(str(date), "%Y-%m-%d"), inflected=True) + return '' + + def initials(self, fio): + if fio: + return (fio.split()[0] + ' ' + ''.join([fio[0:1] + '.' for fio in fio.split()[1:]])).strip() + return '' + + def rubles(self, sum): + "Transform sum number in rubles to text" + text_rubles = numeral.rubles(int(sum)) + copeck = round((sum - int(sum)) * 100) + text_copeck = numeral.choose_plural(int(copeck), (u"копейка", u"копейки", u"копеек")) + return ("%s %02d %s") % (text_rubles, copeck, text_copeck) + + 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 = "" % ( + width, + height, + type, + str(pycompat.to_text(img))) + return toreturn + + def get_contract(self): + partner = int(self.partner_ids[0].id) + contract = self.env['partner.contract.customer'].search( + [('partner_id', '=', partner), ('state', '=', 'signed')], limit=1) + if contract: + return contract + + def get_function_partner(self, partner): + director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) + if director: + if director.function: + return director.function or 'отсутствует' + + def get_name_partner(self, partner): + director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) + if director: + return director.name or 'отсутствует' + + def get_report_filename(self): + today = date.today() + d1 = today.strftime("%d-%m-%Y") + if self.partner_ids[0].parent_id: + p = ''.join(self.partner_ids[0].parent_id.name) + else: + p = ''.join(self.partner_ids[0].name) + # return 'Акт Сверки '+ d1 + ' ' + self.company_id.name+'_'+p + return str(self.company_id.id) + ' - ' + ' ' + d1 + + def sorted_lines(self, list): + list = sorted(list, key=lambda k: k.get('date'), reverse=False) + return list + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# +# import time +# from ast import literal_eval +# from odoo import _, api, fields, models +# from odoo.tools import date_utils,pycompat +# from pytils import dt,numeral +# from datetime import datetime, date +# import re +# import urllib +# +# class GeneralLedgerReportWizard(models.TransientModel): +# """General ledger report wizard.""" +# +# _name = "general.ledger.act_revise.wizard" +# _description = "General Ledger Report Wizard" +# _inherit = "act_revise.abstract_wizard" +# +# # date_range_id = fields.Many2one(comodel_name="date.range", string="Date range") +# date_from = fields.Date(string="Начало даты", required=True, default=lambda self: self._init_date_from()) +# date_to = fields.Date(string="Конец даты", required=True, default=fields.Date.context_today) +# fy_start_date = fields.Date(compute="_compute_fy_start_date") +# target_move = fields.Selection( +# [("posted", "Р’СЃРµ проведенные РїСЂРѕРІРѕРґРєРё"), ("all", "Р’СЃРµ РїСЂРѕРІРѕРґРєРё")], +# string="Цель операции", +# required=True, +# default="posted", +# ) +# account_ids = fields.Many2many( +# comodel_name="account.account", string=_("Filter accounts") +# ) +# centralize = fields.Boolean(string=_("Activate centralization"), default=True) +# hide_account_at_0 = fields.Boolean( +# string=_("Hide account ending balance at 0"), +# help=_("Use this filter to hide an account or a partner " +# "with an ending balance at 0. " +# "If partners are filtered, " +# "debits and credits totals will not match the trial balance."), +# ) +# receivable_accounts_only = fields.Boolean() +# payable_accounts_only = fields.Boolean() +# partner_ids = fields.Many2many( +# comodel_name="res.partner", +# string=_("Filter partners"), +# default=lambda self: self._default_partners(), +# ) +# account_journal_ids = fields.Many2many( +# comodel_name="account.journal", string=_("Filter journals") +# ) +# cost_center_ids = fields.Many2many( +# comodel_name="account.analytic.account", string=_("Filter cost centers") +# ) +# +# not_only_one_unaffected_earnings_account = fields.Boolean(readonly=True) +# foreign_currency = fields.Boolean( +# string=_("Show foreign currency"), +# help=_("Display foreign currency for move lines, unless " +# "account currency is not setup through chart of accounts " +# "will display initial and final balance in that currency."), +# default=lambda self: self._default_foreign_currency(), +# ) +# account_code_from = fields.Many2one( +# comodel_name="account.account", +# help="Starting account in a range", +# ) +# account_code_to = fields.Many2one( +# comodel_name="account.account", +# help="Ending account in a range", +# ) +# grouped_by = fields.Selection( +# selection=[("", "None"), ("partners", "Partners"), ("taxes", "Taxes")], +# default="partners", +# ) +# show_cost_center = fields.Boolean( +# string="Show Analytic Account", +# default=True, +# ) +# domain = fields.Char( +# string="Journal Items Domain", +# default=[], +# help="This domain will be used to select specific domain for Journal " "Items", +# ) +# +# # def _print_report(self, report_type): +# # self.ensure_one() +# # data = self._prepare_report_general_ledger() +# # report = self.env["ir.actions.report"].search( +# # [("report_name", "=", "act_revise.general_ledger"), ("report_type", "=", report_type)], limit=1, ) +# # if self.partner_ids[0].parent_id: +# # partner = int(self.partner_ids[0].parent_id.id) +# # else: +# # partner = int(self.partner_ids[0].id) +# # return { +# # 'type': 'ir.actions.act_url', +# # 'url': '/my/act_revise_contact/%s?date_to=%s&date_from=%s&target_move=%s&company=%s&partner=%s' % ( +# # urllib.parse.quote(self.get_report_filename()), self.date_to, self.date_from, self.target_move, +# # self.company_id.id, partner), +# # 'target': 'new', +# # } +# +# def _get_account_move_lines_domain(self): +# domain = literal_eval(self.domain) if self.domain else [] +# return domain +# +# @api.onchange("account_code_from", "account_code_to") +# def on_change_account_range(self): +# if ( +# self.account_code_from +# and self.account_code_from.code.isdigit() +# and self.account_code_to +# and self.account_code_to.code.isdigit() +# ): +# start_range = self.account_code_from.code +# end_range = self.account_code_to.code +# self.account_ids = self.env["account.account"].search( +# [("code", ">=", start_range), ("code", "<=", end_range)] +# ) +# if self.company_id: +# self.account_ids = self.account_ids.filtered( +# lambda a: a.company_id == self.company_id +# ) +# +# def _init_date_from(self): +# """set start date to begin of current year if fiscal year running""" +# today = fields.Date.context_today(self) +# company = self.company_id or self.env.company +# last_fsc_month = company.fiscalyear_last_month +# last_fsc_day = company.fiscalyear_last_day +# +# if ( +# today.month < int(last_fsc_month) +# or today.month == int(last_fsc_month) +# and today.day <= last_fsc_day +# ): +# return time.strftime("%Y-01-01") +# else: +# return False +# +# def _default_foreign_currency(self): +# return self.env.user.has_group("base.group_multi_currency") +# +# @api.depends("date_from") +# def _compute_fy_start_date(self): +# for wiz in self: +# if wiz.date_from: +# date_from, date_to = date_utils.get_fiscal_year( +# wiz.date_from, +# day=self.company_id.fiscalyear_last_day, +# month=int(self.company_id.fiscalyear_last_month), +# ) +# wiz.fy_start_date = date_from +# else: +# wiz.fy_start_date = False +# +# @api.onchange("company_id") +# def onchange_company_id(self): +# """Handle company change.""" +# count = self.env["account.account"].search_count( +# [ +# ("account_type", "=", "equity_unaffected"), +# ("company_id", "=", self.company_id.id), +# ] +# ) +# self.not_only_one_unaffected_earnings_account = count != 1 +# # if ( +# # self.company_id +# # and self.date_range_id.company_id +# # and self.date_range_id.company_id != self.company_id +# # ): +# # self.date_range_id = False +# if self.company_id and self.account_journal_ids: +# self.account_journal_ids = self.account_journal_ids.filtered( +# lambda p: p.company_id == self.company_id or not p.company_id +# ) +# if self.company_id and self.partner_ids: +# self.partner_ids = self.partner_ids.filtered( +# lambda p: p.company_id == self.company_id or not p.company_id +# ) +# if self.company_id and self.account_ids: +# if self.receivable_accounts_only or self.payable_accounts_only: +# self.onchange_type_accounts_only() +# else: +# self.account_ids = self.account_ids.filtered( +# lambda a: a.company_id == self.company_id +# ) +# if self.company_id and self.cost_center_ids: +# self.cost_center_ids = self.cost_center_ids.filtered( +# lambda c: c.company_id == self.company_id +# ) +# res = { +# "domain": { +# "account_ids": [], +# "partner_ids": [], +# "account_journal_ids": [], +# "cost_center_ids": [], +# # "date_range_id": [], +# } +# } +# if not self.company_id: +# return res +# else: +# res["domain"]["account_ids"] += [("company_id", "=", self.company_id.id)] +# res["domain"]["account_journal_ids"] += [ +# ("company_id", "=", self.company_id.id) +# ] +# res["domain"]["partner_ids"] += self._get_partner_ids_domain() +# res["domain"]["cost_center_ids"] += [ +# ("company_id", "=", self.company_id.id) +# ] +# # res["domain"]["date_range_id"] += [ +# # "|", +# # ("company_id", "=", self.company_id.id), +# # ("company_id", "=", False), +# # ] +# return res +# +# # @api.onchange("date_range_id") +# # def onchange_date_range_id(self): +# # """Handle date range change.""" +# # if self.date_range_id: +# # self.date_from = self.date_range_id.date_start +# # self.date_to = self.date_range_id.date_end +# +# # @api.constrains("company_id", "date_range_id") +# # def _check_company_id_date_range_id(self): +# # for rec in self.sudo(): +# # if ( +# # rec.company_id +# # and rec.date_range_id.company_id +# # and rec.company_id != rec.date_range_id.company_id +# # ): +# # raise ValidationError( +# # _( +# # "The Company in the General Ledger Report Wizard and in " +# # "Date Range must be the same." +# # ) +# # ) +# +# @api.onchange("receivable_accounts_only", "payable_accounts_only") +# def onchange_type_accounts_only(self): +# """Handle receivable/payable accounts only change.""" +# if self.receivable_accounts_only or self.payable_accounts_only: +# domain = [("company_id", "=", self.company_id.id)] +# if self.receivable_accounts_only and self.payable_accounts_only: +# domain += [ +# ("account_type", "in", ("asset_receivable", "liability_payable")) +# ] +# elif self.receivable_accounts_only: +# domain += [("account_type", "=", "asset_receivable")] +# elif self.payable_accounts_only: +# domain += [("account_type", "=", "liability_payable")] +# self.account_ids = self.env["account.account"].search(domain) +# else: +# self.account_ids = None +# +# @api.onchange("partner_ids") +# def onchange_partner_ids(self): +# """Handle partners change.""" +# if self.partner_ids: +# self.receivable_accounts_only = self.payable_accounts_only = True +# else: +# self.receivable_accounts_only = self.payable_accounts_only = False +# +# @api.depends("company_id") +# def _compute_unaffected_earnings_account(self): +# for record in self: +# record.unaffected_earnings_account = self.env["account.account"].search( +# [ +# ("account_type", "=", "equity_unaffected"), +# ("company_id", "=", record.company_id.id), +# ] +# ) +# +# unaffected_earnings_account = fields.Many2one( +# comodel_name="account.account", +# compute="_compute_unaffected_earnings_account", +# store=True, +# ) +# +# # def _print_report(self, report_type): +# # self.ensure_one() +# # data = self._prepare_report_general_ledger() +# # report_name = "act_revise.general_ledger" +# # return ( +# # self.env["ir.actions.report"] +# # .search( +# # [("report_name", "=", report_name), ("report_type", "=", report_type)], +# # limit=1, +# # ) +# # .report_action(self, data=data) +# # ) +# def _print_report(self, report_type): +# self.ensure_one() +# data = self._prepare_report_general_ledger() +# report = self.env["ir.actions.report"].search( +# [("report_name", "=", "act_revise.general_ledger"), ("report_type", "=", report_type)], limit=1, ) +# # report.report_name='Test' +# # report.headers.add('Content-Disposition', 'attachment; filename="Test.pdf";') +# # pdf, _ = request.env.ref('act_revise.action_print_report_general_ledger_qweb').sudo().render_qweb_pdf(self,data=data) +# # pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)),('Content-Disposition', 'attachment; filename="%s";' % report_name),] +# # return request.make_response(pdf, headers=pdfhttpheaders) +# # return ( +# # self.env["ir.actions.report"] +# # .search( +# # [("report_name", "=", "act_revise.general_ledger"), ("report_type", "=", report_type)], +# # limit=1, +# # ) +# # report.report_action(self, data=data) +# # ) +# # name='Test' +# if self.partner_ids[0].parent_id: +# partner = int(self.partner_ids[0].parent_id.id) +# else: +# partner = int(self.partner_ids[0].id) +# account_data = self.env['account.move.line'].sudo().search([ +# ('partner_id', '=', partner.id), +# ('account_id.account_type', 'in', ('liability_payable', 'asset_receivable')), +# ('account_id.non_trade', '=', False), +# ('date', '<=', self.date_to), +# ('date', '>=', self.date_from) +# ]) +# if not account_data: +# raise UserError(f'Проводок для формирования акта по введенным условиям не найдено.') +# return { +# 'type': 'ir.actions.act_url', +# 'url': '/my/act_revise_contact/%s?date_to=%s&date_from=%s&target_move=%s&company=%s&partner=%s' % ( +# urllib.parse.quote(self.get_report_filename()), self.date_to, self.date_from, self.target_move, +# self.company_id.id, partner), +# 'target': 'new', +# } +# +# def _prepare_report_general_ledger(self): +# self.ensure_one() +# return { +# "wizard_id": self.id, +# "date_from": self.date_from, +# "date_to": self.date_to, +# "only_posted_moves": self.target_move == "posted", +# "hide_account_at_0": self.hide_account_at_0, +# "foreign_currency": self.foreign_currency, +# "company_id": self.company_id.id, +# "account_ids": self.account_ids.ids, +# "partner_ids": self.partner_ids.ids, +# "grouped_by": self.grouped_by, +# "cost_center_ids": self.cost_center_ids.ids, +# "show_cost_center": self.show_cost_center, +# "journal_ids": self.account_journal_ids.ids, +# "centralize": self.centralize, +# "fy_start_date": self.fy_start_date, +# "unaffected_earnings_account": self.unaffected_earnings_account.id, +# "account_financial_report_lang": self.env.lang, +# "domain": self._get_account_move_lines_domain(), +# } +# +# def _export(self, report_type): +# """Default export is PDF.""" +# return self._print_report(report_type) +# +# def _get_atr_from_dict(self, obj_id, data, key): +# try: +# return data[obj_id][key] +# except KeyError: +# return data[str(obj_id)][key] +# +# def numer(self, name): +# if name: +# numeration = re.findall('\d+$', name) +# if numeration: return numeration[0] +# return name +# +# def get_data_format(self, date): +# if date and date != 'False': +# return dt.ru_strftime(u'%d.%m.%Y Рі.', date=datetime.strptime(str(date), "%Y-%m-%d"), inflected=True) +# return '' +# +# def initials(self, fio): +# if fio: +# return (fio.split()[0] + ' ' + ''.join([fio[0:1] + '.' for fio in fio.split()[1:]])).strip() +# return '' +# +# def rubles(self, sum): +# "Transform sum number in rubles to text" +# text_rubles = numeral.rubles(int(sum)) +# copeck = round((sum - int(sum)) * 100) +# text_copeck = numeral.choose_plural(int(copeck), (u"копейка", u"копейки", u"копеек")) +# return ("%s %02d %s") % (text_rubles, copeck, text_copeck) +# +# 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 = "" % ( +# width, +# height, +# type, +# str(pycompat.to_text(img))) +# return toreturn +# +# def get_contract(self): +# partner = int(self.partner_ids[0].id) +# contract = self.env['partner.contract.customer'].search( +# [('partner_id', '=', partner), ('state', '=', 'signed')], limit=1) +# if contract: +# return contract +# +# def get_function_partner(self, partner): +# director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) +# if director: +# if director.function: +# return director.function or 'отсутствует' +# +# def get_name_partner(self, partner): +# director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) +# if director: +# return director.name or 'отсутствует' +# +# def get_report_filename(self): +# today = date.today() +# d1 = today.strftime("%d-%m-%Y") +# if self.partner_ids[0].parent_id: +# p = ''.join(self.partner_ids[0].parent_id.name) +# else: +# p = ''.join(self.partner_ids[0].name) +# # return 'РђРєС‚ Сверки '+ d1 + ' ' + self.company_id.name+'_'+p +# return str(self.company_id.id) + ' - ' + ' ' + d1 +# +# def sorted_lines(self, list): +# list = sorted(list, key=lambda k: k.get('date'), reverse=False) +# return list diff --git a/l10n_ru_act_rev/wizard/general_ledger_wizard_view.xml b/l10n_ru_act_rev/wizard/general_ledger_wizard_view.xml new file mode 100644 index 0000000..71e7770 --- /dev/null +++ b/l10n_ru_act_rev/wizard/general_ledger_wizard_view.xml @@ -0,0 +1,164 @@ + + + + + Акт сверки + general.ledger.act_revise.wizard + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +

+ General Ledger can be computed only if selected company have + only one unaffected earnings account. +

+ +
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + Акт сверки + general.ledger.act_revise.wizard + form + + new + + + + Печатать акт сверки + general.ledger.act_revise.wizard + + form + {'default_receivable_accounts_only': 1, 'default_payable_accounts_only': 1} + + new + + + + +
diff --git a/l10n_ru_attorney/README.md b/l10n_ru_attorney/README.md new file mode 100644 index 0000000..58c8d91 --- /dev/null +++ b/l10n_ru_attorney/README.md @@ -0,0 +1,21 @@ +# Российская локализация - Доверенность +name: l10n_ru_attorney + +## Описание +Создание списка доверенностей на получение ТМЦ и их печать. + +###Создание доверенности: +1. Меню Покупки - Доверенности - кнопка "Создать"; +2. На форме указываем: + + 2.1. Контрагент - поставщик; + + 2.2. Заказ на закупку; + + 2.3. Даты действия доверенности ("дата выдачи" и "действительно по"). + + +###Для печати: +1. Меню Настройки - Техническое - Отчеты; +2. Находим в списке l10n_ru_attorney и добавляем в меню "Печать"; +3. Открываем созданную запись доверенности - Действие - "Доверенность". \ No newline at end of file diff --git a/l10n_ru_attorney/__init__.py b/l10n_ru_attorney/__init__.py new file mode 100644 index 0000000..5305644 --- /dev/null +++ b/l10n_ru_attorney/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/l10n_ru_attorney/__manifest__.py b/l10n_ru_attorney/__manifest__.py new file mode 100644 index 0000000..b076846 --- /dev/null +++ b/l10n_ru_attorney/__manifest__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Российская локализация - Доверенность", + + 'summary': """ + Печать доверенности на получение ТМЦ + """, + + 'description': """ + Создание списка доверенностей на получение ТМЦ и их печать. + + Создание доверенности: + 1. Меню Покупки - Доверенности - кнопка "Создать"; + 2. На форме указываем: + 2.1. Контрагент - поставщик; + 2.2. Заказ на закупку; + 2.3. Даты действия доверенности ("дата выдачи" и "действительно по"). + + Для печати: + 1. Меню Настройки - Техническое - Отчеты; + 2. Находим в списке l10n_ru_attorney и добавляем в меню "Печать"; + 3. Открываем созданную запись доверенности - Действие - "Доверенность". + """, + + 'author': "MK.Lab", + 'website': "https://www.inf-centre.ru/", + + 'category': 'Uncategorized', + 'version': '0.1', + + # any module necessary for this one to work correctly + 'depends': ['base', 'account', 'sale', 'purchase', 'hr', 'l10n_ru_base'], + + # always loaded + 'data': [ + 'security/ir.model.access.csv', + 'views/base_consent_views.xml', + 'views/hr_employee_views.xml', + 'views/purchase_order_views.xml', + 'report/consent_report.xml', + ], +} diff --git a/l10n_ru_attorney/models/__init__.py b/l10n_ru_attorney/models/__init__.py new file mode 100644 index 0000000..0cad714 --- /dev/null +++ b/l10n_ru_attorney/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import base_consent +from . import hr_employee +from . import purchase_order \ No newline at end of file diff --git a/l10n_ru_attorney/models/__init__.pyc b/l10n_ru_attorney/models/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bc99192487a41fcc0e13f73ab8ccc2578edebff GIT binary patch literal 202 zcmZSn%*z$GZc#!q0~9a;X$K%K76B3|K*Y$9!@!Ws$PmTIz?j0s5Ujxrl*nWR5*i?) zgbhgK=BK3Q6#Hp_G?xG|LlB72KqZP@fPDRo{M=OilGNf7{rr^teBG4PGB86wF(oBG zuUJ1VHKQ~>DX};;J{ibO%`4G|n5`clpP83g5+AQuP+7tOG{^=hUYe6?2Xaji$RPmS CJSyn` literal 0 HcmV?d00001 diff --git a/l10n_ru_attorney/models/base_consent.py b/l10n_ru_attorney/models/base_consent.py new file mode 100644 index 0000000..70df0bf --- /dev/null +++ b/l10n_ru_attorney/models/base_consent.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ +from datetime import datetime, timedelta + + +class BaseConsent(models.Model): + _name = 'base.consent' + _inherit = ['mail.thread', 'utm.mixin'] + _description = 'Consent' + _order = 'date_from desc' + + name = fields.Char(string=_('Номер')) + date_from = fields.Date(string=_('Дата выдачи'), default=lambda self: fields.Datetime.now()) + date_to = fields.Date(string=_('Действительна по'), default=lambda self: datetime.today() + timedelta(days=180)) + partner_id = fields.Many2one('res.partner', string=_('Контрагент'), required=1) + employee_id = fields.Many2one('hr.employee', string=_('Сотрудник'), required=1) + purchaseorder_id = fields.Many2one('purchase.order', _('Заказ на закупку'), domain="[('partner_id','=',partner_id)]", + required=1) + company_id = fields.Many2one('res.company', string=_('Компания'), + default=lambda self: self.env['res.company']._company_default_get('base.consent'), + required=1) + + @api.model + def create(self, val): + name = self.env['ir.sequence'].next_by_code('base.consent') + if name: + if 'name' in val: + if val['name'] == False: + val.update({ + 'name': name, + }) + + result = super(BaseConsent, self).create(val) + return result + + @api.onchange('purchaseorder_id') + def set_partner(self): + if self.purchaseorder_id: + self.partner_id = self.purchaseorder_id.partner_id + + @api.constrains('purchaseorder_id') + def fill_order(self): + p_orders = self.env['purchase.order'].sudo().browse(self.purchaseorder_id.id) + for order in p_orders: + order.consent_id = self.id diff --git a/l10n_ru_attorney/models/hr_employee.py b/l10n_ru_attorney/models/hr_employee.py new file mode 100644 index 0000000..bfb5a09 --- /dev/null +++ b/l10n_ru_attorney/models/hr_employee.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from odoo import fields, models, _ + + +class HrEmployee(models.Model): + _inherit = 'hr.employee' + + inn = fields.Char(string=_("ИНН")) + pass_kem = fields.Char(string=_("Кем выдан паспорт")) + pass_date = fields.Date(string=_('Дата выдачи паспорта')) + +class HrEmployeePublic(models.Model): + _inherit = 'hr.employee.public' + + inn = fields.Char(related='employee_id.inn', readonly = True) + pass_kem = fields.Char(related='employee_id.pass_kem', readonly = True) + pass_date = fields.Date(related='employee_id.pass_date', readonly = True) + diff --git a/l10n_ru_attorney/models/purchase_order.py b/l10n_ru_attorney/models/purchase_order.py new file mode 100644 index 0000000..aa178c6 --- /dev/null +++ b/l10n_ru_attorney/models/purchase_order.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from odoo import fields, models, _ + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + consent_id = fields.Many2one('base.consent', string=_('Доверенность')) diff --git a/l10n_ru_attorney/report/consent_report.xml b/l10n_ru_attorney/report/consent_report.xml new file mode 100644 index 0000000..80f5e7a --- /dev/null +++ b/l10n_ru_attorney/report/consent_report.xml @@ -0,0 +1,303 @@ + + + + + + + Доверенность + base.consent + (u'Доверенность - %s.pdf' % (object.name)) + qweb-pdf + l10n_ru_attorney.report_consent + + + + A4 + + A4 + 0 + 0 + Portrait + 15 + 15 + 7 + 7 + + 10 + 90 + + + + + diff --git a/l10n_ru_attorney/security/ir.model.access.csv b/l10n_ru_attorney/security/ir.model.access.csv new file mode 100644 index 0000000..ee8128f --- /dev/null +++ b/l10n_ru_attorney/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_base_consent,base.consent,model_base_consent,base.group_user,1,1,1,1 diff --git a/l10n_ru_attorney/views/base_consent_views.xml b/l10n_ru_attorney/views/base_consent_views.xml new file mode 100644 index 0000000..a2e8985 --- /dev/null +++ b/l10n_ru_attorney/views/base_consent_views.xml @@ -0,0 +1,66 @@ + + + + + Consents + base.consent + + + + + + + + + + + + + consent.form + base.consent + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ + + Доверенности + base.consent + list,form + + + + + + Consents + base.consent + CON + 5 + + + +
+
diff --git a/l10n_ru_attorney/views/hr_employee_views.xml b/l10n_ru_attorney/views/hr_employee_views.xml new file mode 100644 index 0000000..440c5d4 --- /dev/null +++ b/l10n_ru_attorney/views/hr_employee_views.xml @@ -0,0 +1,19 @@ + + + + + view_employee_form.inherit + hr.employee + + + + + + + + + + + + + diff --git a/l10n_ru_attorney/views/purchase_order_views.xml b/l10n_ru_attorney/views/purchase_order_views.xml new file mode 100644 index 0000000..4003990 --- /dev/null +++ b/l10n_ru_attorney/views/purchase_order_views.xml @@ -0,0 +1,16 @@ + + + + + purchase.order.form.inherit + purchase.order + + + + + + + + + diff --git a/l10n_ru_base/README.md b/l10n_ru_base/README.md new file mode 100644 index 0000000..d8b931c --- /dev/null +++ b/l10n_ru_base/README.md @@ -0,0 +1,16 @@ +# Российская локализация - Базовый +name: l10n_ru_base + +## Описание +Российская локализация: основные отчеты и печатные формы. Это базовый модуль для работы с модулями локализации. + +###Для включения модулей: +1. Меню Настройки - в боковом меню "Российская локализация"; +2. Выбирается нужный блок для подключения дополнительных возможностей по локализации. + +###Перечень модулей локализации: +1. Российская локализация - Акт сверки (l10n_ru_act_rev) +2. Российская локализация - Доверенность (l10n_ru_attorney) +3. Российская локализация - Договоры (l10n_ru_contract) +4. Российская локализация - Документы (l10n_ru_doc) +5. Российская локализация - УПД в xml-формате (l10n_ru_upd_xml) diff --git a/l10n_ru_base/__init__.py b/l10n_ru_base/__init__.py new file mode 100644 index 0000000..899bcc9 --- /dev/null +++ b/l10n_ru_base/__init__.py @@ -0,0 +1,2 @@ +from . import models + diff --git a/l10n_ru_base/__manifest__.py b/l10n_ru_base/__manifest__.py new file mode 100644 index 0000000..27e6462 --- /dev/null +++ b/l10n_ru_base/__manifest__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Российская локализация - Базовый>", + 'summary': """ + Российская локализация: основные отчеты и печатные формы. + """, + + 'description': """ + Российская локализация: основные отчеты и печатные формы. + + Для включения модулей: + 1. Меню Настройки - в боковом меню "Российская локализация" + 2. Выбирается нужный блок. + """, + + 'author': "MK.Lab", + 'website': "https://www.inf-centre.ru/", + + 'version': '18.0.1.0.0', + 'license': 'LGPL-3', + 'category': 'Uncategorized', + + 'depends': ["account", "portal", "website", 'contacts','base', 'mail', 'sale', 'purchase', 'hr','sale_management', 'sale_stock', 'uom','web'], + + 'data': [ + 'views/res_config_settings_views.xml', + ], +} diff --git a/l10n_ru_base/i18n/ru_RU.po b/l10n_ru_base/i18n/ru_RU.po new file mode 100644 index 0000000..1079acd --- /dev/null +++ b/l10n_ru_base/i18n/ru_RU.po @@ -0,0 +1,117 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_ru_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-12-17 06:36+0000\n" +"PO-Revision-Date: 2024-12-17 06:36+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_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_l10n_ru_act_rev +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Act revise" +msgstr "Акт сверки" + +#. module: l10n_ru_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_act_revise +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +#, python-format +msgid "Act revise" +msgstr "Акт сверки" + +#. module: l10n_ru_base +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__company_status_rf +msgid "Company Status Rf" +msgstr "Статус компании" + +#. module: l10n_ru_base +#: model:ir.model,name:l10n_ru_base.model_res_config_settings +msgid "Config Settings" +msgstr "Параметры конфигурации" + +#. module: l10n_ru_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_fehu_base_consent +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +#, python-format +msgid "Consent" +msgstr "Доверенность" + +#. module: l10n_ru_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_contract +#, python-format +msgid "Contract" +msgstr "Договор" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Contracts" +msgstr "Договоры" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Powers of attorney" +msgstr "Доверенность на получение ТМЦ" + +#. module: l10n_ru_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_l10n_ru_doc +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +#, python-format +msgid "Print forms" +msgstr "Печатные формы" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Report act revise" +msgstr "Отчет Акт сверки" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Report contract" +msgstr "Договоры" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Report report_xml" +msgstr "УПД в формате xml для ЭДО" + +#. module: l10n_ru_base +#. odoo-python +#: code:addons/l10n_ru_base/models/res_config_settings.py:0 +#: model:ir.model.fields,field_description:l10n_ru_base.field_res_config_settings__module_report_xml +#, python-format +msgid "Report_xml" +msgstr "Универсальный передаточный документ (УПД) в формате xml для ЭДО" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "Russian Localization" +msgstr "Российская локализация" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "UPD xml" +msgstr "УПД в формате xml для ЭДО" + +#. module: l10n_ru_base +#: model_terms:ir.ui.view,arch_db:l10n_ru_base.res_config_settings_view_form +msgid "print_forms" +msgstr "Печатные формы документов" diff --git a/l10n_ru_base/models/__init__.py b/l10n_ru_base/models/__init__.py new file mode 100644 index 0000000..4a30401 --- /dev/null +++ b/l10n_ru_base/models/__init__.py @@ -0,0 +1,4 @@ +from . import res_config_settings + + + diff --git a/l10n_ru_base/models/res_config_settings.py b/l10n_ru_base/models/res_config_settings.py new file mode 100644 index 0000000..96b432b --- /dev/null +++ b/l10n_ru_base/models/res_config_settings.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +import logging + +_FIELDS_MODUL = [ + 'module_l10n_ru_act_rev', + 'module_l10n_ru_contract', + 'module_l10n_ru_upd_xml', + 'module_l10n_ru_doc', + 'module_l10n_ru_attorney' +] + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + module_l10n_ru_act_rev = fields.Boolean(_("Act revise")) + module_l10n_ru_contract = fields.Boolean(_("Contract")) + module_l10n_ru_upd_xml = fields.Boolean(_("Report_xml")) + module_l10n_ru_doc = fields.Boolean(_("Print forms")) + module_l10n_ru_attorney = fields.Boolean(_("Consent")) + + @api.model + def write(self, values): + if any(field in values for field in _FIELDS_MODUL): + company = self.env.company + if company.country_id.code != 'RU': + raise UserError("Признак Российской компании не обнаружен!") + + if _FIELDS_MODUL: + missing_modules = set() + for field in _FIELDS_MODUL: + mapped_values = self.mapped(field) + if mapped_values and mapped_values[0]: + module_name = field[7:] + module_installed = self.env['ir.module.module'].search([('name', '=', module_name)], limit=1) + if not module_installed: + missing_modules.add(module_name) + if missing_modules: + message = "Обратитесь в тех.поддержку для получения лицензии для следующих модулей:\n" + \ + "\n".join(missing_modules) + raise UserError(message) + return super(ResConfigSettings, self).write(values) diff --git a/l10n_ru_base/static/description/icon.png b/l10n_ru_base/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea24f8c0237018667c1537a5581be89262b0c34 GIT binary patch literal 4308 zcmeAS@N?(olHy`uVBq!ia0y~yV6J3fU<%}51B(2psIvl6jKx9jP7LeL$-D$|SkfJR z9T^xl_H+M9WCij$3p^r=85sBugD~Uq{1qt-3<8;+E{-7;ac^%L=FJTiaSJqexx%Ah zs-e8#q|FS4P^)JX*;2XYv9uoS^AMb?J@?ML+_k#8f48aL|982v>gW3B&!1mE&tIQ^ zdtd#pd)sRNf7zS+``^pz+u#0P{=V()@8$1vZ-4i{e|y{e`TMr#-nXx%r^4@hdu==? zsdxq{EBgbfNlucLAWG!aiOE1}Nr2ltAf?i3^a(_1PMN3s-P0;1h|AMI0-7Jj6e#R zVnAdQxU?Eo&M_J?qlsWN5j2pP2paOI?>TR8zxVH_#c}`NU;A=z$e{1}wLd@ndm68k W{QmBoKZ`&k6AYfNelF{r5}E)mk#imZ literal 0 HcmV?d00001 diff --git a/l10n_ru_base/views/res_config_settings_views.xml b/l10n_ru_base/views/res_config_settings_views.xml new file mode 100644 index 0000000..c60513a --- /dev/null +++ b/l10n_ru_base/views/res_config_settings_views.xml @@ -0,0 +1,42 @@ + + + + + res.config.settings.view.form.inherit.russian.localization + res.config.settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_ru_contract/README.md b/l10n_ru_contract/README.md new file mode 100644 index 0000000..6b6074f --- /dev/null +++ b/l10n_ru_contract/README.md @@ -0,0 +1,30 @@ +# Российская локализация - Договоры +name: l10n_ru_contract + + +## Описание +Создание договоров с клиентами и поставщиками в системе. +Возможность разделения договоров на виды, отслеживание статуса договора. Вы также можете распечатать договор из системы. + +### Создание вида договора клиента(поставщика): +1. Меню Продажи (Покупки) - Договоры - Виды договора - кнопка "Создать"; +2. На форме указываем: + + 2.1. Журнал и счета дебетовой и кредиторской задолженности; + + 2.2. Присваиваем новое название. + +### Создание договора клиента (поставщика): +1. Меню Продажи (Покупки) - Договоры - кнопка "Создать"; +2. На форме указываем основные и дополнительные условия договора: + + 2.1. Контрагент - клиент (поставщик); + + 2.2. Тип контрагента; + + 2.3. Компанию, от лица которой будет подписан договор; + + 2.4. Вид договора. + +### Для печати: +1. Открываем созданную запись договора - Действие - "Договор". \ No newline at end of file diff --git a/l10n_ru_contract/__init__.py b/l10n_ru_contract/__init__.py new file mode 100644 index 0000000..7db6694 --- /dev/null +++ b/l10n_ru_contract/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import models +from . import report diff --git a/l10n_ru_contract/__manifest__.py b/l10n_ru_contract/__manifest__.py new file mode 100644 index 0000000..a20d105 --- /dev/null +++ b/l10n_ru_contract/__manifest__.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'Российская локализация - Договоры', + 'summary': """ + Создание договоров, их видов и печать + """, + + 'description': """ + Создание договоров с клиентами и поставщиками. Возможность разделения на виды договоров, отслеживание статуса договора и его печатью + Создание вида договора клиента(поставщика): + 1. Меню Продажи (Покупки) - Договоры - Виды договора - кнопка "Создать"; + 2. На форме указываем: + 2.1. Журнал и счета дебетовой и кредиторской задолженности; + 2.2. Присваиваем новое название. + + Создание договора клиента (поставщика): + 1. Меню Продажи (Покупки) - Договоры - кнопка "Создать"; + 2. На форме указываем основные и дополнительные условия договора: + 2.1. Контрагент - клиент (поставщик); + 2.2. Тип контрагента; + 2.3. Компанию, от лица которой будет подписан договор; + 2.4. Вид договора. + + Для печати: + 1. Открываем созданную запись договора - Действие - "Договор". + """, + + 'version': '18.0.1.0.0', + 'sequence': 0, + 'author': 'MK.Lab', + 'website': 'https://www.inf-centre.ru/', + 'external_dependencies': { + 'python': ['pymorphy2'], + }, + 'depends': [ + 'base', + 'mail', + 'account', 'sale', 'sale_management', 'purchase', 'l10n_ru_base' + ], + 'data': [ + 'data/data.xml', + 'views/contract_customer_view.xml', + 'security/ir.model.access.csv', + 'report/report_contract.xml', + 'report/report_contract_order.xml', + 'report/report_contract_order1.xml', + 'report/report_contract_invoice.xml', + + ], + 'installable': True, + 'auto_install': False, +} diff --git a/l10n_ru_contract/data/data.xml b/l10n_ru_contract/data/data.xml new file mode 100644 index 0000000..3b1bf11 --- /dev/null +++ b/l10n_ru_contract/data/data.xml @@ -0,0 +1,21 @@ + + + + + Договор последовательность клиент + partner.contract.customer.sequence + + + + 5 + + + Договор последовательность поставщик + partner.contract.supplier.sequence + + + + 5 + + + diff --git a/l10n_ru_contract/models/__init__.py b/l10n_ru_contract/models/__init__.py new file mode 100644 index 0000000..c1f874e --- /dev/null +++ b/l10n_ru_contract/models/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from . import account_move +from . import contract_customer +from . import crutch_fields_header +from . import dop_field +from . import purchase_order +from . import sale_make_invoice_advance +from . import sale_order diff --git a/l10n_ru_contract/models/__pycache__/__init__.cpython-310.pyc b/l10n_ru_contract/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3aa46226abcb0dd1356067f2cbeaf87c9be113ab GIT binary patch literal 269 zcmYk0v1$V`42Esrg{FlJfsUEF-H>?fQc9#p`q*Knq*4QuN! zPDO2#mkNgzq)MQsn9!S$mv-2rRR*GT27{*5T;m8&);OJSRG5*4NGf<}XPJeX zMuw(fR&YUhV+SHTK8l`Zi@iHh`Vm8dtsHg&HKI5j0a9xmqB!3sJZj^j n0I-8i0C(f_@p4Vc$(j3bO$*95Q4qds&iM!1y#G(boO*r%OEYFV literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/__init__.cpython-35.pyc b/l10n_ru_contract/models/__pycache__/__init__.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba092d028ebaea0994aa199a99b5d080580139ab GIT binary patch literal 174 zcmWgR<>fll;1O%Zz`*brh~a<<$Z`PUVi6#b0z`}qISdTBj0{nX42&sE48fYrFBySS znvAyulk@XRiV~Ac;*(2@OY(D5i~Ka1ZZQ;rj9AG~!~&$i#4p`stC+N$)MTLIn8cKn s{Ji2AnAVuw{FKz3;+XjO%)HE!_;|g7%3B;ZK*7?SR6CGC#X!se02~=A>Hq)$ literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/__init__.cpython-36.pyc b/l10n_ru_contract/models/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fcf5c066557467bc3bfaae5fbba573609861350 GIT binary patch literal 235 zcmX|)L2AP=5Jg9pDNVr(Z%VJ=MXdyHi^&PHDRf~7!gy3FB6*DD1agC1rC0K{t6m|i zj0o+(e|-Lj`Atzg?Vm6D0|0(l|Ch1bvf>K^0fhrEI^nY}^RklyFnfne{tB)uxs(Hq zbLfXz563u@H(@F5cp^I(9eZaeAV({tNq<`7a98CEgftRlLeBVx@Q{4MwN+pIMfrmw rBzi@2x|>Z?uT_soV^n{e$`cwFmDYB&v)1)=ULM~#JUY{+jmUx}9;mP6wNvMA zohr9PpijTV55IP+)s5hS^9dc#&$3*qV)4u!?-(FJI^ks}ebrUI?rPt3jTBJ5injie zY-yXkHZ-Qto21PY6L}1IZO0>7gF5yODFC0Yfe!lJqJw;E!j#PLzePP@&xV(Fkwqx+ zp)P0&7K{%Ou8J=B*{Oj86zmD&tO$ti0gr#;ZTq17+yl@U)#WAS3D8BQwH1DV%`JWb4z5e` literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/__init__.cpython-38.pyc b/l10n_ru_contract/models/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eb08c5fb28f628f0040896d443012c3aff102d9 GIT binary patch literal 247 zcmYjKv5EpQ5KT5Bo?x+^zp#adE9~SruDJ3Vaf@xjl8G2hb|hIB_LJ_Hwzaah69gxM z;Dh((y&0Idoz13KUMm9mX(m0BMAVX~&>$(gUzb0x9|T!=yH literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/__init__.cpython-39.pyc b/l10n_ru_contract/models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d19ed0050947d67a93f401c310f6045e86666d2 GIT binary patch literal 226 zcmYjKy9xp^5KJzIsBpz~{=yZS9}uyzwGk|?3E?(EAde%-iQ*Ue6Mo3GR@Qb_ZVJJH zncbO%9a&X#g19|)aK!n{<{t%`Eix`pfB-eb(w5qyEi7vpB~Tnl!(J564IAsuyA))X zL^s6btqNnU-P!9-i71Wo0Wg|@@5M`bSVM6 fi~Lu?tp{Zy7eYIogjn_0ak|EEFlv)uzLDe$`Mf$4 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/contract_customer.cpython-310.pyc b/l10n_ru_contract/models/__pycache__/contract_customer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df2d23e5a8e82bb5d5e1dbf05d47323e4c19e998 GIT binary patch literal 12914 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 SYwzVS_5qt@D)PMDKL0Pf8fk+7 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/contract_customer.cpython-36.pyc b/l10n_ru_contract/models/__pycache__/contract_customer.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bd803ee7403ca6f1fb047ba343ba370e783deba GIT binary patch literal 8580 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/contract_customer.cpython-38.pyc b/l10n_ru_contract/models/__pycache__/contract_customer.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3ecf8010ad0d0e4b55188f6c177a3c35127e461 GIT binary patch literal 11924 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/contract_customer.cpython-39.pyc b/l10n_ru_contract/models/__pycache__/contract_customer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..682bf56e572d3f6d6a79ff5110d65f37c900e80b GIT binary patch literal 11865 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/dop_field.cpython-311.pyc b/l10n_ru_contract/models/__pycache__/dop_field.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d59e3463c8065e11258e6ba10a30ea6aafd60179 GIT binary patch literal 20499 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 Xbsn^mh@|*aSkzoZRV)v0A5Q%boTaLN literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/dop_field.cpython-37.pyc b/l10n_ru_contract/models/__pycache__/dop_field.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34136b551019cafdc5347e112c2f0a3d48ca33b1 GIT binary patch literal 12498 zcmb_iTW}lKdEOg<1$YrfQPd@}49lWr*cK_#wqmQYYg-q`NyIpoF1jJdAAaV2A zr7U8=R*@VhZQ>|#Z>c9v$mwO;hjtXlo>3jge&|adI#Y0_Pdn46&UC8hK6FM;{l0S+ zO9BGvwo`)p@3~+8^WV=tH#C$n@b}M`uXv-=hVgIAbpFPWcm|Ijn1&$?VOET)nK!Fe z-m2PpyXxc}ljT+=QBC9%Ds5Mi`6SBhN-Cei+o`zKbUux`L_Q;uA|+gr78x-h2E~vV z7Q4jA&ocP|v0IFaJz`Ak72{%`*e?!upKjqDnX}l&8(q8~sn2;w z(QZ6{_<2K|6w_}SV%oD8C$8K12T<~;cnl?vMJ2~j^0+vKl2cL1gDCmDcmgF)L?t<4 zUovt}-sV~4oX{>d%3*S@>{WyxCaZPfRs1mHT`75upj@x{IWu%cG4O(N)th0au~Mp6 z8^s`(&e_Yu7^M9{`@@azY~0wm*1oxMqo-)&2OHn*Q-rRhj*aiMKZ&|+W>uH&ESit7 z`8CvWrth_Xqvq-@R9*WOVt_;4OTBg1U^_KX1AkTnOfs%Eg)L!QJ!|b>r3T)<3PX}t z+8?)XwSSG@t@bC_y52l{#T9W?JYfGS447rV%`>|dH{3e-k?k6FPxM)1aW$CoAV$N% z0WEzeBVv21yQkT{e>6cCE^dJ~u40FM&=gnQji#=uoE;j{#j+H@4w%O3Kfnq6W;25s zwq`y-!z3Gi(0(5^aq`2>KqpVV??p zW<3@AG0&Dm>oc4>kDgwN`J=<=sp1keE_*6C(l077QNcNEIA=yK+hhz`Q9-0T$TpjwrnXAcfX|_|W zstRr@G;BFz-R`E=a1nN}Ye;{suwu+ag`B^Gm8eK}Efi|Ss#hq4nL+`U!g7V_!9wBn_Sn7LmahGs!LfYmP&tP$oo;Jz@4*G3-ziuC6?;KUzw_ldi}WYE~~^VCm)}xt`voU z6*5(-*8*8A1ykBWnG*FzK^ZNRjTK4#@l8BFMSyEMrYh+|4r`ualNSNHk+TTo2wOOB zTlu8tAeV@8DU}1#RGkYnrfFraTloyq10oHS4vGv=IuNGL(kQB}GzW-HWg#Im9HF&P z7L(;#?Ly89Q_`!zoD!icy&|?&>29^uXf$_i=~Z89)SGFJx$Jw=Up|24w|@#rd?O3i zxkcU3{z%yySKBx9iAzDT+L*}=$$QXF9wxY#AWOg#k@o?FHWm}wm@9NRLFit@(x>Y+ zFLX-_Wp57a4U^B6Yel&dCVY;$d1N|ulw(Z*RPgv@FyP%9Hu)PgRZSQEIrlSc`W!$v z{yW5}$kYZ-fp?TSND=2a52Vs6l|(8dQoy(yrXnKN7>`h<)!xtBf7o7Yzt_pU+x|uS z=UN5-wEbTDy}bRU7hlvY`wIyB@3cQ9sc&4H$qnp`x4cuImo@niwjduQ$N}WtM$z{h zbs6-<(G;3o#?!%(nTdXqHT`k)PpH|7BUt&4NW5w09r`(M8uhI;QJsoAWqT$L23{l0lXljhQt%}g^(JiKZKsU=o8^RLca*_-Smy{ z9;Ii5_a1sjc#qLT!h0{hB)rGrDNW+NPfUpuc<1 z0M3`q1JTieX>`?Orz*4?wRt7|OH}Lpqh_a0KZ{3^Qp=XZ!fe^&#;RR>cn79GMk> zC~;JYBb*lUEh{hrbIod*>*jTHj`fLF0*gz`GzZ@(i(uiYV-tSk%CS3UwmG!mmFE|N zsHFMunR0bLJK^)+m!+qU!6Pc3E?0~5-qeKuTeC&qJN4Kj6aKO6)YC8>Z9kBb_D7fs z>V?3&66BJh<9n4ka9(vjbb^(J7beuCVNy?(cZ0h0f@RRx{ph)c%T6JCjr*n6Hz3_I zmJ>nC)W1=)d1yNXPh!TB#jf}x8&VW1{AH17K~@IFnh6}5>(;8(vgDzbC9DI+CAiwa zjx*DAUK0-=Rp+3sVJozx7pCUQHBqcoa<+UN1BDJXKt5Aj#-SGJI`-@%OsJ}N(AK8{ z<4y)m2Xdo%c-ytBF7fKQ3sQhu{Ub%AvJO9bJ7TrS{@=jaqmt|)Yog~N>OqsZngg%kPPNcW;4g}xm6r>OJU*8mz0 zna%9BNQgT8zo9`sjY*YhGa+IWOg49ScAuU2!s&^Nrzb7}4SEaDphL8O`7G0v;%eiP zXYrYPcB3s!zlYX78JL?MGjaC!eb%<8yY@{2R>w~gBH@yqak%CTb*m=6O6Znrg*WO_ z_|ZXxNz}}Gvga)1^BCmM@%V~Ac3Mnlz<4o~NHHfpgG|dJDT|V64$_O9)_mY)S*-bUby>~&%hjx2bGBT|%H`RL=Vya@ zmcrz=z;y7ORPf~^(C()&0{*`J5nRr@inIxfI^7D!LNh}-c48Vw@52@xj&N4cbI>#h z!i20Z*F?CtQ&(E3*L|^43dG8K{z};Uc@$C6WrlE9IbnpjA5cQ-3)0l@EAlij_-C6~zA?}HEEf8Sk zt;4=B**?KGJOtD^I2@<~;Vjwyix7ZUkxncbvJxa&C#)q)R#^5VRYo)>@}@}Y@kDAZ z)xyX)M0ZB}9kkPNM5I!f7T4RqZ2!9BX?Ly zjk;eB%9lO)WfX_WVx!^VTr)U1%C9oi>z7zDR+#sK!d#_Z#94aPA|$&fL%ZVDLT9mF zuH};Y$dkn?2qVbvYI?F>0HGF^)QLk=2Yv`MHR_trl;d;{0mv_6!oS56sk01KnYkb0 zz_qkUK+0?$+m;$SG^y!Gxo|OMkV5z<$~cY0CS{N+0_(aZ_Y0hp%Gt=BYME=!IwH-8 z-P$+z=9cM!Ggg#6L8bI}Q9l}i6FV|oa*GgVE1YYsx;YU%Q`(f&wSAtCd@l*5* z!E&SGMY=JcoV#4CEPMHcU!Je|y%@QKaX-crsYM!yj(N~*9^V!R{f=vEM(vPe1ol!!e!(>O3v6Ls zH?Ntm8a3-1#3y)3@emX&@FieeB`Ll{Vl~w=S6#(hsg_I8w(h)Ut)@21f+RSmw=5-6 zeahUp%vJOJV+&S4){^F0)cIs)fL(5L6Ew3g1YXt8R$*IaXT9vB$GwVI^=d)Z_g-K2 zaAbK>DX2AD6m;7R+urPW|DBlgEzQnxiw=`^1!tAt-xKB3VS}E+PulNe z0EQv9RH(qEj2YBx6%iU#v0xO2aMH0_G}HR z9&BOwAFGy*{CAATd4?3T4z(PpIXzFJHFN-?K)Cxmb8(D}8iOgt*kDpzqrGXgT&Pf2 z3_!KH>*kufjy-dyxxu>`Pq9_`KOlM)FEwqL81e<+Q&O3!pjC-Nlz)8F+@jP|PBEkt z%p(}_4hFYo)L1!FzKnX@H&vtvbNN+_6}n&e+RV9^&Y!y!IxnA}xg;;L(D};D`AfVes|2tjzs4fOMP#{= z8`i{MMv+`3pm8QWf;obDf&~Ehd$dSH2f>^mbipRdM9n9dKM9}EgJvKP_3T#`QTDHR zd^&=LVgOC#WCb!r=jWKCD!m^pFoM*eIj-1Zcqet*ji4?~8k@IgFmKE94=Gp6pu-49 z3*>U$9LLFB13AklRGlfGK%KI{I(3mQRj1l~Kna#uK6k8>Y+Yt)Q9P2R6r1pyhx@nd z)WfR(HkPE_j>!E?KzuBFVUnj(+8T;E%9fO3cksl%#|W^qgOSl~J;hidMq;eIg$!sH zn20nh^dy)b_9g@XY)j})Wp|R{g*C42i*pnPNGIU3o)bv~Elx+ZsilN$Mrn7+RB5)f zz}i97E6p~-R-uj*v^aDu9ravhMhCiMZqv-S2P;&F*Jcc(bhmk@09%F%Kz@s$01yu9 z4a4A@4;FAIJPX%gi&S?n7iGCvgN>JpQoTeWX?rA4NaWJ>(TqL%Yet0_^-Ao)B*?Kj61L1HG3 z$GLuDy-v|07@Cu6>(Xx<`BvP*|J( z0%b4MI2`vyLyosBD#S&tlFda6fhJv|)xWuD%hOSb_9@LpM}9dfai~&-2`>|^l~!w7 zk7N-9w43FIRx?hi9IPmD<#|Dvg4n`)T5Y`(QA=0Foy2rSnT;rompsPqAxYlYJi;5%}T0^+PoWotnyoDQ*>L4lyKuz`FZmaFjJ85$+0|Y477197Gk*;4q#(Cz0EhGkQnsIueqoI+Dkb zV8Cl#kti%rOUJS)F(?Yx;HWJ?HY_?Smr(M7%E8w1A#`AxGZ39_tW@i=v9K~74qas8 z*;)~|P&C?sU>}j)DCQYDv{=GKP!8bAYJCv8bIY|7!@FTZjS`x3z33TL!Gx$;p@A?% z@CXsaV2HL~XudZe-WDNu_m5FRbi`CTjm*vz3hJCx)TvwD<{IzeDgdUBKwKB*n-zf*x8K@7|2QW-T`!B|@|gA-yEc=G6ZX9i0(k zlyH<7C0qxESVSpcS@{-FWRXf1K_PcBF}xeJaKNr_1qr^dn`^jaLJTu;WxAC(XMFRa z)g-7Z)dGtO7qpgYrPgr$q-ZUToVAu|p}lFmKJ#_5@PHP2k(1uV!u?UL@kYG^v!7Vj zstg!1CdF_X+_}* z{%7D`x~^wE%@tLD zLtj$g+W1lXHz+4B<5vGiY7iC7zlmvnwQ)WA{A2|6xUj}2N%#WkM*ElX{0L^@Gk~~= zC{y3ibhY8eZC?%YKfvDBj^rqmPE zgf!m{5^Bv@8$+69lltA!m-1Z8hS_os@(W}VnJu>b7SawNN(G2w(b=a>KwDlxE&<3I z_DIAv?;w|y@2DEwH7_Q0jYvRhY6CE-b+9IcwW-cmHQ8ml0qvjQi;j1*nkYU(Wwx0( zGb?eG?1rxTbfzqPB|5{j%JQaFTag)jPg8*RguAV%>1??qk6_Td>=|XrgboMjJs+3n z!-`jUG>6ffb_}%=eYin01FJG)K)glI4wrVFkw7*lxe5%ZLC(AY>Ao9T-qrE{LhfMS z&n+nTbe7N3aMd0SM|+3 zgzswbDU+mAq(8fHn4&MHZ%t1#MWq&I*l;qa*DJpIWFViu@Y1tqUw+{$2t75}s!mWN zC=tv8AgszrFKiQhYOvzNLR0q-gRp>oSZ4SHYpx#JFTOfW@TlV7a8Td(=&K5K>mz@M z<9(jv4U{VQh9#ut^~N!7?@Qb0jZiWRV`le%S{-F7oYvcr5Ez&!wkQC&;y4~ zrCyuQr_XYvm-&4|YPnV};d}Bhagkq@t8cQ@he7Jg7lo*P*hhR%e_Qr6X~(C%u5O1& xiMBJ?`Q%~q?K+$3?Nj|)xi+ZWQsFaxx@09m@%*V$_Cn!bj~d3mFthP*6q%EFg3vS!VFzFLJN{MnJn^0-HcL-yzAtn~A>}V%< z1i795&fhkr=kJ;^v%CF0fP4LYfOq-3vitqJvj@=no@~03_V3j#{DU(V+xR2%_aSwc ze?Qvo${zTnbLnwJ%97D;mxa2{U{DL@+lH+kn zM%d?#%oA&*N5+Zle61L{Gey57g2*jbg(Njz1+IKdiAH>MXSHH`j+%Km0c%KtiI9uG;X+_RgL;| zqhU6>j1rFc>#a}Jn7xIn1N&pt{djFy!p++{->HEbs9z7Xi!;B0#bJRx^KV|IIuGd1 zohsFJP;CZsUAw*s8eYN(~0A;X)y5e4< z?#3n+8f`rlT-yf3Z8DrfTu(19VKqivPZgJ-ann=5nbr}vS!D-tJ(c7l%@7;58mkg8 z!iK_*D!K$t`?yZ#XvKtIN1?(}d-bbtZ>V7VHeELqD}-+#`GzVrL%eRR8eBoWli8t( z&E>37E3J`;Yt$2Kl#R7*1l++I*?NtmtSOGAK+3xaD7*4*f&&Ei5Tpt21yF*a=W6o@ zXs!xwssc@GRd8LQVFQhIyX#u#$JoKHp)KnQsU3lc3%TMpR^lSH?F|^&SlprF>f5?l z?&Y#OJ1Zd9^+!QCi6>wa-^iN6$Xde8+P<@#5Y~zbcY&tPi3Xm}%dq0h+%x&gLStC^ z!FWxVj8CJaPPDe(!%i-ZW9v#COl6Xhm&;Z1Wj~jTQn?%~W4*-mKrZ)MJzt7zyj-y| z=gVR!xtz#3HJ6vsAVkAKQH&QWm9rTuN=m;37eYjy^z+zWsk_xet=8DKp;vXGR&Dfg%zEIO_1snE^wWUk}(V4Qn-$hr7hrhTEEj;Zhg?s zyx00}>pR*4zT5hs^+DGD!t>8h!H(P!Jz1wZD=YFztWt8R@(F?t-)=y_FQMWBo`714 z%$HI>$?~nY|BtBMxP3UTj!3*|W*xfjZyMPI-FLiQy6|`>>Bi&j(Ur%$Pdr9f9z9ZU zapBG*)h~|GrAKN2PA(jKqz1)ty7x#8(Zxs4ZFKYT9;U00_jbDbc#qK8$9o4Ie!NHN z^y9sgjz8YJ;QWu{y<1F(BY5x8?ss;t*hL3A+Vg^6tI7~^u0=Ihs0Sg0TQ>H_^npz1 zs_}MJWY;RQO34>!z1x2@;xyl<@C45QG;KK~%%;7|Sh6dQu$JtmBhvy9C5|d_gwsU6 zX@y2;E?Z4=#k^w9us+dDV1bFL#=z@E5zc+?&{$Brc<7dyZVb-(#o4(qE@?b`qFA0y zj|Kb>WZ`p%;OOU{ESB@L{=``Di_`hQKla!oW5J>H#8VkNvV%}cx*Ab3tmZ=hVwiCw zC-6%%5U%oUIARKs~i zJbb^Rh;}%w$dZ1PoGDgBzEsNC@+=059IE?ls!|7e^E?;z>?TU6s&ApKk_+x_lscsVH$a zUkd#C4s<;@CJv^@o=K0roNoO7p;v)cc) zL}ZCD+b`=mP@rD zg$K-0)B4P{8u$LZjZNORGqS28GL!qXmm#|YNmbJ zvpV@Q2KgQrrli5V!-Coab}fjSs3SKgk!c#s&?)4x6>|w3*EDr*4 z2p@w>e*)Y7!`8<*!_j?2V!cRvsGTDC0F4xN*O5sOIDnfs6yq(Y=b*(8qlB#1DVsJ#vN0;A@z z*|_Hp48h%>Es*~0KZ*#os^W*=M1triKbXcW)IU)#%q!Ls&{We$h-*nktyK@Ak9>uI8_amoP+<<3&DE+wF)Uty zSB~Py&DUx^=#&B_sCkMolV4}WXl~XIb2FuC9<=exdFW+dMs~@sM9zG*Sjo7Wgl@hJ zLWkLH4PRDsV7%Odq98187)0T9eM9b;Xi<1Te31Hgd}*1^#QL;75ay0Dl%JrezMIkh?|4{~9>R`O%}mUU+? z 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 Zqan)$-}9$Rk@FA_L)sqMHj*0g{uk*8uYLdk literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/__pycache__/dop_field.cpython-39.pyc b/l10n_ru_contract/models/__pycache__/dop_field.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9ce9224884cbb02c53769c06c498a14d3031ada GIT binary patch literal 12023 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/models/account_move.py b/l10n_ru_contract/models/account_move.py new file mode 100644 index 0000000..06cbf32 --- /dev/null +++ b/l10n_ru_contract/models/account_move.py @@ -0,0 +1,50 @@ +from odoo import api, fields, models, exceptions, _ + + +class AccountMove(models.Model): + _inherit = 'account.move' + + mt_contract_id = fields.Many2one('partner.contract.customer', string=_('Номер договора')) + sf_number = fields.Char(string=_('Номер с/ф')) + osnovanie = fields.Char(string=_('Основание')) + sec_partner_id = fields.Many2one('res.partner', string=_('Контрагент'), store=True, compute='_compute_get_pid') + stamp = fields.Boolean(string=_('Печать и подпись'), related='mt_contract_id.stamp') + + @api.depends('partner_id') + def _compute_get_pid(self): + for s in self: + s.sec_partner_id = s.partner_id.parent_id if s.partner_id.parent_id else s.partner_id + + @api.onchange('mt_contract_id') + def set_ons(self): + if self.mt_contract_id: + self.osnovanie = 'Договор № ' + self.mt_contract_id.name + ' от ' + fields.Datetime.from_string( + self.mt_contract_id.date_start).strftime("%d.%m.%Y") + + @api.constrains('state') + def invoice_fields_check(self): + for s in self: + if s.state == 'posted': + if s.mt_contract_id: + errors_list = [] + journal_in_contract = s.mt_contract_id.profile_id.journal_id + payment_term_in_contract = s.mt_contract_id.profile_id.payment_term_id + receivable_in_contract = s.mt_contract_id.profile_id.receivable_account_id + + if journal_in_contract != s.journal_id: + errors_list.append(f'Отличается Журнал - [{s.journal_id.name}] ' + f'и указанный в договоре №{s.mt_contract_id.name} ' + f'Журнал - [{journal_in_contract.name}]\n\n') + + if payment_term_in_contract != s.invoice_payment_term_id: + errors_list.append(f'Отличается поле "Условие оплаты" в инвойсе ' + f'[Условие оплаты - {s.invoice_payment_term_id.name}] ' + f'и указанный в договоре №{s.mt_contract_id.name} ' + f'[Условие оплаты - {payment_term_in_contract.name}]\n\n') + + if receivable_in_contract not in s.line_ids.account_id: + errors_list.append(f'Отличается поле "Счет дебиторской задолженности" в инвойсе ' + f'и указанный в договоре №{s.mt_contract_id.name}') + + if errors_list: + raise exceptions.ValidationError(''.join(errors_list)) \ No newline at end of file diff --git a/l10n_ru_contract/models/contract_customer.py b/l10n_ru_contract/models/contract_customer.py new file mode 100644 index 0000000..b1423e3 --- /dev/null +++ b/l10n_ru_contract/models/contract_customer.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, exceptions, tools, _ +import pymorphy2 +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +from .crutch_fields_header import IP_CONTACT_HEADER, ENTITY_CONTRACT_HEADER, INDIVIDUAL_CONTRACT_HEADER + + +class PartnerContractCustomer(models.Model): + _name = 'partner.contract.customer' + _inherit = ['mail.thread', 'mail.activity.mixin', 'mail.render.mixin'] + + def get_dateend(self): + if self.date_start: + six_months = fields.Datetime.from_string(self.date_start) + relativedelta(months=+11) + else: + six_months = datetime.today() + relativedelta(months=+11) + return fields.Datetime.to_string(six_months) + + name = fields.Char(string=_('Номер')) + date_start = fields.Date(string=_('Дата договора'), required=True, default=fields.Datetime.now()) + partner_id = fields.Many2one('res.partner', string=_('Контрагент'), required=True) + sec_partner_id = fields.Many2one('res.partner', string=_('Контрагент как в заказе')) + company_id = fields.Many2one('res.company', string=_('Компания'), required=True) + name_print = fields.Char(string=_('Имя для печати'), compute='_get_name_print') + name_print1 = fields.Char(string=_('Имя для печати, И.П.'), compute='_get_name_printip') + date_end = fields.Date(string=_('Дата окончания'), required=True, default=get_dateend) + name_dirprint = fields.Char(string=_('Имя нашего директора для печати')) + name_dirprint1 = fields.Char(string=_('Имя нашего директора для печати И.П.')) + lines = fields.One2many('contract.line', 'contract_id', string=_('Договорные цены')) + type = fields.Selection( + [('customer', 'С покупателем'), + ('supplier', 'С поставщиком'), + ('other', 'Прочие расчеты'), + + ], + string=_('Тип договора'), default='customer', required=True) + saleorder_id = fields.Many2one('sale.order', string=_('Заказ/Сделка')) + stamp = fields.Boolean(string=_('Печать и подпись')) + signed = fields.Boolean(string=_('Договор подписан')) + state = fields.Selection( + [('draft', 'Черновик'), + ('progress', 'На согласовании'), + ('signed', 'Подписан, действует'), + ('closed', 'Истёк'), + ], + string=_('Статус'), default='draft', group_expand='_expand_states', index=True + ) + is_template = fields.Boolean(_('Это шаблон')) + copy_from = fields.Many2one('partner.contract.customer', string=_('Копировать из этого шаблона')) + profile_id = fields.Many2one('contract.profile', string=_('Вид договора'), required=True) + credit_limit = fields.Float(string=_('Лимит кредита')) + guid_1s = fields.Char(_('Код договора из 1С')) + buh_code = fields.Char(_('Код договора из бухгалтерии')) + payment_term_id = fields.Many2one('account.payment.term', string=_('Условие оплаты')) + manager_id = fields.Many2one('res.users', string=_('Менеджер по продажам')) + accountant_id = fields.Many2one('res.users', string=_('Бухгалтер по взаиморасчетам')) + time_to_delivery_from = fields.Datetime(_('Время доставки от')) + time_to_delivery_to = fields.Datetime(_('Время доставки до')) + day_of_delivery = fields.Float(_('Дни доставки')) + day_of_otgruzki = fields.Float(_('Дни отгрузки')) + + channel_id = fields.Many2one('saleorder.channel', string=_('Канал продаж')) + team_id = fields.Many2one('crm.team', string=_('Команда продаж')) + order_days_ids = fields.Many2many(comodel_name='contract.day', relation='orderdays', string=_('Дни доставки'), + column1='contract_id', column2='day_id') + shipment_days_ids = fields.Many2many(comodel_name='contract.day', relation='shipmentdays', string=_('Дни отгрузки'), + column1='contract_id', + column2='day_id') + # Доработка хедера договора + partner_type = fields.Selection(string=_('Тип контрагента'), selection=[ + ('person', 'Физ. лицо'), + ('company_ip', 'ИП'), + ('company', 'Юр. лицо') + ], required=True) + contract_header = fields.Html(_('Шапка договора')) + + @api.onchange('partner_type') + def generate_contract_header(self): + self.ensure_one() + self.render_model = 'partner.contract.customer' + if self.partner_type == 'company_ip': + self.contract_header = IP_CONTACT_HEADER + elif self.partner_type == 'person': + self.contract_header = INDIVIDUAL_CONTRACT_HEADER + else: + self.contract_header = ENTITY_CONTRACT_HEADER + # # Рендер Jinja выражение типа {{object.field}} + result = self._render_template(self.contract_header, self.render_model, res_ids=[self.id]) + result = tools.html_sanitize(result[self.id]) + self.contract_header = result + + @api.onchange('sec_partner_id') + def set_pid(self): + self.partner_id = self.sec_partner_id.parent_id if self.sec_partner_id.parent_id else self.sec_partner_id + + def _expand_states(self, states, domain): + return [key for key, val in type(self).state.selection] + + def copy_it(self): + if self.copy_from: + for line in self.copy_from.lines: + line.copy({'contract_id': self.id}) + + def _get_name_print(self): + morph = pymorphy2.MorphAnalyzer() + self.name_print = False + director = self.env['res.partner'].search([('parent_id', '=', self.partner_id.id), ('type', '=', 'director')], + limit=1) + if director: + if len(director.name.split(' ')) == 3: + lastname_old, firstname_old, middlename_old = director.name.split(' ') + + if lastname_old: + lastname_n = morph.parse(lastname_old)[0] + if lastname_n.inflect({'gent'}): + lastname_n = lastname_n.inflect({'gent'}).word + else: + lastname_n = lastname_old + else: + lastname_n = '' + + if firstname_old: + firstname_n = morph.parse(firstname_old)[0] + firstname_n = firstname_n.inflect({'gent'}).word + else: + firstname_n = '' + + if middlename_old: + middlename_n = morph.parse(middlename_old)[0] + middlename_n = middlename_n.inflect({'gent'}).word + else: + middlename_n = '' + + name_print = lastname_n + ' ' + firstname_n + ' ' + middlename_n + + self.name_print = name_print.title() + + def _get_name_print1(self): + # morph = pymorphy2.MorphAnalyzer() + director = self.company_id.chief_id.partner_id if self.company_id.chief_id else False + # raise exceptions.UserError(str(director)) + self.name_dirprint = False + if director: + if len(director.name.split(' ')) == 3: + lastname_old, firstname_old, middlename_old = director.name.split(' ') + + if lastname_old: + lastname_n = morph.parse(lastname_old)[0] + lastname_n = lastname_n.inflect({'gent'}).word + else: + lastname_n = '' + + if firstname_old: + firstname_n = morph.parse(firstname_old)[0] + firstname_n = firstname_n.inflect({'gent'}).word + else: + firstname_n = '' + + if middlename_old: + middlename_n = morph.parse(middlename_old)[0] + middlename_n = middlename_n.inflect({'gent'}).word + else: + middlename_n = '' + + name_print = lastname_n + ' ' + firstname_n + ' ' + middlename_n + + self.name_dirprint = name_print.title() + + @api.model + def create(self, values): + res = super(PartnerContractCustomer, self).create(values) + + if values.get('is_template'): + return res + + if values.get('type') == 'customer': + sequence_code = 'partner.contract.customer.sequence' + elif values.get('type') == 'supplier': + sequence_code = 'partner.contract.supplier.sequence' + else: + return res + + name = self.env['ir.sequence'].next_by_code(sequence_code) + + res.update({ + 'name': name, + }) + + return res + + # @api.model + def write(self, values): + + if 'state' in values: + if self.state != values['state']: + msg = 'Статус: ' + dict(self._fields['state'].selection).get(self.state) + ' -> ' + dict( + self._fields['state'].selection).get(values['state']) + self.message_post(body=msg) + res = super(PartnerContractCustomer, self).write(values) + return res + + def _get_name_print1ip(self): + self.name_dirprint1 = self.company_id.chief_id.partner_id.name if self.company_id.chief_id else False + + def _get_name_printip(self): + self.name_print1 = False + director = self.env['res.partner'].search([('parent_id', '=', self.partner_id.id), ('type', '=', 'director')], + limit=1) + if director: + self.name_print1 = director.name + + def print_supp(self): + # self.filtered(lambda s: s.state == 'draft').write({'state': 'sent'}) + return self.env['report'].get_action(self, 'mta_base.action_mtacontractsupp_report') + + def print_contract_cust(self): + if self.saleorder_id: + return self.saleorder_id.print_contract() + else: + raise exceptions.UserError(_( + 'Вы не можете напечатать договор с Клиентом, потому что нет связи с Заказом. Нужно зайти в Заказ и привязать этот договор.')) + + def contract_action_confirm(self): + if self.state == 'draft': + self.state = 'progress' + elif self.state == 'progress': + self.state = 'signed' + + def contract_in_draft(self): + self.state = 'draft' + + @api.onchange('name') + def set_comp_and_partn(self): + context = self._context + order_id = context.get('sale_order_id') + if order_id: + sale_order = self.env['sale.order'].browse(order_id) + + self.company_id = sale_order.company_id + self.partner_id = sale_order.partner_id + + @api.onchange('profile_id') + def set_payment(self): + if self.profile_id.payment_term_id: + self.payment_term_id = self.profile_id.payment_term_id + + # @api.constrains('name') + def check_name(self): + obj = self.search([('name', '=', self.name), ('id', '!=', self.id), ('state', '!=', 'closed')]) + if obj: + raise exceptions.ValidationError(_('Договор с таким номером уже существует')) + + """ + @api.constrains('profile_id') + def check_profile_id(self): + contracts = self.search([('partner_id', '=', self.partner_id.id), ('id', '!=', self.id)]) + if contracts: + profiles_in_contracts = contracts.profile_id + # raise exceptions.ValidationError(profiles_in_contracts.ids) + if profiles_in_contracts: + ads = self.env['contract.allowed.profiles'].search( + [('allowed_profiles', 'in', profiles_in_contracts.ids)]) + if ads: + raise exceptions.ValidationError((self.profile_id.name, ads.name)) + # raise exceptions.ValidationError(contracts) + """ + + +class Partner(models.Model): + _inherit = 'res.partner' + + contract_count = fields.Integer(string=_('Договоры'), compute='get_count_contract') + pol = fields.Selection(string=_("Пол"), selection=[('m', 'Муж.'), ('j', 'Жен'), ], required=False) + type = fields.Selection(selection_add=[('director', 'Директор')]) + + def get_count_contract(self): + contract = self.env['partner.contract.customer'] + self.contract_count = contract.search_count([('partner_id', '=', self.id)]) + + def action_view_contract(self): + action = self.env.ref('contract.contract_customer_action').read()[0] + + action['domain'] = [('partner_id', '=', self.id)] + + return action + + +class ContractLine(models.Model): + _name = 'contract.line' + contract_id = fields.Many2one('partner.contract.customer', string='Order Reference', required=True, + ondelete='cascade', index=True, copy=False) + _order = "sequence desc" + # name = fields.Text(string='Название для договора') + # price_unit = fields.Float('Цена', default=0.0) + # product_uom = fields.Many2one('uom.uom', string='Единица измерения') + # product_id = fields.Many2one('product.product', string='Услуга', domain=[('sale_ok', '=', True)], change_default=True, ondelete='restrict') + sequence = fields.Integer('Порядок') + name = fields.Char('Номер пункта') + punct = fields.Html('Текст пункта') + + @api.onchange('product_id') + def set_name(self): + self.name = self.product_id.name + + +class AllowedProfiles(models.Model): + _name = 'contract.allowed.profiles' + name = fields.Char(string=_('Одновременно включены следующие виды договоров:')) + allowed_profiles = fields.Many2many('contract.profile', string=_('Виды договоров'), required=True) + + @api.onchange('allowed_profiles') + def set_name(self): + self.name = '' + for profile in self.allowed_profiles: + self.name += profile.name + ' + ' + if self.name: + if self.name[-2] == '+': + self.name = self.name[:-2] + + +class ContractProfile(models.Model): + _name = 'contract.profile' + name = fields.Char(string=_('Вид договора'), required=True) + payable_account_id = fields.Many2one('account.account', string=_('Счет кредиторской задолженности'), required=True) + receivable_account_id = fields.Many2one('account.account', string=_('Счет дебиторской задолженности'), required=True) + max_receivable_id = fields.Float(string=_('Максимальная деб. задолженность'), required=True) + payment_term_id = fields.Many2one('account.payment.term', string=_('Условие оплаты'), required=True) + journal_id = fields.Many2one('account.journal', string=_('Журнал'), required=True) + + +class ContractDay(models.Model): + _name = 'contract.day' + name = fields.Char(_('День')) diff --git a/l10n_ru_contract/models/crutch_fields_header.py b/l10n_ru_contract/models/crutch_fields_header.py new file mode 100644 index 0000000..f290eff --- /dev/null +++ b/l10n_ru_contract/models/crutch_fields_header.py @@ -0,0 +1,33 @@ +ENTITY_CONTRACT_HEADER = """ +{{object.company_id.partner_id.name}}, +именуемое в дальнейшем «Поставщик», в лице +{{(object.company_id.chief_id.partner_id.function or '').lower()}} +{{(object.name_dirprint1 or '').title()}}, + действующего на основании ОГРНИП № {{object.company_id.company_registry or ''}}, с одной стороны, и {{object.partner_id.name or ''}}, +именуемое в дальнейшем «Покупатель», в лице +{{(object.get_function_partner1(object.partner_id.id) or '').lower()}} +{{(object.name_print1 or '').title()}}, действующего на основании устава общества, с другой стороны, вместе именуемые в дальнейшем «Стороны» заключили +настоящий Договор о нижеследующем: + """ +IP_CONTACT_HEADER = """ +{{object.company_id.partner_id.name}}, +именуемое в дальнейшем «Поставщик», в лице +{{(object.company_id.chief_id.partner_id.function or '').lower()}} +{{(object.name_dirprint1 or '').title()}}, + действующего на основании ОГРНИП № {{object.company_id.company_registry or ''}}, с одной стороны, и {{object.partner_id.name or ''}}, +именуемое в дальнейшем «Покупатель», в лице +{{(object.get_function_partner1(object.partner_id.id) or '').lower()}} +{{(object.name_print1 or '').title()}}, действующего на основании ОГРНИП №{{object.partner_id.ogrn or ''}}, + с другой стороны, вместе именуемые в дальнейшем «Стороны» заключили +настоящий Договор о нижеследующем: +""" + +INDIVIDUAL_CONTRACT_HEADER = """ +{{object.company_id.partner_id.name}}, +именуемое в дальнейшем «Поставщик», в лице +{{(object.company_id.chief_id.partner_id.function or '').lower()}} +{{(object.name_dirprint1 or '').title()}}, + действующего на основании ОГРНИП № {{object.company_id.company_registry or ''}}, с одной стороны, и {{object.partner_id.name or ''}}, +именуемое в дальнейшем «Покупатель», вместе именуемые в дальнейшем «Стороны» заключили +настоящий Договор о нижеследующем: + """ diff --git a/l10n_ru_contract/models/dop_field.py b/l10n_ru_contract/models/dop_field.py new file mode 100644 index 0000000..9c8626d --- /dev/null +++ b/l10n_ru_contract/models/dop_field.py @@ -0,0 +1,353 @@ +from odoo import api, fields, models, exceptions +from datetime import datetime +import re +import pymorphy2 +from odoo.tools import pycompat + +FRACTIONS = ( + (u"десятая", u"десятых", u"десятых"), + (u"сотая", u"сотых", u"сотых"), + (u"тысячная", u"тысячных", u"тысячных"), + (u"десятитысячная", u"десятитысячных", u"десятитысячных"), + (u"стотысячная", u"стотысячных", u"стотысячных"), + (u"миллионная", u"милллионных", u"милллионных"), + (u"десятимиллионная", u"десятимилллионных", u"десятимиллионных"), + (u"стомиллионная", u"стомилллионных", u"стомиллионных"), + (u"миллиардная", u"миллиардных", u"миллиардных"), +) + +ONES = { + 0: (u"", u"", u""), + 1: (u"один", u"одна", u"одно"), + 2: (u"два", u"две", u"два"), + 3: (u"три", u"три", u"три"), + 4: (u"четыре", u"четыре", u"четыре"), + 5: (u"пять", u"пять", u"пять"), + 6: (u"шесть", u"шесть", u"шесть"), + 7: (u"семь", u"семь", u"семь"), + 8: (u"восемь", u"восемь", u"восемь"), + 9: (u"девять", u"девять", u"девять"), +} + +TENS = { + 0: u"", + 10: u"десять", + 11: u"одиннадцать", + 12: u"двенадцать", + 13: u"тринадцать", + 14: u"четырнадцать", + 15: u"пятнадцать", + 16: u"шестнадцать", + 17: u"семнадцать", + 18: u"восемнадцать", + 19: u"девятнадцать", + 2: u"двадцать", + 3: u"тридцать", + 4: u"сорок", + 5: u"пятьдесят", + 6: u"шестьдесят", + 7: u"семьдесят", + 8: u"восемьдесят", + 9: u"девяносто", +} + +HUNDREDS = { + 0: u"", + 1: u"сто", + 2: u"двести", + 3: u"триста", + 4: u"четыреста", + 5: u"пятьсот", + 6: u"шестьсот", + 7: u"семьсот", + 8: u"восемьсот", + 9: u"девятьсот", +} + +MALE = 1 +FEMALE = 2 + +import operator +import sys +import types + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + +class Partner_Bank(models.Model): + _inherit = 'res.partner.bank' + bank_corr_acc = fields.Char('Кор.счет') + + +# class Bank(models.Model): +# _inherit = 'res.bank' + +# corr_acc = fields.Char('Corresponding account', size=64) + +# class Users(models.Model): +# _inherit = 'res.users' + +# facsimile = fields.Binary("Facsimile") + +class Company(models.Model): + _inherit = 'res.company' + + inn = fields.Char(related='partner_id.inn', readonly=False) + kpp = fields.Char(related='partner_id.kpp', readonly=False) + okpo = fields.Char(related='partner_id.okpo', readonly=False) + chief_id = fields.Many2one('res.users', 'Имя директора') + stamp = fields.Binary("Stamp") + + +class Partner(models.Model): + _inherit = 'res.partner' + ogrn = fields.Char('ОГРН') + okpo = fields.Char('ОКПО') + inn = fields.Char('ИНН') + kpp = fields.Char('KPP') + passport = fields.Char('Паспорт') + + +class Report_contract_customer(models.Model): + _inherit = 'partner.contract.customer' + + 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 = "" % ( + width, + height, + type, + str(pycompat.to_text(img))) + return toreturn + + def numer(self, name): + if name: + numeration = re.findall('\d+$', name) + if numeration: return numeration[0] + return '' + + def ru_date(self, date): + if date and date != 'False': + return dt.ru_strftime(u'"%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(u'%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): + "Transform sum number in rubles to text" + text_rubles = self.numeral_rubles(int(sum)) + copeck = round((sum - int(sum)) * 100) + text_copeck = self.numeral_choose_plural(int(copeck), (u"копейка", u"копейки", u"копеек")) + return ("%s %02d %s") % (text_rubles, copeck, text_copeck) + + def numeral_rubles(self, amount, zero_for_kopeck=False): + self.check_positive(amount) + pts = [] + amount = round(amount, 2) + pts.append(self.sum_string(int(amount), 1, (u"рубль", u"рубля", u"рублей"))) + remainder = self._get_float_remainder(amount, 2) + iremainder = int(remainder) + + if iremainder != 0 or zero_for_kopeck: + if iremainder < 10 and len(remainder) == 1: + iremainder *= 10 + pts.append(self.sum_string(iremainder, 2, + (u"копейка", u"копейки", u"копеек"))) + return u" ".join(pts) + + def _get_float_remainder(self, fvalue, signs=9): + self.check_positive(fvalue) + if isinstance(fvalue, integer_types): + return "0" + if isinstance(fvalue, Decimal) and fvalue.as_tuple()[2] == 0: + return "0" + + def sum_string(self, amount, gender, items=None): + if isinstance(items, text_type): + items = split_values(items) + if items is None: + items = (u"", u"", u"") + try: + one_item, two_items, five_items = items + except ValueError: + raise ValueError("Items must be 3-element sequence") + self.check_positive(amount) + if amount == 0: + return u"ноль %s" % five_items + into = u'' + tmp_val = amount + into, tmp_val = self._sum_string_fn(into, tmp_val, gender, items) + into, tmp_val = self._sum_string_fn(into, tmp_val, FEMALE, + (u"тысяча", u"тысячи", u"тысяч")) + into, tmp_val = self._sum_string_fn(into, tmp_val, MALE, + (u"миллион", u"миллиона", u"миллионов")) + into, tmp_val = self._sum_string_fn(into, tmp_val, MALE, + (u"миллиард", u"миллиарда", u"миллиардов")) + if tmp_val == 0: + return into + else: + raise ValueError("Cannot operand with numbers bigger than 10**11") + + def _sum_string_fn(self, into, tmp_val, gender, items=None): + if items is None: + items = (u"", u"", u"") + one_item, two_items, five_items = items + self.check_positive(tmp_val) + if tmp_val == 0: + return into, tmp_val + words = [] + rest = tmp_val % 1000 + tmp_val = tmp_val // 1000 + if rest == 0: + if into == u"": + into = u"%s " % five_items + return into, tmp_val + end_word = five_items + words.append(HUNDREDS[rest // 100]) + rest = rest % 100 + rest1 = rest // 10 + tens = rest1 == 1 and TENS[rest] or TENS[rest1] + words.append(tens) + if rest1 < 1 or rest1 > 1: + amount = rest % 10 + end_word = self.numeral_choose_plural(amount, items) + words.append(ONES[amount][gender - 1]) + words.append(end_word) + words.append(into) + words = filter(lambda x: len(x) > 0, words) + return u" ".join(words).strip(), tmp_val + + def check_positive(self, value, strict=False): + if not strict and value < 0: + raise ValueError("Value must be positive or zero, not %s" % str(value)) + if strict and value <= 0: + raise ValueError("Value must be positive, not %s" % str(value)) + + def numeral_choose_plural(self, amount, variants): + if isinstance(variants, text_type): + variants = split_values(variants) + self.check_length(variants, 3) + amount = abs(amount) + if amount % 10 == 1 and amount % 100 != 11: + variant = 0 + elif amount % 10 >= 2 and amount % 10 <= 4 and \ + (amount % 100 < 10 or amount % 100 >= 20): + variant = 1 + else: + variant = 2 + return variants[variant] + + def check_length(self, value, length): + _length = len(value) + if _length != length: + raise ValueError("length must be %d, not %d" % \ + (length, _length)) + + 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.city: repr.append(partner.city) + if partner.street: repr.append(partner.street) + if partner.street2: repr.append(partner.street2) + return ', '.join(repr) + + def address_delivery(self, partner): + if partner: + addr = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'delivery')], limit=1) + repr = [] + if addr: + if addr.zip: repr.append(addr.zip) + if addr.city: repr.append(addr.city) + if addr.street: repr.append(addr.street) + if addr.street2: repr.append(addr.street2) + return ', '.join(repr) + + def get_function_print(self, function): + morph = pymorphy2.MorphAnalyzer() + if function: + f = morph.parse(function)[0] + f = f.inflect({'gent'}).word + return f.title() + + def get_function_partnerip(self, partner): + director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) + if director: + if director.function: + return director.function + + def get_function_partner(self, partner): + res = [] + morph = pymorphy2.MorphAnalyzer() + if partner: + director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) + if director: + if director.function: + list_f = str(director.function).split(' ') + for func in list_f: + f = morph.parse(func)[0] + f = f.inflect({'gent'}).word + res.append(f) + return ' '.join(res) + + def get_function_partner1(self, partner): + if partner: + director = self.env['res.partner'].search([('parent_id', '=', partner), ('type', '=', 'director')], limit=1) + if director: + if director.function: + return director.function + + def get_date_text(self, date): + month_list = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', + 'ноября', 'декабря'] + if date: + date_list = str(date).split('-') + if date_list[0] and date_list[1] and date_list[2]: + return ('"' + date_list[2] + '" ' + month_list[int(date_list[1]) - 1] + ' ' + date_list[0] + ' г.') + + def get_bank(self, partner): + repr = [] + 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.bank_name: repr.append(bank.bank_name) + if bank and bank.acc_number: repr.append(u"Р/счет " + bank.acc_number) + if bank and bank.bank_bic: repr.append(u"БИК " + bank.bank_bic) + if bank and bank.bank_corr_acc: repr.append(u"к/с " + bank.bank_corr_acc) + return '
'.join(repr) diff --git a/l10n_ru_contract/models/purchase_order.py b/l10n_ru_contract/models/purchase_order.py new file mode 100644 index 0000000..d4d5271 --- /dev/null +++ b/l10n_ru_contract/models/purchase_order.py @@ -0,0 +1,13 @@ +from odoo import api, fields, models, exceptions, _ + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + mt_contract_id = fields.Many2one('partner.contract.customer', string=_('Номер договора')) + sec_partner_id = fields.Many2one('res.partner', string=_('Контрагент'), store=True, compute='_compute_get_pid') + + @api.depends('partner_id') + def _compute_get_pid(self): + for s in self: + s.sec_partner_id = s.partner_id.parent_id if s.partner_id.parent_id else s.partner_id diff --git a/l10n_ru_contract/models/sale_make_invoice_advance.py b/l10n_ru_contract/models/sale_make_invoice_advance.py new file mode 100644 index 0000000..76b3381 --- /dev/null +++ b/l10n_ru_contract/models/sale_make_invoice_advance.py @@ -0,0 +1,18 @@ +from odoo import api, fields, models + + +class ContractCreateInvoice(models.TransientModel): + _inherit = 'sale.advance.payment.inv' + + # # при выбора счета "Авансовый платеж" + # @api.model + # def _create_invoice(self, order, so_line, amount): + # res = super(ContractCreateInvoice, self)._create_invoice(order, so_line, amount) + # if order.mt_contract_id: + # res.write({'mt_contract_id': order.mt_contract_id, + # 'journal_id': order.mt_contract_id.profile_id.journal_id, }) + # return res + def _prepare_invoice_values(self, order, name, amount): + invoice_vals = super(ContractCreateInvoice, self)._prepare_invoice_values(order, name, amount) + invoice_vals['mt_contract_id'] = order.mt_contract_id.id + return invoice_vals \ No newline at end of file diff --git a/l10n_ru_contract/models/sale_order.py b/l10n_ru_contract/models/sale_order.py new file mode 100644 index 0000000..ac93e86 --- /dev/null +++ b/l10n_ru_contract/models/sale_order.py @@ -0,0 +1,62 @@ +from odoo import api, fields, models, exceptions, _ +from datetime import datetime + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + mt_contract_id = fields.Many2one('partner.contract.customer', string=_('Номер договора')) + sec_partner_id = fields.Many2one('res.partner', string=_('Контрагент'), store=True, compute='_compute_get_pid') + stamp = fields.Boolean(string=_('Печать и подпись'), related='mt_contract_id.stamp') + + @api.depends('partner_id') + def _compute_get_pid(self): + for s in self: + s.sec_partner_id = s.partner_id.parent_id if s.partner_id.parent_id else s.partner_id + + @api.onchange('mt_contract_id') + def set_ons(self): + if self.mt_contract_id: + self.payment_term_id = self.mt_contract_id.payment_term_id + + @api.constrains('state') + def late_payment_check(self): + if self.mt_contract_id: + if self.state == 'sale': + late_invoices_count = 0 + max_receivable = self.mt_contract_id.profile_id.max_receivable_id # макс. деб. задолженность в договоре + # ищу просроченные инвойсы контрагента указанного в заказе со стейтом "Подтверждено" + invoices_obj = self.env['account.move'].search([('partner_id', '=', self.partner_id.id), + ('state', '=', 'posted'), + ('invoice_date_due', '<', datetime.now().date())]) + + for invoice in invoices_obj: + late_invoices_count += invoice.amount_residual # складываю деб. задолженность по просроченным инвойсам + + if late_invoices_count > max_receivable: + raise exceptions.ValidationError( + f'Нельзя подтвердить заказ, так как у контрагента {self.sec_partner_id.name} нарушено ' + f'условие по дебиторской задолженности.\n\n' + f'Контрагент {self.sec_partner_id.name} должен {late_invoices_count}руб.\n' + f'Максимальная дебиторская задолженность указанная в ' + f'договоре №{self.mt_contract_id.name} - {max_receivable}руб.\n\n' + f'Проверьте следующие неоплаченные счета контрагента:\n' + f'{", ".join([invoice.name for invoice in invoices_obj])}') + + # # при выбора счета "Обычный счет" + # @api.model + # def _create_invoices(self, grouped=False, final=False, date=None): + # res = super(SaleOrder, self)._create_invoices(grouped, final, date) + # if self.mt_contract_id: + # res.write({'mt_contract_id': self.mt_contract_id, + # 'journal_id': self.mt_contract_id.profile_id.journal_id}) + # return res + def _get_invoice_grouping_keys(self): + res = super(SaleOrder, self)._get_invoice_grouping_keys() + res.append('mt_contract_id') + return res #['company_id', 'partner_id', 'currency_id', 'mt_contractid'] + + def _prepare_invoice(self): + invoice_vals = super(SaleOrder, self)._prepare_invoice() + invoice_vals['mt_contract_id'] = self.mt_contract_id.id + return invoice_vals \ No newline at end of file diff --git a/l10n_ru_contract/report/__init__.py b/l10n_ru_contract/report/__init__.py new file mode 100644 index 0000000..ca7d062 --- /dev/null +++ b/l10n_ru_contract/report/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import report_contract +from . import report_contract_order +from . import report_contract_invoice diff --git a/l10n_ru_contract/report/__pycache__/__init__.cpython-310.pyc b/l10n_ru_contract/report/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..837569591d16301b67a05bf43dcb1dd1c710b74e GIT binary patch literal 253 zcmZ8by9&ZU5WGha5rUPH+Af7&X(M7~X=9h>2)Pvlxop^+0YAxKy4K2Hu<}k3#DSfi z*@d0OG@Y=3#a^5s^m{bF5W(z1^;sap3~!j_1-GIQRu+;oBaSSW4<6RJ^izTk$>|DP zM`h*w>~Elv43MAykLz~83J!VV8O2PJk&-|+Mx&@BJ=f}t7LP_;i@o>&79!YPGi-JjTynb;<~9MJ#77X{#(FE!%1%s| z$~iSnntTl3d@~I5_dJ^&gW$b>hamoA40dS##pYbZ6L|2dhom}{nyyK@(+YfZ53T-G zQqbyp!eL2V&`~aIU8$#g2_*J`>)C!f<~6x++fFL5mR>v==}71WHo~yIGY^!4S;t~~ zlNQ+9xw&*0)9=8!%?m@G$hg%|D53S9@?dt0n7@GrG3HnhFP4wn=~W`X>ccgU9~dtf STA?qklzM}k*F(lrsr~`Rf?vb{ literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/__init__.cpython-35.pyc b/l10n_ru_contract/report/__pycache__/__init__.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba3a8e93e0e54f08b4e5c8b6a3af66321932a4b8 GIT binary patch literal 172 zcmWgR<>fll;1O%Vz`*brh~a<<$Z`PUVi6#b0z`}qISdTBj0{nX42&sE48fYrFBySS znvA#ji&6{ni%Q~?^YcoI5|c~(G?{KO6oCv_$xy@sq`<^4-DInnw4BsrpqiM(l$89u n;ux5Y7>Efm@$s2?nI-Y@dIgoYIBatBQ%ZAE?LY<<12F>tv|lPH literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/__init__.cpython-36.pyc b/l10n_ru_contract/report/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..482a4d78d4df98c13f7759a780488e099a61318b GIT binary patch literal 250 zcmZ9FF$%&k6oy}#A|ezg#Vd5s46af8Vt^G(B{(Zhd=rWT-ZC+3ui!pmPFB%svr#%OBp2)oJh=`)V*V7r$$z2 z8j+)JOqMrxHYfxdkjBo3b)j3#STsocH!@Q=WSwPQ7L0t9GIG)<@ul0dVBQ3Ao9#OzMpJ7#uhREee* z5{ufTvbLj6A<%#_cHFJAqCu&4acGJ0n}&G_om`3OdGF=9;V0CJ!x^D!IRfGoRP!;% k`GV^<1;C=>zkUAQ;X-6ZRtqsJTiai1giEege&^vx-iPH#rvLx| literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_barite_specification.cpython-36.pyc b/l10n_ru_contract/report/__pycache__/report_barite_specification.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ea10f1a4ba606783c7f5b9ccc96dd828cbe0607 GIT binary patch literal 706 zcmaJ<&2G~`5Z*thNkkw$0#c7iKGZ&NMW`r3oEjv!`Lb+0TX1B1!>*HxD4g2I=nL>7 zJj7l(@d})naa}1A5-ZK@r}^f`->hHGX49W|IIuzhFC-)& zLEUofB(T#cK3}-D^QP<;+t9hj`VV&FeD~gi_4~7OAhU8{GvCwN5x*>H4jocKwm=JK z=nia+TAs2sKkys=T^{5b=N}}9JBf4Uaz72GwprgNmGJ~zsVfL^LZDX^6~cg=wCygA zR^D9)8zm;CDym@Xt2n|8DpFuN<4n?i}o{2e|=oZO9*# z<@bVyORtQtI;+FRmeo~Nnyzwfw)qxMKif_Z+IObj+AtxhV|0wqh2nzm&;PT^?4SCS zFViHBwQfygwT@FwvbQziM_PZ~ntEW8KE=;*R4?wxJ)syaK0ylv#$3rhLfsWf_kxn> irQ+<(D)f(iNxw{=cGQd(=c!{Hzq1gh5Z*suOoW4JB0@ot0&zv|UI0ZwmPmyQ=&o69ZZ;v-o!8l28)2D>JO)Kl zMZD6sRJ;Nb5;JF8vJ^&|+4fXUO3-3Sht+*7AzC zq7s~)GY}we8AvN8^1G}Qs81~K{l;9DizLnLI%TZ`+k~2YyCl&#Lk=%dSXOahl>lBz z=z#=v%dwikYFRoQxoPyKj-z>quC@N7ojD(uFY1lIs5gPacad>T#kWKdh)2lb6^a#` zAdn+=$5;HGf0HXY!Nw~I;)leBa=bj686T(C7mqsRGVOt@^)-a_gp>|lQm6)uNjqJn z?83V*!6u1Gxk@V7<}ziNL6;PmX#5_I@ss%jJpP=PpAl3UZHT1<=T5*bI;AvFZU-pW z$To-Gx{KM@^!&<3y$2)c7h>bcVJK`DnwhtdNwE9f(1KIhgz9OVvP#Wzj4c=XZZpR;L})lB`j>tRmuv$8-PhWt?c0|sZf6#xJL literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract.cpython-311.pyc b/l10n_ru_contract/report/__pycache__/report_contract.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3acb9e4503830ae41cd8c8d783ce85995ccbaa5 GIT binary patch literal 982 zcmZ`%zi$&U6t>ToG>sY^r3exV5)&c=IaO3*XoZ9#U?Kw`K(|?afqXV^d_|$y*G;TCNZ5R_{xRQnF6NoWy1AGAMM>FgV8IX2H9po7h zrhOzplQjC3jx8dei`pEoDv?VpaA=E#a#;nj9#V%e1dMRMC-Y4ayb8G_u&Js`J>>2) znTH)JNoRIs3w3az`kgCar%%imAcom%MYd~tJJhwC<_7felsL3$`#Wa9g1}6~p*CZI zADS6AGm$DCXtrGIyq2rac|;SK_H4Jy!~V7U!Xv27?JOvYH^B|j*jRhFdtAOTGB&>( zTi=YWFL%Eh^^sA3tDjt0f4@7fY>v;BCrkR7;shmbxj2PXRK*QA_5!88?Qu$Fkt)Hu zu8LPEec83$6v@R~#92uCjKmrYVpX|(=9F6Db#TMkGhVqmyfew?bI|rbE~%u7C?dL& zQK%~q*qy?v;L=r?S$|xu?~Q`J>es86M`{5L6?pfy%W8NfzrJD R@OX528nu5I&NU>;!R}E=KbP)uImVR0Kr}59v}5$!5497?CL~=*JG#-ui|K5K4@rMCCz|Iq){{@%(fJWoXpaiHG z%otQ0W*pdw=AZ@KV^DzMPzbmaFpEG(aF)i8co0(Vg<39rQZ?F?E+=gJ{G-SaF+i1( z2rDDk3@b)Z#IWJOiuVle5Kjof>V7ei~fopi2kDq~O0va#*zZQkQq-Ul)pBGX*- z%tV~vn&5Kp(X0WAAn~YRunt5wf{4}viXakO!XEH*A&7mtI$A2**2ZQp==?x8xm;-H z_s9vteT1${g%_s2^2xbvemUa>CZ&;&oGCASf*Euu(yCQ9-L<)M8 zmY=gN6@P&u%FNl8EQOV3_Gv!e&fDEL!{OoG@0;l_&e$Kew-n-2v~YqB81R}kyyT52 z1!rdr1juU!(u$e9lBELmnPt7dSj#ezq?wp$7K^Ktc}+Q##0o5+2anN&nhi$*6KqlII1Yc@jx zM{LH|{EA=7wVdIhYYF0~#KYudbu>3Vw$|ql*fW_9z*YJjLV84?QznhR|JTpNnr z9K}Z5cGJ6XKEFuMzS^iaX}vV{!iE6}Cdc?lC@%Qw)%d@+m_KOE_$2G4f!3{Qtk&sJ zlh8#?__5aC7pC53dR>Vh;VGS*J@=GiyW0;023*N5LhOpfdO=0>RB8Br8oDR`NFSvu W+asf^^2C@1Z#Sd7qt-xfB<=xe5W6q{ literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract.cpython-37.pyc b/l10n_ru_contract/report/__pycache__/report_contract.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc5983b86c0a9b1a2f2e9629660f2580188fe73b GIT binary patch literal 704 zcmZuvJ#Q015Zy03CW^sn5TT$%T#-9b&>Yi+T3hH%-yZoJsa6_s^n)- zgbMMOwx!}PAR#ex_DPY#NHhCxX7=s8-Fq_}?lQE$$BW_zXY3b!bfyp-p@*j!fB`RA z#dBVXTyS>6K!ChvAg!3nE14@$A6U}+jlC=pQJUFB>{kwK84AjECJ`K=hsPK!%Q>)I z0M8}#K!UpF$Rv=dA0Lig-FQI%C(&0p=$}^o5aK9WOXnzzNxKG@31E_?tm-w1%!ByK&vV$gaK>P z){EFb_3mr1QDRe~q6)S=i+${%O$tn7{0@%slll9&{CS&wLO~gPb`X}C1LqFGE?V&M z`HQSt8UR;^teYj<2;45ZOQ*AC+&{OC-jwyilye&fB$@)_BcZt9t7qf?-eh`bYr-c< zFAlV>O=Y!?yPCw#OTv3vf0>(dTj{keeuSsAl5T|ul(kIa^E>)k+O}I{bX}ep070>h<=ZiEVRs$uO;Dmx-8}{c zRESq{OT{Z7oy3fjNRf__W;~w%&*Qhl;UPo1I$cyhIb*-+vQG*xC&=L;3Shu%*6@-y zq7&Gv zp$8JwCC6$4tM%jEv1>bTs%|_FoolRrZD-DRt9#Yfo>yB(?vrOyQSluS1mZDrcz|Nf zrU>MSedlZbgMXE4ImO0n3F4c?hH|nxni=1<*5}tcWHKIrtMoa9c!QLLE-F+5`lM|a zv47^>mtdpBpiD&-Z2dm=F@lm5n9leE9OD=BxA6G;viOLg3i#w8EDHzDJqEi-%DX2| zi)Lv6TpNnrEX4-o_Ru?XK3m2+A8e;LZoM$|+=c;xPAldkp}64UYV~OR-}lU~C1-q+ z_2NM5)-+b@c&G{Pye9po)}QC5-gFZqun^zn;@caqL0x7 z9C;;QIq?dWkUF#3NRf~jX~yH3@i+cFcB9ddp}aU3*LR$;-?Z5mg_|?f@DdF$;5BP_ z$s17$&fYN)Aa5B+D`xV$EET8^EKB}iEz3ldW^ohK#(}LvMX`O6xH&@&&(K&_a$uzZ zUP?$ng1Y61CJ-%+&nIr)dQ-KNWoTVv{iR(v-(GmIetlB)$-L^bx$n~2QGQxcpPdjJ z(g|ufL9<~qXynBeiE9Q;Z%wK@BOI0aN@)b}_$}M z9y|*5&_hpE=|7_qFwCjw$y+p@dh)&f$R*XcyKmmi?|toW-iPVw5&`*ce#-+&$Pe7) zQpk+q8W{UT5J3YHQjdm~XHjC2J49G}L@;S>u{`JqtmDznvxWVDR0=;4u2_coJDbJ{ zBOwD_&qHvvvd!=k82dyLj|$>hf_hBYg6&brWML+=upTvH<=5l&rjDafs{3*$Qt>?{ zq-tNOXJECSp;eW@JVJbl0)ESTsrg!&W}gfYt~^~ z`CkB29VV;;1|74Fc1inztR@{)n3)h!oo@=IAyH5^UBOTlQGX|Z23V`>h|(~E}=T+Uc_!!L3K&LJo|R{{Zy~K z_^rJ3wY>E4(UJy*PjcSyL&>=* zaip#ppgqO;i>4oBNFi}i=OO45QM0h98B|WLaIW<-sP5?LPc3zC4;-feW&felOqc{4 zv5`=P)1&Yj%=E3APNwoM&URXB4$)El)5*28;hSm!0300s5Y&KCN>9k;&u6^@r$nKp TadmjTcWw0-0)Ngxld69KX2$&2 literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-36.pyc b/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5777642567b0613e16304383f6a745ff37b62f0b GIT binary patch literal 703 zcmaJm-EaMbKDmr1;A(vhA)XRQilRaokdt<~ ziG#U!UxJMilX4YRu+4`!zzixA<-Qu$u(R_C^~3 zw+!V$T)EfOU-}TK#pVy}8nJlIF364t2j@%=P(bhAxKw!v~OcCm?NVgZ1M9&n*ujV1W b^cDRtDeb5kZOv21IDE1Hl$TT*$W7#5)|S2G literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-37.pyc b/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..918be16c178cc180238945e103c352fae919aacf GIT binary patch literal 711 zcmaJ<&59F25bnRpW`ogqRAG<89Cii|-b7XddNKV7^Rj~L3I7wh_(Gxn1{4x$j8p@xTOfB|n<%PZcB zN^tg)fdF~MKw2@EUuC60yONT1eYEf?tR2N?HO(O*7Nk?u zaDryX=E&t9`^Io~aZ?sKqFVp6W63buI{2be)c3QTAG5zhU={B1mbpO+tyObH(ygiYzdxl^#~1l~S+ zT(%nn;1;1g5G?n+`a>Vwd!EH|6Ysvao$kr6O|!D$n79tnFg_8A3%))5&n}C9>T^EJ zvpCdxVOpzo9BJacY6#!b`qRoZeI!dMeuASCyBp>X`DpVQY9KJ=N+u6=SH#>4N}{WZ g<7XEk-S#VbGb!yxGuoV|j&b;8|0_?aG?1CdzafLZ=l}o! literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-38.pyc b/l10n_ru_contract/report/__pycache__/report_contract_order.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1204a1323b362bbf20ea1d2eccbd40fa85cb6f70 GIT binary patch literal 725 zcmaJ<&2AGh5cc1uX+$6#DN>I}d+4q>a6_n7Bsh^uMR3@QwcRn$up0+^6O<^N=wtK% z$G(!UJ@E=im6&lhQY0isn(=sM{Efe{-w%fahI0RUS>15P?r5_w3OA>y{uvrzz-!j< zf;XZNoV{TnKwdMDMoi@oStwBNSepFCT9%3+%lTF4H5N?mD~j!l#LX$HKSE5}X>lVEWZ@FgkRe1c#w7MI>vaA=z9}?I2$b2Le7hK%0PyRE} z>>q@bPtqjxwVsuY(K-w?F<;c=KhXN?qO7}25=-0&TSk6+<`Knc_6gmGoIY1FMhIOI mcPFTb9xM#cE`5CSxAc2r*&Z0p&JkkhzuaEs6&>|tM)EIevA_HP literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-35.pyc b/l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cb9164c477fccb11765aad08da7522617a157ea GIT binary patch literal 885 zcmZ`%ON$dh5U%d&nLOCQu7^NCPvRj6gWhBjQF3rE1~dm@3^bGJRukqCyJuDm*;D*8 zUi~?J_2kj3C#!lU5?HpGuI{O-uJ5bIcr+R=e*XFJkOTaJlO^!}61Sb9Q1~&(0SX2Q zgMvfCfsvL&9zY==5x`!n0F;35s1~3(Y(h8$kVK$DSWKhe7zn1^1?hI}qM}kdw^QbZ zZ{O?HmCm=?WaM#N{|UsX(LlHeh`7ik2|x>qkN6!Zg9GXjiz8O(CbO!nO`6rS#@1D# z%{#rVOueY9-TkaH#aU;IjW@>VInRQQ0O9v>Q~vfDiao%_*I}|@u=jX3m@tQ$!vPHe z>;u^N5@5nAqTjVZHof`o!8SE@sZD$v8$n(4+2`+is>s9K>H6c=Xm_RoLw#}RaLD>m8wd+JW^b? zRp}0SR7)frZ@;;VPr8<^i@Z+rMq7$(hbVxL`G5^r#CDHocl9B@^?urOeJRVd&{Ddg zr2Lzl?q^bdY0|v2gx4#9^QRMC*p#1A&LmMC2__g9x<<*BbK1deHcSM zPae^K+!i6upFSz2X(X1en-1CbsIBkl)yn$udP8IEL!LlWZ4KeO{_{487sS?5YsTz6 F_y^bg=pq0B literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-36.pyc b/l10n_ru_contract/report/__pycache__/report_contract_sto.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..659babf2bfc836c322f7c58c1a8195882b25a60a GIT binary patch literal 860 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 aO%Rpp`K-mHeKFDRGO4b>8pDMcGyVgS>!XPP literal 0 HcmV?d00001 diff --git a/l10n_ru_contract/report/report_contract.py b/l10n_ru_contract/report/report_contract.py new file mode 100644 index 0000000..3baf414 --- /dev/null +++ b/l10n_ru_contract/report/report_contract.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from odoo import api, models + +class ContractCustomerReport(models.AbstractModel): + _name = 'contract.customer.report' + + + def get_report_values(self, docids, data=None): + docs = self.env['partner.contract.customer'].browse(docids) + return { + 'doc_ids': docs.ids, + 'doc_model': 'partner.contract.customer', + 'docs': docs, + } diff --git a/l10n_ru_contract/report/report_contract.xml b/l10n_ru_contract/report/report_contract.xml new file mode 100644 index 0000000..97b9f43 --- /dev/null +++ b/l10n_ru_contract/report/report_contract.xml @@ -0,0 +1,398 @@ + + + + + + A4 + + A4 + 0 + 0 + Portrait + 15 + 30 + 7 + 7 + + 10 + 90 + + + + Договор + partner.contract.customer + qweb-pdf + l10n_ru_contract.report_contract_customer + l10n_ru_contract.report_contract_customer + 'Договор - %s' % (object.name) + + + report + + diff --git a/l10n_ru_contract/report/report_contract_invoice.py b/l10n_ru_contract/report/report_contract_invoice.py new file mode 100644 index 0000000..ccb72fc --- /dev/null +++ b/l10n_ru_contract/report/report_contract_invoice.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from odoo import api, models + + +class ContractCustomerReportInvoice(models.AbstractModel): + _name = 'contract.customer.report_invoice' + + + def get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs, + } diff --git a/l10n_ru_contract/report/report_contract_invoice.xml b/l10n_ru_contract/report/report_contract_invoice.xml new file mode 100644 index 0000000..8aad41d --- /dev/null +++ b/l10n_ru_contract/report/report_contract_invoice.xml @@ -0,0 +1,592 @@ + + + + + + A4 + + A4 + 0 + 0 + Portrait + 15 + 30 + 7 + 7 + + 10 + 90 + + + + Договор со спецификацией + account.move + qweb-pdf + l10n_ru_contract.report_contract_customer_invoice + l10n_ru_contract.report_contract_customer_invoice + 'Договор со спецификацией - %s' % (object.name) + + + report + + diff --git a/l10n_ru_contract/report/report_contract_order.py b/l10n_ru_contract/report/report_contract_order.py new file mode 100644 index 0000000..42a679d --- /dev/null +++ b/l10n_ru_contract/report/report_contract_order.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from odoo import api, models + + +class ContractCustomerReportOrder(models.AbstractModel): + _name = 'contract.customer.report_order' + + + def get_report_values(self, docids, data=None): + docs = self.env['sale.order'].browse(docids) + return { + 'doc_ids': docs.ids, + 'doc_model': 'sale.order', + 'docs': docs, + } + + + diff --git a/l10n_ru_contract/report/report_contract_order.xml b/l10n_ru_contract/report/report_contract_order.xml new file mode 100644 index 0000000..8d28819 --- /dev/null +++ b/l10n_ru_contract/report/report_contract_order.xml @@ -0,0 +1,594 @@ + + + + + + A4 + + A4 + 0 + 0 + Portrait + 15 + 30 + 7 + 7 + + 10 + 90 + + + + Договор со спецификацией + sale.order + qweb-pdf + l10n_ru_contract.report_contract_customer_order + l10n_ru_contract.report_contract_customer_order + 'Договор со спецификацией - %s' % (object.name) + + + report + + diff --git a/l10n_ru_contract/report/report_contract_order1.xml b/l10n_ru_contract/report/report_contract_order1.xml new file mode 100644 index 0000000..0c79c37 --- /dev/null +++ b/l10n_ru_contract/report/report_contract_order1.xml @@ -0,0 +1,406 @@ + + + + + + A4 + + A4 + 0 + 0 + Portrait + 15 + 30 + 7 + 7 + + 10 + 90 + + + + Спецификация + sale.order + qweb-pdf + l10n_ru_contract.report_contract_customer_order1 + l10n_ru_contract.report_contract_customer_order1 + 'Спецификация - %s' % (object.name) + + + report + + diff --git a/l10n_ru_contract/security/ir.model.access.csv b/l10n_ru_contract/security/ir.model.access.csv new file mode 100644 index 0000000..4f09569 --- /dev/null +++ b/l10n_ru_contract/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_partner_contract_customer,access_partner_contract_customer,model_partner_contract_customer,,1,1,1,1 +access_contract_profile,access_contract_profile,model_contract_profile,,1,1,1,1 +access_contract_day,access_contract_day,model_contract_day,,1,1,1,1 +access_contract_allowed_profiles,access_contract_allowed_profiles,model_contract_allowed_profiles,,1,1,1,1 +access_partner_contract_customerline,access_partner_contract_customerline,model_contract_line,,1,1,1,1 diff --git a/l10n_ru_contract/views/contract_customer_view.xml b/l10n_ru_contract/views/contract_customer_view.xml new file mode 100644 index 0000000..3a36f35 --- /dev/null +++ b/l10n_ru_contract/views/contract_customer_view.xml @@ -0,0 +1,357 @@ + + + + + + Договор + partner.contract.customer + +
+
+ +
+ +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + view_saleorder_form + sale.order + + + + + + + + + + + + + view_purchaseorder_formcontr + purchase.order + + + + + + + + + + + + + + view_invoice_form + account.move + + + + + + + + + + + + + + + + Договор + partner.contract.customer + + + + + + + + + + +
+
+
+ Номер: +
+
+ Контрагент:
+ Тип:
+ Вид договора: +
+
+ Наша компания: +
+
+
+
+
+
+ + +
+
+ + + + + + + + + + + + + + +
+
diff --git a/l10n_ru_contract/views/mail_template.xml b/l10n_ru_contract/views/mail_template.xml new file mode 100644 index 0000000..f5c44c4 --- /dev/null +++ b/l10n_ru_contract/views/mail_template.xml @@ -0,0 +1,37 @@ + + + + + Шаблон почты + + ${(object.company_id.email |safe} + ${object.partner_id.email} + Заказ ${object.name or 'n/a' } + + + + + +

+ ]]> +
+
+ + + Договор + + ${(object.company_id.email |safe} + ${object.partner_id.email} + Договор №${(object.name or 'n/a')} ${(object.company_id.name or 'n/a')} - ${(object.partner_id.parent_id.name or object.partner_id.name or 'n/a')} от ${(object.date_start or 'n/a')} + + + + ${object.partner_id.lang} +

+ ]]> +
+
+
+
diff --git a/l10n_ru_doc/README.md b/l10n_ru_doc/README.md new file mode 100644 index 0000000..505c373 --- /dev/null +++ b/l10n_ru_doc/README.md @@ -0,0 +1,38 @@ +# Российская локализация - Документы +name: l10n_ru_doc + +## Описание +Модуль для печати документов в соответствии с законодательством России. + +##Возможности: +* Товарная накладная (ТОРГ-12) +* Счет на оплату (по форме 1С) +* Счет-фактура +* Акт выполненных работ +* Универсальный передаточный документ + +### Товарная накладная (ТОРГ-12) +#### Для печати: +1. Меню Бухгалтерия - Клиенты - Счета (account.move); +2. Отчет "Товарная накладная (ТОРГ-12)". + +### Счет на оплату (по форме 1С) +1. Меню Продажи - Заказ продаж (sale.order)); +2. Отчет "Счет по форме 1С". + +### Счет-фактура +1. Меню Бухгалтерия - Клиенты - Счета (account.move); +2. Отчет "Счет-фактура". + +### Акт выполненных работ +1. Меню Бухгалтерия - Клиенты - Счета (account.move); +2. Отчет "Акт выполненных работ". + +### Универсальный передаточный документ +1. Меню Бухгалтерия - Клиенты - Счета (account.move); +2. В двух вариантах:отчет "Универсальный передаточный документ(УПД)" + + 2.1. Отчет "Универсальный передаточный документ(УПД)"; + + 2.2. Отчет "УПД без печатей"; + diff --git a/l10n_ru_doc/__init__.py b/l10n_ru_doc/__init__.py new file mode 100644 index 0000000..10a94a5 --- /dev/null +++ b/l10n_ru_doc/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import models +from . import report_helper +from . import report diff --git a/l10n_ru_doc/__manifest__.py b/l10n_ru_doc/__manifest__.py new file mode 100644 index 0000000..93e7d4c --- /dev/null +++ b/l10n_ru_doc/__manifest__.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Российская локализация - Документы", + + 'summary': "Первичные документы", + + 'description': """ +Модуль для печати документов в соответствии с законодательством России. +============================================================ +Возможности: + * Товарная накладная (ТОРГ-12) + * Счет на оплату (по форме 1С) + * Счет-фактура + * Акт выполненных работ + * Универсальный передаточный документ + +Для печати: + Товарная накладная (ТОРГ-12) + 1. Меню Бухгалтерия - Клиенты - Счета (account.move); + 2. Отчет "Товарная накладная (ТОРГ-12)". + + Счет на оплату (по форме 1С) + 1. Меню Продажи - Заказ продаж (sale.order)); + 2. Отчет "Счет по форме 1С". + + Счет-фактура + 1. Меню Бухгалтерия - Клиенты - Счета (account.move); + 2. Отчет "Счет-фактура". + + Акт выполненных работ + 1. Меню Бухгалтерия - Клиенты - Счета (account.move); + 2. Отчет "Акт выполненных работ". + + Универсальный передаточный документ + 1. Меню Бухгалтерия - Клиенты - Счета (account.move); + 2. В двух вариантах:отчет "Универсальный передаточный документ(УПД)" + 2.1. Отчет "Универсальный передаточный документ(УПД)"; + 2.2. Отчет "УПД без печатей"; + + """, + + 'author': "CodeUP and MK.Lab", + 'website': "https://www.inf-centre.ru/", + + 'license': 'AGPL-3', + 'category': 'Localization', + 'version': '0.1', + + 'depends': ['base', 'sale', 'account', 'sale_stock', 'uom', 'l10n_ru_base'], + + 'external_dependencies': {'python': ['pytils']}, + + 'data': [ + 'views/account_invoice_view.xml', + 'views/res_partner_view.xml', + 'views/res_company_view.xml', + 'views/res_users_view.xml', + 'views/res_bank_view.xml', + 'views/uom.xml', + 'views/tax.xml', + 'views/product.xml', + 'views/l10n_ru_doc_data.xml', + 'report/l10n_ru_doc_report.xml', + 'report/report_order.xml', + 'report/report_invoice.xml', + 'report/report_bill.xml', + 'report/report_act.xml', + 'report/report_upd.xml', + 'report/report_updn.xml', + ], + + 'demo': [ + 'demo/l10n_ru_doc_demo.xml', + ], +} diff --git a/l10n_ru_doc/demo/l10n_ru_doc_demo.xml b/l10n_ru_doc/demo/l10n_ru_doc_demo.xml new file mode 100644 index 0000000..16d7d63 --- /dev/null +++ b/l10n_ru_doc/demo/l10n_ru_doc_demo.xml @@ -0,0 +1,63 @@ + + + + + + ОАО "СБЕРБАНК РОССИИ" + г.Москва + 044525225 + 30101810400000000225 + + + + 40707810600025341231 + + + + + + + iVBORw0KGgoAAAANSUhEUgAAALQAAABACAYAAACzzl09AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoxMGE3N2JhNy01MThlLTMwNGEtODcxOC0wMmQ5MWYzYTdiNTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjQ2QTI3QjdCQ0JCMTFFMzgwRTQ4NjcwRjlEM0QyMTAiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjQ2QTI3QjZCQ0JCMTFFMzgwRTQ4NjcwRjlEM0QyMTAiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkYzOTcwMjU2QkNCOTExRTM5OEZFRDU5OUQxQUU3MUUzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkYzOTcwMjU3QkNCOTExRTM5OEZFRDU5OUQxQUU3MUUzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+LLXcsQAAAjFJREFUeNrs3TFKM0EUB3BXv+QAgqViYWflBQLbWNhZKwE7QQSPkCMIItgJQW+gtjmCBxLZr34zsMPDiCK/X6c7swPxz/B4zJhuGIYN+Cs2fQQINAg0fL9/5S+6o6NUUT28v3dh/s1NnP/5OT7/7i7Ov7qK83d24vjFoht7X/f4GOfv78f5fd/5s9uhQaBBoGGdNXSzRs7W2GWNfH09On+4v4/jF4vcehcXcf5qpdFuhwaBBoEGgQaBRqBBoOHnNPvQ2b7zxtZWnF+e7SieV+uVZzkOD0efV33r8ixH38f5RV/a2Q47NAg0CDQkde4UYocGgQaBhpT6TuF8Hovq7e3w43B7O36nr+9z55dXq9hHXi7j/N3dOL7RN+6Oj8fXn07j+15e9KHt0CDQINDwpRp6WC5TdwDTNXKjxh7m8zB+mr0TOJnE972+xvVPTzXe7dAg0CDQsNYa+rf58DfCDo1Ag0DDL6+hu7Oz2Kc9OIjPi7MeZd+6/H/Q3WyW6vtWZzlms/j86Smuf34e1/+IVXd1tqM4y4EdGgQaBBqS3CnEDg0CDQINOXUf+u0tdyfw5CSeN354iPP39kbHV+snz19X3+FS9tHLO5HFeOzQINAg0PDVGrpZIzdq7OHyMjU+XSO3vufw+XmtdyKxQ4NAg0BDq4aeNCZMfGbYoUGgQaBRQ4+aJvvI1VmO8k5g8bzsW1fvS/aRm3cii/c522GHBoEGgYYkdwqxQ4NAg0BDzn8BBgBlrqW6k1gn5wAAAABJRU5ErkJggg== + codup-test@mail.ru + www.codup.com + 0000000000 + 000000000 + 00000000 + + + + ООО "CodUP" + ул.Земляничная + дом № 13 + 123456 + г.Москва + CodUP + + + 1 + 1 + iVBORw0KGgoAAAANSUhEUgAAAOYAAADmCAMAAAD2tAmJAAAC2VBMVEUWAGH///8WAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGEWAGF7Mdv3AAAA83RSTlMAAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0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 + + + + Иванов Иван Петрович + codup-test@mail.ru + + + + Иванов Иван Петрович + iVBORw0KGgoAAAANSUhEUgAAAZQAAAETCAMAAAAmrgDyAAAC61BMVEUOF9r///8OF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9oOF9r/ATCgAAAA+HRSTlMAAAECAwQFBgcICQoLDA0ODxAREhQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJj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 + + + + Сидоров Семен Иванович + codup-test@mail.ru + + + + Сидоров Семен Иванович + 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 + + + + diff --git a/l10n_ru_doc/i18n/ru.po b/l10n_ru_doc/i18n/ru.po new file mode 100644 index 0000000..59d03de --- /dev/null +++ b/l10n_ru_doc/i18n/ru.po @@ -0,0 +1,116 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_ru_doc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-19 09:27+0000\n" +"PO-Revision-Date: 2020-08-19 09:27+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_doc +#: model:ir.actions.report,name:l10n_ru_doc.report_account_invoice_act +msgid "Act" +msgstr "Акт об оказании услуг" + +#. module: l10n_ru_doc +#: model:ir.actions.report,name:l10n_ru_doc.report_account_invoice_bill +msgid "Bill" +msgstr "Товарная накладная (ТОРГ-12)" + +#. module: l10n_ru_doc +#: model:ir.model.fields,help:l10n_ru_doc.field_res_company__print_facsimile +#: model:ir.model.fields,help:l10n_ru_doc.field_res_users__print_facsimile +msgid "Check this for adding Facsimiles of responsible persons to documents." +msgstr "Отметьте, для вставки подписей ответственных лиц в документы." + +#. module: l10n_ru_doc +#: model:ir.model.fields,help:l10n_ru_doc.field_res_company__print_stamp +msgid "Check this for adding Stamp of company to documents." +msgstr "Отметьте, для вставки печати организации в документы." + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__chief_id +msgid "Chief" +msgstr "Руководитель организации" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_account_setup_bank_manual_config__bank_corr_acc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_bank__corr_acc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_partner_bank__bank_corr_acc +msgid "Corresponding account" +msgstr "Корр. счет" + +#. module: l10n_ru_doc +#: model_terms:ir.ui.view,arch_db:l10n_ru_doc.view_company_ru_form +msgid "Documents" +msgstr "Документы" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_users__facsimile +msgid "Facsimile" +msgstr "Подпись" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__inn +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_partner__inn +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_users__inn +msgid "INN" +msgstr "ИНН" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__kpp +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_partner__kpp +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_users__kpp +msgid "KPP" +msgstr "КПП" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__okpo +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_partner__okpo +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_users__okpo +msgid "OKPO" +msgstr "ОКПО" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__print_anywhere +msgid "Print Anywhere" +msgstr "Документы" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__print_facsimile +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_users__print_facsimile +msgid "Print Facsimile" +msgstr "Выводить подписи" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__print_stamp +msgid "Print Stamp" +msgstr "Выводить печать" + +#. module: l10n_ru_doc +#: model_terms:ir.ui.view,arch_db:l10n_ru_doc.view_company_ru_form +msgid "Responsible Persons" +msgstr "Ответственные лица" + +#. module: l10n_ru_doc +#: model:ir.model.fields,field_description:l10n_ru_doc.field_res_company__stamp +msgid "Stamp" +msgstr "Печать" + +#. module: l10n_ru_doc +#: model:ir.model.fields,help:l10n_ru_doc.field_res_company__print_anywhere +msgid "Uncheck this, if you want add Facsimile and Stamp only in email." +msgstr "Снимите отметку, если хотите добавлять подписи и печать только в email." + +#. module: l10n_ru_doc +#: model:ir.actions.report,name:l10n_ru_doc.report_account_invoice_upd +msgid "Upd" +msgstr "Универсальный платежный документ (УПД)" diff --git a/l10n_ru_doc/models/__init__.py b/l10n_ru_doc/models/__init__.py new file mode 100644 index 0000000..d378530 --- /dev/null +++ b/l10n_ru_doc/models/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from . import res_partner +from . import res_company +from . import res_users +from . import res_bank +from . import account_invoice +from . import account_move_line +from . import sale +from . import uom +from . import tax +from . import product diff --git a/l10n_ru_doc/models/__pycache__/__init__.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d51288d82ed1d05c9883cd4053eb49107f2c530 GIT binary patch literal 471 zcmY+AOG*SW5QdX}zXlbI$r6%kM1#$7fcb|N-*Cry%W9MA)K7f&!-S9%0jRs{w$ zAzyue1-e7o&88u+KEB@`OG?NmhQBL;a0|!30u)hnBopP7q9@=9Pok&bDNmzk;2F=N z=ioWdqZi->FQS*=C5KIy#LpFbvXf>(`@pQS_DtzD3X_VB qmlsC3MJU^|$tpd1Cg90K5aN8^?W=2OE~CD|Vfa%(mvr?1KBm8l8*W7a literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/account_invoice.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/account_invoice.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9900076d9fec4f4bb4d321cce9f3b2b85cd313b9 GIT binary patch literal 5013 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/product.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/product.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e4d98f7de4e52d46e53bec8d3808afc7ce13f76 GIT binary patch literal 461 zcmYjNJ5R$f5VjpBgwpa@7?_xlGJs)3LZ}i06BQCnS*)n%s)Zy5C#h6cm>Cc(NJzlO zz{bpP@a&a|zrci@RM3;|@!g%jyR+y<`p%!$l78}+80-T}@$2cP~ z!RQbH0q+KZC&-z1?Zp)635xu0+lwM%g270nP?#W-Akw1m(zD`O(6w5uStC%40mTGx z>Wa9}Bozx@geW)K@F^y?)f6`eR+c>L-1t-}QYjnlmBi zd6EgvO^b88MU}d^&G}`Oq|-{sNBK~wQK^WfG4x=VC^LU9ftPOD8&V54Uz?v@Hk6rQ zr6@`!LCQ@K<2qmouykiT=c?i$`>eT`{Vh6C?kC;BMPN;cC|<;Mt{3@+I<9)WaxKO` aavxTg|A#kG+ttIp=9Ycz2p#h>S|z`dfOU%i literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/res_bank.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/res_bank.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d73d6d5733baa2accf4406d1fa3063ed831ce15c GIT binary patch literal 980 zcmZ`&TWb?R6rP!#-JQfFP2&YYP+tR@t*=s~7{Mot=-Yw}+nq_XaWCm?A~aMG+E@RB zKK3uot55j}76i|kZDSQXFdyGJJLfXroUOXuHi5PNay^~J&1gI(_eD57Xi z3L4Xb#jNmRkCN9!G3A{R%de%$knGGhH&Q)!L zqEb4qQ~Y*)ZR$P*uO=~7BxZ`np5`+jD=Pk##ewo6b71+)r2M!NM%SYQU>A4Cl>uX3 zl`1O_A17&AEz8Av4|1JT%j;~V_lKbsQkF@frL=7+p^;^dyd&k&GRZH$2$_{rZL)>& zAlmZrG%;4BkY7UDb7K17c5v}LnpTC57P?+Um8zr3T+bN}4N>!y%bLR*; zl-TZQer$Zmf(7aTKoCv`%=vB>W(N-5EQ}7n3FUvMDp27WIi+z+36QE~d+&7pHZhA* z8z)*HMVmJcC!WC$Oo$)=Y=|w&OrH%m5{G%mc<9 z^MM6NOcCgUg81e(L|Kk1+mOHKdrYt%b$*;dj+5fDH5G91t^Wr93O4}m;QumPvD=L73w#(i LH+RT@-3xvLOkm%p literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/res_company.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/res_company.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaaff1882e174ac5b2ee460aeaf614990d7d32ef GIT binary patch literal 1075 zcmZuw&2H2%5YGQ*ce}f7`MH67Ku9aWE+CG8+OB9%t&j?rTq2Wk*tCfqoP=t_5e{7X z4)n;0XW%t_<-{v+0LDpZ7YRoh&F8Vd8P8{n(P&`c`1XDkf3*$cy9VpSL9l~=aTg63 zV5UZ924-djmT4RqV1fP70GnAS_6Iv~z&SRi?hjmROfBWb2}_|+UM7I0MWmE*mIh7@6GE88W zaK4WR>`9i=l7aFiqab*?s@GSY=6O9?+a*qOQTH`xRWMm7cd<-ZTyGyRq@^j@jUrL; zlJc^iypRbm$v%yWBui3OKVK|abV|x)Qjl0kLID!~=4wGfL`;x67raPbr;Oy70ew;m z0wSt1#>--+MJY<8exsZvOY?fz<~c5Dme-H}pQ8zC`mPiIQYyFIJZ_nG`RZ)RB&&B` z@#wPTdnAd;N>tuisA1RnS-z6`MdC{}iaTh0!!gI! z*c_W1_<5#fdcQqO+kvH#We$EdJC3F?U0&4xrh2$HsP!CTJN@w`%l{5J~MSX Kop;l?Y5f7p9zl`- literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/res_partner.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/res_partner.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed7504ea182f9612bc05bdcec394bdde5101b1df GIT binary patch literal 767 zcmYjPJ#Q2-5ViN?vbVY092At$AzeWhdO!#Ygd#2{(k+E$-8i`o`-OKm(xu7=h$blz zv_L57B0(esQfMi?ty`-61uDjS0bP<%{Q^ z`4p>yL=;G50gY_oY`Vr8oI@+>w8(`HEFfBFkq6xtdBQnz!T(63F4lcmgx-b){X-fp zBGZEanSPrsVHUsu+qx4R@P^x;HPK zG_TZgv)3GqhD+LGEaRzQO#6)C#OuW5J;t8bJUM4P7H3l-<4RiSpq&R(F0~zJnYN!5 zg?931MUHVpX1crfw+Zc3vqI?3{W#-trn~EWQpRbV2+B2yy)EeEiGBOq!K2t(9gt9&u=31vH>O9pDXU r%a4XG_K4o?C!~!^?LIau*3$o*nP=Aw@7xzPZGj7B&dq@XKooOC3CA>ma2z3~4s@P;@!vvphv?wdK%yJ_NAtAxGuR&%N@I^AP zF=J&`0AqH@nCq#Qo{t#2tuy(PiJ2%@phcyLYs&WLN=e8{JNYMVdvj4{y0L@b-`d*mCE^nu9$ literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/sale.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/sale.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94725f82c54ced185eced3bf4bf3388c57208516 GIT binary patch literal 773 zcmZ`%J#Q015S_gb=Que6QXr?LGYB6vRFM^lA{C}^cg^a!S(6LvTeG`PgymG^hu9^5 zXBMke6UKYvobkOOch4wnVMhotx`Vyg2_!^~*b~+*Tt%3k!Y_zyg+r` zB}IjWe)Y1Ib}iA=MK4Ivky(8X*_p1E@3EQ=cqcEJ+ci|plrC@cHkiv@=b|Qy`V&NfZm1c?AJub4zY97a(t>T{$QNhMm z6m0Z2Y`v|Of5AeWO$2XXW@qM`{pKON-4+7*xt@(~;Qchgyx0&7K=V~F3^6QFf&-k8 zfMB$T7-7~GViqT-)}nK`A|IB$S)k&PEf nl^c4Fwhd3!KQkrTIWQNi;Qz+8*D<)eRWGxR4WVIPL`&os{h)U? literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/__pycache__/uom.cpython-310.pyc b/l10n_ru_doc/models/__pycache__/uom.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3399650bd7d8f335d48645b1f0ba063b8dbf64ac GIT binary patch literal 464 zcmYjNu};G<5VakrjY^A{7??UCGC*KpLkNihG0+9EWU->2s}_6Hv}BXPMvEfJXm|0W1%kqtrNO3SLOM zfJ_m7wu7!pWH6A~AW)#xI>^fc1Q7)B)@EO%xd7D;%8v(j;`3o@muY3Q3I>mGx=0JI m<-3MkouX-K*J9iwyR)MF-?&6|TlaR#AM8>qXqA`9GW`X)r+x|m literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/models/account_invoice.py b/l10n_ru_doc/models/account_invoice.py new file mode 100644 index 0000000..2120479 --- /dev/null +++ b/l10n_ru_doc/models/account_invoice.py @@ -0,0 +1,150 @@ +from datetime import datetime +from odoo import api, fields, models + +class AccountInvoice(models.Model): + _inherit = 'account.move' + kladov=fields.Many2one('res.users', string='Ответственный за передачу товаров/услуг') + gruzopol=fields.Many2one('res.partner', string='Грузополучатель') + gruzootpr=fields.Many2one('res.partner', string='Грузоотправитель') + transport=fields.Char('Данные о транспортировке и грузе') + osnovanie=fields.Char('Основание') + payment_text=fields.Char('Текст для платежек в УПД', compute='_compute_get_txtpayment') + payment_num=fields.Char('Номер платежки в УПД', compute='_compute_get_txtpayment') + payment_date = fields.Char('Дата платежки в УПД', compute='_compute_get_txtpayment') + only_service = fields.Boolean('Только услуги', compute='_compute_get_check_service') + + @api.depends('invoice_line_ids') + def _compute_get_check_service(self): + for s in self: + s.only_service = all((line.product_id.type=='service') for line in s.invoice_line_ids) + + def _compute_get_txtpayment(self): + for s in self: + payments = s._get_reconciled_payments() + payment_text = '' + + for payment in payments: + if payment.date: + payment_text += payment.name + ' от ' + \ + fields.Datetime.from_string(payment.date).strftime("%d.%m.%Y") + if payments[-1]!=payment: + payment_text += ', ' + if payments: + s.payment_num = payments[0].name + s.payment_date = fields.Datetime.from_string(payments[0].date).strftime("%d.%m.%Y") + else: + s.payment_num = '' + s.payment_text = '' + s.payment_date = '' + + s.payment_text = payment_text + + # def action_bill_sent(self): + # assert len(self) == 1, 'This option should only be used for a single id at a time.' + # template = self.env.ref('account.email_template_edi_invoice', False) + # compose_form = self.env.ref('mail.email_compose_message_wizard_form', False) + # ctx = { + # 'default_model': 'account.move', + # 'default_res_id': self.id, + # 'default_use_template': bool(template), + # 'default_template_id': template.id, + # 'default_composition_mode': 'comment', + # 'mark_invoice_as_sent': True, + # } + # return { + # 'name': 'Compose Email', + # 'type': 'ir.actions.act_window', + # 'view_type': 'form', + # 'view_mode': 'form', + # 'res_model': 'mail.compose.message', + # 'views': [(compose_form.id, 'form')], + # 'view_id': compose_form.id, + # 'target': 'new', + # 'context': ctx, + # } + + def bill_print(self): + assert len(self) == 1, 'This option should only be used for a single id at a time.' + return self.env['report'].get_action(self, 'l10n_ru_doc.report_upd') + + def get_delivery_doc_name(self): + for s in self: + if s: + pickings = [] + pickings_list = '0' + orders = self.env['sale.order'].sudo().search([('name','=',s.invoice_origin)]) if s.invoice_origin else [] + for o in orders: + if o.picking_ids: + for p in o.picking_ids: + pickings.append(p.name) + if len(pickings)>0: + pickings_list = ';'.join(pickings) + if pickings_list != '0': + return pickings_list + if s.name and s.name.find('/') > -1: + return 'УПД № ' + s.name[len(s.name) - 4:] + return 'УПД № ' + str(s.name) if s.name else '' + + + def get_delivery_doc_date(self): + for s in self: + if s: + delivery_dates = [] + pickings = [] + orders = self.env['sale.order'].sudo().search([('name', '=', s.invoice_origin)]) + for o in orders: + if o.picking_ids: + for p in o.picking_ids: + if p.date: + formatted_date = datetime.strftime(p.date, '%d.%m.%Y') + pickings.append(formatted_date) + if pickings and len(pickings)>0: + delivery_dates.append(';'.join(pickings)) + else: + if s.date: + delivery_dates.append(datetime.strftime(s.date, '%d.%m.%Y')) + return delivery_dates + + def get_function_partner(self, partner=False, type='director'): + if partner: + if partner.parent_id: + partner = partner.parent_id + director = self.env['res.partner'].search([('parent_id', '=', partner.id), + ('type', '=', type)], limit=1) + if director: + if director.function: + return director.function + return '' + + def get_name_partner(self, partner=False, type='director'): + if partner: + if partner.parent_id: + partner = partner.parent_id + director = self.env['res.partner'].search([('parent_id', '=', partner.id), + ('type', '=', type)], limit=1) + if director: + if director.name: + return director.name + return '' + + def get_facsimile_partner(self, partner=False, type='director'): + if partner: + if partner.parent_id: + partner = partner.parent_id + director = self.env['res.partner'].search([('parent_id', '=', partner.id), + ('type', '=', type)], + limit=1) + if director: + if director.facsimile: + return director.facsimile + return '' + + def get_stamp_partner(self, partner=False): + if partner: + if partner.parent_id: + partner = partner.parent_id + if partner.stamp: + return partner.stamp + return False + + diff --git a/l10n_ru_doc/models/account_move_line.py b/l10n_ru_doc/models/account_move_line.py new file mode 100644 index 0000000..06e0f5e --- /dev/null +++ b/l10n_ru_doc/models/account_move_line.py @@ -0,0 +1,29 @@ +from datetime import datetime +from odoo import api, fields, models + +class AccountMoveLine(models.Model): + _inherit = 'account.move.line' + + price_total_pf = fields.Monetary( + string='TotalPF', + compute='_compute_totals', + currency_field='currency_id', + ) + + @api.depends('quantity', 'discount', 'price_unit', 'tax_ids', 'currency_id') + def _compute_totals(self): + super(AccountMoveLine,self)._compute_totals() + for line in self: + line_discount_price_unit = line.price_unit * (1 - (line.discount / 100.0)) + if line.tax_ids.filtered(lambda tax: tax.invisiblePF == False): + taxes_res = line.tax_ids.filtered(lambda tax: tax.invisiblePF == False).compute_all( + line_discount_price_unit, + quantity=line.quantity, + currency=line.currency_id, + product=line.product_id, + partner=line.partner_id, + is_refund=line.is_refund, + ) + line.price_total_pf = taxes_res['total_included'] + else: + line.price_total_pf = line.price_total \ No newline at end of file diff --git a/l10n_ru_doc/models/product.py b/l10n_ru_doc/models/product.py new file mode 100644 index 0000000..c230841 --- /dev/null +++ b/l10n_ru_doc/models/product.py @@ -0,0 +1,5 @@ +from odoo import fields, models + +class ProductTnved(models.Model): + _inherit = 'product.product' + kod_tnved = fields.Char('Код ТНВЭД') diff --git a/l10n_ru_doc/models/res_bank.py b/l10n_ru_doc/models/res_bank.py new file mode 100644 index 0000000..f22d430 --- /dev/null +++ b/l10n_ru_doc/models/res_bank.py @@ -0,0 +1,19 @@ +from odoo import api, fields, models + +class Bank(models.Model): + _inherit = 'res.bank' + + corr_acc = fields.Char('Corresponding account', size=64) + + +class ResPartnerBank(models.Model): + _inherit = 'res.partner.bank' + + bank_corr_acc = fields.Char('Corresponding account', size=64) + + @api.onchange('bank_id') + def onchange_bank_id(self): + for s in self: + s.bank_name = s.bank_id.name + s.bank_bic = s.bank_id.bic + s.bank_corr_acc = s.bank_id.corr_acc diff --git a/l10n_ru_doc/models/res_company.py b/l10n_ru_doc/models/res_company.py new file mode 100644 index 0000000..9ca4ae7 --- /dev/null +++ b/l10n_ru_doc/models/res_company.py @@ -0,0 +1,18 @@ +from odoo import fields, models + +class Company(models.Model): + _inherit = 'res.company' + + inn = fields.Char(related='partner_id.inn', readonly=False) + kpp = fields.Char(related='partner_id.kpp', readonly=False) + okpo = fields.Char(related='partner_id.okpo', readonly=False) + chief_id = fields.Many2one('res.users', 'Chief') + accountant_id = fields.Many2one('res.users', 'General Accountant') + print_facsimile = fields.Boolean(string='Print Facsimile', + help="Check this for adding Facsimiles of responsible persons to documents.") + print_stamp = fields.Boolean(string='Print Stamp', + help="Check this for adding Stamp of company to documents.") + stamp = fields.Binary("Stamp") + print_anywhere = fields.Boolean(string='Print Anywhere', + help="Uncheck this, if you want add Facsimile and Stamp only in email.", + default=True) diff --git a/l10n_ru_doc/models/res_partner.py b/l10n_ru_doc/models/res_partner.py new file mode 100644 index 0000000..e918a39 --- /dev/null +++ b/l10n_ru_doc/models/res_partner.py @@ -0,0 +1,11 @@ +from odoo import fields, models +class ResPartner(models.Model): + _inherit = 'res.partner' + + inn = fields.Char('INN', related='vat') + kpp = fields.Char('KPP', size=9) + okpo = fields.Char('OKPO', size=14) + ogrn = fields.Char('ОГРН') + type = fields.Selection(selection_add=[('director', 'Директор'), ('accountant', 'Бухгалтер')]) + facsimile = fields.Binary("Подпись") + stamp = fields.Binary("Печать") diff --git a/l10n_ru_doc/models/res_users.py b/l10n_ru_doc/models/res_users.py new file mode 100644 index 0000000..aaf70cb --- /dev/null +++ b/l10n_ru_doc/models/res_users.py @@ -0,0 +1,7 @@ +from odoo import fields, models + +class Users(models.Model): + _inherit = 'res.users' + + print_facsimile = fields.Boolean(related='company_id.print_facsimile') + facsimile = fields.Binary() diff --git a/l10n_ru_doc/models/sale.py b/l10n_ru_doc/models/sale.py new file mode 100644 index 0000000..54707e2 --- /dev/null +++ b/l10n_ru_doc/models/sale.py @@ -0,0 +1,8 @@ +from odoo import models + +class SaleOrder(models.Model): + _inherit = 'sale.order' + def print_quotation(self): + self.filtered(lambda s: s.state == 'draft').write({'state': 'sent'}) + return self.env['report'].get_action(self, 'l10n_ru_doc.report_order') + diff --git a/l10n_ru_doc/models/tax.py b/l10n_ru_doc/models/tax.py new file mode 100644 index 0000000..081adb1 --- /dev/null +++ b/l10n_ru_doc/models/tax.py @@ -0,0 +1,6 @@ +from odoo import fields, models + +class TaxInherit(models.Model): + _inherit = 'account.tax' + + invisiblePF = fields.Boolean('Не видно в ПФ') diff --git a/l10n_ru_doc/models/uom.py b/l10n_ru_doc/models/uom.py new file mode 100644 index 0000000..1de1e3b --- /dev/null +++ b/l10n_ru_doc/models/uom.py @@ -0,0 +1,4 @@ +from odoo import fields, models +class UomInherit(models.Model): + _inherit = 'uom.uom' + kod = fields.Char('Код единицы измерения') diff --git a/l10n_ru_doc/report/__init__.py b/l10n_ru_doc/report/__init__.py new file mode 100644 index 0000000..b058f02 --- /dev/null +++ b/l10n_ru_doc/report/__init__.py @@ -0,0 +1,5 @@ +from . import report_order +from . import report_invoice +from . import report_bill +from . import report_act +from . import report_upd diff --git a/l10n_ru_doc/report/__pycache__/__init__.cpython-310.pyc b/l10n_ru_doc/report/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af59652add5da1dea3b73abfc29e1364574d9fd4 GIT binary patch literal 325 zcmYk2y-ve05XbF&wJHhXH8K>pYgHkhfQ8MARdTMdhF8kU#49jy7c%rL z|NZ;j;4iGIji9PNuIEo$zgcc8A$g`baDV{mMJu(G%n5O#lbKWERHrj%#F@@!&WUrK z6Bny!t3}6HK{o<~>pld93?v~D*^PY6G=&6Y}HumsR7n2Bl&5&|r z963ip@g>5VndA4M-m$eR+94_g#4Xs%4C(~R?{}REqXBHx|5?fy*SToSV}G62#};Aq Q_K6=b@Sl~Ulsq2fA2at(Hvj+t literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/report/__pycache__/report_act.cpython-310.pyc b/l10n_ru_doc/report/__pycache__/report_act.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8bc325c14ee776823e19c5a28081a8232c440c0 GIT binary patch literal 758 zcmZuvy^ho{5cXff-jaob0tqB2kSJ1+aQzA0i2@o{;wX^PSlNt^W0k~>1Da8(Yt2Q-bp8mHg5vtA500CN) zh8C0t%xc!~f>ZLG00(hJKq$Htm%NA|dQH;!C!QfG^>L#?)fUn8)f=^Vq3V?~Rd9}l zrUA{%xV)f`&2MN z8IJh(=E10k*}sQUI!_}%k+LltC8eLrz^|(VPNaO_mG#aO^&#dK7U&6#%zoGlJ&#ds zFcTu^4c70?@gYSZXc#*DqX4rKK)3dPZ#lGl=;Z8pVVyz7FT=m;vyG~TE}BrwaFW1HD*N>HvoU7UQUg!~ALu?SooqPh$X5TKgW zw4gL#rdiDkPRUCG9K;m?q3BXv@*;xhElJ~_c!s3Z$F%{a9ir)*cWUuU>6NloaE^uJ z;tSgnk0H+OA6XZrD@M%qq-sj^{9E--3d zg~Wd)@QF}gpt}2Lwq%K{Zj&!`OTW^Oyk(bU%aX6@sJH6NU^;SQc-Bszps`ozZ=7ETH%+tNpPE|bt#WN{z?g@i);-8e$VV*mf#q)M$!4nye^b6!t=x5BUFuG`JxuEoH2YLA zK^czt_vYTXjoH7aQaVo~KasL2YbB+h%D}MG0Vh(PcctEWqCUhPV1=H-$n1x`(Dk4$ zMl&ITUT6K@93N8zik6|nKL{`@0Zilm_nbr1hhEN(7Ou5r)xHjYtIsy78v1BMX+L=~ Q-1!;)?xB7{5_*gM0lsX-B>(^b literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/report/__pycache__/report_invoice.cpython-310.pyc b/l10n_ru_doc/report/__pycache__/report_invoice.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7818d1abcda6d713add4a7268a301e52cb0eaafb GIT binary patch literal 774 zcmZuvv5wR*5cR}PZdvVecN9p_aT3KAB+w(Yhyo~BiK9SDV`VcwZdXaX*h$c>mWJaS zs3@T1kC0m`egRQ1PWGe-7;DDQp7D&|*m^o0Gm=jqF3!FKV?X?2D1sJqQX7*&hET8) zQUH&GA}D#vfjwo&QG8@56s*N1PeTk}v03z!&afG{sMM$mOKAM^wOT$?#YUOjJBPw) zF(#42#HVKD1fUC>v2`J0Wuf zA`lSJh<FDG;~^vY{_*_u2Qco;opLg|&Vv*7Ft zr^O+uyGur~3XoL^Ld7wS>7f#sgtUJDxIL-0dSy}BW3@82+1#^nF7%VfOKDq)W>$1t z(uAnLQAR zfP_Z&XY=4nFN>>3bC~3*A4s{Z7fMP$l!0ff10G5FzOD7nlg1FcPh}#Jp4kg~q4PoG zZ3axh4TyUadR7sL+JwCRVSq)AXqN7OZ`!rK>*)B|)HSxAH7~<2i`jZrLpNHV%6uFWV<%(D@2c$bedZqNU0Tkh;%b zs?k%GO_fQ}*(4~)C12eFL6MkB5_^)y41!}q8guDESl@0PS1+dWSWUGl=eLbJ!|eXO zT$oBoorbkZR8u)jG3+nG{#w9~fme3`7Gw-v?vYP)K|j-Xtn@C(f{mG^3nsmf{Ddso za2_OSs;j&VCwis^-1=v(1KWmN;(v!7{iB4qmA2 z)cSA@zvMD06SD>WB{A3F_4}O;Rg{sIS|3O?b3&BJsL^CpH@QBr*Km4ncf>1I zigo|9B&$@>hN!CmV4HG}QxAUrk9of_!|?BqmUOsm*^Ur-GEqX|>_P(9Km)F$4d;!#@&P)8)63M^Qc(XO9MTc6!7ag-gGPngR2pXzlx?C0Q3E3;tjJgH}UEo!tXdva>4e&aRr@y1k{Fuw&l1>b%(WZ0pxmKbqd7QBj&CEuZ0E$PLbg+?3gN4(lB~q>!fQ00cCkJKk>hC;2P* A0RR91 literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/report/l10n_ru_doc_report.xml b/l10n_ru_doc/report/l10n_ru_doc_report.xml new file mode 100644 index 0000000..328441b --- /dev/null +++ b/l10n_ru_doc/report/l10n_ru_doc_report.xml @@ -0,0 +1,107 @@ + + + + + A4 + + A4 + 0 + 0 + Portrait + 7 + 7 + 7 + 7 + + 35 + 75 + + + A4 Landscape + + A4 + 0 + 0 + Landscape + 7 + 7 + 7 + 7 + + 75 + 60 + + + + Счет по форме 1С + sale.order + qweb-pdf + l10n_ru_doc.report_order + l10n_ru_doc.report_order + 'Счет - %s ' % (object.name+' '+(object.partner_id.parent_id.name if object.partner_id.parent_id else object.partner_id.name)) + + + report + + + + Счет-фактура + account.move + qweb-pdf + l10n_ru_doc.report_invoice + l10n_ru_doc.report_invoice + 'Счет-фактура - %s ' % (object.name+' '+(object.partner_id.parent_id.name if object.partner_id.parent_id else object.partner_id.name)) + + + report + + + + Товарная накладная (ТОРГ-12) + account.move + qweb-pdf + l10n_ru_doc.report_bill + l10n_ru_doc.report_bill + 'Товарная накладная - %s ' % (object.name+' '+(object.partner_id.parent_id.name if object.partner_id.parent_id else object.partner_id.name)) + + + report + + + + Акт выполненных работ + account.move + qweb-pdf + l10n_ru_doc.report_act + l10n_ru_doc.report_act + 'Акт - %s ' % (object.name+' '+(object.partner_id.parent_id.name if object.partner_id.parent_id else object.partner_id.name)) + + + report + + + + Универсальный передаточный документ(УПД) + account.move + qweb-pdf + l10n_ru_doc.report_upd + l10n_ru_doc.report_upd + 'УПД' + + + report + + + + УПД без печатей + account.move + qweb-pdf + l10n_ru_doc.report_updn + l10n_ru_doc.report_updn + 'УПД без печатей' + + + report + + + diff --git a/l10n_ru_doc/report/report_act.py b/l10n_ru_doc/report/report_act.py new file mode 100644 index 0000000..133336e --- /dev/null +++ b/l10n_ru_doc/report/report_act.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from odoo import models +from odoo.addons.l10n_ru_doc.report_helper import QWebHelper + +class RuActReport(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_act' + + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs + } diff --git a/l10n_ru_doc/report/report_act.xml b/l10n_ru_doc/report/report_act.xml new file mode 100644 index 0000000..4af4ce3 --- /dev/null +++ b/l10n_ru_doc/report/report_act.xml @@ -0,0 +1,203 @@ + + + + + + diff --git a/l10n_ru_doc/report/report_bill.py b/l10n_ru_doc/report/report_bill.py new file mode 100644 index 0000000..400d3ad --- /dev/null +++ b/l10n_ru_doc/report/report_bill.py @@ -0,0 +1,14 @@ +from odoo import models +from odoo.addons.l10n_ru_doc.report_helper import QWebHelper + +class RuBillReport(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_bill' + + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs + } diff --git a/l10n_ru_doc/report/report_bill.xml b/l10n_ru_doc/report/report_bill.xml new file mode 100644 index 0000000..c7f5568 --- /dev/null +++ b/l10n_ru_doc/report/report_bill.xml @@ -0,0 +1,758 @@ + + + + + + diff --git a/l10n_ru_doc/report/report_invoice.py b/l10n_ru_doc/report/report_invoice.py new file mode 100644 index 0000000..a71c09a --- /dev/null +++ b/l10n_ru_doc/report/report_invoice.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from odoo import models +from odoo.addons.l10n_ru_doc.report_helper import QWebHelper +class RuInvoiceReport(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_invoice' + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs + } diff --git a/l10n_ru_doc/report/report_invoice.xml b/l10n_ru_doc/report/report_invoice.xml new file mode 100644 index 0000000..78b8b21 --- /dev/null +++ b/l10n_ru_doc/report/report_invoice.xml @@ -0,0 +1,329 @@ + + + + + + diff --git a/l10n_ru_doc/report/report_order.py b/l10n_ru_doc/report/report_order.py new file mode 100644 index 0000000..eb94aca --- /dev/null +++ b/l10n_ru_doc/report/report_order.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from odoo import models +from odoo.addons.l10n_ru_doc.report_helper import QWebHelper +class RuSaleOrderReport(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_order' + def _get_report_values(self, docids, data=None): + docs = self.env['sale.order'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'sale.order', + 'docs': docs + } diff --git a/l10n_ru_doc/report/report_order.xml b/l10n_ru_doc/report/report_order.xml new file mode 100644 index 0000000..f9d2127 --- /dev/null +++ b/l10n_ru_doc/report/report_order.xml @@ -0,0 +1,330 @@ + + + + + + diff --git a/l10n_ru_doc/report/report_upd.py b/l10n_ru_doc/report/report_upd.py new file mode 100644 index 0000000..1537ba8 --- /dev/null +++ b/l10n_ru_doc/report/report_upd.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from odoo import models +from odoo.addons.l10n_ru_doc.report_helper import QWebHelper + +class RuUpdReport(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_upd' + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs + } +class RuUpdReportn(models.AbstractModel): + _name = 'report.l10n_ru_doc.report_updn' + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + return { + 'helper': QWebHelper(), + 'doc_ids': docs.ids, + 'doc_model': 'account.move', + 'docs': docs + } diff --git a/l10n_ru_doc/report/report_upd.xml b/l10n_ru_doc/report/report_upd.xml new file mode 100644 index 0000000..1825c87 --- /dev/null +++ b/l10n_ru_doc/report/report_upd.xml @@ -0,0 +1,1108 @@ + + + + + + diff --git a/l10n_ru_doc/report/report_updn.xml b/l10n_ru_doc/report/report_updn.xml new file mode 100644 index 0000000..b3013c4 --- /dev/null +++ b/l10n_ru_doc/report/report_updn.xml @@ -0,0 +1,1177 @@ + + + + + + diff --git a/l10n_ru_doc/report_helper.py b/l10n_ru_doc/report_helper.py new file mode 100644 index 0000000..f87c4cc --- /dev/null +++ b/l10n_ru_doc/report_helper.py @@ -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 = ""%( + 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.bank_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) diff --git a/l10n_ru_doc/static/description/docs.png b/l10n_ru_doc/static/description/docs.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc91a81c1e5583ece913c89fa54443514169dfc GIT binary patch literal 16383 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 nMS(3-fsB#$P4+IZxfe>7RySo$Ioe(^@U*6sC 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 +
+

Первичные документы РФ

+
+

+Модуль для печати первичных документов в соответствии с законами РФ. +

+

+Возможности: +

    +
  • Товарная накладная (ТОРГ-12)
  • +
  • Счет на оплату
  • +
  • Счет-фактура
  • +
  • Акт выполненных работ
  • +
  • Вывод подписей и печати
  • +
+

+
+
+
+ +
+
+
+ + +
+ +
\ No newline at end of file diff --git a/l10n_ru_doc/static/description/support.png b/l10n_ru_doc/static/description/support.png new file mode 100644 index 0000000000000000000000000000000000000000..2805ec72a4dd9e7262b4c5b745e8228e2a46302e GIT binary patch literal 20040 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 literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/static/description/waybill.png b/l10n_ru_doc/static/description/waybill.png new file mode 100644 index 0000000000000000000000000000000000000000..8bab6182bcfeca85cdef52e55fe7dd685dfd0b24 GIT binary patch literal 16671 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 z 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 I!X)_r0fw&s6951J literal 0 HcmV?d00001 diff --git a/l10n_ru_doc/static/src/css/l10n_ru_doc.css b/l10n_ru_doc/static/src/css/l10n_ru_doc.css new file mode 100644 index 0000000..d77b69a --- /dev/null +++ b/l10n_ru_doc/static/src/css/l10n_ru_doc.css @@ -0,0 +1,7 @@ +@charset "utf-8"; +.openerp .codup_sign > img { + width: 235px; + height: 65px; + max-width: 235px; + max-height: 65px; +} \ No newline at end of file diff --git a/l10n_ru_doc/views/account_invoice_view.xml b/l10n_ru_doc/views/account_invoice_view.xml new file mode 100644 index 0000000..891dcc1 --- /dev/null +++ b/l10n_ru_doc/views/account_invoice_view.xml @@ -0,0 +1,36 @@ + + + + + + account.invoice.ru.form + account.move + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_ru_doc/views/l10n_ru_doc_data.xml b/l10n_ru_doc/views/l10n_ru_doc_data.xml new file mode 100644 index 0000000..169bcd7 --- /dev/null +++ b/l10n_ru_doc/views/l10n_ru_doc_data.xml @@ -0,0 +1,14 @@ + + + + + + + 1 + + + + + + + diff --git a/l10n_ru_doc/views/product.xml b/l10n_ru_doc/views/product.xml new file mode 100644 index 0000000..7fea41d --- /dev/null +++ b/l10n_ru_doc/views/product.xml @@ -0,0 +1,16 @@ + + + + + tnved_product + product.product + + + + + + + + + + diff --git a/l10n_ru_doc/views/res_bank_view.xml b/l10n_ru_doc/views/res_bank_view.xml new file mode 100644 index 0000000..7468aac --- /dev/null +++ b/l10n_ru_doc/views/res_bank_view.xml @@ -0,0 +1,18 @@ + + + + + + res.bank.ru.form + res.bank + form + + + + + + + + + + diff --git a/l10n_ru_doc/views/res_company_view.xml b/l10n_ru_doc/views/res_company_view.xml new file mode 100644 index 0000000..bb56f29 --- /dev/null +++ b/l10n_ru_doc/views/res_company_view.xml @@ -0,0 +1,42 @@ + + + + + + res.companyruform + res.company + + + + + + + + + + ИНН + + + ОГРН + + + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_ru_doc/views/res_partner_view.xml b/l10n_ru_doc/views/res_partner_view.xml new file mode 100644 index 0000000..262dd15 --- /dev/null +++ b/l10n_ru_doc/views/res_partner_view.xml @@ -0,0 +1,36 @@ + + + + + + res.partner.ru.form + res.partner + + + + + + + + + + ИНН + + + + + + + + + + + + + + + + + + + diff --git a/l10n_ru_doc/views/res_users_view.xml b/l10n_ru_doc/views/res_users_view.xml new file mode 100644 index 0000000..e7ae0cf --- /dev/null +++ b/l10n_ru_doc/views/res_users_view.xml @@ -0,0 +1,33 @@ + + + + + + res.users.signature.form + res.users + + + + + + + + + + + + res.users.simple.form + res.users + + + + + + + + + + + + + diff --git a/l10n_ru_doc/views/tax.xml b/l10n_ru_doc/views/tax.xml new file mode 100644 index 0000000..3cefac6 --- /dev/null +++ b/l10n_ru_doc/views/tax.xml @@ -0,0 +1,17 @@ + + + + + view_taxiher_form + account.tax + + + + + + + + + + + diff --git a/l10n_ru_doc/views/uom.xml b/l10n_ru_doc/views/uom.xml new file mode 100644 index 0000000..76173dc --- /dev/null +++ b/l10n_ru_doc/views/uom.xml @@ -0,0 +1,28 @@ + + + + + view_uomiher_form + uom.uom + + + + + + + + + + view_uomiher_tree + uom.category + + + + + + + + + + + diff --git a/l10n_ru_upd_xml/README.md b/l10n_ru_upd_xml/README.md new file mode 100644 index 0000000..4f5cc45 --- /dev/null +++ b/l10n_ru_upd_xml/README.md @@ -0,0 +1,9 @@ +# Российская локализация - УПД в xml-формате +name: l10n_ru_upd_xml + +## Описание +Формирует универсальный передаточный документ в формате XML. + +###Для печати: +1. Меню Бухгалтерия - Клиенты - Счета (account.move); +2. Кнопка "Печать УПД в xml-формате". diff --git a/l10n_ru_upd_xml/__init__.py b/l10n_ru_upd_xml/__init__.py new file mode 100644 index 0000000..9a4992b --- /dev/null +++ b/l10n_ru_upd_xml/__init__.py @@ -0,0 +1,3 @@ +from . import controllers +from . import models +from . import reports diff --git a/l10n_ru_upd_xml/__manifest__.py b/l10n_ru_upd_xml/__manifest__.py new file mode 100644 index 0000000..19c9568 --- /dev/null +++ b/l10n_ru_upd_xml/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Российская локализация - УПД в xml-формате", + + 'summary': """ + Формирует УПД в формате XML, формат 5.01""", + + 'description': """ + Формирует УПД в формате XML. + + Для печати: + 1. Меню Бухгалтерия - Клиенты - Счета (account.move); + 2. Кнопка "Печать УПД в xml-формате". + """, + + 'author': "MK.Lab", + 'website': "https://www.inf-centre.ru/", + + 'category': 'Uncategorized', + 'version': '0.1', + "depends": ["web", "base", "account", "l10n_ru_doc", 'l10n_ru_base'], + "data": [ + #"views/webclient_templates.xml", + "views/ir_actions_report_view.xml", + "views/res_partner_view.xml", + "views/res_company_view.xml", + "views/res_users_view.xml", + "views/views_uom_okei.xml", + "views/view_account_move.xml", + "reports/upd_report.xml", + "reports/report.xml", + ], + + "assets": { + "web.assets_backend": [ + "l10n_ru_upd_xml/static/src/js/report/action_manager_report.js", + ], + }, + + "external_dependencies": { + "python": [ + "lxml" + ] + }, +} diff --git a/l10n_ru_upd_xml/controllers/__init__.py b/l10n_ru_upd_xml/controllers/__init__.py new file mode 100644 index 0000000..65a8c12 --- /dev/null +++ b/l10n_ru_upd_xml/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import main diff --git a/l10n_ru_upd_xml/controllers/main.py b/l10n_ru_upd_xml/controllers/main.py new file mode 100644 index 0000000..d5e9a65 --- /dev/null +++ b/l10n_ru_upd_xml/controllers/main.py @@ -0,0 +1,91 @@ +# Copyright (C) 2014-2015 Grupo ESOC +# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). + +import json +import logging + +from werkzeug.urls import url_parse + +from odoo.http import content_disposition, request, route, serialize_exception +from odoo.tools import html_escape +from odoo.tools.safe_eval import safe_eval, time + +from odoo.addons.web.controllers import report + +_logger = logging.getLogger(__name__) + + +class ReportController(report.ReportController): + @route() + def report_routes( + self, reportname, docids=None, converter=None, options=None, **kwargs + ): + if converter != "xml": + return super().report_routes( + reportname, + docids=docids, + converter=converter, + options=options, + **kwargs, + ) + if docids: + docids = [int(_id) for _id in docids.split(",")] + data = {**json.loads(options or "{}"), **kwargs} + context = dict(request.env.context) + if "context" in data: + data["context"] = json.loads(data["context"] or "{}") + # Ignore 'lang' here, because the context in data is the one from the + # webclient *but* if the user explicitely wants to change the lang, this + # mechanism overwrites it. + if "lang" in data["context"]: + del data["context"]["lang"] + context.update(data["context"]) + report_Obj = request.env["ir.actions.report"] + xml = report_Obj.with_context(**context)._render_qweb_xml( + reportname, docids, data=data + )[0] + xmlhttpheaders = [("Content-Type", "text/xml"), ("Content-Length", len(xml))] + return request.make_response(xml, headers=xmlhttpheaders) + + @route() + def report_download(self, data, context=None, token=None): + requestcontent = json.loads(data) + url, report_type = requestcontent[0], requestcontent[1] + reportname = "???" + if report_type != "qweb-xml": + return super().report_download(data, context=context, token=token) + try: + reportname = url.split("/report/xml/")[1].split("?")[0] + docids = None + if "/" in reportname: + reportname, docids = reportname.split("/") + report = request.env["ir.actions.report"]._get_report_from_name(reportname) + filename = None + if docids: + response = self.report_routes( + reportname, docids=docids, converter="xml", context=context + ) + ids = [int(x) for x in docids.split(",")] + obj = request.env[report.model].browse(ids) + if report.print_report_name and not len(obj) > 1: + report_name = safe_eval( + report.print_report_name, {"object": obj, "time": time} + ) + filename = f"{report_name}.{report.xml_extension}" + else: + data = url_parse(url).decode_query(cls=dict) + if "context" in data: + context = json.loads(context or "{}") + data_context = json.loads(data.pop("context")) + context = json.dumps({**context, **data_context}) + response = self.report_routes( + reportname, converter="xml", context=context, **data + ) + filename = filename or f"{report.name}.{report.xml_extension}" + response.headers.add("Content-Disposition", content_disposition(filename)) + return response + except Exception as e: + _logger.exception(f"Error while generating report {reportname}") + se = serialize_exception(e) + error = {"code": 200, "message": "Odoo Server Error", "data": se} + return request.make_response(html_escape(json.dumps(error))) diff --git a/l10n_ru_upd_xml/demo/demo.xml b/l10n_ru_upd_xml/demo/demo.xml new file mode 100644 index 0000000..b5678e1 --- /dev/null +++ b/l10n_ru_upd_xml/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/l10n_ru_upd_xml/models/__init__.py b/l10n_ru_upd_xml/models/__init__.py new file mode 100644 index 0000000..b1c835f --- /dev/null +++ b/l10n_ru_upd_xml/models/__init__.py @@ -0,0 +1,7 @@ +from . import ir_actions_report +from . import res_company +from . import res_partner +from . import res_users +from . import uom_uom +from . import account_move +from . import account_move_line diff --git a/l10n_ru_upd_xml/models/account_move.py b/l10n_ru_upd_xml/models/account_move.py new file mode 100644 index 0000000..ae8f73d --- /dev/null +++ b/l10n_ru_upd_xml/models/account_move.py @@ -0,0 +1,210 @@ +from odoo import api, fields, models, _ +import hashlib +from odoo.exceptions import UserError + + +class AccountMove(models.Model): + _inherit = 'account.move' + + edi = fields.Char(string=_('ID EDI'), compute='_compute_sh1_edi') + kpp = fields.Char(string=_('КПП'), compute='_compute_get_kpp') + + def _compute_get_kpp(self): + for s in self: + pid = self.partner_id.parent_id or self.partner_id + + s.kpp = pid.kpp if (s.partner_id == s.partner_shipping_id or not s.partner_shipping_id) else s.partner_shipping_id.kpp + + @api.depends('name') + def _compute_sh1_edi(self): + for record in self: + name_value = record.name if isinstance(record.name, str) else '' + hash_object = hashlib.sha1(name_value.encode('utf-8')) + # hash_object = hashlib.sha1((self.name).encode('utf-8')) + pid = record.partner_id.parent_id or record.partner_id + record.edi = 'ON_NSCHFDOPPR_2BM-' + str(pid.edi) + '_' + str(record.company_id.edi) + '_' + hash_object.hexdigest() + + def print_upd(self): + for s in self: + mes = str(s.check_correct_upd()).strip() + if mes != "": + raise UserError(_(u"Не удалось сформировать УПД. Выявлены следующие ошибки:\n{}".format(mes))) + else: + return self.env.ref('l10n_ru_upd_xml.upd_xml_report').sudo().report_action(s.id) # render_qweb_xml(s.id) + + def check_correct_upd(self, manually=True): + for s in self: + mes = "" + company = s.company_id + if s.name == '/': + mes += u"Отсутствует наименование документа. Проверидите документ, чтобы назваие сформировалось автоматически.\n" + if not s.only_service and s.get_delivery_doc_name() == '0': + mes += u"Отсутствуют связанные отгрузки.\n" + if not company: + company = self.env.company + if not company: + mes += u"Не указана компания.\n" + else: + if not company.edi: + mes += u"Не указан идентификатор компании для Diadoc.\n" + if not company.name: + mes += u"Не указано наименование компании.\n" + if not company.okpo: + mes += u"Не указано ОКПО компании.\n" + if not company.inn: + mes += u"Не указан ИНН компании.\n" + else: + if len(company.inn) == 12: + if not company.partner_id.last_name_IP: + mes += u"Не указана фамилия ИП для вашей компании.\n" + if not company.partner_id.first_name_IP: + mes += u"Не указано имя ИП для вашей компании.\n" + if not company.partner_id.middle_name_IP: + mes += u"Не указано отчество ИП для вашей компании.\n" + elif len(company.inn) == 10: + if not company.kpp: + mes += u"Не указан КПП компании.\n" + else: + mes += u"Некорректный ИНН компании.\n" + if not company.city: + mes += u"Не указан город компании.\n" + if not company.street: + mes += u"Не указан адрес компании.\n" + if not company.chief_id: + mes += u"Не указан руководитель компании.\n" + else: + if not company.chief_id.function: + mes += u"Не указана должность руководителя компании.\n" + if not company.chief_id.last_name: + mes += u"Не указана фамилия руководителя компании.\n" + if not company.chief_id.first_name: + mes += u"Не указано имя руководителя компании.\n" + if not company.chief_id.second_name: + mes += u"Не указано отчество руководителя компании.\n" + pid = s.partner_id.parent_id + if not pid: + pid = s.partner_id + if not pid: + mes += u"Не указан контрагент.\n" + else: + if not pid.edi: + mes += u"Не указан идентификатор контрагента для Diadoc.\n" + if not pid.name: + mes += u"Не указано наименование контрагента.\n" + if not pid.okpo: + mes += u"Не указано ОКПО контрагента.\n" + if not pid.inn: + mes += u"Не указан ИНН контрагента.\n" + else: + if len(pid.inn) == 12: + if not pid.last_name_IP: + mes += u"Не указана фамилия ИП для контрагента.\n" + if not pid.first_name_IP: + mes += u"Не указано имя ИП для контрагента.\n" + if not pid.middle_name_IP: + mes += u"Не указано отчество ИП для контрагента.\n" + elif len(pid.inn) == 10: + if not pid.kpp: + mes += u"Не указан КПП контрагента.\n" + else: + mes += u"Некорректный ИНН контрагента.\n" + if not pid.city: + mes += u"Не указан город контрагента.\n" + if not pid.street: + mes += u"Не указан адрес контрагента.\n" + if manually: + if not s.edi: + mes += u"Не указан идентификатор документа для Diadoc.\n" + if not s.name: + mes += u"Не указано наименование документа\n" + if not s.invoice_date: + mes += u"Не указана дата документа\n" + if not s.only_service: + gruzootpr = s.gruzootpr + if not gruzootpr: + gruzootpr = pid + if gruzootpr.parent_id: + gruzootpr = gruzootpr.parent_id + if not gruzootpr: + mes += u"Не указан грузоотправитель.\n" + else: + if not gruzootpr.name: + mes += u"Не указано наименование грузоотправителя.\n" + if not gruzootpr.okpo: + mes += u"Не указано ОКПО грузоотправителя.\n" + if not gruzootpr.inn: + mes += u"Не указан ИНН грузоотправителя.\n" + else: + if len(gruzootpr.inn) == 12: + if not gruzootpr.last_name_IP: + mes += u"Не указана фамилия ИП для грузоотправителя.\n" + if not gruzootpr.first_name_IP: + mes += u"Не указано имя ИП для грузоотправителя.\n" + if not gruzootpr.middle_name_IP: + mes += u"Не указано отчество ИП для грузоотправителя.\n" + elif len(gruzootpr.inn) == 10: + if not gruzootpr.kpp: + mes += u"Не указан КПП грузоотправителя.\n" + else: + mes += u"Некорректный ИНН грузоотправителя.\n" + if not gruzootpr.city: + mes += u"Не указан город грузоотправителя.\n" + if not gruzootpr.street: + mes += u"Не указан адрес грузоотправителя.\n" + gruzopol = s.gruzopol + if not gruzopol: + gruzopol = pid + if gruzopol.parent_id: + gruzopol = gruzopol.parent_id + if not gruzopol: + mes += u"Не указан грузополучатель.\n" + else: + if not gruzopol.name: + mes += u"Не указано наименование грузополучателя.\n" + if not gruzopol.okpo: + mes += u"Не указано ОКПО грузополучателя.\n" + if not gruzopol.inn: + mes += u"Не указан ИНН грузополучателя.\n" + else: + if len(gruzopol.inn) == 12: + if not gruzopol.last_name_IP: + mes += u"Не указана фамилия ИП для грузополучателя.\n" + if not gruzopol.first_name_IP: + mes += u"Не указано имя ИП для грузополучателя.\n" + if not gruzopol.middle_name_IP: + mes += u"Не указано отчество ИП для грузополучателя.\n" + elif len(gruzopol.inn) == 10: + if not gruzopol.kpp: + mes += u"Не указан КПП грузополучателя.\n" + else: + mes += u"Некорректный ИНН грузополучателя.\n" + if not gruzopol.city: + mes += u"Не указан город грузополучателя.\n" + if not gruzopol.street: + mes += u"Не указан адрес грузополучателя.\n" + if s.payment_num: + if not s.payment_date: + mes += u"Не указана дата платежки в УПД.\n" + if not s.invoice_line_ids: + mes += u"Отсутствуют строки заказа.\n" + else: + for line in s.invoice_line_ids: + if not line.price_unit: + mes += u"Не указана цена за единицу для товара {}.\n".format(line.name) + if not line.quantity: + mes += u"Не указано количество для товара {}.\n".format(line.name) + if not line.product_uom_id.okei: + mes += u"Не указан код ОКЕИ для единицы измерения {}.\n".format(line.product_uom_id.name) + if not s.mt_contract_id: + mes += u"Не указан договор.\n" + else: + if not s.mt_contract_id.name: + mes += u"Не указано наименование договора.\n" + if not s.mt_contract_id.date_start: + mes += u"Не указана дата договора.\n" + if not s.kladov: + mes += u"Не указано лицо, ответственное за передачу товаров/услуг.\n" + else: + if not s.kladov.partner_id.function: + mes += u"Не указана должность лица, ответственного за передачу товаров/услуг.\n" + return str(mes) diff --git a/l10n_ru_upd_xml/models/account_move_line.py b/l10n_ru_upd_xml/models/account_move_line.py new file mode 100644 index 0000000..ae892d1 --- /dev/null +++ b/l10n_ru_upd_xml/models/account_move_line.py @@ -0,0 +1,7 @@ +from odoo import models, fields, api, _ + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + uom_okei = fields.Char(string=_('Код ОКЕИ'), related='product_uom_id.okei') diff --git a/l10n_ru_upd_xml/models/ir_actions_report.py b/l10n_ru_upd_xml/models/ir_actions_report.py new file mode 100644 index 0000000..8cb9538 --- /dev/null +++ b/l10n_ru_upd_xml/models/ir_actions_report.py @@ -0,0 +1,62 @@ +from odoo import fields, models, api + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + report_type = fields.Selection( + selection_add=[("qweb-xml", "XML")], ondelete={"qweb-xml": "set default"} + ) + xsd_schema = fields.Binary( + string="XSD Validation Schema", + attachment=True, + help="File with XSD Schema for checking content of result report. Can be empty " + "if validation is not required.", + ) + xml_encoding = fields.Selection( + selection=[ + ("WINDOWS-1251", "WINDOWS-1251") # will be used as default even if nothing is selected + ], + string="XML Encoding", + help=( + "Encoding for XML reports. If nothing is selected, " + "then UTF-8 will be applied." + ), + ) + xml_declaration = fields.Boolean( + string="XML Declaration", + help=( + """Add `` at the start """ + """of final report file.""" + ), + default=True, + ) + xml_extension = fields.Char( + default="xml", + help="Extension for XML Reports, by default is `xml`", + ) + + @api.model + def _render_qweb_xml(self, report_ref, res_ids, data=None): + """ + Call `generate_report` method of report abstract class + `report.` or of standard class for XML report + rendering - `report.report_xml.abstract` + + Args: + * docids(list) - IDs of instances for those report will be generated + * data(dict, None) - variables for report rendering + + Returns: + * str - result content of report + * str - type of result content + """ + report = self._get_report(report_ref) + report_model = self.env.get( + f"report.{report.report_name}", self.env["report.l10n_ru_upd_xml.abstract"] + ) + return report_model.generate_report( + ir_report=report, # will be used to get settings of report + docids=res_ids, + data=data or {}, + ) diff --git a/l10n_ru_upd_xml/models/res_company.py b/l10n_ru_upd_xml/models/res_company.py new file mode 100644 index 0000000..e9143df --- /dev/null +++ b/l10n_ru_upd_xml/models/res_company.py @@ -0,0 +1,11 @@ +from odoo import api, fields, models, _ + + +class ResCompany(models.Model): + _inherit = 'res.company' + + inn = fields.Char(related='partner_id.inn', readonly=False, string=_('ИНН')) + kpp = fields.Char(related='partner_id.kpp', readonly=False, string=_('КПП')) + okpo = fields.Char(related='partner_id.okpo', readonly=False, string=_('ОКПО')) + edi = fields.Char(string='ID EDI', readonly=False) + chief_id = fields.Many2one('res.users', string=_('Управляющий')) diff --git a/l10n_ru_upd_xml/models/res_partner.py b/l10n_ru_upd_xml/models/res_partner.py new file mode 100644 index 0000000..4dbf28b --- /dev/null +++ b/l10n_ru_upd_xml/models/res_partner.py @@ -0,0 +1,36 @@ +from odoo import api, fields, models, _ + +class ResPartner(models.Model): + _inherit = 'res.partner' + + inn = fields.Char(_('ИНН'), size=12) + kpp = fields.Char(_('КПП'), size=9) + okpo = fields.Char(_('ОКПО'), size=14) + edi = fields.Char(_('ID EDI')) + house = fields.Char(_('Дом')) + office = fields.Char(_('Квартира, офис')) + fias_id = fields.Char(_('Код ФИАС')) + last_name_IP = fields.Char(_('Фамилия ИП'), compute='_compute_get_fio', readonly=False) + first_name_IP = fields.Char(_('Имя ИП'), compute='_compute_get_fio', readonly=False) + middle_name_IP = fields.Char(_('Отчество ИП'), compute='_compute_get_fio', readonly=False) + + @api.depends('name') + def _compute_get_fio(self): + for s in self: + if s.name: + name = s.name + if name.find('ИП ') != -1: + name = name[name.find(' ') + 1:] + s.last_name_IP = name[:name.find(' ')] + name = name[name.find(' ') + 1:] + s.first_name_IP = name[:name.find(' ')] + name = name[name.find(' ') + 1:] + s.middle_name_IP = name + else: + s.last_name_IP = "" + s.first_name_IP = "" + s.middle_name_IP = "" + else: + s.last_name_IP = "" + s.first_name_IP = "" + s.middle_name_IP = "" diff --git a/l10n_ru_upd_xml/models/res_users.py b/l10n_ru_upd_xml/models/res_users.py new file mode 100644 index 0000000..4ac723b --- /dev/null +++ b/l10n_ru_upd_xml/models/res_users.py @@ -0,0 +1,25 @@ +from odoo import api, fields, models, _ + +class ResUsers(models.Model): + _inherit = 'res.users' + + last_name = fields.Char(string=_('Фамилия'), compute='_compute_update_name') + first_name = fields.Char(string=_('Имя'), compute='_compute_update_name') + second_name = fields.Char(string=_('Отчество'), compute='_compute_update_name') + + @api.depends('name') + def _compute_update_name(self): + for s in self: + s.last_name = '' + s.first_name = '' + s.second_name = '' + if s.name: + s.last_name = s.name + s.first_name = '' + s.second_name = '' + if len(s.name.split(' ')) == 3: + s.last_name, s.first_name, s.second_name = s.name.split(' ') + if len(s.name.split(' ')) == 4: + s.last_name, s.first_name, second_name1, second_name2 = s.name.split(' ') + s.second_name = second_name1 + ' ' + second_name2 + diff --git a/l10n_ru_upd_xml/models/uom_uom.py b/l10n_ru_upd_xml/models/uom_uom.py new file mode 100644 index 0000000..88cd122 --- /dev/null +++ b/l10n_ru_upd_xml/models/uom_uom.py @@ -0,0 +1,7 @@ +from odoo import fields, models, _ + + +class UomUom(models.Model): + _inherit = "uom.uom" + + okei = fields.Char(string="Код ОКЕИ") diff --git a/l10n_ru_upd_xml/reports/__init__.py b/l10n_ru_upd_xml/reports/__init__.py new file mode 100644 index 0000000..fff0f44 --- /dev/null +++ b/l10n_ru_upd_xml/reports/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). + +from . import report_report_xml_abstract diff --git a/l10n_ru_upd_xml/reports/demo_report.xml b/l10n_ru_upd_xml/reports/demo_report.xml new file mode 100644 index 0000000..5eae777 --- /dev/null +++ b/l10n_ru_upd_xml/reports/demo_report.xml @@ -0,0 +1,76 @@ + + + + diff --git a/l10n_ru_upd_xml/reports/report.xml b/l10n_ru_upd_xml/reports/report.xml new file mode 100644 index 0000000..2f70da0 --- /dev/null +++ b/l10n_ru_upd_xml/reports/report.xml @@ -0,0 +1,14 @@ + + + + + УПД xml + account.move + qweb-xml + l10n_ru_upd_xml.demo_report_xml_view + l10n_ru_upd_xml.demo_report_xml_view + '%s' % (object.edi) + + report + + diff --git a/l10n_ru_upd_xml/reports/report_report_xml_abstract.py b/l10n_ru_upd_xml/reports/report_report_xml_abstract.py new file mode 100644 index 0000000..c8641f1 --- /dev/null +++ b/l10n_ru_upd_xml/reports/report_report_xml_abstract.py @@ -0,0 +1,44 @@ +# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). + +from base64 import b64decode +from xml.dom import minidom + +from lxml import etree + +from odoo import api, models,SUPERUSER_ID +from odoo.exceptions import ValidationError + + +class ReportXmlAbstract(models.AbstractModel): + _name = "report.l10n_ru_upd_xml.abstract" + _description = "Abstract XML Report" + + @api.model + def generate_report(self, ir_report, docids, data=None): + data = data or {} + data.setdefault("report_type", "text") + data = ir_report._get_rendering_context(ir_report, docids, data) + + result_bin = ir_report._render_template(ir_report.report_name, data) + + parsed_result_bin = minidom.parseString(result_bin) + result = parsed_result_bin.toprettyxml(indent=" ") + + # remove empty lines + utf8 = "UTF-8" + cp1251="WINDOWS-1251" + result = "\n".join( + line for line in result.splitlines() if line and not line.isspace() + ).encode('utf8') + + content = etree.tostring( + etree.fromstring(result), + encoding=ir_report.xml_encoding or cp1251, + xml_declaration=True, + pretty_print=True, + ) + return content, "xml" + + @api.model + def _get_report_values(self, docids, data=None): + return data or {} diff --git a/l10n_ru_upd_xml/reports/upd_report.xml b/l10n_ru_upd_xml/reports/upd_report.xml new file mode 100644 index 0000000..ffe9100 --- /dev/null +++ b/l10n_ru_upd_xml/reports/upd_report.xml @@ -0,0 +1,215 @@ + + + + diff --git a/l10n_ru_upd_xml/security/ir.model.access.csv b/l10n_ru_upd_xml/security/ir.model.access.csv new file mode 100644 index 0000000..7a89480 --- /dev/null +++ b/l10n_ru_upd_xml/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_upd_xml_upd_xml,upd_xml.upd_xml,model_upd_xml_upd_xml,base.group_user,1,1,1,1 diff --git a/l10n_ru_upd_xml/static/src/js/report/action_manager_report.js b/l10n_ru_upd_xml/static/src/js/report/action_manager_report.js new file mode 100644 index 0000000..b667794 --- /dev/null +++ b/l10n_ru_upd_xml/static/src/js/report/action_manager_report.js @@ -0,0 +1,50 @@ +/** @odoo-module **/ + +import {download} from "@web/core/network/download"; +import {registry} from "@web/core/registry"; + +function getReportUrl({report_name, context, data}, env) { + // Rough copy of action_service.js _getReportUrl method. + let url = `/report/xml/${report_name}`; + const actionContext = context || {}; + if (data && JSON.stringify(data) !== "{}") { + const encodedOptions = encodeURIComponent(JSON.stringify(data)); + const encodedContext = encodeURIComponent(JSON.stringify(actionContext)); + return `${url}?options=${encodedOptions}&context=${encodedContext}`; + } + if (actionContext.active_ids) { + url += `/${actionContext.active_ids.join(",")}`; + } + const userContext = env.services.user ? encodeURIComponent(JSON.stringify(env.services.user.context)) : ''; + return `${url}?context=${userContext}`; +} +async function triggerDownload(action, {onClose}, env) { + // Rough copy of action_service.js _triggerDownload method. + env.services.ui.block(); + const data = JSON.stringify([getReportUrl(action, env), action.report_type]); + console.log('triggerDownload env.services.user.context:', env.services.user); + const context = env.services.user ? encodeURIComponent(JSON.stringify(env.services.user.context)) : ''; + try { + await download({url: "/report/download", data: {data, context}}); + } finally { + env.services.ui.unblock(); + } + if (action.close_on_report_download) { + return env.services.action.doAction( + {type: "ir.actions.act_window_close"}, + {onClose} + ); + } + if (onClose) { + onClose(); + } +} +registry + .category("ir.actions.report handlers") + .add("xml_handler", async function (action, options, env) { + if (action.report_type === "qweb-xml") { + await triggerDownload(action, options, env); + return true; + } + return false; + }); diff --git a/l10n_ru_upd_xml/views/ir_actions_report_view.xml b/l10n_ru_upd_xml/views/ir_actions_report_view.xml new file mode 100644 index 0000000..1a22f93 --- /dev/null +++ b/l10n_ru_upd_xml/views/ir_actions_report_view.xml @@ -0,0 +1,24 @@ + + + + ir.actions.report.view.form.report.xml + ir.actions.report + + + + + + + + + + + + + diff --git a/l10n_ru_upd_xml/views/res_company_view.xml b/l10n_ru_upd_xml/views/res_company_view.xml new file mode 100644 index 0000000..5585d92 --- /dev/null +++ b/l10n_ru_upd_xml/views/res_company_view.xml @@ -0,0 +1,23 @@ + + + + + + res.company.ru.form + res.company + + + + + + + + + + + + + + + diff --git a/l10n_ru_upd_xml/views/res_partner_view.xml b/l10n_ru_upd_xml/views/res_partner_view.xml new file mode 100644 index 0000000..7859540 --- /dev/null +++ b/l10n_ru_upd_xml/views/res_partner_view.xml @@ -0,0 +1,29 @@ + + + + + + res.partner.ru.form + res.partner + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_ru_upd_xml/views/res_users_view.xml b/l10n_ru_upd_xml/views/res_users_view.xml new file mode 100644 index 0000000..4fd3b58 --- /dev/null +++ b/l10n_ru_upd_xml/views/res_users_view.xml @@ -0,0 +1,21 @@ + + + + + + res.users.signature.form + res.users + + + + + + + + + + + + + + diff --git a/l10n_ru_upd_xml/views/view_account_move.xml b/l10n_ru_upd_xml/views/view_account_move.xml new file mode 100644 index 0000000..a371d32 --- /dev/null +++ b/l10n_ru_upd_xml/views/view_account_move.xml @@ -0,0 +1,17 @@ + + + + edi account move + account.move + + + + +