Compare commits

..

15 Commits

Author SHA1 Message Date
David Beal
0ba12b8812 tmp 2016-12-20 16:31:55 +01:00
David Beal
c867b1d76f ADD module web_sheet_width_custom 2016-12-02 09:00:53 +01:00
David Beal
b41f188eb4 IMP add filter Not company on supplierinfo 2016-11-30 12:14:42 +01:00
Levent Karakaş
891c64bb1f [FIX] Fix to get purchase suggest work without the need to patch (#24)
* Fix to get it work without the need to patch
2016-11-22 09:45:03 +01:00
David Beal
b9e07ea986 IMP add icons 2016-11-18 10:37:43 +01:00
David Beal
12fbd5dc2c IMP add product.supplierinfo standalone view 2016-11-16 18:56:02 +01:00
David Beal
7948193fe0 FIX only get supplier code, not default code to avoid confusing 2016-11-11 21:58:03 +01:00
David Beal
64cb3d44ad Merge pull request #22 from akretion/supplier-code
IMP field product_supplier_code added to stk.move
2016-11-11 18:35:24 +01:00
David Beal
08f434b6a0 FIX store field product_code in stock.move 2016-11-11 18:31:56 +01:00
David Beal
6176b37fa6 IMP field product_supplier_code added to stk.move 2016-11-10 14:51:13 +01:00
Alexis de Lattre
4015f5b1c9 Add module crm_usability 2016-11-07 19:05:25 +01:00
Alexis de Lattre
ef920f58f4 noupdate for email template 2016-11-07 10:27:03 +01:00
Alexis de Lattre
c108f617c2 Update ACL 2016-10-23 17:42:41 +02:00
David Beal
4acce9509f [DOC] add TODO in code 2016-10-20 19:32:53 +02:00
Alexis de Lattre
e9ab3187e7 Add module account_fiscal_position_payable_receivable 2016-10-18 15:50:27 +02:00
992 changed files with 11355 additions and 17556 deletions

View File

@@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015-2018 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': 'Aged Partner Balance from Partner',
'version': '10.0.0.1.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Direct access to the aged partner balance report from the partner form',
'description': """
Aged Partner Balance from Partner
=================================
This module adds a button on the partner form view (the icon on the button is a banknote) to easily open the detailed aged partner balance of the partner in PDF format.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account_financial_report_qweb'],
'data': ['partner_view.xml'],
'installable': True,
}

View File

@@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2015-2018 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).
from odoo import models, fields, api
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.depends('credit', 'debit')
def _compute_balance(self):
for partner in self:
partner.balance = partner.credit - partner.debit
# The field 'currency_id' defined in the account module
# is a computed field that gets the company currency
balance = fields.Monetary(
compute='_compute_balance', readonly=True,
string="Account Balance")
def open_aged_open_invoices_report(self):
wiz = self.env['aged.partner.balance.wizard'].create({
'show_move_line_details': True,
'partner_ids': [(6, 0, self.ids)],
})
action = wiz.button_export_pdf()
return action

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2018 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_partner_form" model="ir.ui.view">
<field name="name">account.balance.button.partner.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.partner_view_buttons"/>
<field name="arch" type="xml">
<button name="open_partner_history" type="object" position="after">
<button class="oe_stat_button" type="object"
name="open_aged_open_invoices_report"
attrs="{'invisible': [('parent_id', '!=', False)]}"
icon="fa-money">
<div class="o_form_field o_stat_info">
<span class="o_stat_value"><field name="balance"/></span>
<span class="o_stat_text">Account Balance</span>
</div>
</button>
</button>
</field>
</record>
</odoo>

View File

@@ -1,35 +0,0 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=======================================
Import French HSBC Card Bank Statements
=======================================
This module allows you to import French HSBC credit cards bank statements (CSV version).
Configuration
=============
Create a bank journal dedicated to HSBC credit cards. Associate it with a new bank account on which you will set the account number to *HSBC_CARD_EUR*.
Usage
=====
In the dashboard of the *Accounting* menu, click on the button *Import Statement* located on the journal corresponding to the bank account of the statement file you are importing.
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 smashing it by providing a detailed and welcomed feedback.
Credits
=======
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>

View File

@@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 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': 'Import French HSBC Card Bank Statements',
'version': '10.0.1.0.0',
'license': 'AGPL-3',
'author': "Akretion",
'website': 'http://www.akretion.com',
'summary': 'Import French HSBC Card Bank Statements in Odoo (CSV version)',
'depends': ['account_bank_statement_import'],
'data': ['views/account_bank_statement_import.xml'],
'installable': True,
}

View File

@@ -1,69 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_bank_statement_import_fr_cfonb
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-13 03:36+0000\n"
"PO-Revision-Date: 2017-01-13 03:36+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Norwegian Bokmål (Norway) (https://www.transifex.com/oca/teams/23907/nb_NO/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: nb_NO\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: account_bank_statement_import_fr_cfonb
#: code:addons/account_bank_statement_import_fr_cfonb/models/account_bank_statement_import.py:146
#, python-format
msgid "Account %s"
msgstr ""
#. module: account_bank_statement_import_fr_cfonb
#: model:ir.ui.view,arch_db:account_bank_statement_import_fr_cfonb.account_bank_statement_import_view
msgid "CFONB (French format, fixed-length text lines of 120 caracters)"
msgstr ""
#. module: account_bank_statement_import_fr_cfonb
#: model:ir.model,name:account_bank_statement_import_fr_cfonb.model_account_bank_statement_import
msgid "Import Bank Statement"
msgstr "Importer bankutsagn"
#. module: account_bank_statement_import_fr_cfonb
#: code:addons/account_bank_statement_import_fr_cfonb/models/account_bank_statement_import.py:70
#, python-format
msgid ""
"Line %d is %d caracters long. All lines of a CFONB bank statement file must "
"be 120 caracters long."
msgstr ""
"Linje %d er %d tegn langt. Alle linjer i en CFONB-bankutsagnsfil må være 120"
" tegn langt."
#. module: account_bank_statement_import_fr_cfonb
#: code:addons/account_bank_statement_import_fr_cfonb/models/account_bank_statement_import.py:110
#, python-format
msgid ""
"Only single-account files and single-currency files are supported for the "
"moment. It is not the case starting from line %d."
msgstr ""
"Kun enkeltkontofiler og enkeltmyntenhetsfiler støttes for øyeblikket. Dette "
"er ikke tilfellet fra og med linje %d og utover."
#. module: account_bank_statement_import_fr_cfonb
#: code:addons/account_bank_statement_import_fr_cfonb/models/account_bank_statement_import.py:99
#, python-format
msgid ""
"The 2 first letters of the first line are '%s'. A CFONB file should start "
"with '01'"
msgstr ""
#. module: account_bank_statement_import_fr_cfonb
#: code:addons/account_bank_statement_import_fr_cfonb/models/account_bank_statement_import.py:52
#, python-format
msgid "The file is empty."
msgstr "Filen er tom."

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" ?>
<!--
© 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_bank_statement_import_view" model="ir.ui.view">
<field name="name">hsbc.fr.csv.account.bank.statement.import.form</field>
<field name="model">account.bank.statement.import</field>
<field name="inherit_id" ref="account_bank_statement_import.account_bank_statement_import_view"/>
<field name="arch" type="xml">
<xpath expr="//ul[@id='statement_format']" position="inside">
<li>French HSBC Credit Cards (CSV format)</li>
</xpath>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,105 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 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).
import logging
import unicodecsv
from tempfile import TemporaryFile
from datetime import datetime
from odoo import models, fields, api, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class AccountBankStatementImport(models.TransientModel):
_inherit = 'account.bank.statement.import'
@api.model
def _check_hsbc_card_csv(self, data_file):
return data_file.strip().startswith(
'Titulaire;Division;;Cpt Affaires;Num carte;')
@api.model
def _parse_file(self, data_file):
""" Import a file in French HSBC CSV Credit card format"""
hsbc_csv = self._check_hsbc_card_csv(data_file)
if not hsbc_csv:
return super(AccountBankStatementImport, self)._parse_file(
data_file)
transactions = []
fileobj = TemporaryFile('w+')
fileobj.write(data_file)
fileobj.seek(0)
reader = unicodecsv.DictReader(
fileobj,
fieldnames=[
'company', 'division', 'empty', 'account',
'card_num', 'title', 'lastname', 'firstname',
'op_code', 'seller_type', 'seller', 'date', 'acc_date',
'hour', 'city', 'code', 'label', 'local_amount',
'local_currency', 'acc_amount', 'acc_currency'],
delimiter=';',
quoting=unicodecsv.QUOTE_MINIMAL,
encoding='latin1')
i = 0
start_balance = end_balance = 0.0
currency_code = 'EUR'
account_number = 'HSBC_CARD_EUR'
for line in reader:
i += 1
if i == 1:
continue # skip title line
_logger.debug("Line %d: %s" % (i, line))
if not line:
continue
# cleanup
for key, value in line.iteritems():
line[key] = value and value.strip() or False
if not line['date'] or not line['acc_amount']:
continue
labels = [
'%s %s' % (line['firstname'], line['lastname']),
'%s (%s)' % (line['seller'], line['seller_type']),
line['city']]
if line['local_currency'] != currency_code:
labels.append(
'%s %s' % (line['local_amount'], line['local_currency']))
name = ', '.join(labels)
amount = float(
line['acc_amount'].replace(',', '.').replace(' ', '')) * -1
end_balance += amount
date_dt = datetime.strptime(line['date'], '%d/%m/%Y')
date_str = fields.Date.to_string(date_dt)
if line['acc_currency'] != currency_code:
raise UserError(_(
"On line %d of the HSBC CSV file, the column "
"'Dev Cpt Affaires' contains '%s' instead of 'EUR'")
% (line['acc_currency'], i))
vals_line = {
'date': date_str,
'name': name,
'ref': False,
# unfortunately, I'm obliged to include i in
# the unique_import_id, which will disable the auto-delete
# of already imported lines. But experice has proven that
# Internet payment often have hour=00:00, and it's possible
# to have 2 internet payments for the same supplier the same
# day with the same amount (e.g. purchase a return ticket)
'unique_import_id': '%s-%s-%.2f-%s-%d' % (
date_str, line['hour'], amount, name, i),
'amount': amount,
'partner_id': False,
}
transactions.append(vals_line)
vals_bank_statement = {
'name': _('HSBC Cards'),
'balance_start': start_balance,
'balance_end_real': end_balance,
'transactions': transactions,
}
fileobj.close()
# from pprint import pprint
# pprint(vals_bank_statement)
return currency_code, account_number, [vals_bank_statement]

View File

@@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
# © 2015-2016 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 Bank Statement Import Usability',
'version': '10.0.0.1.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account_bank_statement_import module',
'description': """
Account Bank Statement Import Usability
=======================================
This module adds the following changes:
* Works if the bank statement file only contain the account number and not the full IBAN
* remove start balance and end balance (doesn't work with OFX, which is one of the most used file format !)
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account_bank_statement_import'],
'data': ['account_view.xml'],
'installable': True,
}

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Bank Statement Import Usability 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 Bank Statement Import Usability',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account_bank_statement_import module',
'description': """
Account Bank Statement Import Usability
=======================================
This module adds the following changes:
* Blocks the *Automagically create bank account*, because it's too dangerous : it creates new bank accounts and new account journal... and the user doesn't even realize that !
* Works if the bank statement file only contain the account number and not the full IBAN
* If you have 2 accounts with the same number (I know a company that has an account in EUR and an account in USD with the same number), you should force the journal and it will work (instead of blocking with an error message)
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account_bank_statement_import'],
'data': ['account_view.xml'],
'installable': True,
}

View File

@@ -1,18 +1,64 @@
# -*- coding: utf-8 -*-
# © 2015-2016 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).
##############################################################################
#
# Account Bank Statement Import Usability 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/>.
#
##############################################################################
from odoo import models, api
from openerp import models, api
class AccountBankStatementImport(models.TransientModel):
"""Extend model account.bank.statement."""
_inherit = 'account.bank.statement.import'
def _check_journal_bank_account(self, journal, account_number):
if account_number in journal.bank_account_id.sanitized_acc_number:
return True
return False
@api.model
def _find_bank_account_id(self, account_number):
"""Compared to the code in the module account_bank_statement_import,
this code:
- works when the account_number is not a complete IBAN,
but just an account number (most statement files only have the
account number)
- works if you have 2 bank accounts with the same number
(I have seen that at Crédit du Nord: the company had 1 account in USD
and 1 account in EUR with the same number !)
-> for that, I filter on the journal if the journal_id field is set
"""
bank_account_id = None
if account_number and len(account_number) > 4:
if self.journal_id:
self._cr.execute("""
SELECT id FROM res_partner_bank
WHERE replace(replace(acc_number,' ',''),'-','') like %s
AND journal_id=%s
ORDER BY id
""", ('%' + account_number + '%', self.journal_id.id))
else:
self._cr.execute("""
SELECT id FROM res_partner_bank
WHERE replace(replace(acc_number,' ',''),'-','') like %s
AND journal_id is not null
ORDER BY id
""", ('%' + account_number + '%', ))
bank_account_ids = [id[0] for id in self._cr.fetchall()]
if bank_account_ids:
bank_account_id = bank_account_ids[0]
return bank_account_id
class AccountBankStatement(models.Model):
@@ -30,6 +76,5 @@ class AccountBankStatement(models.Model):
# This code is present in the 'account' module, but I override it here
# and not in account_usability because the users who don't have
# account_bank_statement_import may want to keep start/end balance
@api.multi
def _balance_check(self):
def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
return True

View File

@@ -1,16 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2016 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).
Copyright (C) 2016 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<odoo>
<!--
Let's try again to work with balance_start and balance_end_real
in v10 to see if we can work with it in v10 or not...
If we really can't, I'll re-activate this view inheritance again
<openerp>
<data>
<record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">bank_statement_import_usability.account.bank.statement.form</field>
@@ -25,7 +21,6 @@
</field>
</field>
</record>
-->
<record id="view_bank_statement_tree" model="ir.ui.view">
<field name="name">bank_statement_import_usability.account.bank.statement.tree</field>
@@ -45,4 +40,5 @@
</record>
</odoo>
</data>
</openerp>

View File

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

View File

@@ -1,33 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 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 Bank Statement No Reconcile Guess',
'version': '10.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': "Don't pre-select lines to reconcile in bank statements",
'description': """
Account Bank Statement No Reconcile Guess
=========================================
Here is a scenario where the "reconcile guess" feature is a problem for the accountant:
1) The accountant imports a large bank statement with 40 bank statement lines.
2) The "reconcile guess" feature will pre-select reconcile of line X with line 39 of the bank statement. But this guess is a mistake and line X should be reconciled with line 2 of the bank statement.
=> The accountant will not understand why he can't select line X to be reconciled with line 2 of the bank statement. To be able to reconcile line 2 correctif, he has to:
3) click several times on the "next page" button to reach line 39 of the bank statement and unselect line X.
4) Go back to line 2 of the bank statement and now he will be able to select line X.
This module disables the "reconcile guess" feature to avoid this problem.
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': [],
'installable': True,
}

View File

@@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 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).
from odoo import models
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
def get_reconciliation_proposition(self, excluded_ids=None):
self.ensure_one()
return self.env['account.move.line']

View File

@@ -42,5 +42,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['account_credit_control', 'partner_aged_open_invoices'],
'data': ['account_credit_control_view.xml'],
'installable': False,
'installable': True,
}

View File

@@ -20,5 +20,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['account_cutoff_accrual_picking', 'report_aeroo'],
'data': ['report.xml'],
'installable': False,
'installable': True,
}

View File

@@ -39,5 +39,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['account_cutoff_prepaid', 'report_aeroo'],
'data': ['report.xml'],
'installable': False,
'installable': True,
}

View File

@@ -43,5 +43,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['account_banking_sepa_direct_debit', 'account_payment_partner'],
'data': [],
'installable': False,
'installable': True,
}

View File

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

View File

@@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
# © 2015-2016 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 Financial Report Qweb Usability',
'version': '10.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account_financial_report_qweb module',
'description': """
Account Financial Report Usability
==================================
The usability enhancements include:
TODO
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': [
'account_financial_report_qweb',
],
'data': [
'views/reports.xml',
'views/layouts.xml',],
'installable': True,
}

View File

@@ -1,3 +0,0 @@
.list_table, .data_table, .totals_table, .list_table .act_as_row {
font-size:15px;
}

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_specific" inherit_id="account_financial_report_qweb.assets_specific">
<xpath expr="." position="inside">
<link href="/account_financial_report_qweb_usability/static/src/css/reports.css" rel="stylesheet"/>
</xpath>
</template>
</odoo>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="report_qweb_paperformat_horizontal" model="report.paperformat">
<field name="name">Account financial report qweb horizontal paperformat</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="page_height">297</field>
<field name="page_width">210</field>
<field name="orientation">Landscape</field>
<field name="margin_top">12</field>
<field name="margin_bottom">8</field>
<field name="margin_left">5</field>
<field name="margin_right">5</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">10</field>
<field name="dpi">110</field>
</record>
<record id="account_financial_report_qweb.action_report_general_ledger_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat_horizontal"/>
</record>
<record id="account_financial_report_qweb.action_report_journal_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat_horizontal"/>
</record>
<record id="account_financial_report_qweb.action_report_open_items_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat_horizontal"/>
</record>
</odoo>

View File

@@ -1,4 +0,0 @@
# -*- coding: utf-8 -*-
from . import general_ledger_wizard
from . import open_items_wizard

View File

@@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 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 fields, models
class GeneralLedgerReportWizard(models.TransientModel):
_inherit = 'general.ledger.report.wizard'
foreign_currency = fields.Boolean(default=False)
def onchange_partner_ids(self):
# Neutralize native onchange method
return

View File

@@ -1,12 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 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 fields, models
class OpenItemsReportWizard(models.TransientModel):
_inherit = "open.items.report.wizard"
foreign_currency = fields.Boolean(default=False)

View File

@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# © 2016 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': '10.0.1.0.0',
'version': '8.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Configure payable/receivable accounts on fiscal positions',

View File

@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# © 2016 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, api
from openerp import models, fields, api
class AccountFiscalPosition(models.Model):
@@ -10,26 +10,26 @@ class AccountFiscalPosition(models.Model):
receivable_account_id = fields.Many2one(
'account.account', string='Partner Receivable Account',
company_dependent=True, domain=[('internal_type', '=', 'receivable')])
company_dependent=True, domain=[('type', '=', 'receivable')])
payable_account_id = fields.Many2one(
'account.account', string='Partner Payable Account',
company_dependent=True, domain=[('internal_type', '=', 'payable')])
company_dependent=True, domain=[('type', '=', 'payable')])
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.onchange('property_account_position_id')
@api.onchange('property_account_position')
def fiscal_position_receivable_payable_change(self):
fp = self.property_account_position_id
fp = self.property_account_position
ipo = self.env['ir.property']
if fp.receivable_account_id:
self.property_account_receivable_id = fp.receivable_account_id
self.property_account_receivable = fp.receivable_account_id
else:
self.property_account_receivable_id = ipo.get(
'property_account_receivable_id', 'res.partner')
self.property_account_receivable = ipo.get(
'property_account_receivable', 'res.partner')
if fp.payable_account_id:
self.property_account_payable_id = fp.payable_account_id
self.property_account_payable = fp.payable_account_id
else:
self.property_account_payable_id = ipo.get(
'property_account_payable_id', 'res.partner')
self.property_account_payable = ipo.get(
'property_account_payable', 'res.partner')

View File

@@ -4,7 +4,8 @@
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<openerp>
<data>
<record id="view_account_position_form" model="ir.ui.view">
@@ -12,12 +13,16 @@
<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>
<xpath expr="//field[@name='country_group_id']/.." position="after">
<group string="Payable and Receivable Accounts"
name="payable_receivable_account" col="4">
<field name="receivable_account_id"/>
<field name="payable_account_id"/>
</group>
</xpath>
</field>
</record>
</odoo>
</data>
</openerp>

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Fiscal Position Translate 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

View File

@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Fiscal Position Translate 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 Fiscal Position Translate',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Make the Notes field on fiscal position translatable',
'description': """
Account Fiscal Position Translate
=================================
Makes the Notes field on the fiscal position translatable (it was native on 7.0, but it is not on 8.0).
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,32 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Fiscal Position Translate 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 openerp.osv import orm, fields
class account_fiscal_position(orm.Model):
_inherit = 'account.fiscal.position'
_columns = {
# add translate=True
'note': fields.text('Notes', translate=True),
}

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Hide Analytic Lines',
'version': '8.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Hide analytic lines',
'description': """
Account Hide Analytic Lines
===========================
This module hides analytic lines. If you don't use timesheets, you should
not use analytic lines at all. Instead, you should only use
account move lines with the analytic account field (technical name: *analytic_account_id*).
Why ? Because, when you change the analytic account on an account move line,
the analytic line is not updated by Odoo. So, if you use the report available in *Reporting > Accounting > Analytic Entries Analysis*, as this report is based on analytic lines, the results will not take into account the changes of analytic account that you made on some account move lines.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account', 'base_usability'],
'data': ['account_view.xml'],
'installable': True,
}

View File

@@ -0,0 +1,63 @@
<?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).
-->
<openerp>
<data>
<record id="account.account_analytic_journal_entries" model="ir.ui.menu">
<field name="groups_id" eval="[(6, 0, [ref('base_usability.group_nobody')])]"/>
</record>
<!-- Chart of analytic accounts -->
<record id="account.menu_action_analytic_account_tree2" model="ir.ui.menu">
<field name="groups_id" eval="[(6, 0, [ref('base_usability.group_nobody')])]"/>
</record>
<record id="account.next_id_40" model="ir.ui.menu">
<field name="groups_id" eval="[(6, 0, [ref('base_usability.group_nobody')])]"/>
</record>
<record id="account.account_analytic_journal_values" model="ir.values">
<field name="value" eval="False"/>
</record>
<record id="view_move_line_form" model="ir.ui.view">
<field name="name">account_hide_analytic_line.account_move_line_form</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form"/>
<field name="arch" type="xml">
<page groups="analytic.group_analytic_accounting" position="attributes">
<attribute name="invisible">1</attribute>
</page>
</field>
</record>
<record id="view_account_entries_report_search" model="ir.ui.view">
<field name="name">account.entries.report.search: add groupby</field>
<field name="model">account.entries.report</field>
<field name="inherit_id" ref="account.view_account_entries_report_search"/>
<field name="arch" type="xml">
<group expand="1" position="inside">
<filter name="account_groupby" string="Account" context="{'group_by': 'account_id'}"/>
<filter name="analytic_account_groupby" string="Analytic Account" context="{'group_by': 'analytic_account_id'}"/>
</group>
</field>
</record>
<!-- Natively, this action is based on analytic.entries.report
We switch that to account.entries.report with good context value to
have a similar result -->
<record id="account.action_analytic_entries_report" model="ir.actions.act_window">
<field name="res_model">account.entries.report</field>
<field name="context">{'search_default_thisyear': 1, 'search_default_analytic_account_groupby': 1}</field>
<field name="search_view_id" ref="view_account_entries_report_search"/>
<field name="domain">[('analytic_account_id', '!=', False)]</field>
</record>
</data>
</openerp>

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,44 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Del Attachment Cancel 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 Delete Attachment on Cancel',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Delete the attachment on the invoice when it is set back to draft',
'description': """
Account Invoice Delete Attachment on Cancel
===========================================
When a customer 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 a user asks for the Invoice report, it will be taken from the attachment. But, when a customer invoice/refund is cancelled, set back to draft, modified and re-validated, the Invoice report is still the old PDF file, which is often raised as a bug by the users.
With this module, when a customer invoice/refund is set back to draft, the attachment is deleted.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'installable': True,
}

View File

@@ -0,0 +1,57 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Del Attachment Cancel 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/>.
#
##############################################################################
from openerp import models, api, _
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
@api.multi
def invoice_filename_to_match(self):
return 'INV%.pdf'
@api.multi
def action_cancel_draft(self):
res = super(AccountInvoice, self).action_cancel_draft()
iao = self.env['ir.attachment']
for invoice in self:
# search for attachments
if 'out' in invoice.type:
filename_to_match = invoice.invoice_filename_to_match()
attachs = iao.search([
('res_id', '=', invoice.id),
('res_model', '=', self._name),
('type', '=', 'binary'),
('datas_fname', '=like', filename_to_match),
])
if len(attachs) == 1:
# delete attachment
attach = attachs[0]
attach_name = attach.name
# I need sudo() because the user that has the right to
# do a "back2draft" on an invoice may not have the right
# to delete an account.invoice
attachs.sudo().unlink()
invoice.message_post(
_('Attachement %s has been deleted') % attach_name)
return res

View File

@@ -0,0 +1 @@
# -*- encoding: utf-8 -*-

View File

@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Groupby Commercial Partner 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 Groupby Commercial Partner',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Group by commercial partner instead of partner in invoices',
'description': """
Account Invoice Group-by Commercial Partner
===========================================
By default Odoo v8 makes a groupby on partner_id on invoice ; this module changes this to groupby commercial_partner_id.
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,35 @@
<?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_account_invoice_filter" model="ir.ui.view">
<field name="name">account.invoice.groupby.commercial.partner</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<filter name="group_by_partner_id" position="attributes">
<attribute name="context">{'group_by':'commercial_partner_id'}</attribute>
</filter>
</field>
</record>
<record id="view_account_invoice_report_search" model="ir.ui.view">
<field name="name">account.invoice.groupby.commercial.partner.invoice.report</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.view_account_invoice_report_search"/>
<field name="arch" type="xml">
<filter name="partner_id" position="attributes">
<attribute name="context">{'group_by':'commercial_partner_id','residual_visible':True}</attribute>
</filter>
</field>
</record>
</data>
</openerp>

View File

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

View File

@@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
# © 2015-2017 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
{
'name': 'Account Invoice Margin',
'version': '10.0.1.0.0',
'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,43 @@
# -*- encoding: 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

@@ -1,10 +1,27 @@
# -*- coding: utf-8 -*-
# © 2015-2017 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).
# -*- encoding: 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/>.
#
##############################################################################
from odoo import models, fields, api
import odoo.addons.decimal_precision as dp
from openerp import models, fields, api
import openerp.addons.decimal_precision as dp
class AccountInvoiceLine(models.Model):
@@ -22,53 +39,56 @@ class AccountInvoiceLine(models.Model):
digits=dp.get_precision('Product Price'),
help="Cost price in invoice currency in the unit of measure "
"of the invoice line")
margin_invoice_currency = fields.Monetary(
margin_invoice_currency = fields.Float(
string='Margin in Invoice Currency', readonly=True, store=True,
compute='_compute_margin', currency_field='currency_id')
margin_company_currency = fields.Monetary(
compute='_compute_margin',
digits=dp.get_precision('Account'))
margin_company_currency = fields.Float(
string='Margin in Company Currency', readonly=True, store=True,
compute='_compute_margin', currency_field='company_currency_id')
compute='_compute_margin',
digits=dp.get_precision('Account'))
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.one
@api.depends(
'standard_price_company_currency', 'invoice_id.currency_id',
'invoice_id.type', 'invoice_id.company_id',
'invoice_id.date_invoice', 'quantity', 'price_subtotal')
def _compute_margin(self):
for il in self:
standard_price_inv_cur = 0.0
margin_inv_cur = 0.0
margin_comp_cur = 0.0
margin_rate = 0.0
inv = il.invoice_id
if inv and inv.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
standard_price_inv_cur =\
inv.company_id.currency_id.with_context(
date=inv.date_invoice).compute(
il.standard_price_company_currency,
inv.currency_id)
margin_inv_cur =\
il.price_subtotal - il.quantity * standard_price_inv_cur
margin_comp_cur = inv.currency_id.with_context(
date=inv.date_invoice).compute(
margin_inv_cur, inv.company_id.currency_id)
if il.price_subtotal:
margin_rate = 100 * margin_inv_cur / il.price_subtotal
# for a refund, margin should be negative
# but margin rate should stay positive
if inv.type == 'out_refund':
margin_inv_cur *= -1
margin_comp_cur *= -1
il.standard_price_invoice_currency = standard_price_inv_cur
il.margin_invoice_currency = margin_inv_cur
il.margin_company_currency = margin_comp_cur
il.margin_rate = margin_rate
standard_price_inv_cur = 0.0
margin_inv_cur = 0.0
margin_comp_cur = 0.0
margin_rate = 0.0
if (
self.invoice_id and
self.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
standard_price_inv_cur =\
self.invoice_id.company_id.currency_id.with_context(
date=self.invoice_id.date_invoice).compute(
self.standard_price_company_currency,
self.invoice_id.currency_id)
margin_inv_cur =\
self.price_subtotal - self.quantity * standard_price_inv_cur
margin_comp_cur = self.invoice_id.currency_id.with_context(
date=self.invoice_id.date_invoice).compute(
margin_inv_cur, self.invoice_id.company_id.currency_id)
if self.price_subtotal:
margin_rate = 100 * margin_inv_cur / self.price_subtotal
# for a refund, margin should be negative
# but margin rate should stay positive
if self.invoice_id.type == 'out_refund':
margin_inv_cur *= -1
margin_comp_cur *= -1
self.standard_price_invoice_currency = standard_price_inv_cur
self.margin_invoice_currency = margin_inv_cur
self.margin_company_currency = margin_comp_cur
self.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,
@@ -81,11 +101,10 @@ class AccountInvoiceLine(models.Model):
if vals.get('product_id'):
pp = self.env['product.product'].browse(vals['product_id'])
std_price = pp.standard_price
inv_uom_id = vals.get('uom_id')
inv_uom_id = vals.get('uos_id')
if inv_uom_id and inv_uom_id != pp.uom_id.id:
inv_uom = self.env['product.uom'].browse(inv_uom_id)
std_price = pp.uom_id._compute_price(
std_price, inv_uom)
std_price = self.env['product.uom']._compute_price(
pp.uom_id.id, std_price, inv_uom_id)
vals['standard_price_company_currency'] = std_price
return super(AccountInvoiceLine, self).create(vals)
@@ -93,7 +112,7 @@ class AccountInvoiceLine(models.Model):
def write(self, vals):
if not vals:
vals = {}
if 'product_id' in vals or 'uom_id' in vals:
if 'product_id' in vals or 'uos_id' in vals:
for il in self:
if 'product_id' in vals:
if vals.get('product_id'):
@@ -103,21 +122,21 @@ class AccountInvoiceLine(models.Model):
pp = False
else:
pp = il.product_id or False
# uom_id is NOT a required field
if 'uom_id' in vals:
if vals.get('uom_id'):
# uos_id is NOT a required field
if 'uos_id' in vals:
if vals.get('uos_id'):
inv_uom = self.env['product.uom'].browse(
vals['uom_id'])
vals['uos_id'])
else:
inv_uom = False
else:
inv_uom = il.uom_id or False
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 = pp.uom_id._compute_price(
std_price, inv_uom)
std_price = self.env['product.uom']._compute_price(
pp.uom_id.id, std_price, inv_uom.id)
il.write({'standard_price_company_currency': std_price})
return super(AccountInvoiceLine, self).write(vals)
@@ -125,26 +144,26 @@ class AccountInvoiceLine(models.Model):
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
margin_invoice_currency = fields.Monetary(
margin_invoice_currency = fields.Float(
string='Margin in Invoice Currency',
readonly=True, compute='_compute_margin', store=True,
currency_field='currency_id')
margin_company_currency = fields.Monetary(
digits=dp.get_precision('Account'))
margin_company_currency = fields.Float(
string='Margin in Company Currency',
readonly=True, compute='_compute_margin', store=True,
currency_field='company_currency_id')
digits=dp.get_precision('Account'))
@api.one
@api.depends(
'type',
'invoice_line_ids.margin_invoice_currency',
'invoice_line_ids.margin_company_currency')
'invoice_line.margin_invoice_currency',
'invoice_line.margin_company_currency')
def _compute_margin(self):
for inv in self:
margin_inv_cur = 0.0
margin_comp_cur = 0.0
if inv.type in ('out_invoice', 'out_refund'):
for il in inv.invoice_line_ids:
margin_inv_cur += il.margin_invoice_currency
margin_comp_cur += il.margin_company_currency
inv.margin_invoice_currency = margin_inv_cur
inv.margin_company_currency = margin_comp_cur
margin_inv_cur = 0.0
margin_comp_cur = 0.0
if self.type in ('out_invoice', 'out_refund'):
for il in self.invoice_line:
margin_inv_cur += il.margin_invoice_currency
margin_comp_cur += il.margin_company_currency
self.margin_invoice_currency = margin_inv_cur
self.margin_company_currency = margin_comp_cur

View File

@@ -1,62 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2018 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).
from odoo import models, fields, api
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
margin = fields.Float(string='Margin', readonly=True)
# why digits=0 ??? Why is it like that in the native "account" module
user_currency_margin = fields.Float(
string="Margin", compute='_compute_user_currency_margin', digits=0)
_depends = {
'account.invoice': [
'account_id', 'amount_total_company_signed',
'commercial_partner_id', 'company_id',
'currency_id', 'date_due', 'date_invoice', 'fiscal_position_id',
'journal_id', 'partner_bank_id', 'partner_id', 'payment_term_id',
'residual', 'state', 'type', 'user_id',
],
'account.invoice.line': [
'account_id', 'invoice_id', 'price_subtotal', 'product_id',
'quantity', 'uom_id', 'account_analytic_id',
'margin_company_currency',
],
'product.product': ['product_tmpl_id'],
'product.template': ['categ_id'],
'product.uom': ['category_id', 'factor', 'name', 'uom_type'],
'res.currency.rate': ['currency_id', 'name'],
'res.partner': ['country_id'],
}
@api.depends('currency_id', 'date', 'margin')
def _compute_user_currency_margin(self):
context = dict(self._context or {})
user_currency_id = self.env.user.company_id.currency_id
currency_rate_id = self.env['res.currency.rate'].search([
('rate', '=', 1),
'|',
('company_id', '=', self.env.user.company_id.id),
('company_id', '=', False)], limit=1)
base_currency_id = currency_rate_id.currency_id
ctx = context.copy()
for record in self:
ctx['date'] = record.date
record.user_currency_margin = base_currency_id.with_context(
ctx).compute(record.margin, user_currency_id)
# TODO check for refunds
def _sub_select(self):
select_str = super(AccountInvoiceReport, self)._sub_select()
select_str += ", SUM(ail.margin_company_currency) AS margin"
return select_str
def _select(self):
select_str = super(AccountInvoiceReport, self)._select()
select_str += ", sub.margin AS margin"
return select_str

View File

@@ -1,32 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2015-2017 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).
Copyright (C) 2015 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<odoo>
<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="company_id" position="after">
<field name="discount" position="after">
<field name="standard_price_company_currency"
groups="base.group_no_one"/>
groups="account.group_account_user"/>
<field name="standard_price_invoice_currency"
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="base.group_no_one"/>
groups="account.group_account_user"/>
<field name="margin_invoice_currency"
groups="base.group_no_one"/>
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="account.group_account_user"/>
<field name="margin_company_currency"
groups="base.group_no_one"/>
<label for="margin_rate" groups="base.group_no_one"/>
<div name="margin_rate" groups="base.group_no_one">
<field name="margin_rate" class="oe_inline"/> %
</div>
groups="account.group_account_user"/>
</field>
</field>
</record>
@@ -38,12 +37,23 @@
<field name="arch" type="xml">
<field name="move_id" position="after">
<field name="margin_invoice_currency"
string="Margin" groups="base.group_no_one"/>
string="Margin"
widget="monetary"
options="{'currency_field': 'currency_id'}"
groups="account.group_account_user"/>
<field name="margin_company_currency"
groups="base.group_no_one"/>
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="base.group_no_one"/>
<field name="standard_price_company_currency" groups="base.group_no_one"/>
<field name="margin_invoice_currency" groups="base.group_no_one"/>
<field name="margin_company_currency" groups="base.group_no_one"/>
<field name="margin_rate" groups="base.group_no_one"/>
</xpath>
</field>
</record>
</odoo>
</data>
</openerp>

View File

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

View File

@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Margin Report 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 Report',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Add margin measure in Invoices Analysis',
'description': """
This module adds the measure *Margin* in the Invoices Analysis pivot table. It is in a separate module because it depends on the module *bi_invoice_company_currency* (in which I re-wrote the Invoice Analysis pivot table).
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account_invoice_margin', 'bi_invoice_company_currency'],
'data': [],
'installable': True,
}

View File

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

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Margin Report 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/>.
#
##############################################################################
from openerp import models, fields
import openerp.addons.decimal_precision as dp
class AccountInvoiceReportBi(models.Model):
_inherit = "account.invoice.report.bi"
margin_company_currency = fields.Float(
string='Margin', readonly=True,
digits=dp.get_precision('Account'))
def _select(self):
select = super(AccountInvoiceReportBi, self)._select()
select += """
, sum(ail.margin_company_currency) AS margin_company_currency
"""
return select

View File

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

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Partner Bank Usability module for Odoo
# Copyright (C) 2013-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/>.
#
##############################################################################
{
'name': 'Account Invoice Partner Bank Usability',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Configure a bank account by default for customer invoices',
'description': """
Account Invoice Partner Bank Usability
======================================
This module adds a configuration parameter on the company that allows you to choose which bank account of your company will be selected by default on customer invoices.
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': ['company_view.xml'],
'installable': True,
}

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Partner Bank Usability module for Odoo
# Copyright (C) 2013-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 import models, fields
class ResCompany(models.Model):
_inherit = 'res.company'
default_out_invoice_partner_bank_id = fields.Many2one(
'res.partner.bank',
string='Default Bank Account for Customer Invoices',
copy=False, ondelete='restrict',
help="This is the bank account of your company that will be selected "
"by default when you create a customer invoice.")
class AccountInvoice(models.Model):
_inherit = "account.invoice"
def invoice_out_default_bank_account(self):
partner_bank_id = False
if self._context.get('type') == 'out_invoice' or \
self._context.get('inv_type') == 'out_invoice':
partner_bank_id = self.env.user.company_id.\
default_out_invoice_partner_bank_id.id or False
return partner_bank_id
partner_bank_id = fields.Many2one(default=invoice_out_default_bank_account)

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 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_company_form" model="ir.ui.view">
<field name="name">account_invoice_partner_bank_usability.company.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form" />
<field name="arch" type="xml">
<group name="account_grp" position="inside">
<field name="default_out_invoice_partner_bank_id"
domain="[('company_id', '=', id)]"/>
</group>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Picking Label module for OpenERP
# Copyright (C) 2013-2014 Akretion
# @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,42 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Invoice Picking Label module for OpenERP
# Copyright (C) 2014 Akretion
# @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 Picking Label',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Adds field picking_ids_label on account.invoice',
'description': """
Account Invoice Picking Label
=============================
Adds a function field named *picking_ids_label* on invoices. This field contains the list of pickings related to the invoice as a string. This field is designed to be displayed in the invoice report.""",
'author': 'Akretion',
'website': 'http://www.akretion.com/',
'depends': ['stock_account'],
'data': [],
'installable': True,
'active': False,
}

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Invoice Picking Label module for OpenERP
# Copyright (C) 2013-2014 Akretion
# @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"
def _compute_picking_ids_label(
self, cr, uid, ids, name, arg, context=None):
res = {}
for invoice in self.read(
cr, uid, ids, ['picking_ids'], context=context):
label = ''
if invoice['picking_ids']:
pickings = self.pool['stock.picking'].read(
cr, uid, invoice['picking_ids'], ['name'],
context=context)
first = True
for picking in pickings:
if first:
label += picking['name']
first = False
else:
label += ', %s' % picking['name']
res[invoice['id']] = label
return res
_columns = {
'picking_ids_label': fields.function(
_compute_picking_ids_label, type='char', string='Pickings'),
}

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,46 @@
# -*- 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.
This module adds a field *sale_ids* on the object account.invoice, which is the reverse many2many field of the field *invoice_ids* of the object sale.order. It is displayed in a dedicated tab on the invoice form 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': ['sale'],
'data': ['account_invoice_view.xml'],
'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

@@ -0,0 +1,25 @@
<?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="invoice_form" model="ir.ui.view">
<field name="name">account_invoice_sale_link.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page name="sale_ids" string="Sale Orders">
<field name="sale_ids"/>
</page>
</notebook>
</field>
</record>
</data>
</openerp>

View File

@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2018 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': 'partner_address_street3 / account_invoice_transmit_method compat.',
'version': '10.0.0.1.0',
'category': 'Partner',
'license': 'AGPL-3',
'summary': 'Compatibility between partner_address_street3 and account_invoice_transmit_method',
'description': """
Glue module between partner_address_street3 and account_invoice_transmit_method
===============================================================================
Stupid technical module to workaround an Odoo framework limitation about the inherit of the context attribute in a view.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['partner_address_street3', 'account_invoice_transmit_method'],
'data': [
'partner_view.xml',
],
'installable': True,
'auto_install': True,
}

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">Compatibility partner_address_street3 / account_invoice_transmit_method</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="priority">1000</field>
<field name="arch" type="xml">
<field name="child_ids" position="attributes">
<attribute name="context">{'default_parent_id': active_id, 'default_street': street, 'default_street2': street2, 'default_city': city, 'default_state_id': state_id, 'default_zip': zip, 'default_country_id': country_id, 'default_supplier': supplier, 'default_customer': customer, 'default_lang': lang, 'default_customer_invoice_transmit_method_code': customer_invoice_transmit_method_code, 'default_supplier_invoice_transmit_method_code': supplier_invoice_transmit_method_code, 'default_street3': street3}</attribute>
</field>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# Copyright 2018 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Account Invoice Update Wizard',
'version': '8.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Wizard to update non-legal fields of an open/paid invoice',
'description': """
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
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'data': [
'wizard/account_invoice_update_view.xml',
'views/account_invoice.xml',
],
'installable': True,
}

View File

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

View File

@@ -1,198 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
from odoo.exceptions import UserError
class TestAccountInvoiceUpdateWizard(TransactionCase):
def setUp(self):
super(TestAccountInvoiceUpdateWizard, self).setUp()
self.customer12 = self.env.ref('base.res_partner_12')
self.product16 = self.env.ref('product.product_product_16')
self.product24 = self.env.ref('product.product_product_24')
uom_unit = self.env.ref('product.product_uom_categ_unit')
self.invoice1 = self.env['account.invoice'].create({
'name': 'Test invoice',
'partner_id': self.customer12.id,
})
self.inv_line1 = self.env['account.invoice.line'].create({
'invoice_id': self.invoice1.id,
'name': "Line1",
'product_id': self.product16.id,
'product_uom_id': uom_unit.id,
'account_id': self.invoice1.account_id.id,
'price_unit': 42.0,
})
self.inv_line2 = self.env['account.invoice.line'].create({
'invoice_id': self.invoice1.id,
'name': "Line2",
'product_id': self.product24.id,
'product_uom_id': uom_unit.id,
'account_id': self.invoice1.account_id.id,
'price_unit': 1111.1,
})
self.aa1 = self.env.ref('analytic.analytic_partners_camp_to_camp')
self.aa2 = self.env.ref('analytic.analytic_nebula')
self.atag1 = self.env.ref('analytic.tag_contract')
self.atag2 = self.env['account.analytic.tag'].create({
'name': u'',
})
def create_wizard(self):
UpdateWizard = self.env['account.invoice.update'].with_context(
active_model='account.invoice',
active_id=self.invoice1.id)
self.wiz = UpdateWizard.create({})
def test_add_analytic_account_line1(self):
""" Add analytic account on an invoice line
after the invoice has been approved.
This will:
- update the move line
- create a new analytic line.
"""
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.account_analytic_id = self.aa1
self.wiz.run()
related_ml = self.invoice1.move_id.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 an invoice line
after the invoice has been approved.
This will:
- update the move line
- update the existing analytic line."""
self.inv_line1.account_analytic_id = self.aa2
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.account_analytic_id = self.aa1
self.wiz.run()
related_ml = self.invoice1.move_id.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_error_grouped_move_lines(self):
""" Change analytic account on an invoice line
after the invoice has been approved where both
lines were grouped in the same move line.
This will raise an error.
"""
self.invoice1.journal_id.group_invoice_lines = True
self.inv_line2.product_id = self.product16
self.inv_line2.unit_price = 42.0
self.invoice1.action_invoice_open()
self.create_wizard()
line1 = self.wiz.line_ids[0]
line1.account_analytic_id = self.aa1
with self.assertRaises(UserError):
self.wiz.run()
def test_add_analytic_tags_line1(self):
""" Add analytic tags on an invoice line
after the invoice has been approved.
This will update move line.
"""
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.invoice1.move_id.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 an invoice line
after the invoice has been approved.
It will update move line and analytic line
"""
self.inv_line1.account_analytic_id = self.aa2
self.inv_line1.analytic_tag_ids = self.atag1
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.invoice1.move_id.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 an invoice line
after the invoice has been approved.
This will:
- update move line
- create an analytic line
"""
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.account_analytic_id = self.aa1
wiz_line.analytic_tag_ids = self.atag2
self.wiz.run()
related_ml = self.invoice1.move_id.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 invoice has been approved.
This will raise an error as it is not implemented.
"""
self.inv_line1.account_analytic_id = self.aa2
self.invoice1.action_invoice_open()
self.create_wizard()
wiz_line = self.wiz.line_ids.filtered(
lambda rec: rec.invoice_line_id == self.inv_line1)
wiz_line.account_analytic_id = False
self.wiz.run()
related_ml = self.invoice1.move_id.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,29 +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="invoice_supplier_form" model="ir.ui.view">
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="arch" type="xml">
<button name="action_invoice_cancel" position="before">
<button name="%(account_invoice_update_action)d" type="action" string="Update Invoice" states="open,paid" groups="account.group_account_invoice"/>
</button>
</field>
</record>
<record id="invoice_form" model="ir.ui.view">
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<button name="action_invoice_cancel" position="before">
<button name="%(account_invoice_update_action)d" type="action" string="Update Invoice" states="open,paid" groups="account.group_account_invoice"/>
</button>
</field>
</record>
</odoo>

View File

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

View File

@@ -1,308 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
# Copyright 2018 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 AccountInvoiceUpdate(models.TransientModel):
_name = 'account.invoice.update'
_description = 'Wizard to update non-legal fields of invoice'
invoice_id = fields.Many2one(
'account.invoice', string='Invoice', required=True,
readonly=True)
type = fields.Selection(related='invoice_id.type', readonly=True)
company_id = fields.Many2one(
related='invoice_id.company_id', readonly=True)
partner_id = fields.Many2one(
related='invoice_id.partner_id', readonly=True)
user_id = fields.Many2one('res.users', string='Salesperson')
payment_term_id = fields.Many2one(
'account.payment.term', string='Payment Term')
reference = fields.Char(string='Invoice Reference')
name = fields.Char(string='Reference/Description')
origin = fields.Char(string='Source Document')
comment = fields.Text('Additional Information')
partner_bank_id = fields.Many2one(
'res.partner.bank', string='Bank Account')
line_ids = fields.One2many(
'account.invoice.line.update', 'parent_id', string='Invoice Lines')
@api.model
def _simple_fields2update(self):
'''List boolean, date, datetime, char, text fields'''
return ['reference', 'name', 'origin', 'comment']
@api.model
def _m2o_fields2update(self):
return ['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,
'name': line.name,
'quantity': line.quantity,
'price_subtotal': line.price_subtotal,
'account_analytic_id': line.account_analytic_id.id,
'analytic_tag_ids': aa_tags,
}])
return res
@api.model
def default_get(self, fields_list):
res = super(AccountInvoiceUpdate, self).default_get(fields_list)
assert self._context.get('active_model') == 'account.invoice',\
'active_model should be account.invoice'
inv = self.env['account.invoice'].browse(self._context['active_id'])
res = self._prepare_default_get(inv)
return res
@api.onchange('type')
def type_on_change(self):
res = {'domain': {}}
if self.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
@api.multi
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 'payment_term_id' in vals:
pterm_list = self.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 ["account_analytic_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
@api.multi
def _prepare_move(self):
mvals = {}
inv = self.invoice_id
ini_ref = inv.move_id.ref
ref = inv.reference or inv.name
if ini_ref != ref:
mvals['ref'] = ref
return mvals
@api.multi
def _get_matching_inv_line(self, move_line):
""" Find matching invoice line by product """
# TODO make it accept more case as lines won't
# be grouped unless journal.group_invoice_line is True
inv_line = self.invoice_id.invoice_line_ids.filtered(
lambda rec: rec.product_id == move_line.product_id)
if len(inv_line) <> 1:
raise UserError(
"Cannot match a single invoice line to move line %s" %
move_line.name)
return inv_line
@api.multi
def _prepare_move_line(self, inv_line):
mlvals = {}
inv_line_upd = self.line_ids.filtered(
lambda rec: rec.invoice_line_id == inv_line)
ini_aa = inv_line.account_analytic_id
new_aa = inv_line_upd.account_analytic_id
if ini_aa != new_aa:
mlvals['analytic_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)]
return mlvals
@api.multi
def _prepare_analytic_line(self, inv_line):
alvals = {}
inv_line_upd = self.line_ids.filtered(
lambda rec: rec.invoice_line_id == inv_line)
ini_aa = inv_line.account_analytic_id
new_aa = inv_line_upd.account_analytic_id
if ini_aa != new_aa:
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:
alvals['tag_ids'] = [(6, None, new_aa_tags.ids)]
return alvals
@api.multi
def _update_payment_term_move(self):
self.ensure_one()
inv = self.invoice_id
if (
self.payment_term_id and
self.payment_term_id != inv.payment_term_id and
inv.move_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_ids:
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.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.iteritems():
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.payment_term_id.name, self.payment_term_id.name))
for line in lines:
line.date_maturity = new_pterm[iamount].pop()
@api.multi
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.move_id:
mvals = self._prepare_move()
if mvals:
inv.move_id.write(mvals)
for ml in inv.move_id.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
inv_line = self._get_matching_inv_line(ml)
mlvals = self._prepare_move_line(inv_line)
if mlvals:
updated = True
ml.write(mlvals)
aalines = ml.analytic_line_ids
alvals = self._prepare_analytic_line(inv_line)
if aalines and alvals:
updated = True
if ('account_id' in alvals and
alvals['account_id'] is False):
former_aa = inv_line.account_analytic_id
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(_(
'Non-legal fields of invoice updated via the Invoice Update '
'wizard.'))
return True
class AccountInvoiceLineUpdate(models.TransientModel):
_name = 'account.invoice.line.update'
_description = 'Update non-legal fields of invoice lines'
parent_id = fields.Many2one(
'account.invoice.update', string='Wizard', ondelete='cascade')
invoice_line_id = fields.Many2one(
'account.invoice.line', string='Invoice Line', readonly=True)
name = fields.Text(string='Description', required=True)
quantity = fields.Float(
string='Quantity', digits=dp.get_precision('Product Unit of Measure'),
readonly=True)
price_subtotal = fields.Float(
string='Amount', readonly=True, digits=dp.get_precision('Account'))
account_analytic_id = fields.Many2one(
'account.analytic.account', string='Analytic Account')
analytic_tag_ids = fields.Many2many(
'account.analytic.tag', string='Analytic Tags')

View File

@@ -1,53 +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.invoice.update</field>
<field name="arch" type="xml">
<form string="Update Invoice Wizard">
<group name="main">
<field name="invoice_id" invisible="1"/>
<field name="type" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="reference" attrs="{'invisible': [('type', 'not in', ('in_invoice', 'in_refund'))]}"/>
<field name="origin"/>
<field name="name"/>
<field name="payment_term_id" widget="selection"/>
<field name="partner_bank_id"/>
<field name="user_id"/>
<field name="comment"/>
</group>
<group name="lines">
<field name="line_ids" nolabel="1">
<tree editable="bottom">
<field name="invoice_line_id" invisible="1"/>
<field name="name"/>
<field name="quantity"/>
<field name="price_subtotal"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="analytic_tag_ids" groups="analytic.group_analytic_accounting" 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.invoice.update</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -1,33 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016-2018 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 Line Filter Wizard',
'version': '10.0.2.0.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Easy and fast access to the details of an account',
'description': """
Account Move Line Filter Wizard
===============================
This module adds a *Show Account* wizard under *Accounting > Adviser*. This wizard gives an easy and fast access to the details of an account:
* access to the General Ledger Report,
* access to the Open Items Report (if the user selected a reconciliable account and the Unreconciled filter),
* access to the Journal Items view.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': [
'account_usability',
'account_financial_report_qweb',
'account_fiscal_year',
],
'data': ['wizard/account_move_line_filter_view.xml'],
'installable': True,
}

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Move Line Filter Wizard module for Odoo
# Copyright (C) 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/>.
#
##############################################################################
{
'name': 'Account Move Line Filter Wizard',
'version': '0.1',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Easy and fast access to the details of an account',
'description': """
Account Move Line Filter Wizard
===============================
This module adds a wizard in Accounting > ... >
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account_usability'],
'data': ['wizard/account_move_line_filter_view.xml'],
'installable': True,
}

View File

@@ -1,62 +1,54 @@
# -*- coding: utf-8 -*-
# Copyright 2016-2018 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).
##############################################################################
#
# Account Move Line Filter Wizard module for Odoo
# Copyright (C) 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 odoo import models, fields, api, _
from odoo.exceptions import UserError
from openerp import models, fields, api
class AccountMoveLineFilterWizard(models.TransientModel):
_name = 'account.move.line.filter.wizard'
_description = 'Wizard for easy and fast access to account move lines'
date_range_id = fields.Many2one(
'date.range', string='Date Range (only for General Ledger)')
partner_id = fields.Many2one(
'res.partner', string='Partner', domain=[('parent_id', '=', False)])
account_id = fields.Many2one(
'account.account', string='Account',
domain=[('deprecated', '=', False)], required=True)
account_reconcile = fields.Boolean(
related='account_id.reconcile', readonly=True)
domain=[('type', 'not in', ('view', 'closed'))], required=True)
account_reconcile = fields.Boolean(related='account_id.reconcile')
reconcile = fields.Selection([
('unreconciled', 'Unreconciled or Partially Reconciled'),
('unreconciled', 'Unreconciled'),
('reconciled', 'Fully Reconciled'),
# ('partial_reconciled', 'Partially Reconciled'),
('partial_reconciled', 'Partially Reconciled'),
], string='Reconciliation Filter')
@api.model
def default_get(self, fields_list):
res = super(AccountMoveLineFilterWizard, self).default_get(fields_list)
today = fields.Date.context_today(self)
fy_type_id = self.env.ref('account_fiscal_year.fiscalyear').id
dro = self.env['date.range']
date_range = dro.search([
('type_id', '=', fy_type_id),
('company_id', '=', self.env.user.company_id.id),
('date_start', '<=', today),
('date_end', '>=', today)
], limit=1)
if not date_range:
date_range = dro.search([
('type_id', '=', fy_type_id),
('company_id', '=', self.env.user.company_id.id),
], order='date_start desc', limit=1)
if date_range:
res['date_range_id'] = date_range.id
return res
@api.onchange('partner_id')
def partner_id_change(self):
if self.partner_id:
if self.partner_id.customer:
self.account_id =\
self.partner_id.property_account_receivable_id.id
self.partner_id.property_account_receivable.id
else:
self.account_id =\
self.partner_id.property_account_payable_id.id
self.account_id = self.partner_id.property_account_payable.id
@api.multi
def go(self):
self.ensure_one()
action = self.env['ir.actions.act_window'].for_xml_id(
@@ -68,33 +60,3 @@ class AccountMoveLineFilterWizard(models.TransientModel):
if self.reconcile:
action['context']['search_default_%s' % self.reconcile] = True
return action
def show_report_general_ledger(self):
self.ensure_one()
if self.account_reconcile:
assert self.reconcile != 'unreconciled'
if not self.date_range_id:
raise UserError(_(
"Select a date range to show the General Ledger report."))
wvals = {
'account_ids': [(6, 0, [self.account_id.id])],
'date_from': self.date_range_id.date_start,
'date_to': self.date_range_id.date_end,
}
if self.partner_id:
wvals['partner_ids'] = [(6, 0, [self.partner_id.id])]
wiz = self.env['general.ledger.report.wizard'].create(wvals)
action = wiz.button_export_html()
return action
def show_report_open_items(self):
self.ensure_one()
assert self.account_reconcile and self.reconcile == 'unreconciled'
wvals = {
'account_ids': [(6, 0, [self.account_id.id])],
}
if self.partner_id:
wvals['partner_ids'] = [(6, 0, [self.partner_id.id])]
wiz = self.env['open.items.report.wizard'].create(wvals)
action = wiz.button_export_html()
return action

View File

@@ -1,38 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016-2019 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).
Copyright (C) 2016 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<odoo>
<openerp>
<data>
<record id="account_move_line_filter_wizard_form" model="ir.ui.view">
<field name="name">account_move_line_filter_wizard_form</field>
<field name="model">account.move.line.filter.wizard</field>
<field name="arch" type="xml">
<form string="Show Account">
<form string="Account Move Lines">
<group name="filters" string="Filters">
<field name="partner_id"/>
<field name="account_id"/>
<field name="account_reconcile" invisible="1"/>
<field name="reconcile"
attrs="{'invisible': [('account_reconcile', '!=', True)]}"/>
<field name="date_range_id" attrs="{'invisible': [('account_reconcile', '=', True), ('reconcile', '=', 'unreconciled')]}"/>
</group>
<footer>
<button type="object" name="show_report_general_ledger" string="General Ledger Report" class="btn-primary" attrs="{'invisible': [('account_reconcile', '=', True), ('reconcile', '=', 'unreconciled')]}"/>
<button type="object" name="show_report_open_items" string="Open Items Report" class="btn-primary" attrs="{'invisible': ['|', ('account_reconcile', '=', False), ('reconcile', '!=', 'unreconciled')]}"/>
<button type="object" name="go" string="Journal Items" class="btn-primary"/>
<button special="cancel" string="Cancel" class="btn-default"/>
<button type="object" name="go" string="Go" class="oe_highlight"/>
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="account_move_line_filter_wizard_action" model="ir.actions.act_window">
<field name="name">Show Account</field>
<field name="name">Journal Items of Account</field>
<field name="res_model">account.move.line.filter.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
@@ -44,4 +42,5 @@
sequence="-1"/>
</odoo>
</data>
</openerp>

View File

@@ -40,5 +40,5 @@ This module has been written by Alexis de Lattre from Akretion
'website': 'http://www.akretion.com/',
'depends': ['account_cutoff_prepaid', 'account_move_line_report_xls'],
'data': [],
'installable': False,
'installable': True,
}

View File

@@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# © 2017 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 No Analytic Tags',
'version': '10.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'No Analytic Tags in Accounting',
'description': """
Account No Analytic Tags
========================
This module hides analytic tags on invoices and move lines.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account', 'base_usability'],
'data': ['account_view.xml'],
'installable': True,
}

View File

@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2017 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>
<!-- INVOICE -->
<record id="invoice_supplier_form" model="ir.ui.view">
<field name="name">account_no_analytic_tags.supplier.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='analytic_tag_ids']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
<record id="invoice_form" model="ir.ui.view">
<field name="name">account_no_analytic_tags.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='analytic_tag_ids']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
<!-- ACCOUNT MOVE LINE -->
<record id="view_move_line_form" model="ir.ui.view">
<field name="name">account_no_analytic_tags.move.line.form</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form"/>
<field name="arch" type="xml">
<field name="analytic_tag_ids" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
<!-- ANALYTIC ACCOUNT -->
<record id="view_account_analytic_account_form" model="ir.ui.view">
<field name="name">account_no_analytic_tags.analytic.account.form</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field name="arch" type="xml">
<field name="tag_ids" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
<record id="account.account_analytic_tag_menu" model="ir.ui.menu">
<field name="groups_id" eval="[(6, 0, [ref('base_usability.group_nobody')])]"/>
</record>
</odoo>

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Force Maturity Date 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/>.
#
##############################################################################
from . import payment_line

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Force Maturity Date 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 Payment Force Maturity Date',
'version': '1.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Add a Force Maturity Date field on payment lines',
'description': """
Account Payment Force Maturity Date
===================================
This module adds a field *Force Maturity Date* on payment lines. If this field is set, the maturity date of the payment line will take the value of this field instead of taking the value of the maturity date of the related account move line.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'depends': ['account_payment'],
'data': ['payment_view.xml'],
}

View File

@@ -0,0 +1,27 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_payment_force_maturity_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-06 15:02+0000\n"
"PO-Revision-Date: 2015-05-06 15:02+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_payment_force_maturity_date
#: field:payment.line,force_maturity_date:0
msgid "Force Due Date"
msgstr ""
#. module: account_payment_force_maturity_date
#: model:ir.model,name:account_payment_force_maturity_date.model_payment_line
msgid "Payment Line"
msgstr ""

View File

@@ -0,0 +1,27 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_payment_force_maturity_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-06 15:03+0000\n"
"PO-Revision-Date: 2015-05-06 15:03+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_payment_force_maturity_date
#: field:payment.line,force_maturity_date:0
msgid "Force Due Date"
msgstr "Force la date d'échéance"
#. module: account_payment_force_maturity_date
#: model:ir.model,name:account_payment_force_maturity_date.model_payment_line
msgid "Payment Line"
msgstr "Ligne de paiement"

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Force Maturity Date 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/>.
#
##############################################################################
from openerp import models, fields, api
class PaymentLine(models.Model):
_inherit = 'payment.line'
@api.one
@api.depends(
'move_line_id', 'move_line_id.date_maturity', 'force_maturity_date')
def _compute_ml_maturity_date(self):
ml_maturity_date = False
if self.force_maturity_date:
ml_maturity_date = self.force_maturity_date
elif self.move_line_id:
ml_maturity_date = self.move_line_id.date_maturity
self.ml_maturity_date = ml_maturity_date
ml_maturity_date = fields.Date(compute='_compute_ml_maturity_date')
force_maturity_date = fields.Date(string='Force Due Date')

View File

@@ -0,0 +1,23 @@
<?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_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='ml_inv_ref']" position="after">
<field name="force_maturity_date"/>
</xpath>
</field>
</record>
</data>
</openerp>

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,23 @@
<?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="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Security 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,45 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Account Payment Security 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 Security',
'version': '1.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Only members of Account Payment can create/write on bank accounts',
'description': """
Account Payment Security
========================
By default in OpenERP, members of the group *Contact Creation* can create and modify bank accounts ; this can be a risk, as explained in this mail : https://lists.launchpad.net/openerp-community/msg01035.html
With this module, only the members of the group *Accounting / Payments* can create and modify bank accounts. Also, some rights on the configuration of bank accounts (res.partner.bank.type and res.partner.bank.type.field) are moved from the group *Contact Creation* to *Financial Manager*.
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': [
'security/ir.model.access.csv',
],
'active': False,
}

View File

@@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
base.access_res_partner_bank_group_partner_manager,Full access on res.partner.bank to Account Payment,base.model_res_partner_bank,account_payment.group_account_payment,1,1,1,1
base.access_res_bank_group_partner_manager,Full access on res.bank to Account Payment,base.model_res_bank,account_payment.group_account_payment,1,1,1,1
base.access_res_partner_bank_type_group_partner_manager,Full access on res.partner.bank.type to Financial Manager,base.model_res_partner_bank_type,account.group_account_manager,1,1,1,1
base.access_res_partner_bank_type_field_group_partner_manager,Full access on res.partner.bank.type.field to Financial Manager,base.model_res_partner_bank_type_field,account.group_account_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 base.access_res_partner_bank_group_partner_manager Full access on res.partner.bank to Account Payment base.model_res_partner_bank account_payment.group_account_payment 1 1 1 1
3 base.access_res_bank_group_partner_manager Full access on res.bank to Account Payment base.model_res_bank account_payment.group_account_payment 1 1 1 1
4 base.access_res_partner_bank_type_group_partner_manager Full access on res.partner.bank.type to Financial Manager base.model_res_partner_bank_type account.group_account_manager 1 1 1 1
5 base.access_res_partner_bank_type_field_group_partner_manager Full access on res.partner.bank.type.field to Financial Manager base.model_res_partner_bank_type_field account.group_account_manager 1 1 1 1

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
# -*- encoding: utf-8 -*-
from . import account
from . import account_invoice_report
from . import partner
from . import wizard

View File

@@ -1,48 +0,0 @@
# -*- coding: utf-8 -*-
# © 2015-2016 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 Usability',
'version': '10.0.1.0.0',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account module',
'description': """
Account Usability
=================
The usability enhancements include:
* show the supplier invoice number in the tree view of supplier invoices
* add an *Overdue* filter on invoice search view (this feature was previously located in te module *account_invoice_overdue_filter*)
* Increase the default limit of 80 lines in account move and account move line view.
* Fast search on *Reconcile Ref* for account move line.
* disable reconciliation "guessing"
Together with this module, I recommend the use of the following modules:
* account_invoice_supplier_ref_unique (OCA project account-invoicing)
* account_move_line_no_default_search (OCA project account-financial-tools)
* invoice_fiscal_position_update (OCA project account-invoicing)
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': [
'account',
'base_view_inheritance_extension',
'base_usability', # needed only to access base_usability.group_nobody
# in v12, I may create a module only for group_nobody
],
'data': [
'account_view.xml',
'account_report.xml',
'account_invoice_report_view.xml',
'partner_view.xml',
'product_view.xml',
'wizard/account_invoice_mark_sent_view.xml',
'wizard/account_move_backtodraft_view.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,54 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Usability 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 Usability',
'version': '0.3',
'category': 'Accounting & Finance',
'license': 'AGPL-3',
'summary': 'Small usability enhancements in account module',
'description': """
Account Usability
=================
The usability enhancements include:
* show the supplier invoice number in the tree view of supplier invoices
* add an *Overdue* filter on invoice search view (this feature was previously located in te module *account_invoice_overdue_filter*)
* Increase the default limit of 80 lines in account move and account move line view.
* Fast search on *Reconcile Ref* for account move line.
* disable reconciliation "guessing"
Together with this module, I recommend the use of the following modules:
* account_invoice_supplier_ref_unique (OCA project account-invoicing)
* account_move_line_no_default_search (OCA project account-financial-tools)
* invoice_fiscal_position_update (OCA project account-invoicing)
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['account'],
'conflicts': ['account_invoice_overdue_filter'],
'data': ['account_view.xml'],
'installable': True,
}

View File

@@ -1,111 +1,64 @@
# -*- coding: utf-8 -*-
# © 2015-2016 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).
##############################################################################
#
# Account Usability 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/>.
#
##############################################################################
from odoo import models, fields, api, _
from odoo.tools import float_compare, float_is_zero, float_round
from odoo.tools.misc import formatLang
from odoo.exceptions import UserError, ValidationError
from odoo import SUPERUSER_ID
import logging
logger = logging.getLogger(__name__)
from openerp import models, fields, api, _
from openerp.tools import float_compare
from openerp.exceptions import Warning as UserError
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
origin = fields.Char(track_visibility='onchange')
supplier_invoice_number = fields.Char(track_visibility='onchange')
internal_number = fields.Char(track_visibility='onchange')
reference = fields.Char(track_visibility='onchange')
sent = fields.Boolean(track_visibility='onchange')
date_invoice = fields.Date(track_visibility='onchange')
date_due = fields.Date(track_visibility='onchange')
payment_term_id = fields.Many2one(track_visibility='onchange')
payment_term = fields.Many2one(track_visibility='onchange')
period_id = fields.Many2one(track_visibility='onchange')
account_id = fields.Many2one(track_visibility='onchange')
journal_id = fields.Many2one(track_visibility='onchange')
partner_bank_id = fields.Many2one(track_visibility='onchange')
fiscal_position_id = fields.Many2one(track_visibility='onchange')
amount_total = fields.Monetary(track_visibility='onchange')
# for those fields, the 'account' module sets track_visibility='always':
partner_id = fields.Many2one(track_visibility='onchange')
currency_id = fields.Many2one(track_visibility='onchange')
type = fields.Selection(track_visibility='onchange')
amount_untaxed = fields.Monetary(track_visibility='onchange')
# I want to see the number of cancelled invoice in chatter
move_id = fields.Many2one(track_visibility='onchange')
# for invoice report
has_discount = fields.Boolean(
compute='_compute_has_discount', readonly=True)
# has_attachment is useful for those who use attachment to archive
# supplier invoices. It allows them to find supplier invoices
# that don't have any attachment
has_attachment = fields.Boolean(
compute='_compute_has_attachment',
search='_search_has_attachment', readonly=True)
fiscal_position = fields.Many2one(track_visibility='onchange')
def _compute_has_discount(self):
prec = self.env['decimal.precision'].precision_get('Discount')
for inv in self:
has_discount = False
for line in inv.invoice_line_ids:
if not float_is_zero(line.discount, precision_digits=prec):
has_discount = True
break
inv.has_discount = has_discount
def _compute_has_attachment(self):
iao = self.env['ir.attachment']
for inv in self:
if iao.search([
('res_model', '=', 'account.invoice'),
('res_id', '=', inv.id),
('type', '=', 'binary'),
('company_id', '=', inv.company_id.id)], limit=1):
inv.has_attachment = True
else:
inv.has_attachment = False
def _search_has_attachment(self, operator, value):
att_inv_ids = {}
if operator == '=':
search_res = self.env['ir.attachment'].search_read([
('res_model', '=', 'account.invoice'),
('type', '=', 'binary'),
('res_id', '!=', False)], ['res_id'])
for att in search_res:
att_inv_ids[att['res_id']] = True
res = [('id', value and 'in' or 'not in', att_inv_ids.keys())]
return res
# when you have an invoice created from a lot of sale orders, the 'name'
# field is very large, which makes the name_get() of that invoice very big
# which screws-up the form view of that invoice because of the link at the
# top of the screen
# That's why we have to cut the name_get() when it's too long
def name_get(self):
old_res = super(AccountInvoice, self).name_get()
res = []
for old_re in old_res:
name = old_re[1]
if name and len(name) > 100:
# nice cut
name = u'%s ...' % ', '.join(name.split(', ')[:3])
# if not enough, hard cut
if len(name) > 120:
name = u'%s ...' % old_re[1][:120]
res.append((old_re[0], name))
@api.multi
def onchange_payment_term_date_invoice(self, payment_term_id, date_invoice):
res = super(AccountInvoice, self).onchange_payment_term_date_invoice(
payment_term_id, date_invoice)
if res and isinstance(res, dict) and 'value' in res:
res['value']['period_id'] = False
return res
# I really hate to see a "/" in the 'name' field of the account.move.line
# generated from customer invoices linked to the partners' account because:
# 1) the label of an account move line is an important field, we can't
# write a rubbish '/' in it !
# 2) the 'name' field of the account.move.line is used in the overdue
# letter, and '/' is not meaningful for our customer !
# 2) the 'name' field of the account.move.line is used in the overdue letter,
# and '/' is not meaningful for our customer !
@api.multi
def action_move_create(self):
res = super(AccountInvoice, self).action_move_create()
def action_number(self):
res = super(AccountInvoice, self).action_number()
for inv in self:
self._cr.execute(
"UPDATE account_move_line SET name= "
@@ -115,111 +68,28 @@ class AccountInvoice(models.Model):
self.invalidate_cache()
return res
def delete_lines_qty_zero(self):
lines = self.env['account.invoice.line'].search([
('invoice_id', 'in', self.ids), ('quantity', '=', 0)])
lines.unlink()
return True
@api.model
def _fix_invoice_attachment_filename(self):
# This script is designed to fix attachment of invoices
# badly generated by Odoo v8. I found this problem in Nov 2018 at
# Encres Dubuit when investigating a bug where Odoo would create a
# new attachment when printing an old invoice that already had the
# PDF of the invoice as attachment
logger.info('START fix customer invoice attachment filename')
# Run this script as admin to fix problem in all companies
self = self.sudo()
attachs = self.env['ir.attachment'].search([
('res_model', '=', 'account.invoice'),
('res_id', '!=', False),
('type', '=', 'binary'),
('name', '=like', 'INV%.pdf'),
('datas_fname', '=like', 'INV%.pdf.pdf')])
for attach in attachs:
inv = self.browse(attach.res_id)
if inv.type in ('out_invoice', 'out_refund'):
attach.datas_fname = attach.name
logger.info(
'Fixed field datas_fname of attachment ID %s name %s',
attach.id, attach.name)
logger.info('END fix customer invoice attachment filename')
class AccountFiscalYear(models.Model):
_inherit = 'account.fiscalyear'
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
# In the 'account' module, we have related stored field for:
# company_id, partner_id, currency_id
invoice_type = fields.Selection(
related='invoice_id.type', store=True, readonly=True)
date_invoice = fields.Date(
related='invoice_id.date_invoice', store=True, readonly=True)
commercial_partner_id = fields.Many2one(
related='invoice_id.partner_id.commercial_partner_id',
store=True, readonly=True, compute_sudo=True)
state = fields.Selection(
related='invoice_id.state', store=True, readonly=True,
string='Invoice State')
invoice_number = fields.Char(
related='invoice_id.move_id.name', store=True, readonly=True,
string='Invoice Number')
# For companies that have a fiscal year != calendar year
# I want to be able to write '2015-2016' in the code field
# => size=9 instead of 6
code = fields.Char(size=9)
class AccountJournal(models.Model):
_inherit = 'account.journal'
hide_bank_statement_balance = fields.Boolean(
string='Hide Bank Statement Balance',
help="You may want to enable this option when your bank "
"journal is generated from a bank statement file that "
"doesn't handle start/end balance (QIF for instance) and "
"you don't want to enter the start/end balance manually: it "
"will prevent the display of wrong information in the accounting "
"dashboard and on bank statements.")
@api.multi
@api.depends(
'name', 'currency_id', 'company_id', 'company_id.currency_id', 'code')
def name_get(self):
res = []
if self._context.get('journal_show_code_only'):
for journal in self:
res.append((journal.id, journal.code))
res = []
for record in self:
res.append((record.id, record.code))
return res
else:
for journal in self:
currency = journal.currency_id or\
journal.company_id.currency_id
name = "[%s] %s (%s)" % (
journal.code, journal.name, currency.name)
res.append((journal.id, name))
return res
@api.constrains('default_credit_account_id', 'default_debit_account_id')
def _check_account_type_on_bank_journal(self):
bank_acc_type = self.env.ref('account.data_account_type_liquidity')
for jrl in self:
if jrl.type in ('bank', 'cash'):
if (
jrl.default_debit_account_id and
jrl.default_debit_account_id.user_type_id !=
bank_acc_type):
raise ValidationError(_(
"On journal '%s', the default debit account '%s' "
"should be configured with Type = 'Bank and Cash'.")
% (jrl.display_name,
jrl.default_debit_account_id.display_name))
if (
jrl.default_credit_account_id and
jrl.default_credit_account_id.user_type_id !=
bank_acc_type):
raise ValidationError(_(
"On journal '%s', the default credit account '%s' "
"should be configured with Type = 'Bank and Cash'.")
% (jrl.display_name,
jrl.default_credit_account_id.display_name))
return super(AccountJournal, self).name_get()
class AccountAccount(models.Model):
@@ -235,87 +105,6 @@ class AccountAccount(models.Model):
else:
return super(AccountAccount, self).name_get()
# https://github.com/odoo/odoo/issues/23040
@api.model
def _fix_bank_account_types(self):
companies = self.env['res.company'].search([])
if len(companies) > 1 and self.env.user.id != SUPERUSER_ID:
logger.info(
"Multi-company setup detected, running script with sudo ")
self = self.sudo()
logger.info("START the script 'fix bank and cash account types'")
bank_type = self.env.ref('account.data_account_type_liquidity')
asset_type = self.env.ref('account.data_account_type_current_assets')
journals = self.env['account.journal'].search(
[('type', 'in', ('bank', 'cash'))], order='company_id')
journal_accounts_bank_type = self
for journal in journals:
for account in [
journal.default_credit_account_id,
journal.default_debit_account_id]:
if account:
if account.user_type_id != bank_type:
account.user_type_id = bank_type.id
logger.info(
'Company %s: Account %s updated to Bank '
'and Cash type',
account.company_id.display_name, account.code)
if account not in journal_accounts_bank_type:
journal_accounts_bank_type += account
accounts = self.search([
('user_type_id', '=', bank_type.id)], order='company_id, code')
for account in accounts:
if account not in journal_accounts_bank_type:
account.user_type_id = asset_type.id
logger.info(
'Company %s: Account %s updated to Current Asset type',
account.company_id.display_name, account.code)
logger.info("END of the script 'fix bank and cash account types'")
return True
@api.model
def _create_account_groups(self, level=2, name_prefix=u'Comptes '):
'''Should be launched by a script. Make sure the account_group module is installed
(the account_usability module doesn't depend on it currently'''
assert level >= 1
assert isinstance(level, int)
companies = self.env['res.company'].search([])
if len(companies) > 1:
logger.info(
'Multi-company detected: running script create_account_groups '
'as admin')
self = self.sudo()
ago = self.env['account.group']
groups = ago.search([])
if groups:
raise UserError(_("Some account groups already exists"))
accounts = self.search([])
struct = {'childs': {}}
for account in accounts:
if len(account.code) <= level:
logger.warning(
"Account '%s' in company '%s' is smaller than "
"level (%d).",
account.display_name, account.company_id.display_name,
level)
continue
n = 1
parent = struct
gparent = False
while n <= level:
group_code = account.code[:n]
if group_code not in parent['childs']:
new_group = ago.create({
'name': u'%s%s' % (name_prefix or '', group_code),
'code_prefix': group_code,
'parent_id': gparent and gparent.id or False,
})
parent['childs'][group_code] = {'obj': new_group, 'childs': {}}
parent = parent['childs'][group_code]
gparent = parent['obj']
n += 1
account.group_id = gparent.id
class AccountAnalyticAccount(models.Model):
_inherit = 'account.analytic.account'
@@ -325,145 +114,43 @@ class AccountAnalyticAccount(models.Model):
if self._context.get('analytic_account_show_code_only'):
res = []
for record in self:
res.append((record.id, record.code or record.name))
res.append((
record.id,
record.code or record._get_one_full_name(record)))
return res
else:
return super(AccountAnalyticAccount, self).name_get()
_sql_constraints = [(
'code_company_unique',
'unique(code, company_id)',
'An analytic account with the same code already '
'exists in the same company!')]
class AccountMove(models.Model):
_inherit = 'account.move'
default_move_line_name = fields.Char(
string='Default Label', states={'posted': [('readonly', True)]})
# By default, we can still modify "ref" when account move is posted
# which seems a bit lazy for me...
ref = fields.Char(states={'posted': [('readonly', True)]})
date = fields.Date(copy=False)
default_account_id = fields.Many2one(
related='journal_id.default_debit_account_id', readonly=True)
default_credit = fields.Float(
compute='_compute_default_credit_debit', readonly=True)
default_debit = fields.Float(
compute='_compute_default_credit_debit', readonly=True)
@api.depends('line_ids.credit', 'line_ids.debit')
def _compute_default_credit_debit(self):
for move in self:
total_debit = total_credit = default_debit = default_credit = 0.0
for l in move.line_ids:
total_debit += l.debit
total_credit += l.credit
# I could use float_compare, but I don't think it's really needed
# in this context
if total_debit > total_credit:
default_credit = total_debit - total_credit
else:
default_debit = total_credit - total_debit
move.default_credit = default_credit
move.default_debit = default_debit
@api.model
def _fix_debit_credit_round_bug(self):
logger.info('START script _fix_debit_credit_round_bug')
moves = self.sudo().search([]) # sudo to search in all companies
bug_move_ids = []
for move in moves:
buggy = False
for l in move.line_ids:
if not float_is_zero(l.debit, precision_digits=2):
debit_rounded = float_round(l.debit, precision_digits=2)
if float_compare(l.debit, debit_rounded, precision_digits=6):
logger.info('Bad move to fix ID %d company_id %d name %s ref %s date %s journal %s (line ID %d debit=%s)', move.id, move.company_id.id, move.name, move.ref, move.date, move.journal_id.code, l.id, l.debit)
buggy = True
break
else:
credit_rounded = float_round(l.credit, precision_digits=2)
if float_compare(l.credit, credit_rounded, precision_digits=6):
logger.info('Bad move to fix ID %d company_id %d name %s ref %s date %s journal %s (line ID %d credit=%s)', move.id, move.company_id.id, move.name, move.ref, move.date, move.journal_id.code, l.id, l.credit)
buggy = True
break
if buggy:
bug_move_ids.append(move.id)
bal = 0.0
max_credit = (False, 0)
for l in move.line_ids:
if not float_is_zero(l.debit, precision_digits=2):
new_debit = float_round(l.debit, precision_digits=2)
self._cr.execute(
'UPDATE account_move_line set debit=%s, balance=%s where id=%s',
(new_debit, new_debit, l.id))
bal -= new_debit
elif not float_is_zero(l.credit, precision_digits=2):
new_credit = float_round(l.credit, precision_digits=2)
self._cr.execute(
'UPDATE account_move_line set credit=%s, balance=%s where id=%s',
(new_credit, new_credit * -1, l.id))
bal += new_credit
if new_credit > max_credit[1]:
max_credit = (l, new_credit)
if not float_is_zero(bal, precision_digits=2):
assert abs(bal) < 0.05
l = max_credit[0]
new_credit = max_credit[1]
new_new_credit = float_round(new_credit - bal, precision_digits=2)
assert new_new_credit > 0
self._cr.execute(
'UPDATE account_move_line set credit=%s, balance=%s where id=%s',
(new_new_credit, new_new_credit * -1, l.id))
logger.info('Move ID %d fixed', move.id)
logger.info('%d buggy moves fixed (IDs: %s)', len(bug_move_ids), bug_move_ids)
logger.info('END detect_equilibre_bug')
@api.onchange('date')
def date_onchange(self):
if self.date:
self.period_id = self.env['account.period'].find(self.date)
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
# Native order:
# _order = "date desc, id desc"
# Problem: when you manually create a journal entry, the
# order of the lines is inverted when you save ! It is quite annoying for
# the user...
_order = "date desc, id asc"
# Update field only to add a string (there is no string in account module)
invoice_id = fields.Many2one(string='Invoice')
date_maturity = fields.Date(copy=False)
account_reconcile = fields.Boolean(
related='account_id.reconcile', readonly=True)
full_reconcile_id = fields.Many2one(string='Full Reconcile')
matched_debit_ids = fields.One2many(string='Partial Reconcile Debit')
matched_credit_ids = fields.One2many(string='Partial Reconcile Credit')
reconcile_string = fields.Char(
compute='_compute_reconcile_string', string='Reconcile', store=True)
@api.onchange('credit')
def _credit_onchange(self):
prec = self.env['decimal.precision'].precision_get('Account')
if (
not float_is_zero(self.credit, precision_digits=prec) and
not float_is_zero(self.debit, precision_digits=prec)):
if self.credit and self.debit:
self.debit = 0
@api.onchange('debit')
def _debit_onchange(self):
prec = self.env['decimal.precision'].precision_get('Account')
if (
not float_is_zero(self.debit, precision_digits=prec) and
not float_is_zero(self.credit, precision_digits=prec)):
if self.debit and self.credit:
self.credit = 0
@api.onchange('currency_id', 'amount_currency')
def _amount_currency_change(self):
prec = self.env['decimal.precision'].precision_get('Account')
if (
self.currency_id and
not float_is_zero(self.amount_currency, precision_digits=prec)):
self.amount_currency and
not self.credit and
not self.debit):
date = self.date or None
amount_company_currency = self.currency_id.with_context(
date=date).compute(
@@ -472,87 +159,13 @@ class AccountMoveLine(models.Model):
if float_compare(
amount_company_currency, 0,
precision_digits=precision) == -1:
self.credit = amount_company_currency * -1
self.debit = amount_company_currency * -1
else:
self.debit = amount_company_currency
def show_account_move_form(self):
self.ensure_one()
action = self.env['ir.actions.act_window'].for_xml_id(
'account', 'action_move_line_form')
action.update({
'res_id': self.move_id.id,
'view_id': False,
'views': False,
'view_mode': 'form,tree',
})
return action
@api.depends(
'full_reconcile_id', 'matched_debit_ids', 'matched_credit_ids')
def _compute_reconcile_string(self):
for line in self:
rec_str = False
if line.full_reconcile_id:
rec_str = line.full_reconcile_id.name
else:
rec_str = ', '.join([
'a%d' % pr.id for pr in line.matched_debit_ids + line.matched_credit_ids])
line.reconcile_string = rec_str
class AccountPartialReconcile(models.Model):
_inherit = "account.partial.reconcile"
_rec_name = "id"
def name_get(self):
res = []
for rec in self:
# There is no seq for partial rec, so I simulate one with the ID
# Prefix for full rec: 'A' (upper case)
# Prefix for partial rec: 'a' (lower case)
amount_fmt = formatLang(self.env, rec.amount, currency_obj=rec.company_currency_id)
name = 'a%d (%s)' % (rec.id, amount_fmt)
res.append((rec.id, name))
return res
class AccountBankStatement(models.Model):
_inherit = 'account.bank.statement'
start_date = fields.Date(
compute='_compute_dates', string='Start Date', readonly=True,
store=True)
end_date = fields.Date(
compute='_compute_dates', string='End Date', readonly=True,
store=True)
hide_bank_statement_balance = fields.Boolean(
related='journal_id.hide_bank_statement_balance', readonly=True)
@api.multi
@api.depends('line_ids.date')
def _compute_dates(self):
for st in self:
dates = [line.date for line in st.line_ids]
st.start_date = dates and min(dates) or False
st.end_date = dates and max(dates) or False
@api.multi
@api.depends('name', 'start_date', 'end_date')
def name_get(self):
res = []
for statement in self:
name = "%s (%s => %s)" % (
statement.name, statement.start_date, statement.end_date)
res.append((statement.id, name))
return res
self.credit = amount_company_currency
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
# Native order is:
# _order = 'statement_id desc, sequence, id desc'
_order = 'statement_id desc, date desc, sequence, id desc'
# Disable guessing for reconciliation
# because my experience with several customers shows that it is a problem
@@ -569,58 +182,81 @@ class AccountBankStatementLine(models.Model):
# figure out that the fact that the user can't find move line 'x'
# is caused by this.
# Set search_reconciliation_proposition to False by default
# TODO: re-write in v10
# def get_data_for_reconciliations(
# self, cr, uid, ids, excluded_ids=None,
# search_reconciliation_proposition=False, context=None):
# # Make variable name shorted for PEP8 !
# search_rec_prop = search_reconciliation_proposition
# return super(AccountBankStatementLine, self).\
# get_data_for_reconciliations(
# cr, uid, ids, excluded_ids=excluded_ids,
# search_reconciliation_proposition=search_rec_prop,
# context=context)
def _prepare_reconciliation_move(self, move_ref):
vals = super(AccountBankStatementLine, self).\
_prepare_reconciliation_move(move_ref)
# By default, ref contains the name of the statement + name of the
# statement line. It causes 2 problems:
# 1) The 'ref' field is too big
# 2) The name of the statement line is already written in the name of
# the move line -> not useful to have the info 2 times
# In the end, I think it's better to just put nothing (we could write
# the name of the statement which has the account number, but it
# doesn't bring any useful info to the accountant)
# The only "good" thing to do would be to have a sequence per
# statement line and write it in this 'ref' field
# But that would required an additionnal field on statement lines
vals['ref'] = False
return vals
def get_data_for_reconciliations(
self, cr, uid, ids, excluded_ids=None,
search_reconciliation_proposition=False, context=None):
# Make variable name shorted for PEP8 !
search_rec_prop = search_reconciliation_proposition
return super(AccountBankStatementLine, self).\
get_data_for_reconciliations(
cr, uid, ids, excluded_ids=excluded_ids,
search_reconciliation_proposition=search_rec_prop,
context=context)
@api.multi
def show_account_move(self):
self.ensure_one()
action = self.env['ir.actions.act_window'].for_xml_id(
'account', 'action_move_journal_line')
if self.journal_entry_ids:
if self.journal_entry_id:
action.update({
'views': False,
'view_id': False,
'view_mode': 'form,tree',
'res_id': self.journal_entry_ids[0].id,
'res_id': self.journal_entry_id.id,
})
return action
else:
raise UserError(_(
'No journal entry linked to this bank statement line.'))
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.multi
def show_receivable_account(self):
self.ensure_one()
account_id = self.property_account_receivable.id
return self.common_show_account(self.ids[0], account_id)
@api.multi
def show_payable_account(self):
self.ensure_one()
account_id = self.property_account_payable.id
return self.common_show_account(self.ids[0], account_id)
def common_show_account(self, partner_id, account_id):
action = self.env['ir.actions.act_window'].for_xml_id(
'account', 'action_account_moves_all_tree')
action['context'] = {
'search_default_partner_id': [partner_id],
'default_partner_id': partner_id,
'search_default_account_id': account_id,
}
return action
@api.multi
def _compute_journal_item_count(self):
amlo = self.env['account.move.line']
for partner in self:
partner.journal_item_count = amlo.search_count([
('partner_id', '=', partner.id),
('account_id', '=', partner.property_account_receivable.id)])
partner.payable_journal_item_count = amlo.search_count([
('partner_id', '=', partner.id),
('account_id', '=', partner.property_account_payable.id)])
journal_item_count = fields.Integer(
compute='_compute_journal_item_count',
string="Journal Items", readonly=True)
payable_journal_item_count = fields.Integer(
compute='_compute_journal_item_count',
string="Payable Journal Items", readonly=True)
class AccountFiscalPosition(models.Model):
_inherit = 'account.fiscal.position'
note = fields.Text(translate=True)
@api.model
def get_fiscal_position_no_partner(
self, company_id=None, vat_subjected=False, country_id=None):
@@ -659,14 +295,3 @@ class AccountFiscalPosition(models.Model):
if fps:
return fps[0]
return False
class AccountReconcileModel(models.Model):
_inherit = 'account.reconcile.model'
@api.onchange('name')
def onchange_name(self):
# Do NOT copy by default name on label
# Because it's much better to have the bank statement line label as
# label of the counter-part move line, then the label of the button
assert True # Stupid line of code just to have something...

View File

@@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2018 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).
from odoo import models, fields
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
number = fields.Char(string="Number", readonly=True)
def _sub_select(self):
select_str = super(AccountInvoiceReport, self)._sub_select()
select_str += ", ai.number"
return select_str
def _select(self):
select_str = super(AccountInvoiceReport, self)._select()
select_str += ", sub.number"
return select_str
def _group_by(self):
group_by_str = super(AccountInvoiceReport, self)._group_by()
group_by_str += ", ai.number"
return group_by_str

View File

@@ -1,51 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 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="account_invoice_report_tree" model="ir.ui.view">
<field name="name">usability.account.invoice.report.tree</field>
<field name="model">account.invoice.report</field>
<field name="arch" type="xml">
<tree string="Invoices Analysis">
<field name="number"/>
<field name="date"/>
<field name="date_due"/>
<field name="type"/>
<field name="commercial_partner_id"/>
<field name="user_id"/>
<field name="product_id"/>
<field name="product_qty" sum="1"/>
<field name="uom_name" groups="product.group_uom"/>
<field name="price_total" sum="1"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="account.action_account_invoice_report_all_supp" model="ir.actions.act_window">
<field name="context">{'search_default_current': 1, 'search_default_supplier': 1, 'search_default_year': 1}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
</record>
<record id="account.action_account_invoice_report_all" model="ir.actions.act_window">
<field name="context">{'search_default_current': 1, 'search_default_customer': 1, 'search_default_year': 1}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
</record>
<record id="view_account_invoice_report_pivot" model="ir.ui.view">
<field name="name">usability.account.invoice.report</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.view_account_invoice_report_pivot"/>
<field name="arch" type="xml">
<pivot position="attributes">
<attribute name="disable_linking"></attribute>
</pivot>
</field>
</record>
</odoo>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 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="account.account_invoices" model="ir.actions.report.xml">
<!-- Don't attach on supplier invoices/refunds ! -->
<field name="attachment">(object.type in ('out_invoice', 'out_refund')) and (object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')</field>
</record>
</odoo>

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