Compare commits

..

89 Commits
14.0 ... 7.0

Author SHA1 Message Date
Alexis de Lattre
c1d0fd885d Code clean-up in purchase_auto_invoice_method 2018-04-24 16:55:30 +02:00
Alexis de Lattre
4ee0d18712 FIX hr_holidays_usability use float_compare 2017-06-09 13:09:37 +02:00
Alexis de Lattre
6f8ffc403a Add menu to force qty on leave request 2017-04-07 14:26:16 +02:00
Alexis de Lattre
c492904e2b Minor update 2016-10-13 17:06:48 +02:00
Alexis de Lattre
64e08b93de Add constraint 2016-05-18 15:08:51 +02:00
Alexis de Lattre
e3793989c0 Update to sync with new-report-intrastat 2016-05-12 18:46:44 +02:00
Alexis de Lattre
158648e604 Backport intrastat_product_type from 8 to 7 2016-05-12 17:38:04 +02:00
Alexis de Lattre
38dd25f471 Avoid a division by zero 2016-04-26 23:53:35 +02:00
Alexis de Lattre
81d97b2981 Add possibility to make a manual update of standard_price from BOM
Add script to automate the update of standard_price for phantom BOM
Add user_id on price.history
2016-04-13 22:41:08 +02:00
Alexis de Lattre
87ec05e5ef Inherit copy() 2016-03-23 21:57:58 +01:00
Alexis de Lattre
237c0e484a Small usability stuff 2016-03-22 17:57:56 +01:00
Alexis de Lattre
cc1efeafdb Add components cost and total cost on BOM
Add standard price in BOM lines
2016-03-22 17:57:13 +01:00
Alexis de Lattre
753333521f Add ability to put a key in ctx to disable generation of a price history line 2016-03-11 14:41:42 +01:00
Alexis de Lattre
e22b56c7a9 FIX computation for products partially produced
Disable raise when labor cost is null
2016-03-11 14:40:58 +01:00
Alexis de Lattre
a93a203f2d Add mrp.bom.labour.line, to be able to have several labor cost profile on a single BOM 2016-03-10 12:21:05 +01:00
Alexis de Lattre
698327c5a1 Add mrp_usability 2016-02-26 19:24:00 +01:00
Alexis de Lattre
4f566a8ff8 Add Extra cost on BOM
Split the method to write standard_price on product in 2: one to compute the unit price of the MO, another one to update the standard_price on the product
2016-02-26 19:22:45 +01:00
Alexis de Lattre
f80e8117fe Add module account_invoice_margin 2016-02-26 15:16:54 +01:00
Alexis de Lattre
0331fb1290 Add module product_usability 2016-02-26 10:21:46 +01:00
Alexis de Lattre
941366ee47 Add module mrp_average_cost 2016-02-26 10:20:56 +01:00
Alexis de Lattre
cb3942f501 Update description 2015-12-19 01:38:11 +01:00
Alexis de Lattre
c030d20c68 Add module delivery_carrier_zpl_label_print 2015-12-18 18:45:26 +01:00
Alexis de Lattre
84c6b03e09 Add module purchase_line_move_state 2015-12-17 19:56:14 +01:00
Alexis de Lattre
07a90ce45f Add module purchase_date_planned_update 2015-12-17 19:55:28 +01:00
Florian da Costa
7d5efb1c49 add possibility to search supplier code in stock.picking.in 2015-11-04 16:25:12 +01:00
Florian da Costa
fea48b5738 add french translation to product search supplier code 2015-10-30 13:58:10 +01:00
Florian da Costa
fe28781b9f add product_search_supplier_code 2015-10-30 11:52:22 +01:00
Alexis de Lattre
ca6bfa9227 Add readonly=True on related field 2015-06-29 16:23:53 +02:00
Alexis de Lattre
55589c52c2 Update translation 2015-06-19 19:02:07 +02:00
Alexis de Lattre
b2a259308d Rename fields and update translation 2015-06-19 18:56:27 +02:00
Alexis de Lattre
b2a0e44121 Add posted counters + update translation 2015-06-19 18:29:57 +02:00
Alexis de Lattre
1108f79664 FIX record rule 2015-06-19 17:56:29 +02:00
Alexis de Lattre
085aeb62c5 Update strings, POT file and FR translation 2015-06-12 09:41:17 +02:00
Alexis de Lattre
94c693a06f MAJ POT files 2015-06-12 00:20:13 +02:00
Alexis de Lattre
7a07d438e4 Introduce new wizard and counters 2015-06-12 00:06:36 +02:00
Alexis de Lattre
7831277c14 Add default value for mass allocation wizard 2015-06-11 14:47:57 +02:00
Alexis de Lattre
2dbf95cb97 Add mass allocation wizard
Add counter info on form view of hr.holidays
Fix an issue when checking counter
2015-06-11 12:43:43 +02:00
Alexis de Lattre
edcd3c7637 FIX an overlap issue when a user requests 2 half-days on the same day with different types 2015-06-11 09:47:26 +02:00
Alexis de Lattre
7d0f3976dd Add warning 2015-06-10 17:31:33 +02:00
Alexis de Lattre
10c8a2e681 hr_holidays_usability: various fixes + usability improvements 2015-06-10 14:44:18 +02:00
Alexis de Lattre
6702381665 Add module hr_holidays_usability 2015-05-22 18:06:41 +02:00
Alexis de Lattre
753d4b5d5d Better default options 2015-05-20 21:57:35 +02:00
Alexis de Lattre
810a7d795b Add module account_banking_payment_transfer_simple 2015-04-08 18:28:32 +02:00
Alexis de Lattre
1230dbb711 add module eradicate_quick_create 2015-04-08 15:29:16 +02:00
Alexis de Lattre
8756bc4b24 Adapt to changes in stock module 2015-04-08 11:32:17 +02:00
Alexis de Lattre
8973d4bf98 Add module account_invoice_del_attachment_cancel
Add .gitignore
2015-01-20 18:05:46 +01:00
Alexis de Lattre
7130581012 Add module partner_default_lang_parent 2015-01-19 13:01:32 +01:00
Alexis de Lattre
898b1e6d2e Backport module sale_stock_show_delivery_address to v7 2015-01-19 12:09:37 +01:00
Alexis de Lattre
a330ae1711 Small improvement 2014-12-12 16:55:45 +01:00
Alexis de Lattre
c6e8c79d45 Update comments 2014-12-12 12:31:00 +01:00
Alexis de Lattre
bdf4a7e15d Add module stock_tracking_ul 2014-11-15 00:06:14 +01:00
Alexis de Lattre
560beb826b Add currency in PO tree view. 2014-10-16 23:34:41 +02:00
Alexis de Lattre
80145000d8 Add currency_id in sale tree view 2014-10-16 23:12:48 +02:00
Alexis de Lattre
2ef4a5946c Add module account_invoice_overdue_filter 2014-10-15 10:43:57 +02:00
Alexis de Lattre
b7d902aa2d Order inventory: latest first 2014-10-14 17:26:31 +02:00
Alexis de Lattre
48a720f8dd Add module stock_inventory_usability 2014-10-14 12:55:02 +02:00
Alexis de Lattre
64ab60d350 Remove asterisk_click2dial_project_issue following update of the Asterisk connector 2014-08-30 00:07:34 +02:00
Alexis de Lattre
14bacaeba5 Add module base_partner_link_on_users. 2014-06-11 10:06:28 +02:00
Alexis de Lattre
fe08942e39 Move button. 2014-05-23 19:25:34 +02:00
Alexis de Lattre
bc4dd21316 Add € symbol. 2014-05-23 19:24:02 +02:00
Alexis de Lattre
0c5a496ba2 Add module l10n_fr_infogreffe_connector. 2014-05-23 17:43:06 +02:00
Alexis de Lattre
0a626f39ae Add module asterisk_click2dial_project_issue. 2014-05-23 09:09:07 +02:00
Alexis de Lattre
e9806b73c6 Add module base_partner_always_multi_contacts. 2014-05-15 23:20:03 +02:00
Alexis de Lattre
2b522f5702 Add base_title_on_partner module. 2014-05-15 11:29:34 +02:00
Alexis de Lattre
082c133128 Add link to issues on partner form. 2014-04-23 16:32:54 +02:00
Alexis de Lattre
c33ef19086 Add module stock_hide_journal_id. 2014-04-23 16:20:44 +02:00
Alexis de Lattre
6f07d50d90 Add translation files. 2014-04-18 18:18:17 +02:00
Alexis de Lattre
037e4d4214 Add module project_issue_extension. 2014-04-18 18:08:17 +02:00
Alexis de Lattre
53b1ff6ed4 Add module product_disable_quick_create. 2014-04-18 17:06:43 +02:00
Alexis de Lattre
2847f14dc7 Add module account_invoice_sale_link. 2014-04-10 18:26:19 +02:00
Alexis de Lattre
4fb4ed9ca4 Add module sale_markup_group_user to address this issue : https://bugs.launchpad.net/sale-financial/+bug/1305987 2014-04-10 18:23:11 +02:00
Alexis de Lattre
98bc291b54 Add module base_fix_display_address. 2014-04-10 12:52:03 +02:00
Alexis de Lattre
532b9cb53c Remove the module sale_auto_order_policy, which was in fact useless because the feature was native ! 2014-04-10 12:44:43 +02:00
Alexis de Lattre
5075221428 Remove code... it was native ! 2014-04-09 12:13:58 +02:00
Alexis de Lattre
3ee3edb8ce Add module stock_display_sale_id 2014-03-25 00:10:01 +01:00
Alexis de Lattre
f3085a163f Add module account_payment_hide_communication2. 2014-03-22 01:48:30 +01:00
Alexis de Lattre
7b04e578af Add ship_except to list of states. 2014-03-07 16:01:47 +01:00
Alexis de Lattre
9daeeca997 Better label on the second tab of PO. 2014-02-20 17:32:53 +01:00
Alexis de Lattre
0c5366420f Add purchase_usability_extension and sale_usability_extension. 2014-02-20 16:47:28 +01:00
Alexis de Lattre
f388d0d10f Add module account_payment_security. 2014-02-19 11:02:40 +01:00
Alexis de Lattre
e588686d5f Add module account_move_line_start_end_dates_xls. 2014-02-17 14:46:01 +01:00
Alexis de Lattre
2e6e1c07bf Add module stock_display_destination_move. 2014-01-17 17:16:56 +01:00
Alexis de Lattre
a98dbc0b1c Cosmetic. 2014-01-08 23:56:40 +01:00
Alexis de Lattre
529b585d07 Add module sale_auto_order_policy. 2014-01-08 23:30:47 +01:00
Alexis de Lattre
46d177fb9f Add sale_fiscal_position_update_button. 2014-01-08 23:29:59 +01:00
Alexis de Lattre
24abaec406 Add module purchase_auto_invoice_method. 2013-12-16 18:50:27 +01:00
Alexis de Lattre
673afbac0f FIX module description. 2013-12-12 11:16:02 +01:00
Alexis de Lattre
5dc05f3c81 Add module stock_invoice_try_again 2013-12-09 18:12:45 +01:00
Alexis de Lattre
dce0604e7d Add module stock_invoice_service_from_delivery 2013-12-09 18:12:38 +01:00
1169 changed files with 8845 additions and 35063 deletions

View File

@@ -1,27 +0,0 @@
===============================
Bank Reconciliation Report XLSX
===============================
In Odoo v13+, a bank reconciliation report is not really needed because all the payments executed that are not debited/credited on the bank account are in separate waiting accounts. But accountants want a bank reconciliation report, so this module adds one, even if it is quite different from a classic bank reconciliation report.
Configuration
=============
This module doesn't require any configuration.
Usage
=====
You can launch the Bank Reconciliation Report wizard from:
* the menu *Accounting > Reports > Bank > Bank Reconciliation*,
* the invoicing dashboard: on a bank journal, click on the options, then select *Bank Reconciliation*.
* the form view of a bank statement: click on the button *Bank Reconciliation Report*.
Credits
=======
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>

View File

@@ -1,2 +0,0 @@
from . import report
from . import wizard

View File

@@ -1,21 +0,0 @@
# Copyright 2017-2024 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Bank Reconciliation Report",
"version": "14.0.2.0.0",
"license": "AGPL-3",
"author": "Akretion",
"website": "https://github.com/akretion/odoo-usability",
"summary": "Bank reconciliation XLSX report",
"depends": ["account", "report_xlsx"],
"data": [
"report/report.xml",
"wizard/bank_reconciliation_report_wizard_view.xml",
"views/account_bank_statement.xml",
"views/account_journal.xml",
"security/ir.model.access.csv",
],
"installable": True,
}

View File

@@ -1,268 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_bank_reconciliation_summary_xlsx
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-23 10:04+0000\n"
"PO-Revision-Date: 2024-10-23 10:04+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: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Amount"
msgstr "Montant"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Balance %s:"
msgstr "Solde %s :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Bank Balance:"
msgstr "Solde bancaire :"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__journal_ids
msgid "Bank Journals"
msgstr "Journaux de banque"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.actions.act_window,name:account_bank_reconciliation_summary_xlsx.bank_reconciliation_report_wizard_action
#: model:ir.ui.menu,name:account_bank_reconciliation_summary_xlsx.bank_reconciliation_report_wizard_menu
#: model_terms:ir.ui.view,arch_db:account_bank_reconciliation_summary_xlsx.account_journal_dashboard_kanban_view
msgid "Bank Reconciliation"
msgstr "Rapprochement bancaire"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: model_terms:ir.ui.view,arch_db:account_bank_reconciliation_summary_xlsx.view_bank_statement_form
#, python-format
msgid "Bank Reconciliation Report"
msgstr "Rapport de rapprochement bancaire"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model,name:account_bank_reconciliation_summary_xlsx.model_bank_reconciliation_report_wizard
msgid "Bank Reconciliation Report Wizard"
msgstr "Assistant de rapport de rapprochement bancaire"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.actions.report,name:account_bank_reconciliation_summary_xlsx.bank_reconciliation_xlsx
msgid "Bank Reconciliation XLSX"
msgstr "Rapprochement bancaire XLSX"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model,name:account_bank_reconciliation_summary_xlsx.model_report_bank_reconciliation_xlsx
msgid "Bank Reconciliation XLSX Report"
msgstr "Rapport de rapprochement bancaire XLSX"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.ui.menu,name:account_bank_reconciliation_summary_xlsx.menu_report_bank_root
msgid "Bank Reports"
msgstr "Rapports bancaires"
#. module: account_bank_reconciliation_summary_xlsx
#: model_terms:ir.ui.view,arch_db:account_bank_reconciliation_summary_xlsx.bank_reconciliation_report_wizard_form
msgid "Cancel"
msgstr "Annuler"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__company_id
#, python-format
msgid "Company"
msgstr "Société"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Counter-part"
msgstr "Contre partie"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__create_date
msgid "Created on"
msgstr "Créé le"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Currency"
msgstr "Devise"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__date
#, python-format
msgid "Date"
msgstr "Date"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Description"
msgstr "Description"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Difference:"
msgstr "Écart :"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__display_name
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_report_bank_reconciliation_xlsx__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields.selection,name:account_bank_reconciliation_summary_xlsx.selection__bank_reconciliation_report_wizard__move_state__draft_posted
msgid "Draft and Posted Entries"
msgstr "Écritures brouillon et comptabilisées"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__move_state
#, python-format
msgid "Entries"
msgstr "Écritures"
#. module: account_bank_reconciliation_summary_xlsx
#: model_terms:ir.ui.view,arch_db:account_bank_reconciliation_summary_xlsx.bank_reconciliation_report_wizard_form
msgid "Export XLSX"
msgstr "Exporter en XLSX"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Generated from Odoo on %s by %s"
msgstr "Généré par Odoo le %s par %s"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__id
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_report_bank_reconciliation_xlsx__id
msgid "ID"
msgstr ""
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Journal"
msgstr ""
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Journal Entry"
msgstr "Pièce"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Justification:"
msgstr "Justification :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Label"
msgstr "Libellé"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard____last_update
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_report_bank_reconciliation_xlsx____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "No bank journal selected."
msgstr "Aucun journal de banque sélectionné."
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "None"
msgstr "Aucun"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid ""
"On bank journal %(journal)s which is configured with currency "
"%(journal_currency)s, the account %(account)s must be configured with the "
"same currency (current account currency: %(account_currency)s)."
msgstr ""
"Sur le journal de banque %(journal)s qui est configuré avec la devise "
"%(journal_currency)s, le compte %(account)s doit être configuré avec la même"
" devise (devise actuelle du compte : %(account_currency)s)."
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Partner"
msgstr "Partenaire"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields.selection,name:account_bank_reconciliation_summary_xlsx.selection__bank_reconciliation_report_wizard__move_state__posted
msgid "Posted Entries"
msgstr "Écritures comptabilisées"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Ref."
msgstr "Réf."
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Sub-total:"
msgstr "Sous-total :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "TOTAL:"
msgstr "TOTAL :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid ""
"The are %(count)s journal items in account %(account)s that have a currency "
"other than %(currency)s or where currency is not set."
msgstr ""
"Il y a %(count)s écritures comptables dans le compte %(account)s qui ont une"
" devise autre que %(currency)s ou dont la devise n'est pas définie."

View File

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

View File

@@ -1,375 +0,0 @@
# Copyright 2017-2024 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, models
from odoo.exceptions import UserError
from datetime import datetime
from odoo.tools.misc import format_datetime
import pytz
class BankReconciliationXlsx(models.AbstractModel):
_name = "report.bank.reconciliation.xlsx"
_description = "Bank Reconciliation XLSX Report"
_inherit = "report.report_xlsx.abstract"
def _prepare_payment_move_lines(self, jdi, account, unreconciled_only=True):
domain = [
("company_id", "=", jdi['company'].id),
("account_id", "=", account.id),
("journal_id", "=", jdi['journal'].id),
("date", "<=", jdi['wizard'].date),
]
if jdi['wizard'].move_state == 'posted':
domain.append(('parent_state', '=', 'posted'))
elif jdi['wizard'].move_state == 'draft_posted':
domain.append(('parent_state', 'in', ('draft', 'posted')))
if unreconciled_only:
limit_datetime_naive = datetime.combine(jdi['wizard'].date, datetime.max.time())
tz = pytz.timezone(self.env.user.tz)
limit_datetime_aware = tz.localize(limit_datetime_naive)
limit_datetime_utc = limit_datetime_aware.astimezone(pytz.utc)
limit_datetime = limit_datetime_utc.replace(tzinfo=None)
domain += [
'|', ('full_reconcile_id', '=', False),
('full_reconcile_id.create_date', '>', limit_datetime)]
mlines = self.env["account.move.line"].search(domain)
res = []
for mline in mlines:
move = mline.move_id
cpart = []
for line in move.line_ids:
if (
line.account_id != account
and line.account_id.code not in cpart
):
cpart.append(line.account_id.code)
counterpart = " ,".join(cpart)
if jdi['currency'] == mline.currency_id:
amount = mline.amount_currency
else:
amount = mline.currency_id._convert(
mline.amount_currency, jdi['currency'], jdi['company'], mline.date)
res.append(
{
"date": mline.date,
"ref": move.ref or "",
"label": mline.name,
"partner": mline.partner_id.display_name or "",
"amount": amount,
"move_name": move.name,
"counterpart": counterpart,
}
)
return res
def _write_move_lines_block(self, jdi, row, account, add2total=True):
# Returns row
# For suspense lines, it may not add any cells if there are no suspense lines
# => in this case, it doesn't increment row
# If it adds cells, it returns row + 2 to add 2 empty rows at the end
sheet = jdi['sheet']
style = jdi['style']
style_suffix = not add2total and '_warn' or ''
subtotal = 0.0
mlines = self._prepare_payment_move_lines(jdi, account)
if mlines or add2total:
sheet.write(row, 0, '%s %s' % (account.name, account.code), style[f"title{style_suffix}"])
sheet.write(row, 1, "", style[f"title{style_suffix}"])
if not mlines:
if add2total:
sheet.write(row, 2, _("None"), style['none'])
else:
return row
else:
row += 1
col_labels = [
_("Date"),
_("Partner"),
_("Amount"),
_("Journal Entry"),
_("Counter-part"),
_("Ref."),
_("Label"),
]
col = 0
for col_label in col_labels:
sheet.write(row, col, col_label, style['col_header'])
col += 1
row += 1
start_line = row + 1
for mline in mlines:
sheet.write(row, 0, mline["date"], style['regular_date'])
sheet.write(row, 1, mline["partner"], style['regular'])
sheet.write(row, 2, mline["amount"], style[jdi['currency']])
sheet.write(row, 3, mline["move_name"], style['regular'])
sheet.write(row, 4, mline["counterpart"], style['regular'])
sheet.write(row, 5, mline["ref"], style['regular'])
sheet.write(row, 6, mline["label"], style['regular'])
subtotal += mline["amount"]
row += 1
end_line = row
for col in range(1):
sheet.write(row, col, "", style[f"title{style_suffix}"])
sheet.write(row, 1, _("Sub-total:") + ' ', style[f"title_right{style_suffix}"])
formula = f"=SUM({jdi['total_col']}{start_line}:{jdi['total_col']}{end_line})"
sheet.write_formula(row, 2, formula, style[f"{jdi['currency']}_bg{style_suffix}"], subtotal)
if add2total:
jdi['total'] += subtotal
jdi['total_formula'] += f"+{jdi['total_col']}{row + 1}"
return row + 2
def generate_xlsx_report(self, workbook, data, wizard):
lang = self.env.user.lang
self = self.with_context(lang=lang)
wizard = wizard.with_context(lang=lang)
if not wizard.journal_ids:
raise UserError(_("No bank journal selected."))
date_dt = wizard.date
company = wizard.company_id
style = self._get_style(workbook, company)
move_state_label = dict(
wizard.fields_get('move_state', 'selection')['move_state']['selection'])
generated_on_label = _('Generated from Odoo on %s by %s') % (
format_datetime(self.env, datetime.utcnow()),
self.env.user.name)
for journal in wizard.journal_ids:
row = 0
sheet = workbook.add_worksheet(journal.code or journal.name)
bank_account = journal.default_account_id
jdi = {
'wizard': wizard,
'company': company,
'journal': journal,
'currency': journal.currency_id or company.currency_id,
'bank_account': bank_account,
'style': style,
'workbook': workbook,
'sheet': sheet,
'total': 0.0,
'total_formula': '=',
'total_col': 'C',
}
sheet.write(
row,
0,
_("Bank Reconciliation Report"),
style['doc_title'],
)
row += 1
sheet.write(row, 0, generated_on_label, style['small'])
sheet.set_row(0, 26)
sheet.set_column(0, 0, 10)
sheet.set_column(1, 1, 35)
sheet.set_column(2, 2, 15)
sheet.set_column(3, 3, 15)
sheet.set_column(4, 4, 25)
sheet.set_column(5, 5, 30)
sheet.set_column(6, 6, 60)
row += 3
sheet.write(row, 0, _("Company"), style['wizard_field'])
sheet.write(row, 1, company.display_name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Date"), style['wizard_field'])
sheet.write(row, 1, date_dt, style['wizard_value_date'])
row += 1
sheet.write(row, 0, _("Journal"), style['wizard_field'])
sheet.write(row, 1, journal.display_name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Currency"), style['wizard_field'])
sheet.write(row, 1, jdi['currency'].name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Entries"), style['wizard_field'])
sheet.write(row, 1, move_state_label[wizard.move_state], style['wizard_value'])
# Setup check
if journal.currency_id and journal.currency_id != company.currency_id:
if journal.currency_id != bank_account.currency_id:
raise UserError(_(
"On bank journal %(journal)s which is configured with currency "
"%(journal_currency)s, the account %(account)s must be configured "
"with the same currency (current account currency: %(account_currency)s).",
journal=journal.display_name,
journal_currency=journal.currency_id.name,
account=bank_account.display_name,
account_currency=bank_account.currency_id.name or _('None')))
bad_line_count = self.env['account.move.line'].search_count([
('company_id', '=', company.id),
('journal_id', '=', journal.id),
('account_id', '=', bank_account.id),
('currency_id', '!=', jdi['currency'].id),
])
if bad_line_count:
raise UserError(_(
"The are %(count)s journal items in account %(account)s "
"that have a currency other than %(currency)s or where "
"currency is not set.",
count=bad_line_count,
account=bank_account.display_name,
currency=jdi['currency'].name))
# 1) Show balance of bank account
row += 3
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Balance %s:") % bank_account.code + ' ', style['title_right'])
if wizard.move_state == 'posted':
domain = [('parent_state', '=', 'posted')]
else:
# by default, the native method _get_journal_bank_account_balance()
# has ('parent_state', '!=', 'cancel')
domain = None
account_bal, nb_lines = journal._get_journal_bank_account_balance(domain=domain)
sheet.write(row, 2, account_bal, style[f"{jdi['currency']}_bg"])
jdi['total'] += account_bal
jdi['total_formula'] += f"{jdi['total_col']}{row + 1}"
row += 2
# 2) Show payment lines IN (debit)
debit_account = journal.payment_debit_account_id
row = self._write_move_lines_block(jdi, row, debit_account)
# 3) Show payment lines OUT (credit)
credit_account = journal.payment_credit_account_id
row = self._write_move_lines_block(jdi, row, credit_account)
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("TOTAL:") + ' ', style['title_right'])
sheet.write_formula(
row, 2, jdi['total_formula'], style[f"{jdi['currency']}_bg"], jdi['total'])
total_row = row
row += 2
# 4) Show suspense account lines
row = self._write_move_lines_block(
jdi, row, journal.suspense_account_id, add2total=False)
# Static cells
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Bank Balance:") + ' ', style['title_right'])
sheet.write(row, 2, 0, style[f"{jdi['currency']}_bg_manual"])
bank_bal_row = row
row += 2
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Difference:") + ' ', style['title_right'])
sheet.write_formula(
row, 2, f"={jdi['total_col']}{total_row + 1}-{jdi['total_col']}{bank_bal_row + 1}",
style[f"{jdi['currency']}_bg"], jdi['total'])
row += 2
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Justification:") + ' ', style['title_right'])
justif_lines = 6
sheet.write_formula(
row, 2, f"=SUM({jdi['total_col']}{row+3}:{jdi['total_col']}{row+3+justif_lines-1})",
style[f"{jdi['currency']}_bg"], 0)
row += 1
col_labels = [
_("Date"),
_("Description"),
_("Amount"),
]
col = 0
for col_label in col_labels:
sheet.write(row, col, col_label, style['col_header'])
col += 1
for x in range(justif_lines):
row += 1
sheet.write(row, 0, "", style['regular_date'])
sheet.write(row, 1, "", style['regular'])
sheet.write(row, 2, "", style[jdi['currency']])
def _get_style(self, workbook, company):
style = {}
font_size = 10
light_grey = "#eeeeee"
light_blue = "#e0edff"
subtotal_orange = "#ffcc00"
subtotal_warn = "#ffff99"
amount_manual = "#ffeeab"
title_warn = "#ff9999"
lang_code = self.env.user.lang
lang = False
if lang_code:
lang = self.env["res.lang"].search([("code", "=", lang_code)])
if not lang:
lang = self.env["res.lang"].search([], limit=1)
xls_date_format = (
lang.date_format.replace("%Y", "yyyy")
.replace("%m", "mm")
.replace("%d", "dd")
.replace("%y", "yy")
)
style['doc_title'] = workbook.add_format(
{"bold": True, "font_size": font_size + 4})
style['small'] = workbook.add_format({"font_size": font_size - 3})
style['col_header'] = workbook.add_format(
{
"bold": True,
"bg_color": light_grey,
"text_wrap": True,
"font_size": font_size,
"align": "center",
}
)
title_style = {
"bold": True,
"bg_color": light_blue,
"font_size": font_size,
"align": "left",
}
style['title_right'] = workbook.add_format(dict(title_style, align="right"))
style['title'] = workbook.add_format(dict(title_style))
style['wizard_field'] = workbook.add_format(dict(title_style, bg_color=light_grey))
wizard_value_style = {
"bg_color": light_blue,
"bold": True,
"font_size": font_size,
"align": "left",
}
style['wizard_value'] = workbook.add_format(wizard_value_style)
style['wizard_value_date'] = workbook.add_format(
dict(wizard_value_style, num_format=xls_date_format))
style['none'] = workbook.add_format(
{"bold": True, "font_size": font_size, "align": "right", "bg_color": subtotal_orange}
)
# WARN for suspense account
style['title_warn'] = workbook.add_format(
dict(title_style, align="left", bg_color=title_warn))
style['title_right_warn'] = workbook.add_format(
dict(title_style, align="right", bg_color=title_warn))
style['regular'] = workbook.add_format({"font_size": font_size, "border": 1})
if "%" in xls_date_format:
# fallback
xls_date_format = "yyyy-mm-dd"
style['regular_date'] = workbook.add_format(
{"num_format": xls_date_format, "font_size": font_size, "align": "left", "border": 1}
)
for currency in self.env['res.currency'].search([]):
symbol = currency.symbol or currency.name
decimals = '0' * currency.decimal_places
if currency.position == 'before':
cur_format = f"{symbol} #,##0.{decimals}"
else:
cur_format = f"#,##0.{decimals} {symbol}"
# It seems that Excel replaces automatically the decimal
# and thousand separator by those of the language under which
# Excel runs
currency_style = {"num_format": cur_format, "font_size": font_size}
style[currency] = workbook.add_format(dict(currency_style, border=1))
style[f'{currency}_bg'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_orange))
style[f'{currency}_bg_warn'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_warn))
style[f'{currency}_bg_manual'] = workbook.add_format(
dict(currency_style, bg_color=amount_manual))
return style

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2024 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="bank_reconciliation_xlsx" model="ir.actions.report">
<field name="name">Bank Reconciliation XLSX</field>
<field name="model">bank.reconciliation.report.wizard</field>
<field name="report_type">xlsx</field>
<field name="report_name">bank.reconciliation.xlsx</field>
<field name="report_file">bank.reconciliation.xlsx</field>
<field name="print_report_name">'bank_reconciliation-%s' % (object.date)</field>
</record>
</odoo>

View File

@@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_bank_reconciliation_report_wizard_user,Full access on bank.reconciliation.report.wizard,model_bank_reconciliation_report_wizard,account.group_account_user,1,1,1,1
access_bank_reconciliation_report_wizard_readonly,Full access on bank.reconciliation.report.wizard,model_bank_reconciliation_report_wizard,account.group_account_readonly,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_bank_reconciliation_report_wizard_user Full access on bank.reconciliation.report.wizard model_bank_reconciliation_report_wizard account.group_account_user 1 1 1 1
3 access_bank_reconciliation_report_wizard_readonly Full access on bank.reconciliation.report.wizard model_bank_reconciliation_report_wizard account.group_account_readonly 1 1 1 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2024 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">bank_rec_summary.account.bank.statement.form</field>
<field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form" />
<field name="arch" type="xml">
<button name="button_reprocess" position="after">
<button
name="%(bank_reconciliation_report_wizard_action)d"
type="action"
string="Bank Reconciliation Report"
context="{'default_journal_ids': [journal_id]}"
/>
</button>
</field>
</record>
</odoo>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2018-2024 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<!-- Accounting Dashboard -->
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
<field
name="name"
>bank_reconciliation_summary.account_journal_dashboard</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
<field name="arch" type="xml">
<xpath expr="//a[@name='open_collect_money']/.." position="before">
<div name="bank_reconciliation_report">
<a
role="menuitem"
type="action"
name="%(bank_reconciliation_report_wizard_action)d"
context="{'default_journal_ids': [active_id]}"
>Bank Reconciliation</a>
</div>
</xpath>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,42 +0,0 @@
# Copyright 2017-2024 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class BankReconciliationReportWizard(models.TransientModel):
_name = "bank.reconciliation.report.wizard"
_description = "Bank Reconciliation Report Wizard"
_check_company_auto = True
company_id = fields.Many2one(
'res.company', string='Company',
ondelete='cascade', required=True,
default=lambda self: self.env.company)
date = fields.Date(required=True, default=fields.Date.context_today)
move_state = fields.Selection(
[("posted", "Posted Entries"), ("draft_posted", "Draft and Posted Entries")],
string="Entries",
required=True,
default="posted",
)
journal_ids = fields.Many2many(
"account.journal",
string="Bank Journals",
domain="[('type', '=', 'bank'), ('company_id', '=', company_id)]",
required=True,
check_company=True,
default=lambda self: self._default_journal_ids(),
)
@api.model
def _default_journal_ids(self):
journals = self.env["account.journal"].search(
[
("type", "=", "bank"),
("bank_account_id", "!=", False),
("company_id", "=", self.env.company.id),
]
)
return journals

View File

@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2024 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="bank_reconciliation_report_wizard_form" model="ir.ui.view">
<field name="name">bank.reconciliation.report.wizard.form</field>
<field name="model">bank.reconciliation.report.wizard</field>
<field name="arch" type="xml">
<form>
<group name="main">
<field name="company_id" invisible="1" />
<field name="date" />
<field name="journal_ids" widget="many2many_tags" options="{'no_open': True, 'no_create': True}"/>
<field name="move_state" widget="radio"/>
</group>
<footer>
<button
name="%(account_bank_reconciliation_summary_xlsx.bank_reconciliation_xlsx)d"
string="Export XLSX"
type="action"
class="btn-primary"
/>
<button special="cancel" string="Cancel" />
</footer>
</form>
</field>
</record>
<record id="bank_reconciliation_report_wizard_action" model="ir.actions.act_window">
<field name="name">Bank Reconciliation</field>
<field name="res_model">bank.reconciliation.report.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
id="menu_report_bank_root"
parent="account.menu_finance_reports"
name="Bank Reports"
sequence="12"
/>
<menuitem
id="bank_reconciliation_report_wizard_menu"
action="bank_reconciliation_report_wizard_action"
parent="menu_report_bank_root"
sequence="10"
/>
</odoo>

View File

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

View File

@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
# (C) 2014 ACSONE SA/NV (<http://acsone.eu>).
#
# All other contributions are (C) by their respective contributors
#
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Banking - Payments Transfer Account (simple)',
'version': '0.2',
'license': 'AGPL-3',
'author': "Akretion,Odoo Community Association (OCA)",
'website': 'http://www.akretion.com',
'category': 'Banking addons',
'depends': [
'account_banking_payment_export',
],
'data': [
'view/payment_mode.xml',
'workflow/account_payment_workflow.xml',
],
'description': '''
This is a simple equivalent for Odoo v7 of the module *account_banking_payment_transfer* for v8.0.
I developped this module to be able to make some SEPA direct debits / credit transfer with transfer move on Odoo v7, without installing the module account_banking (I can't install account_banking because I used the OCA modules from https://github.com/OCA/bank-statement-reconcile)
''',
'installable': True,
}

View File

@@ -1,4 +1,4 @@
from . import sale
from . import account_move
from . import account_move_line
from . import account_payment
from . import payment_line
from . import payment_mode
from . import account_move_line

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
#
# All other contributions are (C) by their respective contributors
#
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
class account_move_line(orm.Model):
_inherit = "account.move.line"
def get_balance(self, cr, uid, ids, context=None):
"""
Return the balance of any set of move lines.
Not to be confused with the 'balance' field on this model, which
returns the account balance that the move line applies to.
"""
total = 0.0
if not ids:
return total
for line in self.read(
cr, uid, ids, ['debit', 'credit'], context=context):
total += (line['debit'] or 0.0) - (line['credit'] or 0.0)
return total

View File

@@ -0,0 +1,246 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
# (C) 2014 ACSONE SA (<http://acsone.eu>).
# (C) 2014 Akretion (www.akretion.com)
#
# All other contributions are (C) by their respective contributors
#
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp.tools.translate import _
class PaymentOrder(orm.Model):
_inherit = 'payment.order'
# @api.multi
# def get_partial_reconcile_ids(self):
# self.ensure_one()
# reconcile_partial_ids = [line.move_line_id.reconcile_partial_id.id
# for line in self.line_ids if
# line.move_line_id.reconcile_partial_id.id]
# return reconcile_partial_ids
# @api.one
# def get_partial_reconcile_count(self):
# self.partial_reconcile_count = len(self.get_partial_reconcile_ids())
def action_rejected(self, cr, uid, ids, context=None):
return True
# @api.multi
# def action_done(self):
# for line in self.line_ids:
# line.date_done = fields.Date.context_today(self)
# self.date_done = fields.Date.context_today(self)
# state is written in workflow definition
# return True
# @api.multi
# def _get_transfer_move_lines(self):
# """
# Get the transfer move lines (on the transfer account).
# """
# res = []
# for order in self:
# for order_line in order.line_ids:
# move_line = order_line.transfer_move_line_id
# if move_line:
# res.append(move_line)
# return res
# @api.multi
# def get_transfer_move_line_ids(self, *args):
# '''Used in the workflow for trigger_expr_id'''
# return [move_line.id for move_line in self._get_transfer_move_lines()]
# @api.multi
# def test_done(self):
# """
# Test if all moves on the transfer account are reconciled.
#
# Called from the workflow to move to the done state when
# all transfer move have been reconciled through bank statements.
# """
# return all([move_line.reconcile_id for move_line in
# self._get_transfer_move_lines()])
# @api.multi
# def test_undo_done(self):
# return not self.test_done()
def _prepare_transfer_move(self, cr, uid, order, context=None):
# TODO question : can I use self.mode.xxx in an @api.model ??
# It works, but I'm not sure we are supposed to do that !
# I didn't want to use api.one to avoid having to
# do self._prepare_transfer_move()[0] in action_sent
# I prefer to just have to do self._prepare_transfer_move()
vals = {
'journal_id': order.mode.transfer_journal_id.id,
'ref': '%s %s' % (
order.payment_order_type[:3].upper(), order.reference)
}
return vals
def _prepare_move_line_transfer_account(
self, cr, uid, order, amount, move_id, payment_lines, labels,
context=None):
payment_order_type = order.payment_order_type
if len(payment_lines) == 1:
partner_id = payment_lines[0].partner_id.id
name = _('%s line %s') % (
labels[payment_order_type], payment_lines[0].name)
else:
partner_id = False
name = '%s %s' % (
labels[payment_order_type], order.reference)
vals = {
'name': name,
'move_id': move_id,
'partner_id': partner_id,
'account_id': order.mode.transfer_account_id.id,
'credit': (payment_order_type == 'payment' and
amount or 0.0),
'debit': (payment_order_type == 'debit' and
amount or 0.0),
}
return vals
def _prepare_move_line_partner_account(
self, cr, uid, line, move_id, labels, context=None):
payment_order_type = line.order_id.payment_order_type
if line.move_line_id:
account_id = line.move_line_id.account_id.id
else:
if payment_order_type == 'debit':
account_id = line.partner_id.property_account_receivable.id
else:
account_id = line.partner_id.property_account_payable.id
vals = {
'name': _('%s line %s') % (
labels[payment_order_type], line.name),
'move_id': move_id,
'partner_id': line.partner_id.id,
'account_id': account_id,
'credit': (payment_order_type == 'debit' and
line.amount or 0.0),
'debit': (payment_order_type == 'payment' and
line.amount or 0.0),
}
return vals
# @api.model
# def action_sent_no_move_line_hook(self, pay_line):
# """This function is designed to be inherited"""
# return
def action_done(self, cr, uid, ids, context=None):
"""
Create the moves that pay off the move lines from
the debit order. This happens when the debit order file is
generated.
"""
am_obj = self.pool['account.move']
aml_obj = self.pool['account.move.line']
pl_obj = self.pool['payment.line']
labels = {
'payment': _('Payment order'),
'debit': _('Direct debit order'),
}
for order in self.browse(cr, uid, ids, context=context):
if order.mode.transfer_journal_id and order.mode.transfer_account_id:
# prepare a dict "trfmoves" that can be used when
# self.mode.transfer_move_option = date or line
# key = unique identifier (date or True or line.id)
# value = [pay_line1, pay_line2, ...]
trfmoves = {}
if order.mode.transfer_move_option == 'line':
for line in order.line_ids:
trfmoves[line.id] = [line]
else:
if order.date_prefered in ('now', 'fixed'):
trfmoves[True] = []
for line in order.line_ids:
trfmoves[True].append(line)
else: # date_prefered == due
for line in order.line_ids:
if line.date in trfmoves:
trfmoves[line.date].append(line)
else:
trfmoves[line.date] = [line]
for identifier, lines in trfmoves.iteritems():
mvals = self._prepare_transfer_move(
cr, uid, order, context=context)
move_id = am_obj.create(cr, uid, mvals, context=context)
total_amount = 0
for line in lines:
# TODO: take multicurrency into account
# create the payment/debit counterpart move line
# on the partner account
partner_ml_vals = self._prepare_move_line_partner_account(
cr, uid, line, move_id, labels, context=context)
partner_move_line_id = aml_obj.create(
cr, uid, partner_ml_vals, context=context)
total_amount += line.amount
# register the payment/debit move line
# on the payment line and call reconciliation on it
line.write({'transit_move_line_id': partner_move_line_id})
if line.move_line_id:
pl_obj.debit_reconcile(cr, uid, line.id, context=context)
#else:
# self.action_sent_no_move_line_hook(line)
# create the payment/debit move line on the transfer account
trf_ml_vals = self._prepare_move_line_transfer_account(
cr, uid, order, total_amount, move_id, lines, labels,
context=context)
aml_obj.create(cr, uid, trf_ml_vals, context=context)
# post account move
am_obj.post(cr, uid, [move_id], context=context)
# State field is written by act_sent_wait
order.write({'state': 'done'})
return True
# @api.multi
# def partial(self):
# self.ensure_one()
# view_id = self.env.ref('account.view_move_line_tree').id
# reconcile_partial_ids = self.get_partial_reconcile_ids()
# reconcile_partial_domain = [('reconcile_partial_id', 'in',
# reconcile_partial_ids)]
# return {
# 'name': _('Partial Reconcile Moves Line'),
# 'context': self.env.context,
# 'domain': reconcile_partial_domain,
# 'view_type': 'form',
# 'view_mode': 'tree,form',
# 'res_model': 'account.move.line',
# 'views': [(view_id, 'tree')],
# 'type': 'ir.actions.act_window',
# 'target': 'current',
# }

View File

@@ -0,0 +1,195 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
#
# All other contributions are (C) by their respective contributors
#
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp import netsvc
from openerp.tools.translate import _
class PaymentLine(orm.Model):
'''
Add some fields; make destination bank account
mandatory, as it makes no sense to send payments into thin air.
Edit: Payments can be by cash too, which is prohibited by mandatory bank
accounts.
'''
_inherit = 'payment.line'
def _get_transfer_move_line(self, cr, uid, ids, name, arg, context=None):
res = {}
for order_line in self.browse(cr, uid, ids, context=context):
if order_line.transit_move_line_id:
order_type = order_line.order_id.payment_order_type
trf_lines = order_line.transit_move_line_id.move_id.line_id
for move_line in trf_lines:
if order_type == 'debit' and move_line.debit > 0:
res[order_line.id] = move_line.id
elif order_type == 'payment' and move_line.credit > 0:
res[order_line.id] = move_line.id
else:
res[order_line.id] = False
return res
_columns = {
'msg': fields.char('Message', size=255, required=False, readonly=True),
'date_done': fields.date(
'Date Confirmed', select=True, readonly=True),
'transit_move_line_id': fields.many2one(
'account.move.line', 'Transfer move line',
readonly=True,
help="Move line through which the payment/debit order "
"pays the invoice",
),
'transfer_move_line_id': fields.function(
_get_transfer_move_line,
type='many2one',
relation='account.move.line',
string='Transfer move line counterpart',
readonly=True,
help="Counterpart move line on the transfer account",
),
}
_defaults = {
'msg': '',
}
"""
Hooks for processing direct debit orders, such as implemented in
account_direct_debit module.
"""
def get_storno_account_id(self, cr, uid, payment_line_id, amount,
currency_id, context=None):
"""
Hook for verifying a match of the payment line with the amount.
Return the account associated with the storno.
Used in account_banking interactive mode
:param payment_line_id: the single payment line id
:param amount: the (signed) amount debited from the bank account
:param currency: the bank account's currency *browse object*
:return: an account if there is a full match, False otherwise
:rtype: database id of an account.account resource.
"""
return False
def debit_storno(self, cr, uid, payment_line_id, amount,
currency_id, storno_retry=True, context=None):
"""
Hook for handling a canceled item of a direct debit order.
Presumably called from a bank statement import routine.
Decide on the direction that the invoice's workflow needs to take.
You may optionally return an incomplete reconcile for the caller
to reconcile the now void payment.
:param payment_line_id: the single payment line id
:param amount: the (negative) amount debited from the bank account
:param currency: the bank account's currency *browse object*
:param boolean storno_retry: whether the storno is considered fatal \
or not.
:return: an incomplete reconcile for the caller to fill
:rtype: database id of an account.move.reconcile resource.
"""
return False
def debit_reconcile(self, cr, uid, payment_line_id, context=None):
"""
Reconcile a debit order's payment line with the the move line
that it is based on. Called from payment_order.action_sent().
As the amount is derived directly from the counterpart move line,
we do not expect a write off. Take partial reconciliations into
account though.
:param payment_line_id: the single id of the canceled payment line
"""
if isinstance(payment_line_id, (list, tuple)):
payment_line_id = payment_line_id[0]
reconcile_obj = self.pool.get('account.move.reconcile')
move_line_obj = self.pool.get('account.move.line')
payment_line = self.browse(cr, uid, payment_line_id, context=context)
transit_move_line = payment_line.transit_move_line_id
torec_move_line = payment_line.move_line_id
if (not transit_move_line or not torec_move_line):
raise orm.except_orm(
_('Can not reconcile'),
_('No move line for line %s') % payment_line.name
)
if torec_move_line.reconcile_id:
raise orm.except_orm(
_('Error'),
_('Move line %s has already been reconciled') %
torec_move_line.name
)
if (transit_move_line.reconcile_id or
transit_move_line.reconcile_partial_id):
raise orm.except_orm(
_('Error'),
_('Move line %s has already been reconciled') %
transit_move_line.name
)
def is_zero(total):
return self.pool.get('res.currency').is_zero(
cr, uid, transit_move_line.company_id.currency_id, total)
line_ids = [transit_move_line.id, torec_move_line.id]
if torec_move_line.reconcile_partial_id:
line_ids = [
x.id for x in
torec_move_line.reconcile_partial_id.line_partial_ids
] + [transit_move_line.id]
total = move_line_obj.get_balance(cr, uid, line_ids)
vals = {
'type': 'auto',
'line_id': is_zero(total) and [(6, 0, line_ids)] or [(6, 0, [])],
'line_partial_ids': (is_zero(total) and
[(6, 0, [])] or
[(6, 0, line_ids)]),
}
if torec_move_line.reconcile_partial_id:
reconcile_obj.write(
cr, uid, [torec_move_line.reconcile_partial_id.id],
vals, context=context)
else:
reconcile_obj.create(
cr, uid, vals, context=context)
workflow = netsvc.LocalService("workflow")
for line_id in line_ids:
workflow.trg_trigger(
uid, 'account.move.line', line_id, cr)
# If a bank transaction of a storno was first confirmed
# and now canceled (the invoice is now in state 'debit_denied'
if torec_move_line.invoice:
workflow.trg_validate(
uid, 'account.invoice', torec_move_line.invoice.id,
'undo_debit_denied', cr)

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
# (C) 2014 Akretion (www.akretion.com)
#
# All other contributions are (C) by their respective contributors
#
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
class PaymentMode(orm.Model):
_inherit = "payment.mode"
_columns = {
'transfer_account_id': fields.many2one(
'account.account', 'Transfer account',
domain=[('type', '=', 'other'), ('reconcile', '=', True)],
help='Pay off lines in sent orders with a move on this '
'account. You can only select accounts of type regular '
'that are marked for reconciliation'),
'transfer_journal_id': fields.many2one(
'account.journal', 'Transfer journal',
help='Journal to write payment entries when confirming '
'a debit order of this mode'),
'transfer_move_option': fields.selection([
('date', 'One move per payment date'),
('line', 'One move per payment line'),
], 'Transfer move option')
}
_defaults = {
'transfer_move_option': 'date',
}

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Add the payment mode transfer account settings
-->
<record id="view_payment_mode_form_inherit" model="ir.ui.view">
<field name="name">payment.mode.form.inherit</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_banking_payment_export.view_payment_mode_form_inherit"/>
<field name="arch" type="xml">
<xpath expr="/form/group[@col='4']" position="inside">
<group name="trf-move-config" string="Transfer move settings" colspan="2">
<field name="transfer_account_id"
domain="[('type', '=', 'other'),
('reconcile', '=', True),
('company_id', '=', company_id)]"
context="{
'default_type': 'other',
'default_reconcile': True,
'default_company_id': company_id}"
/>
<field name="transfer_journal_id"
domain="[('company_id', '=', company_id)]"
/>
<field name="transfer_move_option"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="account_payment.act_done" model="workflow.activity">
<field name="action">action_done()</field>
</record>
</data>
</openerp>

View File

@@ -1,68 +0,0 @@
=======================================
Account Default Report Without Paiement
=======================================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2035514c3af2d372479b91ca5314fe2f5ff90523f11fb8cc874b4fac8b375f50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github
:target: https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement
:alt: akretion/odoo-usability
|badge1| |badge2| |badge3|
This module switch the default account report to the one without paiement
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/akretion/odoo-usability/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_default_report_without_paiement%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Akretion
Contributors
~~~~~~~~~~~~
* Kévin Roche <kevin.roche@akretion.com>
Maintainers
~~~~~~~~~~~
.. |maintainer-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px
:target: https://github.com/Kev-Roche
:alt: Kev-Roche
Current maintainer:
|maintainer-Kev-Roche|
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement>`_ project on GitHub.
You are welcome to contribute.

View File

@@ -1,22 +0,0 @@
# Copyright 2024 Akretion (https://www.akretion.com).
# @author Kévin Roche <kevin.roche@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Account Default Report Without Paiement",
"summary": "Account Default Report Without Paiement",
"version": "14.0.1.0.0",
"category": "reports",
"website": "https://github.com/OCA/account",
"author": "Akretion, Odoo Community Association (OCA)",
"license": "AGPL-3",
"maintainers":["Kev-Roche"],
"application": False,
"installable": True,
"depends": [
"account",
],
"data": [
"data/data.xml",
],
}

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright (C) 2024 Akretion (<http://www.akretion.com>).
@author Kévin Roche <kevin.roche@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="account.account_invoices" model="ir.actions.report">
<field name="report_name">account.report_invoice</field>
<field name="report_file">account.report_invoice</field>
</record>
<record id="account.account_invoices_without_payment" model="ir.actions.report">
<field name="name">Factures avec paiement</field>
<field name="report_name">account.report_invoice_with_payments</field>
<field name="report_file">account.report_invoice_with_payments</field>
</record>
</odoo>

View File

@@ -1 +0,0 @@
* Kévin Roche <kevin.roche@akretion.com>

View File

@@ -1 +0,0 @@
This module switch the default account report to the one without paiement

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,418 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Account Default Report Without Paiement</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="account-default-report-without-paiement">
<h1 class="title">Account Default Report Without Paiement</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2035514c3af2d372479b91ca5314fe2f5ff90523f11fb8cc874b4fac8b375f50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p>This module switch the default account report to the one without paiement</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/akretion/odoo-usability/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_default_report_without_paiement%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Kévin Roche &lt;<a class="reference external" href="mailto:kevin.roche&#64;akretion.com">kevin.roche&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>Current maintainer:</p>
<p><a class="reference external image-reference" href="https://github.com/Kev-Roche"><img alt="Kev-Roche" src="https://github.com/Kev-Roche.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement">akretion/odoo-usability</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>
</div>
</body>
</html>

View File

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

View File

@@ -1,23 +0,0 @@
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Account Fiscal Position Payable Receivable",
"version": "12.0.1.0.0",
"category": "Accounting & Finance",
"license": "AGPL-3",
"summary": "Configure payable/receivable accounts on fiscal positions",
"description": """
Account Fiscal Position Payable Receivable
==========================================
This module allows to configure a special *Partner Receivable Account* and a special *Partner Payable Account* on fiscal positions. This is used in the onchange of the fiscal position of partners.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
"author": "Akretion",
"website": "http://www.akretion.com",
"depends": ["account"],
"data": ["views/account_fiscal_position_view.xml"],
"installable": False,
}

View File

@@ -1,2 +0,0 @@
from . import account_fiscal_position
from . import res_partner

View File

@@ -1,21 +0,0 @@
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields
class AccountFiscalPosition(models.Model):
_inherit = "account.fiscal.position"
receivable_account_id = fields.Many2one(
"account.account",
string="Partner Receivable Account",
company_dependent=True,
domain=[("internal_type", "=", "receivable")],
)
payable_account_id = fields.Many2one(
"account.account",
string="Partner Payable Account",
company_dependent=True,
domain=[("internal_type", "=", "payable")],
)

View File

@@ -1,25 +0,0 @@
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, api
class ResPartner(models.Model):
_inherit = "res.partner"
@api.onchange("property_account_position_id")
def fiscal_position_receivable_payable_change(self):
fp = self.property_account_position_id
ipo = self.env["ir.property"]
if fp.receivable_account_id:
self.property_account_receivable_id = fp.receivable_account_id
else:
self.property_account_receivable_id = ipo.get(
"property_account_receivable_id", "res.partner"
)
if fp.payable_account_id:
self.property_account_payable_id = fp.payable_account_id
else:
self.property_account_payable_id = ipo.get(
"property_account_payable_id", "res.partner"
)

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_account_position_form" model="ir.ui.view">
<field name="name">receivable_payable.fiscal_position_form</field>
<field name="model">account.fiscal.position</field>
<field name="inherit_id" ref="account.view_account_position_form" />
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="receivable_account_id"/>
<field name="payable_account_id"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Del Attachment Cancel module for OpenERP
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_invoice

View File

@@ -0,0 +1,45 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Del Attachment Cancel module for OpenERP
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Invoice Delete Attachment on Cancel',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Delete the attachment on the invoice when it is cancelled',
'description': """
Account Invoice Delete Attachment on Cancel
===========================================
When an invoice is validated, on the first generation of the invoice report, a copy of the report is stored as attachment on the invoice. After that, every time you a user asks for the Invoice report, it will be taken from the attachment.
With this module, when an invoice is cancelled, the attachment is deleted.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'data': [],
'installable': True,
}

View File

@@ -0,0 +1,53 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Del Attachment Cancel module for OpenERP
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
from openerp.tools.translate import _
class AccountInvoice(orm.Model):
_inherit = 'account.invoice'
def action_cancel(self, cr, uid, ids, context=None):
res = super(AccountInvoice, self).action_cancel(
cr, uid, ids, context=context)
iao = self.pool['ir.attachment']
for invoice in self.browse(cr, uid, ids, context=context):
# search for attachments
if 'out' in invoice.type:
attach_ids = iao.search(
cr, uid, [
('res_id', '=', invoice.id),
('res_model', '=', self._name),
('type', '=', 'binary'),
('datas_fname', '=like', 'INV%.pdf'),
], context=context)
if len(attach_ids) == 1:
# delete attachment
attach = iao.browse(
cr, uid, attach_ids[0], context=context)
attach_name = attach.name
iao.unlink(cr, uid, attach_ids, context=context)
self.message_post(
cr, uid, invoice.id,
_('Attachement %s has been deleted') % attach_name)
return res

View File

@@ -1 +1,3 @@
from . import models
# -*- coding: utf-8 -*-
from . import account_invoice

View File

@@ -1,24 +0,0 @@
# Copyright 2015-2019 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Invoice Margin',
'version': '14.0.1.0.0',
'category': 'Invoicing Management',
'license': 'AGPL-3',
'summary': 'Copy standard price on invoice line and compute margins',
'description': """
This module copies the field *standard_price* of the product on the invoice line when the invoice line is created. The allows the computation of the margin of the invoice.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['account'],
'data': [
'views/account_move.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Margin module for Odoo
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Invoice Margin',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Copy standard price on invoice line and compute margins',
'description': """
This module copies the field *standard_price* of the product on the invoice line when the invoice line is created. The allows the computation of the margin of the invoice.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'data': [
'account_invoice_view.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,286 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Margin module for Odoo
# Copyright (C) 2015-2016 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
import openerp.addons.decimal_precision as dp
class AccountInvoiceLine(orm.Model):
_inherit = 'account.invoice.line'
def _compute_margin(self, cr, uid, ids, name, arg, context=None):
if context is None:
context = {}
res = {}
# we need an up-to-date price_subtotal
# We cannot read il.price_subtotal, because it may be out-of-date
# (I saw that with invoices in foreign currency)
price_subtotal = self._amount_line(cr, uid, ids, name, arg, context)
for il in self.browse(cr, uid, ids, context=context):
standard_price_inv_cur = 0.0
margin_inv_cur = 0.0
margin_comp_cur = 0.0
margin_rate = 0.0
if (
il.invoice_id and
il.invoice_id.type in ('out_invoice', 'out_refund')):
# it works in _get_current_rate
# even if we set date = False in context
# standard_price_inv_cur is in the UoM of the invoice line
rco = self.pool['res.currency']
ctx_currency = context.copy()
if il.invoice_id.date_invoice:
ctx_currency['date'] = il.invoice_id.date_invoice
standard_price_inv_cur =\
rco.compute(
cr, uid, il.invoice_id.company_id.currency_id.id,
il.invoice_id.currency_id.id,
il.standard_price_company_currency,
context=ctx_currency)
margin_inv_cur =\
price_subtotal[il.id] - il.quantity * standard_price_inv_cur
margin_comp_cur = rco.compute(
cr, uid, il.invoice_id.currency_id.id,
il.invoice_id.company_id.currency_id.id,
margin_inv_cur, context=ctx_currency)
if price_subtotal[il.id]:
margin_rate = 100 * margin_inv_cur / price_subtotal[il.id]
# for a refund, margin should be negative
# but margin rate should stay positive
if il.invoice_id.type == 'out_refund':
margin_inv_cur *= -1
margin_comp_cur *= -1
res[il.id] = {
'standard_price_invoice_currency': standard_price_inv_cur,
'margin_invoice_currency': margin_inv_cur,
'margin_company_currency': margin_comp_cur,
'margin_rate': margin_rate,
}
return res
def _get_lines_from_invoices(self, cr, uid, ids, context=None):
return self.pool['account.invoice.line'].search(
cr, uid, [('invoice_id', 'in', ids)], context=context)
_columns = {
'standard_price_company_currency': fields.float(
'Cost Price per Unit in Company Currency', readonly=True,
digits_compute=dp.get_precision('Product Price'),
help="Cost price in company currency in the unit of measure "
"of the invoice line (which may be different from the unit "
"of measure of the product)."),
'standard_price_invoice_currency': fields.function(
_compute_margin, string='Cost Price per Unit in Invoice Currency',
type='float', readonly=True, multi='il-margin', store={
'account.invoice.line': (
lambda self, cr, uid, ids, c={}: ids, [
'standard_price_company_currency',
'quantity',
'price_unit',
'discount',
'invoice_line_tax_id'], 10),
'account.invoice': (
_get_lines_from_invoices, [
'type',
'currency_id',
'date_invoice',
'company_id'], 20),
},
digits_compute=dp.get_precision('Product Price'),
help="Cost price in invoice currency in the unit of measure "
"of the invoice line"),
'margin_invoice_currency': fields.function(
_compute_margin, string='Margin in Invoice Currency',
type='float', readonly=True, multi='il-margin', store={
'account.invoice.line': (
lambda self, cr, uid, ids, c={}: ids, [
'standard_price_company_currency',
'quantity',
'price_unit',
'discount',
'invoice_line_tax_id'], 10),
'account.invoice': (
_get_lines_from_invoices, [
'type',
'currency_id',
'date_invoice',
'company_id'], 20),
},
digits_compute=dp.get_precision('Account')),
'margin_company_currency': fields.function(
_compute_margin, type='float',
string='Margin in Company Currency', readonly=True,
multi='il-margin', store={
'account.invoice.line': (
lambda self, cr, uid, ids, c={}: ids, [
'standard_price_company_currency',
'quantity',
'price_unit',
'discount',
'invoice_line_tax_id'], 10),
'account.invoice': (
_get_lines_from_invoices, [
'type',
'currency_id',
'date_invoice',
'company_id'], 20),
},
digits_compute=dp.get_precision('Account')),
'margin_rate': fields.function(
_compute_margin, type='float',
string="Margin Rate", readonly=True, multi='il-margin', store={
'account.invoice.line': (
lambda self, cr, uid, ids, c={}: ids, [
'standard_price_company_currency',
'quantity',
'price_unit',
'discount',
'invoice_line_tax_id'], 10),
'account.invoice': (
_get_lines_from_invoices, [
'type',
'currency_id',
'date_invoice',
'company_id'], 20),
},
digits=(16, 2),
help="Margin rate in percentage of the sale price"),
}
# We want to copy standard_price on invoice line for customer
# invoice/refunds. We can't do that via on_change of product_id,
# because it is not always played when invoice is created from code
# => we inherit write/create
# We write standard_price_company_currency even on supplier invoice/refunds
# because we don't have access to the 'type' of the invoice
def create(self, cr, uid, vals, context=None):
if (
vals.get('product_id') and
'standard_price_company_currency' not in vals):
pp = self.pool['product.product'].browse(
cr, uid, vals['product_id'], context=context)
std_price = pp.standard_price
inv_uom_id = vals.get('uos_id')
if inv_uom_id and inv_uom_id != pp.uom_id.id:
std_price = self.pool['product.uom']._compute_price(
cr, uid, pp.uom_id.id, std_price, inv_uom_id)
vals['standard_price_company_currency'] = std_price
return super(AccountInvoiceLine, self).create(
cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
"""This code can seem a bit strange with the super() inside
the loop, but it is required if we want to support all scenarios,
including very strange scenarios where you write a uos_id on
several lines with different products, etc...
OK, these scenarios will probably never happen, but I prefer
to make sure that the code is right and works in all
scenarios
"""
if not vals:
vals = {}
if isinstance(ids, (int, long)):
ids = [ids]
if 'product_id' in vals or 'uos_id' in vals:
for il in self.browse(cr, uid, ids, context=context):
if 'product_id' in vals:
if vals.get('product_id'):
pp = self.pool['product.product'].browse(
cr, uid, vals['product_id'], context=context)
else:
pp = False
else:
pp = il.product_id or False
# uos_id is NOT a required field
if 'uos_id' in vals:
if vals.get('uos_id'):
inv_uom = self.pool['product.uom'].browse(
cr, uid, vals['uos_id'], context=context)
else:
inv_uom = False
else:
inv_uom = il.uos_id or False
std_price = 0.0
if pp:
std_price = pp.standard_price
if inv_uom and inv_uom != pp.uom_id:
std_price = self.pool['product.uom']._compute_price(
cr, uid, pp.uom_id.id, std_price, inv_uom.id)
vals_line = vals.copy()
vals_line['standard_price_company_currency'] = std_price
super(AccountInvoiceLine, self).write(
cr, uid, [il.id], vals_line, context=context)
return True
else:
return super(AccountInvoiceLine, self).write(
cr, uid, ids, vals, context=context)
class AccountInvoice(orm.Model):
_inherit = 'account.invoice'
def _compute_margin(self, cr, uid, ids, name, arg, context=None):
res = {}
for inv in self.browse(cr, uid, ids, context=context):
margin_inv_cur = 0.0
margin_comp_cur = 0.0
if inv.type in ('out_invoice', 'out_refund'):
for il in inv.invoice_line:
margin_inv_cur += il.margin_invoice_currency
margin_comp_cur += il.margin_company_currency
res[inv.id] = {
'margin_invoice_currency': margin_inv_cur,
'margin_company_currency': margin_comp_cur,
}
return res
def _get_invoices_from_inv_lines(self, cr, uid, ids, context=None):
return self.pool['account.invoice'].search(
cr, uid, [('invoice_line', 'in', ids)], context=context)
_columns = {
'margin_invoice_currency': fields.function(
_compute_margin, type='float',
string='Margin in Invoice Currency',
readonly=True, multi='inv-margin',
digits_compute=dp.get_precision('Account'), store={
'account.invoice': (
lambda self, cr, uid, ids, c={}: ids, [
'type', 'currency_id'], 10),
'account.invoice.line': (
_get_invoices_from_inv_lines, [
'margin_company_currency'], 20),
}),
'margin_company_currency': fields.function(
_compute_margin, type='float',
string='Margin in Company Currency',
readonly=True, multi='inv-margin',
digits_compute=dp.get_precision('Account'), store={
'account.invoice': (
lambda self, cr, uid, ids, c={}: ids, [
'type', 'currency_id'], 10),
'account.invoice.line': (
_get_invoices_from_inv_lines, [
'margin_company_currency'], 20),
}),
}

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="view_invoice_line_form" model="ir.ui.view">
<field name="name">margin.account.invoice.line.form</field>
<field name="model">account.invoice.line</field>
<field name="inherit_id" ref="account.view_invoice_line_form"/>
<field name="arch" type="xml">
<field name="discount" position="after">
<field name="standard_price_company_currency"
groups="account.group_account_user"/>
<field name="standard_price_invoice_currency"
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="account.group_account_user"/>
<field name="margin_invoice_currency"
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="account.group_account_user"/>
<field name="margin_company_currency"
groups="account.group_account_user"/>
</field>
</field>
</record>
<record id="invoice_form" model="ir.ui.view">
<field name="name">margin.account.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<field name="move_id" position="after">
<field name="margin_invoice_currency"
string="Margin"
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="account.group_account_user"/>
<field name="margin_company_currency"
groups="account.group_account_user"/>
</field>
<xpath expr="//field[@name='invoice_line']/tree/field[@name='price_subtotal']" position="after">
<field name="standard_price_invoice_currency" groups="account.group_account_user"/>
<field name="standard_price_company_currency" groups="base.group_no_one"/>
<field name="margin_invoice_currency" groups="account.group_account_user"/>
<field name="margin_company_currency" groups="base.group_no_one"/>
<field name="margin_rate" groups="base.group_no_one"/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -1,2 +0,0 @@
from . import account_move
from . import account_invoice_report

View File

@@ -1,36 +0,0 @@
# Copyright 2018-2019 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
margin = fields.Float(string='Margin', readonly=True)
# added margin_company_currency on account.move.line
_depends = {
'account.move': [
'name', 'state', 'move_type', 'partner_id', 'invoice_user_id', 'fiscal_position_id',
'invoice_date', 'invoice_date_due', 'invoice_payment_term_id', 'partner_bank_id',
],
'account.move.line': [
'quantity', 'price_subtotal', 'amount_residual', 'balance', 'amount_currency',
'move_id', 'product_id', 'product_uom_id', 'account_id', 'analytic_account_id',
'journal_id', 'company_id', 'currency_id', 'partner_id',
'margin_company_currency',
],
'product.product': ['product_tmpl_id'],
'product.template': ['categ_id'],
'uom.uom': ['category_id', 'factor', 'name', 'uom_type'],
'res.currency.rate': ['currency_id', 'name'],
'res.partner': ['country_id'],
}
@api.model
def _select(self):
select_str = super()._select()
select_str += ", line.margin_company_currency * currency_table.rate AS margin"
return select_str

View File

@@ -1,155 +0,0 @@
# Copyright 2015-2021 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
standard_price_company_currency = fields.Float(
string='Unit Cost Price in Company Currency', readonly=True,
digits='Product Price',
help="Unit Cost price in company currency in the unit of measure "
"of the invoice line (which may be different from the unit "
"of measure of the product).")
standard_price_invoice_currency = fields.Float(
string='Unit Cost Price in Invoice Currency',
compute='_compute_margin', store=True, digits='Product Price',
help="Unit Cost price in invoice currency in the unit of measure "
"of the invoice line.")
margin_invoice_currency = fields.Monetary(
string='Margin in Invoice Currency', store=True,
compute='_compute_margin', currency_field='currency_id')
margin_company_currency = fields.Monetary(
string='Margin in Company Currency', store=True,
compute='_compute_margin', currency_field='company_currency_id')
margin_rate = fields.Float(
string="Margin Rate", readonly=True, store=True,
compute='_compute_margin',
digits=(16, 2), help="Margin rate in percentage of the sale price")
@api.depends(
'standard_price_company_currency', 'move_id.currency_id',
'move_id.move_type', 'move_id.company_id',
'move_id.invoice_date', 'quantity', 'price_subtotal')
def _compute_margin(self):
for ml in self:
standard_price_inv_cur = 0.0
margin_inv_cur = 0.0
margin_comp_cur = 0.0
margin_rate = 0.0
move = ml.move_id
if move.move_type and move.move_type in ('out_invoice', 'out_refund'):
# it works in _get_current_rate
# even if we set date = False in context
# standard_price_inv_cur is in the UoM of the invoice line
date = move.date or fields.Date.context_today(self)
company = move.company_id
company_currency = company.currency_id
standard_price_inv_cur =\
company_currency._convert(
ml.standard_price_company_currency,
ml.currency_id, company, date)
margin_inv_cur =\
ml.price_subtotal - ml.quantity * standard_price_inv_cur
margin_comp_cur = move.currency_id._convert(
margin_inv_cur, company_currency, company, date)
if ml.price_subtotal:
margin_rate = 100 * margin_inv_cur / ml.price_subtotal
# for a refund, margin should be negative
# but margin rate should stay positive
if move.move_type == 'out_refund':
margin_inv_cur *= -1
margin_comp_cur *= -1
ml.standard_price_invoice_currency = standard_price_inv_cur
ml.margin_invoice_currency = margin_inv_cur
ml.margin_company_currency = margin_comp_cur
ml.margin_rate = margin_rate
# We want to copy standard_price on invoice line for customer
# invoice/refunds. We can't do that via on_change of product_id,
# because it is not always played when invoice is created from code
# => we inherit write/create
# We write standard_price_company_currency even on supplier invoice/refunds
# because we don't have access to the 'type' of the invoice
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('product_id') and not vals.get('display_type'):
pp = self.env['product.product'].browse(vals['product_id'])
std_price = pp.standard_price
inv_uom_id = vals.get('product_uom_id')
if inv_uom_id and inv_uom_id != pp.uom_id.id:
inv_uom = self.env['uom.uom'].browse(inv_uom_id)
std_price = pp.uom_id._compute_price(
std_price, inv_uom)
vals['standard_price_company_currency'] = std_price
return super().create(vals_list)
def write(self, vals):
if not vals:
vals = {}
if 'product_id' in vals or 'product_uom_id' in vals:
for il in self:
if 'product_id' in vals:
if vals.get('product_id'):
pp = self.env['product.product'].browse(
vals['product_id'])
else:
pp = False
else:
pp = il.product_id or False
# uom_id is NOT a required field
if 'product_uom_id' in vals:
if vals.get('product_uom_id'):
inv_uom = self.env['uom.uom'].browse(
vals['product_uom_id'])
else:
inv_uom = False
else:
inv_uom = il.uom_id or False
std_price = 0.0
if pp:
std_price = pp.standard_price
if inv_uom and inv_uom != pp.uom_id:
std_price = pp.uom_id._compute_price(
std_price, inv_uom)
il.write({'standard_price_company_currency': std_price})
return super().write(vals)
class AccountMove(models.Model):
_inherit = 'account.move'
margin_invoice_currency = fields.Monetary(
string='Margin in Invoice Currency',
compute='_compute_margin', store=True,
currency_field='currency_id')
margin_company_currency = fields.Monetary(
string='Margin in Company Currency',
compute='_compute_margin', store=True,
currency_field='company_currency_id')
@api.depends(
'move_type',
'invoice_line_ids.margin_invoice_currency',
'invoice_line_ids.margin_company_currency')
def _compute_margin(self):
rg_res = self.env['account.move.line'].read_group(
[
('move_id', 'in', self.ids),
('display_type', '=', False),
('exclude_from_invoice_tab', '=', False),
('move_id.move_type', 'in', ('out_invoice', 'out_refund')),
],
['move_id', 'margin_invoice_currency:sum', 'margin_company_currency:sum'],
['move_id'])
mapped_data = dict([(x['move_id'][0], {
'margin_invoice_currency': x['margin_invoice_currency'],
'margin_company_currency': x['margin_company_currency'],
}) for x in rg_res])
for move in self:
move.margin_invoice_currency = mapped_data.get(move.id, {}).get('margin_invoice_currency')
move.margin_company_currency = mapped_data.get(move.id, {}).get('margin_company_currency')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015-2024 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_move_form" model="ir.ui.view">
<field name="name">margin.account.move.form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<group name="sale_info_group" position="inside">
<field name="margin_invoice_currency"
groups="base.group_no_one"
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="margin_company_currency"
groups="base.group_no_one"
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
</group>
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='price_total']" position="after">
<field name="standard_price_invoice_currency" optional="hide" attrs="{'column_invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="margin_invoice_currency" optional="hide" attrs="{'column_invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="margin_rate" optional="hide" string="Margin Rate (%)" attrs="{'column_invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
</xpath>
<xpath expr="//field[@name='invoice_line_ids']/form//field[@name='price_total']/.." position="inside">
<field name="standard_price_company_currency"
groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="standard_price_invoice_currency"
groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="margin_invoice_currency"
groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<field name="margin_company_currency"
groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<label for="margin_rate" groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
<div name="margin_rate" groups="base.group_no_one" attrs="{'invisible': [('parent.move_type', 'not in', ('out_invoice', 'out_refund'))]}">
<field name="margin_rate" class="oe_inline"/> %
</div>
</xpath>
</field>
</record>
<record id="view_invoice_tree" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_invoice_tree"/>
<field name="arch" type="xml">
<field name="amount_residual_signed" position="after">
<field name="margin_company_currency" optional="hide" sum="1" invisible="context.get('default_move_type') not in ('out_invoice', 'out_refund')" string="Margin"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,21 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Overdue Filter module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

View File

@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Overdue Filter module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Invoice Overdue Filter',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Add an Overdue filter in the invoice search view',
'description': """
Account Invoice Overdue Filter
==============================
This module adds a filter *Overdue* in the invoice search view.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'data': ['account_invoice_view.xml'],
'installable': True,
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="view_account_invoice_filter" model="ir.ui.view">
<field name="name">filter.overdue.account.invoice.search</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<filter name="unpaid" position="after">
<filter name="overdue" string="Overdue"
domain="[('state', '=', 'open'), ('date_due', '&lt;', current_date)]"/>
</filter>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Partner Bank Usability module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_invoice

View File

@@ -0,0 +1,45 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Partner Bank Usability module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Invoice Partner Bank Usability',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'If the company has a single bank account, get the first one on the customer invoice',
'description': """
Account Invoice Partner Bank Usability
======================================
If the company has a single bank account, we set this single bank account by default on the customer invoice.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'data': [],
'images': [],
'installable': True,
'active': False,
}

View File

@@ -0,0 +1,46 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Partner Bank Usability module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
class account_invoice(orm.Model):
_inherit = "account.invoice"
def invoice_out_get_first_partner_bank(self, cr, uid, context=None):
'''Get the first bank account of your company on customer invoice
if your company only has one bank account'''
if context is None:
context = {}
res_partner_bank_id = False
if context.get('type') == 'out_invoice' or \
context.get('inv_type') == 'out_invoice':
cur_user = self.pool['res.users'].browse(
cr, uid, uid, context=context)
partner_banks = cur_user.company_id.partner_id.bank_ids
if partner_banks and len(partner_banks) == 1:
res_partner_bank_id = partner_banks[0].id
return res_partner_bank_id
_defaults = {
'partner_bank_id': invoice_out_get_first_partner_bank,
}

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Sale Link module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_invoice

View File

@@ -0,0 +1,44 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Sale Link module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Invoice Sale Link',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Add the reverse link from invoices to sale orders',
'description': """
Account Invoice Sale Link
=========================
On the customer invoice report, you usually need to display the customer order number. For that, you need to have the link from invoices to sale orders, and this link is not available in the official addons.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['sale'],
'data': [],
'installable': True,
'active': False,
}

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Sale Link module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
class account_invoice(orm.Model):
_inherit = 'account.invoice'
_columns = {
# This is the reverse link of the field 'invoice_ids' of sale.order
# defined in addons/sale/sale.py
'sale_ids': fields.many2many(
'sale.order', 'sale_order_invoice_rel', 'invoice_id',
'order_id', 'Sale Orders', readonly=True,
help="This is the list of sale orders related to this invoice."),
}

View File

@@ -1,39 +0,0 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Account Invoice Update Wizard
=============================
This module adds a button *Update Invoice* on Customer and Supplier invoices in
Open or Paid state. This button starts a wizard which allows the user to update
non-legal fields of the invoice:
* Source Document
* Reference/Description
* Payment terms (update allowed only to a payment term with same number of terms
of the same amount and on invoices without any payment)
* Bank Account
* Salesman
* Notes
* Description of invoice lines
* Analytic account
* Analytic tags
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/akretion/odoo-usability/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>
* Florian da Costa <florian.dacosta@akretion.com>
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Mykhailo Panarin <m.panarin@mobilunity.com>
* Artem Kostyuk <a.kostyuk@mobilunity.com>

View File

@@ -1,2 +0,0 @@
from . import models
from . import wizard

View File

@@ -1,22 +0,0 @@
# Copyright 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# Copyright 2018-2019 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Invoice Update Wizard',
'version': '14.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Wizard to update non-legal fields of an open/paid invoice',
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': [
'account',
],
'data': [
'security/ir.model.access.csv',
'wizard/account_move_update_view.xml',
'views/account_move.xml',
],
'installable': True,
}

View File

@@ -1,243 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_invoice_update_wizard
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \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: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__price_subtotal
msgid "Amount"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__analytic_account_id
msgid "Analytic Account"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__analytic_tag_ids
msgid "Analytic Tags"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__partner_bank_id
msgid "Bank Account"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Bill Reference"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Cancel"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__company_id
msgid "Company"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__create_uid
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__create_uid
msgid "Created by"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__create_date
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__create_date
msgid "Created on"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__currency_id
msgid "Currency"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Customer Reference"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__name
msgid "Description"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move__display_name
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__display_name
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__display_name
msgid "Display Name"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__display_type
msgid "Display Type"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move__id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__id
msgid "ID"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_id
msgid "Invoice"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__invoice_line_id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__line_ids
msgid "Invoice Lines"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.actions.act_window,name:account_invoice_update_wizard.account_invoice_update_action
msgid "Invoice Update Wizard"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move
msgid "Journal Entry"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move____last_update
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update____last_update
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update____last_update
msgid "Last Modified on"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__write_uid
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__write_date
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid "Non-legal fields of invoice updated via the Invoice Update wizard."
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields.selection,name:account_invoice_update_wizard.selection__account_move_line_update__display_type__line_note
msgid "Note"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__partner_id
msgid "Partner"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_payment_term_id
msgid "Payment Term"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__quantity
msgid "Quantity"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__ref
msgid "Reference"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__user_id
msgid "Salesperson"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields.selection,name:account_invoice_update_wizard.selection__account_move_line_update__display_type__line_section
msgid "Section"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__sequence
msgid "Sequence"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_origin
msgid "Source Document"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,help:account_invoice_update_wizard.field_account_move_line_update__display_type
msgid "Technical field for UX purpose."
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid ""
"The original payment term '%s' doesn't have the same terms (number of terms "
"and/or amount) as the new payment term '%s'. You can only switch to a "
"payment term that has the same number of terms with the same amount."
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid ""
"This wizard doesn't support the update of payment terms on an invoice which "
"is partially or fully paid."
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__move_type
msgid "Type"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Update"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.view_move_form_inherit
msgid "Update Invoice"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Update Invoice Wizard"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move_line_update
msgid "Update non-legal fields of invoice lines"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__parent_id
msgid "Wizard"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move_update
msgid "Wizard to update non-legal fields of invoice"
msgstr ""

View File

@@ -1,250 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_invoice_update_wizard
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__price_subtotal
msgid "Amount"
msgstr "Montant"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__analytic_account_id
msgid "Analytic Account"
msgstr "Compte Analytique"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__analytic_tag_ids
msgid "Analytic Tags"
msgstr "Tag Analytique"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__partner_bank_id
msgid "Bank Account"
msgstr "Compte Bancaire"
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
#, fuzzy
msgid "Bill Reference"
msgstr "Reference Client"
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Cancel"
msgstr "Annuler"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__company_id
msgid "Company"
msgstr "Société"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__create_uid
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__create_date
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__create_date
msgid "Created on"
msgstr "Créé le"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__currency_id
msgid "Currency"
msgstr "Devise"
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
#, fuzzy
msgid "Customer Reference"
msgstr "Reference Client"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__name
msgid "Description"
msgstr "Description"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move__display_name
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__display_name
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__display_name
msgid "Display Name"
msgstr "Nom"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__display_type
msgid "Display Type"
msgstr "Type Affichage"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move__id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__id
msgid "ID"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_id
msgid "Invoice"
msgstr "Facture"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__invoice_line_id
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__line_ids
msgid "Invoice Lines"
msgstr "Ligne de factures"
#. module: account_invoice_update_wizard
#: model:ir.actions.act_window,name:account_invoice_update_wizard.account_invoice_update_action
msgid "Invoice Update Wizard"
msgstr "Assistance de mise à jour de la facture"
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move
msgid "Journal Entry"
msgstr "Entrée comptable"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move____last_update
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update____last_update
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update____last_update
msgid "Last Modified on"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__write_uid
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__write_date
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid "Non-legal fields of invoice updated via the Invoice Update wizard."
msgstr "Champs non légaux mis à jour via l'assistant"
#. module: account_invoice_update_wizard
#: model:ir.model.fields.selection,name:account_invoice_update_wizard.selection__account_move_line_update__display_type__line_note
msgid "Note"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__partner_id
msgid "Partner"
msgstr "Client"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_payment_term_id
msgid "Payment Term"
msgstr "Condition de paiement"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__quantity
msgid "Quantity"
msgstr "Quantité"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__ref
#, fuzzy
msgid "Reference"
msgstr "Reference Client"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__user_id
msgid "Salesperson"
msgstr "Vendeur"
#. module: account_invoice_update_wizard
#: model:ir.model.fields.selection,name:account_invoice_update_wizard.selection__account_move_line_update__display_type__line_section
msgid "Section"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__sequence
msgid "Sequence"
msgstr "Sequence"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__invoice_origin
msgid "Source Document"
msgstr "Origine du document"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,help:account_invoice_update_wizard.field_account_move_line_update__display_type
msgid "Technical field for UX purpose."
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid ""
"The original payment term '%s' doesn't have the same terms (number of terms "
"and/or amount) as the new payment term '%s'. You can only switch to a "
"payment term that has the same number of terms with the same amount."
msgstr ""
#. module: account_invoice_update_wizard
#: code:addons/account_invoice_update_wizard/wizard/account_move_update.py:0
#, python-format
msgid ""
"This wizard doesn't support the update of payment terms on an invoice which "
"is partially or fully paid."
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_update__move_type
msgid "Type"
msgstr ""
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Update"
msgstr "Mettre à jour"
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.view_move_form_inherit
msgid "Update Invoice"
msgstr "Mettre à jour"
#. module: account_invoice_update_wizard
#: model_terms:ir.ui.view,arch_db:account_invoice_update_wizard.account_invoice_update_form
msgid "Update Invoice Wizard"
msgstr "Assistant de mise à jour"
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move_line_update
msgid "Update non-legal fields of invoice lines"
msgstr "Mettre à jour les champs non légaux des lignes de facture"
#. module: account_invoice_update_wizard
#: model:ir.model.fields,field_description:account_invoice_update_wizard.field_account_move_line_update__parent_id
msgid "Wizard"
msgstr ""
#. module: account_invoice_update_wizard
#: model:ir.model,name:account_invoice_update_wizard.model_account_move_update
msgid "Wizard to update non-legal fields of invoice"
msgstr "Assistant pour mettre à jours les champs non légaux"
#~ msgid "Account"
#~ msgstr "Compte"

View File

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

View File

@@ -1,18 +0,0 @@
# Copyright 2019-2022 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class AccountMove(models.Model):
_inherit = 'account.move'
def prepare_update_wizard(self):
self.ensure_one()
wizard = self.env['account.move.update']
res = wizard._prepare_default_get(self)
action = self.env["ir.actions.actions"]._for_xml_id(
'account_invoice_update_wizard.account_invoice_update_action')
action['name'] = "Update Wizard"
action['res_id'] = wizard.create(res).id
return action

View File

@@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_move_update,account.move.update.user,model_account_move_update,account.group_account_invoice,1,1,1,1
access_account_move_line_update,account.move.line.update.user,model_account_move_line_update,account.group_account_invoice,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_move_update account.move.update.user model_account_move_update account.group_account_invoice 1 1 1 1
3 access_account_move_line_update account.move.line.update.user model_account_move_line_update account.group_account_invoice 1 1 1 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

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

View File

@@ -1,173 +0,0 @@
# Copyright 2018-2022 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import SavepointCase
class TestAccountInvoiceUpdateWizard(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.customer12 = cls.env.ref('base.res_partner_12')
cls.product16 = cls.env.ref('product.product_product_16')
uom_unit = cls.env.ref('uom.product_uom_categ_unit')
cls.move1 = cls.env['account.move'].create({
'name': 'Test invoice',
'partner_id': cls.customer12.id,
'move_type': 'out_invoice',
'invoice_line_ids': [
[0, None, {
'name': 'Line1',
'product_id': cls.product16.id,
'product_uom_id': uom_unit.id,
'quantity': 1,
'price_unit': 42.0,
'credit': 42.0,
'debit': 0
}],
],
})
cls.aa1 = cls.env.ref('analytic.analytic_partners_camp_to_camp')
cls.aa2 = cls.env.ref('analytic.analytic_nebula')
cls.atag1 = cls.env.ref('analytic.tag_contract')
cls.atag2 = cls.env['account.analytic.tag'].create({
'name': '',
})
def create_wizard(self, move):
res = move.prepare_update_wizard()
self.wiz = self.env['account.move.update'].browse(res['res_id'])
def test_add_analytic_account_line1(self):
""" Add analytic account on a move line
after the move has been approved.
This will:
- update the move line
- create a new analytic line.
"""
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_account_id = self.aa1
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertEqual(related_ml.analytic_account_id, self.aa1)
self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1)
def test_change_analytic_account_line1(self):
""" Change analytic account on a move line
after the move has been approved.
This will:
- update the move line
- update the existing analytic line."""
move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16)
move_line1.analytic_account_id = self.aa2
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_account_id = self.aa1
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertEqual(related_ml.analytic_account_id, self.aa1)
self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1)
def test_add_analytic_tags_line1(self):
""" Add analytic tags on a move line
after the move has been approved.
This will update move line.
"""
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertEqual(related_ml.analytic_tag_ids, self.atag2)
self.assertFalse(related_ml.analytic_line_ids)
def test_change_analytic_tags_line1(self):
""" Change analytic tags on a move line
after the move has been approved.
It will update move line and analytic line
"""
move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16)
move_line1.analytic_account_id = self.aa2
move_line1.analytic_tag_ids = self.atag1
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertEqual(related_ml.analytic_tag_ids, self.atag2)
self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2)
def test_add_analytic_info_line1(self):
""" Add analytic account and tags on a move line
after the move has been approved.
This will:
- update move line
- create an analytic line
"""
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_account_id = self.aa1
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertEqual(related_ml.analytic_account_id, self.aa1)
self.assertEqual(related_ml.analytic_tag_ids, self.atag2)
self.assertEqual(related_ml.analytic_line_ids.account_id, self.aa1)
self.assertEqual(related_ml.analytic_line_ids.tag_ids, self.atag2)
def test_empty_analytic_account_line1(self):
""" Remove analytic account
after the move has been approved.
This will raise an error as it is not implemented.
"""
move_line1 = self.move1.invoice_line_ids.filtered(lambda rec: rec.product_id == self.product16)
move_line1.analytic_account_id = self.aa2
self.move1._post()
self.create_wizard(self.move1)
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id.product_id.id == self.product16.id)
wiz_line.analytic_account_id = False
self.wiz.run()
related_ml = self.move1.invoice_line_ids.filtered(
lambda rec: rec.product_id == self.product16)
self.assertFalse(related_ml.analytic_account_id)
self.assertFalse(related_ml.analytic_line_ids)

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_move_form_inherit" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<button name="button_draft" position="before">
<button name="prepare_update_wizard" type="object" string="Update Invoice" groups="account.group_account_invoice" attrs="{'invisible': ['|', ('state', '!=', 'posted'), ('move_type', '=', 'entry')]}"/>
<button name="prepare_update_wizard" type="object" string="Update Entry" groups="account.group_account_invoice" attrs="{'invisible': ['|', ('state', '!=', 'posted'), ('move_type', '!=', 'entry')]}"/>
</button>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,261 +0,0 @@
# Copyright 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# Copyright 2018-2022 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api, _
from odoo.exceptions import UserError
import odoo.addons.decimal_precision as dp
class AccountMoveUpdate(models.TransientModel):
_name = 'account.move.update'
_description = 'Wizard to update non-legal fields of invoice'
invoice_id = fields.Many2one(
'account.move', string='Invoice', required=True,
readonly=True)
move_type = fields.Selection(related='invoice_id.move_type')
company_id = fields.Many2one(related='invoice_id.company_id')
partner_id = fields.Many2one(related='invoice_id.partner_id')
user_id = fields.Many2one('res.users', string='Salesperson')
invoice_payment_term_id = fields.Many2one(
'account.payment.term', string='Payment Term')
ref = fields.Char(string='Reference') # field label is customized in the view
invoice_date = fields.Date()
invoice_origin = fields.Char(string='Source Document')
partner_bank_id = fields.Many2one(
'res.partner.bank', string='Bank Account')
line_ids = fields.One2many(
'account.move.line.update', 'parent_id', string='Invoice Lines')
@api.model
def _simple_fields2update(self):
'''List boolean, date, datetime, char, text fields'''
return ['ref', 'invoice_origin', 'invoice_date']
@api.model
def _m2o_fields2update(self):
return ['invoice_payment_term_id', 'user_id', 'partner_bank_id']
@api.model
def _prepare_default_get(self, invoice):
res = {'invoice_id': invoice.id, 'line_ids': []}
for sfield in self._simple_fields2update():
res[sfield] = invoice[sfield]
for m2ofield in self._m2o_fields2update():
res[m2ofield] = invoice[m2ofield].id or False
for line in invoice.invoice_line_ids:
aa_tags = line.analytic_tag_ids
aa_tags = [(6, 0, aa_tags.ids)] if aa_tags else False
res['line_ids'].append([0, 0, {
'invoice_line_id': line.id,
'sequence': line.sequence,
'name': line.name,
'quantity': line.quantity,
'price_subtotal': line.price_subtotal,
'analytic_account_id': line.analytic_account_id.id,
'currency_id': line.currency_id.id,
'analytic_tag_ids': aa_tags,
'display_type': line.display_type,
}])
return res
@api.onchange('move_type')
def move_type_on_change(self):
res = {'domain': {}}
if self.move_type in ('out_invoice', 'out_refund'):
res['domain']['partner_bank_id'] =\
"[('partner_id.ref_company_ids', 'in', [company_id])]"
else:
res['domain']['partner_bank_id'] =\
"[('partner_id', '=', partner_id)]"
return res
def _prepare_invoice(self):
vals = {}
inv = self.invoice_id
for sfield in self._simple_fields2update():
if self[sfield] != inv[sfield]:
vals[sfield] = self[sfield]
for m2ofield in self._m2o_fields2update():
if self[m2ofield] != inv[m2ofield]:
vals[m2ofield] = self[m2ofield].id or False
if 'invoice_payment_term_id' in vals:
pterm_list = self.invoice_payment_term_id.compute(
value=1, date_ref=inv.date_invoice)[0]
if pterm_list:
vals['date_due'] = max(line[0] for line in pterm_list)
return vals
@api.model
def _line_simple_fields2update(self):
return ["name"]
@api.model
def _line_m2o_fields2update(self):
return ["analytic_account_id"]
@api.model
def _line_m2m_fields2update(self):
return ["analytic_tag_ids"]
@api.model
def _prepare_invoice_line(self, line):
vals = {}
for field in self._line_simple_fields2update():
if line[field] != line.invoice_line_id[field]:
vals[field] = line[field]
for field in self._line_m2o_fields2update():
if line[field] != line.invoice_line_id[field]:
vals[field] = line[field].id
for field in self._line_m2m_fields2update():
if line[field] != line.invoice_line_id[field]:
vals[field] = [(6, 0, line[field].ids)]
return vals
def _prepare_move_line_and_analytic_line(self, inv_line):
mlvals = {}
alvals = {}
inv_line_upd = self.line_ids.filtered(
lambda rec: rec.invoice_line_id == inv_line)
ini_aa = inv_line.analytic_account_id
new_aa = inv_line_upd.analytic_account_id
if ini_aa != new_aa:
mlvals['analytic_account_id'] = new_aa.id
alvals['account_id'] = new_aa.id
ini_aa_tags = inv_line.analytic_tag_ids
new_aa_tags = inv_line_upd.analytic_tag_ids
if ini_aa_tags != new_aa_tags:
mlvals['analytic_tag_ids'] = [(6, None, new_aa_tags.ids)]
alvals['tag_ids'] = [(6, None, new_aa_tags.ids)]
return mlvals, alvals
def _update_payment_term_move(self):
self.ensure_one()
inv = self.invoice_id
if (
self.invoice_payment_term_id and
self.invoice_payment_term_id != inv.invoice_payment_term_id):
# I don't update pay term when the invoice is partially (or fully)
# paid because if you have a payment term with several lines
# of the same amount, you would also have to take into account
# the reconcile marks to put the new maturity date on the right
# lines
if inv.payment_id:
raise UserError(_(
"This wizard doesn't support the update of payment "
"terms on an invoice which is partially or fully "
"paid."))
prec = self.env['decimal.precision'].precision_get('Account')
term_res = self.invoice_payment_term_id.compute(
inv.amount_total, inv.date_invoice)[0]
new_pterm = {} # key = int(amount * 100), value = [date1, date2]
for entry in term_res:
amount = int(entry[1] * 10 * prec)
if amount in new_pterm:
new_pterm[amount].append(entry[0])
else:
new_pterm[amount] = [entry[0]]
mlines = {} # key = int(amount * 100), value : [line1, line2]
for line in inv.move_id.line_ids:
if line.account_id == inv.account_id:
amount = int(abs(line.credit - line.debit) * 10 * prec)
if amount in mlines:
mlines[amount].append(line)
else:
mlines[amount] = [line]
for iamount, lines in mlines.items():
if len(lines) != len(new_pterm.get(iamount, [])):
raise UserError(_(
"The original payment term '%s' doesn't have the "
"same terms (number of terms and/or amount) as the "
"new payment term '%s'. You can only switch to a "
"payment term that has the same number of terms "
"with the same amount.") % (
inv.invoice_payment_term_id.name, self.invoice_payment_term_id.name))
for line in lines:
line.date_maturity = new_pterm[iamount].pop()
def run(self):
self.ensure_one()
inv = self.invoice_id
updated = False
# re-write date_maturity on move line
self._update_payment_term_move()
ivals = self._prepare_invoice()
if ivals:
updated = True
inv.write(ivals)
if inv:
for ml in inv.line_ids.filtered(
# we are only interested in invoice lines, not tax lines
lambda rec: bool(rec.product_id)
):
if ml.credit == 0.0:
continue
analytic_account = ml.analytic_account_id
mlvals, alvals = self._prepare_move_line_and_analytic_line(ml)
if mlvals:
updated = True
ml.write(mlvals)
aalines = ml.analytic_line_ids
if aalines and alvals:
updated = True
if ('account_id' in alvals and
alvals['account_id'] is False):
former_aa = analytic_account
to_remove_aalines = aalines.filtered(
lambda rec: rec.account_id == former_aa)
# remove existing analytic line
to_remove_aalines.unlink()
else:
aalines.write(alvals)
elif 'account_id' in alvals:
# Create analytic lines if analytic account
# is added later
ml.create_analytic_lines()
for line in self.line_ids:
ilvals = self._prepare_invoice_line(line)
if ilvals:
updated = True
line.invoice_line_id.write(ilvals)
if updated:
inv.message_post(body=_(
'Non-legal fields of invoice updated via the Invoice Update '
'wizard.'))
# Purge existing PDF
report = self.env.ref("account.account_invoices")
attachment = report.retrieve_attachment(inv)
# attachment may be None
if attachment:
attachment.unlink()
return True
class AccountMoveLineUpdate(models.TransientModel):
_name = 'account.move.line.update'
_description = 'Update non-legal fields of invoice lines'
_order = "sequence, name"
sequence = fields.Integer()
parent_id = fields.Many2one(
'account.move.update', string='Wizard', ondelete='cascade')
invoice_line_id = fields.Many2one(
'account.move.line', string='Invoice Line', readonly=True)
name = fields.Text(string='Description', required=True)
display_type = fields.Selection([
('line_section', "Section"),
('line_note', "Note")], default=False, help="Technical field for UX purpose.")
quantity = fields.Float(
string='Quantity', digits='Product Unit of Measure', readonly=True)
price_subtotal = fields.Monetary(
string='Amount', readonly=True)
analytic_account_id = fields.Many2one(
'account.analytic.account', string='Analytic Account')
analytic_tag_ids = fields.Many2many(
'account.analytic.tag', string='Analytic Tags')
currency_id = fields.Many2one('res.currency', readonly=True)

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="account_invoice_update_form" model="ir.ui.view">
<field name="model">account.move.update</field>
<field name="arch" type="xml">
<form string="Update Invoice Wizard">
<group name="main">
<field name="invoice_id" invisible="1"/>
<field name="move_type" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field string="Bill Date" attrs="{'invisible': [('move_type', 'not in', ('in_invoice', 'in_refund'))]}" name="invoice_date"/>
<field string="Supplier Bill Reference" attrs="{'invisible': [('move_type', 'not in', ('in_invoice', 'in_refund'))]}" name="ref"/>
<field string="Customer Reference" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}" name="ref"/>
<field string="Ref" attrs="{'invisible': [('move_type', '!=', 'entry')]}" name="ref"/>
<field name="invoice_origin" attrs="{'invisible': [('move_type', '=', 'entry')]}"/>
<!-- update of payment term is broken -->
<!-- <field name="invoice_payment_term_id" widget="selection"/>-->
<field name="partner_bank_id" attrs="{'invisible': [('move_type', '=', 'entry')]}"/>
<field name="user_id" options="{'no_open': True, 'no_create': True, 'no_create_edit': True}" attrs="{'invisible': [('move_type', '=', 'entry')]}"/>
</group>
<group name="lines">
<field name="line_ids" nolabel="1" widget="section_and_note_one2many">
<tree editable="bottom" create="false" delete="false" edit="true">
<field name="invoice_line_id" invisible="1"/>
<field name="display_type" invisible="1"/>
<field name="currency_id" invisible="1"/>
<field name="name"/>
<field name="quantity" attrs="{'invisible': [('display_type', '!=', False)], 'column_invisible': [('parent.move_type', '=', 'entry')]}"/>
<field name="price_subtotal" attrs="{'invisible': [('display_type', '!=', False)], 'column_invisible': [('parent.move_type', '=', 'entry')]}"/>
<field name="analytic_account_id" attrs="{'invisible': [('display_type', '!=', False)]}" groups="analytic.group_analytic_accounting"/>
<field name="analytic_tag_ids" attrs="{'invisible': [('display_type', '!=', False)]}" groups="analytic.group_analytic_tags" widget="many2many_tags"/>
</tree>
</field>
</group>
<footer>
<button name="run" type="object" class="oe_highlight" string="Update"/>
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="account_invoice_update_action" model="ir.actions.act_window">
<field name="name">Invoice Update Wizard</field>
<field name="res_model">account.move.update</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -1,39 +0,0 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Account Invoice Update Wizard
=============================
This module adds a button *Update Invoice* on Customer and Supplier invoices in
Open or Paid state. This button starts a wizard which allows the user to update
non-legal fields of the invoice:
* Source Document
* Reference/Description
* Payment terms (update allowed only to a payment term with same number of terms
of the same amount and on invoices without any payment)
* Bank Account
* Salesman
* Notes
* Description of invoice lines
* Analytic account
* Analytic tags
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/akretion/odoo-usability/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>
* Florian da Costa <florian.dacosta@akretion.com>
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Mykhailo Panarin <m.panarin@mobilunity.com>
* Artem Kostyuk <a.kostyuk@mobilunity.com>

View File

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

View File

@@ -1,17 +0,0 @@
# Copyright 2022 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
'name': 'Account Invoice Update Wizard Payment Mode',
'version': '14.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Add Payment Mode to Invoice Update Wizard',
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['account_invoice_update_wizard', 'account_payment_partner'],
'data': ['wizard/account_move_update_view.xml'],
'installable': True,
'auto_install': True,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_move_form_inherit" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<button name="button_draft" position="before">
<button name="prepare_update_wizard" type="object" string="Update Invoice" states="posted" groups="account.group_account_invoice"/>
</button>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,24 +0,0 @@
# Copyright 2022 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models, fields, api, _
class AccountMoveUpdate(models.TransientModel):
_inherit = 'account.move.update'
payment_mode_filter_type_domain = fields.Char(
related='invoice_id.payment_mode_filter_type_domain')
partner_bank_filter_type_domain = fields.Many2one(
related='invoice_id.partner_bank_filter_type_domain')
bank_account_required = fields.Boolean(
related='invoice_id.bank_account_required')
payment_mode_id = fields.Many2one("account.payment.mode")
@api.model
def _m2o_fields2update(self):
m2o_list = super()._m2o_fields2update()
m2o_list.append('payment_mode_id')
return m2o_list

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="account_invoice_update_form" model="ir.ui.view">
<field name="model">account.move.update</field>
<field name="inherit_id" ref="account_invoice_update_wizard.account_invoice_update_form"/>
<field name="arch" type="xml">
<field name="partner_bank_id" position="before">
<field name="payment_mode_filter_type_domain" invisible="1"/>
<field name="partner_bank_filter_type_domain" invisible="1"/>
<field name="bank_account_required" invisible="1"/>
<field name="payment_mode_id" domain="[('payment_type', '=', payment_mode_filter_type_domain), ('company_id', '=', company_id)]"/>
</field>
<field name="partner_bank_id" position="attributes">
<attribute name="domain">
[('partner_id', '=', partner_bank_filter_type_domain),
'|',('company_id', '=', company_id),('company_id', '=', False)]
</attribute>
<attribute name="attrs">{'required': [('bank_account_required', '=', True),('move_type', 'in', ('in_invoice', 'in_refund'))]}</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -1,18 +0,0 @@
# Copyright 2022 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Menu Usability',
'version': '14.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account_menu module',
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['account_menu'],
'data': [
'views/account_menu.xml',
],
'installable': True,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<!-- Accounting Templates are useful only when creating a new company/loading
a chart of accounts, so we put it under 'Settings > Technical' and not
under 'Invoicing > Configuration' which already has a lot of menu entries -->
<record id="account_menu.menu_account_coa_settings" model="ir.ui.menu">
<field name="name">Accounting Templates</field>
<field name="parent_id" ref="base.menu_custom"/>
</record>
</odoo>

View File

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

View File

@@ -1,29 +0,0 @@
# Copyright 2022 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Move Label Copy',
'version': '14.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'When creating a Journal Entry manually, copy label from line to line',
'description': """
Account Move Label Copy
=======================
This module is ONLY for users who don't accept to use the 'Reference' (ref) to store the description of the journal entry (the recommended method), but want to use the label on the lines for that purpose (name field of account.move.line). With this module, the label of the first line will be copied by default to the other lines upon creation of each line.
I don't recommend the use of this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': [
'account',
'base_view_inheritance_extension',
],
'data': [
'views/account_move.xml',
],
'installable': True,
}

View File

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

View File

@@ -1,13 +0,0 @@
# Copyright 2022 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountMove(models.Model):
_inherit = "account.move"
default_move_line_name = fields.Char(
related='line_ids.name',
string='Default Journal Item Label')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_move_form" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<field name="narration" position="after">
<field name="default_move_line_name" invisible="1"/>
</field>
<xpath expr="//page[@id='aml_tab']/field[@name='line_ids']" position="attributes">
<attribute name="context" operation="python_dict" key="default_name">default_move_line_name</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Move Line Start End Dates XLS module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_move_line

View File

@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Move Line Start End Dates XLS module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Move Line Start End Dates XLS',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Adds start and end dates in the XLS export of the move lines',
'description': """
Account Move Line Start End Dates XLS
=====================================
This module adds *Start Date* and *End Date* in the XLS export of the account move lines.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com/',
'depends': ['account_cutoff_prepaid', 'account_move_line_report_xls'],
'data': [],
'active': False,
}

View File

@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Move Line Start End Dates XLS module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import xlwt
from openerp.osv import orm
from openerp.addons.report_xls.utils import _render
from openerp.addons.report_xls.report_xls import report_xls
class account_move_line(orm.Model):
_inherit = 'account.move.line'
def _report_xls_template(self, cr, uid, context=None):
res = super(account_move_line, self)._report_xls_template(
cr, uid, context=context)
bc = '22'
aml_cell_style_date = xlwt.easyxf(
'borders: left thin, right thin, top thin, bottom thin, '
'left_colour %s, right_colour %s, top_colour %s, '
'bottom_colour %s; align: horz left;'
% (bc, bc, bc, bc), num_format_str=report_xls.date_format)
res.update({
'start_date': {
'header': [1, 13, 'text', _render("_('Start Date')")],
'lines': [1, 0, _render(
"line.start_date and line.start_date != 'False' and "
"'date' or 'text'"), _render(
"line.start_date and line.start_date != 'False' and "
"datetime.strptime(line.start_date, '%Y-%m-%d') or None"),
None, aml_cell_style_date],
'totals': [1, 0, 'text', None]},
'end_date': {
'header': [1, 13, 'text', _render("_('End Date')")],
'lines': [1, 0, _render(
"line.end_date and line.end_date != 'False' and "
"'date' or 'text'"), _render(
"line.end_date and line.end_date != 'False' and "
"datetime.strptime(line.end_date, '%Y-%m-%d') or None"),
None, aml_cell_style_date],
'totals': [1, 0, 'text', None]},
})
return res

View File

@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Hide Communication2 module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Hide Communication2 module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Account Payment Hide Communication2',
'version': '1.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Hide the field Communication2 on Payment Lines',
'description': """
Account Payment Hide Communication2
===================================
This module hides the field 'Communication2' on the form view of Payment Lines. I consider that is field is useless and tend to confuse users.
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
""",
'author': 'Akretion',
'depends': ['account_payment'],
'data': [
'payment_view.xml',
],
'active': False,
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="view_payment_order_form" model="ir.ui.view">
<field name="name">hide.communication2.on.payment.line.form</field>
<field name="model">payment.order</field>
<field name="inherit_id" ref="account_payment.view_payment_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='line_ids']/form//field[@name='communication2']" position="replace" />
</field>
</record>
</data>
</openerp>

View File

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

View File

@@ -1,25 +0,0 @@
# Copyright 2024 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Payment Line Manual Account',
'version': '14.0.1.0.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Ability to select the account on payment lines without journal item',
'description': """
With this module, when you manually create a payment line that is not linked to a journal item, you can select an account (by default, it is set to the payable/receivable account of the partner) : this account will be used as the counter part of the outbound/inbound payment account configured on the bank journal. It covers special needs of a few companies that use SEPA credit transfer for the same partner in different accounting scenarios.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'maintainers': ['alexis-via'],
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['account_payment_order'],
'data': [
"views/account_payment_line.xml",
],
'installable': True,
}

Some files were not shown because too many files have changed in this diff Show More