Compare commits
2 Commits
10.0-accou
...
11.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ba4eadc15 | ||
|
|
79d8f6edc5 |
56
.gitignore
vendored
56
.gitignore
vendored
@@ -1,56 +0,0 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
env/
|
|
||||||
bin/
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.coverage
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
|
|
||||||
# Pycharm
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# Mr Developer
|
|
||||||
.mr.developer.cfg
|
|
||||||
.project
|
|
||||||
.pydevproject
|
|
||||||
|
|
||||||
# Rope
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# Backup files
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
8
README.rst
Normal file
8
README.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Odoo Usability : 11.0 Branch
|
||||||
|
============================
|
||||||
|
|
||||||
|
Branch unmaintained by Akretion.
|
||||||
|
|
||||||
|
Please check these forks:
|
||||||
|
|
||||||
|
- https://github.com/camptocamp/odoo-usability
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import partner
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import wizard
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -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."
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_bank_statement_import
|
|
||||||
@@ -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]
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_bank_statement_import
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -1,35 +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).
|
|
||||||
|
|
||||||
from odoo import models, api
|
|
||||||
|
|
||||||
|
|
||||||
class AccountBankStatementImport(models.TransientModel):
|
|
||||||
_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
|
|
||||||
|
|
||||||
|
|
||||||
class AccountBankStatement(models.Model):
|
|
||||||
_inherit = 'account.bank.statement'
|
|
||||||
|
|
||||||
# When we use the import of bank statement via files,
|
|
||||||
# the start/end_balance is usually computed from the lines itself
|
|
||||||
# because we don't have the 'real' information in the file
|
|
||||||
# But, in the module account_bank_statement_import, in the method
|
|
||||||
# _create_bank_statement(), the bank statement lines already present in
|
|
||||||
# Odoo are filtered out, but the start/end balance is not adjusted,
|
|
||||||
# so the user has to manually modifiy it the close the bank statement
|
|
||||||
# I think the solution is just to remove the start/end balance system
|
|
||||||
# on the bank statement when we use the file import
|
|
||||||
# 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):
|
|
||||||
return True
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?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).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<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
|
|
||||||
|
|
||||||
<record id="view_bank_statement_form" model="ir.ui.view">
|
|
||||||
<field name="name">bank_statement_import_usability.account.bank.statement.form</field>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="balance_start" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="balance_end_real" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</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>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="balance_start" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="balance_end_real" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<tree position="attributes">
|
|
||||||
<attribute name="colors">blue:state=='draft';black:state=='confirm'</attribute>
|
|
||||||
</tree>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -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']
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_credit_control
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Credit Control Usability 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 Credit Control Usability',
|
|
||||||
'version': '0.1',
|
|
||||||
'category': 'Accounting & Finance',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Small usability enhancements in account_credit_control module',
|
|
||||||
'description': """
|
|
||||||
Account Credit Control Usability
|
|
||||||
================================
|
|
||||||
|
|
||||||
The usability enhancements include:
|
|
||||||
|
|
||||||
* add phone call in the list of channels
|
|
||||||
* hide some fields
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': 'Akretion',
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': ['account_credit_control', 'partner_aged_open_invoices'],
|
|
||||||
'data': ['account_credit_control_view.xml'],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Credit Control Usability 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 openerp import models, fields, api
|
|
||||||
|
|
||||||
|
|
||||||
class CreditControlPolicyLevel(models.Model):
|
|
||||||
_inherit = "credit.control.policy.level"
|
|
||||||
_rec_name = 'internal_name'
|
|
||||||
|
|
||||||
channel = fields.Selection(selection_add=[('phone', 'Phone Call')])
|
|
||||||
name = fields.Char(
|
|
||||||
string='Subject',
|
|
||||||
help="Will be displayed in the subject of the emails and in "
|
|
||||||
"the letters")
|
|
||||||
internal_name = fields.Char(string='Internal Name', required=True)
|
|
||||||
|
|
||||||
|
|
||||||
class CreditControlLine(models.Model):
|
|
||||||
_inherit = "credit.control.line"
|
|
||||||
|
|
||||||
channel = fields.Selection(selection_add=[('phone', 'Phone Call')])
|
|
||||||
note = fields.Text(string='Notes')
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def open_aged_open_invoices_report(self):
|
|
||||||
self.ensure_one()
|
|
||||||
return self.partner_id.open_aged_open_invoices_report()
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def go_to_partner_form(self):
|
|
||||||
self.ensure_one()
|
|
||||||
action = self.env['ir.actions.act_window'].for_xml_id(
|
|
||||||
'base', 'action_partner_customer_form')
|
|
||||||
action.update({
|
|
||||||
'view_mode': 'form,kanban,tree',
|
|
||||||
'views': False,
|
|
||||||
'res_id': self.partner_id.id,
|
|
||||||
'context': {},
|
|
||||||
})
|
|
||||||
return action
|
|
||||||
|
|
||||||
|
|
||||||
class CreditControlRun(models.Model):
|
|
||||||
_inherit = "credit.control.run"
|
|
||||||
|
|
||||||
date = fields.Date(default=fields.Date.context_today)
|
|
||||||
|
|
||||||
|
|
||||||
class ResPartner(models.Model):
|
|
||||||
_inherit = 'res.partner'
|
|
||||||
|
|
||||||
@api.one
|
|
||||||
@api.depends('credit_control_line_ids')
|
|
||||||
def _credit_control_line_count(self):
|
|
||||||
try:
|
|
||||||
self.credit_control_line_count = len(self.credit_control_line_ids)
|
|
||||||
except:
|
|
||||||
self.credit_control_line_count = 0
|
|
||||||
|
|
||||||
credit_control_line_count = fields.Integer(
|
|
||||||
compute='_credit_control_line_count',
|
|
||||||
string="# of Credit Control Lines", readonly=True)
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<record id="credit_control_line_tree" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit_control_line_tree</field>
|
|
||||||
<field name="model">credit.control.line</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_control_line_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="account_id" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="move_line_id" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="mail_message_id" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="partner_id" position="after">
|
|
||||||
<button name="go_to_partner_form" type="object"
|
|
||||||
string="Go to Partner" icon="terp-gtk-jump-to-ltr"/>
|
|
||||||
<button name="open_aged_open_invoices_report" type="object"
|
|
||||||
string="Open Aged Open Invoices Report" icon="STOCK_ZOOM_IN"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="credit_control_line_form" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit_control_line_form</field>
|
|
||||||
<field name="model">credit.control.line</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_control_line_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//field[@name='currency_id']/.." position="after">
|
|
||||||
<group name="note">
|
|
||||||
<field name="note"/>
|
|
||||||
</group>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="credit_control_policy_form" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit.control.policy.form</field>
|
|
||||||
<field name="model">credit.control.policy</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_control_policy_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//field[@name='level_ids']/tree/field[@name='name']" position="before">
|
|
||||||
<field name="internal_name"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='level_ids']/form//field[@name='name']" position="replace">
|
|
||||||
<group name="level-main">
|
|
||||||
|
|
||||||
<field name="internal_name"/>
|
|
||||||
<field name="name"/>
|
|
||||||
</group>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="credit_mangement_policy_level_form" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit.control.policy.level.form</field>
|
|
||||||
<field name="model">credit.control.policy.level</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_mangement_policy_level_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="name" position="before">
|
|
||||||
<field name="internal_name"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="credit_control_policy_level_tree" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit.control.policy.level.tree</field>
|
|
||||||
<field name="model">credit.control.policy.level</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_control_policy_level_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="name" position="before">
|
|
||||||
<field name="internal_name"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="credit_control_line_search" model="ir.ui.view">
|
|
||||||
<field name="name">credit_control_usability.credit_control_line_search</field>
|
|
||||||
<field name="model">credit.control.line</field>
|
|
||||||
<field name="inherit_id" ref="account_credit_control.credit_control_line_search"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<filter name="filter_manual" position="after">
|
|
||||||
<filter name="phone" string="Phone Call" domain="[('channel', '=', 'phone')]"/>
|
|
||||||
<filter name="letter" string="Letter" domain="[('channel', '=', 'letter')]"/>
|
|
||||||
<filter name="email" string="Email" domain="[('channel', '=', 'email')]"/>
|
|
||||||
</filter>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="partner_credit_control_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Credit Control Lines</field>
|
|
||||||
<field name="res_model">credit.control.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="context">{'search_default_partner_id': active_id}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_partner_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_credit_control_usability.button.res.partner.form</field>
|
|
||||||
<field name="model">res.partner</field>
|
|
||||||
<field name="inherit_id" ref="base.view_partner_form" />
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//div[@name='buttons']" position="inside">
|
|
||||||
<button class="oe_inline oe_stat_button" type="action"
|
|
||||||
name="%(partner_credit_control_line_action)d"
|
|
||||||
attrs="{'invisible': [('customer', '=', False)]}"
|
|
||||||
icon="fa-gavel">
|
|
||||||
<field string="Credit Control"
|
|
||||||
name="credit_control_line_count" widget="statinfo"/>
|
|
||||||
</button>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- rapport -->
|
|
||||||
<template id="report_credit_control_summary_document" inherit_id="account_credit_control.report_credit_control_summary_document">
|
|
||||||
<xpath expr="//span[@t-field='l.amount_due']" position="attributes">
|
|
||||||
<attribute name="t-field-options">{"widget": "monetary", "display_currency": "l.currency_id or l.company_id.currency_id"}</attribute>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# -*- 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 Cutoff Accrual Picking ODS',
|
|
||||||
'version': '8.0.0.1.0',
|
|
||||||
'category': 'Tools',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Adds an Aeroo ODS report on cutoff accrual',
|
|
||||||
'description': """
|
|
||||||
Account Cutoff Accrual Picking ODS
|
|
||||||
==================================
|
|
||||||
|
|
||||||
This module will add an Aeroo ODS report on Accrued Revenue and Accrued Expense.
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': "Akretion",
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': ['account_cutoff_accrual_picking', 'report_aeroo'],
|
|
||||||
'data': ['report.xml'],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="account_cutoff_accrual_picking_ods" model="ir.actions.report.xml">
|
|
||||||
<field name="name">Cutoff Accrual ODS</field>
|
|
||||||
<field name="model">account.cutoff</field>
|
|
||||||
<field name="report_name">account.cutoff.accrual.picking.ods</field>
|
|
||||||
<field name="report_type">aeroo</field>
|
|
||||||
<field name="in_format">oo-ods</field>
|
|
||||||
<field name="report_rml">account_cutoff_accrual_picking_ods/cutoff_accrual.ods</field>
|
|
||||||
<field name="parser_state">default</field>
|
|
||||||
<field name="tml_source">file</field>
|
|
||||||
<field name="out_format" ref="report_aeroo.report_mimetypes_ods_ods"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_cutoff_accrual_picking_ods_button" model="ir.values">
|
|
||||||
<field name="name">Cutoff Accrual ODS</field>
|
|
||||||
<field name="model">account.cutoff</field>
|
|
||||||
<field name="key2">client_print_multi</field>
|
|
||||||
<field name="value" eval="'ir.actions.report.xml,%d'%account_cutoff_accrual_picking_ods"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Cutoff Prepaid ODS 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 Cutoff Prepaid ODS',
|
|
||||||
'version': '8.0.0.1.0',
|
|
||||||
'category': 'Tools',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Adds an Aeroo ODS report on cutoff prepaid',
|
|
||||||
'description': """
|
|
||||||
Account Cutoff Prepaid ODS
|
|
||||||
===========================
|
|
||||||
|
|
||||||
This module will add an Aeroo ODS report on Prepaid Revenue and Prepaid Expense.
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': "Akretion",
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': ['account_cutoff_prepaid', 'report_aeroo'],
|
|
||||||
'data': ['report.xml'],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="account_cutoff_prepaid_ods" model="ir.actions.report.xml">
|
|
||||||
<field name="name">Cutoff Prepaid ODS</field>
|
|
||||||
<field name="model">account.cutoff</field>
|
|
||||||
<field name="report_name">account.cutoff.prepaid.ods</field>
|
|
||||||
<field name="report_type">aeroo</field>
|
|
||||||
<field name="in_format">oo-ods</field>
|
|
||||||
<field name="report_rml">account_cutoff_prepaid_ods/cutoff_prepaid.ods</field>
|
|
||||||
<field name="parser_state">default</field>
|
|
||||||
<field name="tml_source">file</field>
|
|
||||||
<field name="out_format" ref="report_aeroo.report_mimetypes_ods_ods"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_cutoff_prepaid_ods_button" model="ir.values">
|
|
||||||
<field name="name">Cutoff Prepaid ODS</field>
|
|
||||||
<field name="model">account.cutoff</field>
|
|
||||||
<field name="key2">client_print_multi</field>
|
|
||||||
<field name="value" eval="'ir.actions.report.xml,%d'%account_cutoff_prepaid_ods"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Direct Debit Autogenerate 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 account_invoice
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Direct Debit Autogenerate 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 Direct Debit Autogenerate',
|
|
||||||
'version': '0.1',
|
|
||||||
'category': 'Accounting & Finance',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Auto-generate direct debit order on invoice validation',
|
|
||||||
'description': """
|
|
||||||
Account Direct Debit Autogenerate
|
|
||||||
=================================
|
|
||||||
|
|
||||||
With this module, when you validate a customer invoice whose payment mode is SEPA Direct Debit :
|
|
||||||
|
|
||||||
* if a draft Direct Debit order for SEPA Direct Debit already exists, a new payment line is added to it for the invoice,
|
|
||||||
|
|
||||||
* otherwise, a new SEPA Direct Debit order is created for this 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_banking_sepa_direct_debit', 'account_payment_partner'],
|
|
||||||
'data': [],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Direct Debit Autogenerate module for Odoo
|
|
||||||
# Copyright (C) 2015 Akretion (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, _
|
|
||||||
from openerp.exceptions import Warning
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoice(models.Model):
|
|
||||||
_inherit = 'account.invoice'
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _prepare_payment_order(self, invoice):
|
|
||||||
vals = {
|
|
||||||
'mode': invoice.payment_mode_id.id,
|
|
||||||
'payment_order_type': 'debit',
|
|
||||||
}
|
|
||||||
return vals
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _prepare_payment_line(self, move_line, payment_order):
|
|
||||||
assert move_line.invoice, 'The move line must be linked to an invoice'
|
|
||||||
if not move_line.invoice.mandate_id:
|
|
||||||
raise Warning(
|
|
||||||
_('Missing Mandate on Invoice %s') % move_line.invoice.number)
|
|
||||||
vals = {
|
|
||||||
'order_id': payment_order.id,
|
|
||||||
'move_line_id': move_line.id,
|
|
||||||
'partner_id': move_line.partner_id.id,
|
|
||||||
'amount_currency': move_line.debit,
|
|
||||||
'communication': move_line.invoice.number.replace('/', ''),
|
|
||||||
'state': 'structured',
|
|
||||||
'date': move_line.date_maturity,
|
|
||||||
'currency': move_line.invoice.currency_id.id,
|
|
||||||
'mandate_id': move_line.invoice.mandate_id.id,
|
|
||||||
'bank_id': move_line.invoice.mandate_id.partner_bank_id.id,
|
|
||||||
}
|
|
||||||
return vals
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def invoice_validate(self):
|
|
||||||
'''Create Direct debit payment order on invoice validation or update
|
|
||||||
an existing draft Direct Debit pay order'''
|
|
||||||
res = super(AccountInvoice, self).invoice_validate()
|
|
||||||
poo = self.env['payment.order']
|
|
||||||
plo = self.env['payment.line']
|
|
||||||
for invoice in self:
|
|
||||||
if (
|
|
||||||
invoice.type == 'out_invoice'
|
|
||||||
and invoice.payment_mode_id
|
|
||||||
and invoice.payment_mode_id.type
|
|
||||||
and invoice.payment_mode_id.type.code
|
|
||||||
and invoice.payment_mode_id.type.code.
|
|
||||||
startswith('pain.008.001.')):
|
|
||||||
payorders = poo.search([
|
|
||||||
('state', '=', 'draft'),
|
|
||||||
('payment_order_type', '=', 'debit'),
|
|
||||||
('mode', '=', invoice.payment_mode_id.id),
|
|
||||||
# mode is attached to company
|
|
||||||
])
|
|
||||||
if payorders:
|
|
||||||
payorder = payorders[0]
|
|
||||||
payorder_type = _('existing')
|
|
||||||
else:
|
|
||||||
payorder_vals = self._prepare_payment_order(invoice)
|
|
||||||
payorder = poo.create(payorder_vals)
|
|
||||||
payorder_type = _('new')
|
|
||||||
logger.info(
|
|
||||||
'New Direct Debit Order created %s'
|
|
||||||
% payorder.reference)
|
|
||||||
move_lines = [
|
|
||||||
line for line in invoice.move_id.line_id
|
|
||||||
if line.account_id == invoice.account_id]
|
|
||||||
for move_line in move_lines:
|
|
||||||
if not invoice.mandate_id:
|
|
||||||
raise Warning(
|
|
||||||
_("Missing Mandate on invoice %s")
|
|
||||||
% invoice.number)
|
|
||||||
# add payment line
|
|
||||||
pl_vals = self._prepare_payment_line(move_line, payorder)
|
|
||||||
pl = plo.create(pl_vals)
|
|
||||||
invoice.message_post(
|
|
||||||
_("A new payment line %s has been automatically "
|
|
||||||
"created on the %s direct debit order %s")
|
|
||||||
% (pl.name, payorder_type, payorder.reference))
|
|
||||||
return res
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_fiscal_position
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
{
|
|
||||||
'name': 'Account Fiscal Position Payable Receivable',
|
|
||||||
'version': '10.0.1.0.0',
|
|
||||||
'category': 'Accounting & Finance',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Configure payable/receivable accounts on fiscal positions',
|
|
||||||
'description': """
|
|
||||||
Account Fiscal Position Payable Receivable
|
|
||||||
==========================================
|
|
||||||
|
|
||||||
This module allows to configure a special *Partner Receivable Account* and a special *Partner Payable Account* on fiscal positions. This is used in the onchange of the fiscal position of partners.
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': "Akretion",
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': ['account'],
|
|
||||||
'data': [
|
|
||||||
'account_fiscal_position_view.xml',
|
|
||||||
],
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import models, fields, api
|
|
||||||
|
|
||||||
|
|
||||||
class AccountFiscalPosition(models.Model):
|
|
||||||
_inherit = 'account.fiscal.position'
|
|
||||||
|
|
||||||
receivable_account_id = fields.Many2one(
|
|
||||||
'account.account', string='Partner Receivable Account',
|
|
||||||
company_dependent=True, domain=[('internal_type', '=', 'receivable')])
|
|
||||||
payable_account_id = fields.Many2one(
|
|
||||||
'account.account', string='Partner Payable Account',
|
|
||||||
company_dependent=True, domain=[('internal_type', '=', 'payable')])
|
|
||||||
|
|
||||||
|
|
||||||
class ResPartner(models.Model):
|
|
||||||
_inherit = 'res.partner'
|
|
||||||
|
|
||||||
@api.onchange('property_account_position_id')
|
|
||||||
def fiscal_position_receivable_payable_change(self):
|
|
||||||
fp = self.property_account_position_id
|
|
||||||
ipo = self.env['ir.property']
|
|
||||||
if fp.receivable_account_id:
|
|
||||||
self.property_account_receivable_id = fp.receivable_account_id
|
|
||||||
else:
|
|
||||||
self.property_account_receivable_id = ipo.get(
|
|
||||||
'property_account_receivable_id', 'res.partner')
|
|
||||||
if fp.payable_account_id:
|
|
||||||
self.property_account_payable_id = fp.payable_account_id
|
|
||||||
else:
|
|
||||||
self.property_account_payable_id = ipo.get(
|
|
||||||
'property_account_payable_id', 'res.partner')
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
© 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="view_account_position_form" model="ir.ui.view">
|
|
||||||
<field name="name">receivable_payable.fiscal_position_form</field>
|
|
||||||
<field name="model">account.fiscal.position</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_position_form" />
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="company_id" position="after">
|
|
||||||
<field name="receivable_account_id"/>
|
|
||||||
<field name="payable_account_id"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_invoice
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# -*- 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).
|
|
||||||
|
|
||||||
from odoo import models, fields, api
|
|
||||||
import odoo.addons.decimal_precision as dp
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoiceLine(models.Model):
|
|
||||||
_inherit = 'account.invoice.line'
|
|
||||||
|
|
||||||
standard_price_company_currency = fields.Float(
|
|
||||||
string='Cost Price in Company Currency', readonly=True,
|
|
||||||
digits=dp.get_precision('Product Price'),
|
|
||||||
help="Cost price in company currency in the unit of measure "
|
|
||||||
"of the invoice line (which may be different from the unit "
|
|
||||||
"of measure of the product).")
|
|
||||||
standard_price_invoice_currency = fields.Float(
|
|
||||||
string='Cost Price in Invoice Currency', readonly=True,
|
|
||||||
compute='_compute_margin', store=True,
|
|
||||||
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(
|
|
||||||
string='Margin in Invoice Currency', readonly=True, store=True,
|
|
||||||
compute='_compute_margin', currency_field='currency_id')
|
|
||||||
margin_company_currency = fields.Monetary(
|
|
||||||
string='Margin in Company Currency', readonly=True, store=True,
|
|
||||||
compute='_compute_margin', currency_field='company_currency_id')
|
|
||||||
margin_rate = fields.Float(
|
|
||||||
string="Margin Rate", readonly=True, store=True,
|
|
||||||
compute='_compute_margin',
|
|
||||||
digits=(16, 2), help="Margin rate in percentage of the sale price")
|
|
||||||
|
|
||||||
@api.depends(
|
|
||||||
'standard_price_company_currency', '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
|
|
||||||
|
|
||||||
# We want to copy standard_price on invoice line for customer
|
|
||||||
# invoice/refunds. We can't do that via on_change of product_id,
|
|
||||||
# because it is not always played when invoice is created from code
|
|
||||||
# => we inherit write/create
|
|
||||||
# We write standard_price_company_currency even on supplier invoice/refunds
|
|
||||||
# because we don't have access to the 'type' of the invoice
|
|
||||||
@api.model
|
|
||||||
def create(self, vals):
|
|
||||||
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')
|
|
||||||
if inv_uom_id and inv_uom_id != pp.uom_id.id:
|
|
||||||
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)
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def write(self, vals):
|
|
||||||
if not vals:
|
|
||||||
vals = {}
|
|
||||||
if 'product_id' in vals or 'uom_id' in vals:
|
|
||||||
for il in self:
|
|
||||||
if 'product_id' in vals:
|
|
||||||
if vals.get('product_id'):
|
|
||||||
pp = self.env['product.product'].browse(
|
|
||||||
vals['product_id'])
|
|
||||||
else:
|
|
||||||
pp = False
|
|
||||||
else:
|
|
||||||
pp = il.product_id or False
|
|
||||||
# uom_id is NOT a required field
|
|
||||||
if 'uom_id' in vals:
|
|
||||||
if vals.get('uom_id'):
|
|
||||||
inv_uom = self.env['product.uom'].browse(
|
|
||||||
vals['uom_id'])
|
|
||||||
else:
|
|
||||||
inv_uom = False
|
|
||||||
else:
|
|
||||||
inv_uom = il.uom_id or False
|
|
||||||
std_price = 0.0
|
|
||||||
if pp:
|
|
||||||
std_price = pp.standard_price
|
|
||||||
if inv_uom and inv_uom != pp.uom_id:
|
|
||||||
std_price = pp.uom_id._compute_price(
|
|
||||||
std_price, inv_uom)
|
|
||||||
il.write({'standard_price_company_currency': std_price})
|
|
||||||
return super(AccountInvoiceLine, self).write(vals)
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoice(models.Model):
|
|
||||||
_inherit = 'account.invoice'
|
|
||||||
|
|
||||||
margin_invoice_currency = fields.Monetary(
|
|
||||||
string='Margin in Invoice Currency',
|
|
||||||
readonly=True, compute='_compute_margin', store=True,
|
|
||||||
currency_field='currency_id')
|
|
||||||
margin_company_currency = fields.Monetary(
|
|
||||||
string='Margin in Company Currency',
|
|
||||||
readonly=True, compute='_compute_margin', store=True,
|
|
||||||
currency_field='company_currency_id')
|
|
||||||
|
|
||||||
@api.depends(
|
|
||||||
'type',
|
|
||||||
'invoice_line_ids.margin_invoice_currency',
|
|
||||||
'invoice_line_ids.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
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<?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).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<record id="view_invoice_line_form" model="ir.ui.view">
|
|
||||||
<field name="name">margin.account.invoice.line.form</field>
|
|
||||||
<field name="model">account.invoice.line</field>
|
|
||||||
<field name="inherit_id" ref="account.view_invoice_line_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="discount" position="after">
|
|
||||||
<field name="standard_price_company_currency"
|
|
||||||
groups="account.group_account_user"/>
|
|
||||||
<field name="standard_price_invoice_currency"
|
|
||||||
widget="monetary"
|
|
||||||
options="{'currency_field': 'currency_id'}"
|
|
||||||
groups="account.group_account_user"/>
|
|
||||||
<field name="margin_invoice_currency"
|
|
||||||
groups="account.group_account_user"/>
|
|
||||||
<field name="margin_company_currency"
|
|
||||||
groups="account.group_account_user"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="invoice_form" model="ir.ui.view">
|
|
||||||
<field name="name">margin.account.invoice.form</field>
|
|
||||||
<field name="model">account.invoice</field>
|
|
||||||
<field name="inherit_id" ref="account.invoice_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="move_id" position="after">
|
|
||||||
<field name="margin_invoice_currency"
|
|
||||||
string="Margin" groups="account.group_account_user"/>
|
|
||||||
<field name="margin_company_currency"
|
|
||||||
groups="account.group_account_user"/>
|
|
||||||
</field>
|
|
||||||
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='price_subtotal']" position="after">
|
|
||||||
<field name="standard_price_invoice_currency" groups="base.group_no_one" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
|
||||||
<field name="standard_price_company_currency" groups="base.group_no_one" widget="monetary" options="{'currency_field': 'company_currency_id'}"/>
|
|
||||||
<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"/>
|
|
||||||
<field name="company_currency_id" invisible="1"/>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import report
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# -*- 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': False,
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import invoice_report
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# -*- 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
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from . import wizard
|
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from . import test_account_invoice_update_wizard
|
|
||||||
@@ -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)
|
|
||||||
@@ -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>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from . import account_invoice_update
|
|
||||||
@@ -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')
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import wizard
|
|
||||||
@@ -1,25 +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.1.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 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,
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_move_line_filter
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# -*- 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).
|
|
||||||
|
|
||||||
from odoo 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'
|
|
||||||
|
|
||||||
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)
|
|
||||||
reconcile = fields.Selection([
|
|
||||||
('unreconciled', 'Unreconciled'),
|
|
||||||
('reconciled', 'Fully Reconciled'),
|
|
||||||
# ('partial_reconciled', 'Partially Reconciled'),
|
|
||||||
], string='Reconciliation Filter')
|
|
||||||
|
|
||||||
@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
|
|
||||||
else:
|
|
||||||
self.account_id =\
|
|
||||||
self.partner_id.property_account_payable_id.id
|
|
||||||
|
|
||||||
def go(self):
|
|
||||||
self.ensure_one()
|
|
||||||
action = self.env['ir.actions.act_window'].for_xml_id(
|
|
||||||
'account', 'action_account_moves_all_a')
|
|
||||||
action['context'] = {'search_default_account_id': [self.account_id.id]}
|
|
||||||
if self.partner_id:
|
|
||||||
action['context']['search_default_partner_id'] =\
|
|
||||||
[self.partner_id.id]
|
|
||||||
if self.reconcile:
|
|
||||||
action['context']['search_default_%s' % self.reconcile] = True
|
|
||||||
return action
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="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).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<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="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)]}"/>
|
|
||||||
</group>
|
|
||||||
<footer>
|
|
||||||
<button type="object" name="go" string="Go" class="btn-primary"/>
|
|
||||||
<button special="cancel" string="Cancel" class="btn-default"/>
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_move_line_filter_wizard_action" model="ir.actions.act_window">
|
|
||||||
<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>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<menuitem id="account_move_line_filter_wizard_menu"
|
|
||||||
action="account_move_line_filter_wizard_action"
|
|
||||||
parent="account.menu_finance_entries"
|
|
||||||
sequence="-1"/>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_move_line
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Move Line Start End Dates XLS module for Odoo
|
|
||||||
# Copyright (C) 2014-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 Start End Dates XLS',
|
|
||||||
'version': '0.1',
|
|
||||||
'category': 'Accounting & Finance',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Adds start and end dates in the XLS export of the move lines',
|
|
||||||
'description': """
|
|
||||||
Account Move Line Start End Dates XLS
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
This module adds *Start Date* and *End Date* in the XLS export of the account move lines.
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion
|
|
||||||
<alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': 'Akretion',
|
|
||||||
'website': 'http://www.akretion.com/',
|
|
||||||
'depends': ['account_cutoff_prepaid', 'account_move_line_report_xls'],
|
|
||||||
'data': [],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Account Move Line Start End Dates XLS module for Odoo
|
|
||||||
# Copyright (C) 2014-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/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
import xlwt
|
|
||||||
from openerp import models, api
|
|
||||||
from openerp.addons.report_xls.utils import _render
|
|
||||||
from openerp.addons.report_xls.report_xls import report_xls
|
|
||||||
|
|
||||||
|
|
||||||
class AccountMoveLine(models.Model):
|
|
||||||
_inherit = 'account.move.line'
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _report_xls_fields(self):
|
|
||||||
res = super(AccountMoveLine, self)._report_xls_fields()
|
|
||||||
return res + ['start_date', 'end_date']
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _report_xls_template(self):
|
|
||||||
res = super(AccountMoveLine, self)._report_xls_template()
|
|
||||||
bc = '22'
|
|
||||||
aml_cell_style_date = xlwt.easyxf(
|
|
||||||
'borders: left thin, right thin, top thin, bottom thin, '
|
|
||||||
'left_colour %s, right_colour %s, top_colour %s, '
|
|
||||||
'bottom_colour %s; align: horz left;'
|
|
||||||
% (bc, bc, bc, bc), num_format_str=report_xls.date_format)
|
|
||||||
res.update({
|
|
||||||
'start_date': {
|
|
||||||
'header': [1, 13, 'text', _render("_('Start Date')")],
|
|
||||||
'lines': [1, 0, _render(
|
|
||||||
"line.start_date and line.start_date != 'False' and "
|
|
||||||
"'date' or 'text'"), _render(
|
|
||||||
"line.start_date and line.start_date != 'False' and "
|
|
||||||
"datetime.strptime(line.start_date, '%Y-%m-%d') or None"),
|
|
||||||
None, aml_cell_style_date],
|
|
||||||
'totals': [1, 0, 'text', None]},
|
|
||||||
'end_date': {
|
|
||||||
'header': [1, 13, 'text', _render("_('End Date')")],
|
|
||||||
'lines': [1, 0, _render(
|
|
||||||
"line.end_date and line.end_date != 'False' and "
|
|
||||||
"'date' or 'text'"), _render(
|
|
||||||
"line.end_date and line.end_date != 'False' and "
|
|
||||||
"datetime.strptime(line.end_date, '%Y-%m-%d') or None"),
|
|
||||||
None, aml_cell_style_date],
|
|
||||||
'totals': [1, 0, 'text', None]},
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@@ -1 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
@@ -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'],
|
|
||||||
'data': ['account_view.xml'],
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
||||||
@@ -1,46 +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>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account
|
|
||||||
from . import partner
|
|
||||||
from . import wizard
|
|
||||||
@@ -1,45 +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_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',
|
|
||||||
'partner_view.xml',
|
|
||||||
'product_view.xml',
|
|
||||||
'wizard/account_invoice_mark_sent_view.xml',
|
|
||||||
],
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
||||||
@@ -1,472 +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).
|
|
||||||
|
|
||||||
from odoo import models, fields, api, _
|
|
||||||
from odoo.tools import float_compare, float_is_zero
|
|
||||||
from odoo.exceptions import UserError, ValidationError
|
|
||||||
from odoo import SUPERUSER_ID
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoice(models.Model):
|
|
||||||
_inherit = 'account.invoice'
|
|
||||||
|
|
||||||
origin = 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')
|
|
||||||
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)
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
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
|
|
||||||
|
|
||||||
# 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 !
|
|
||||||
@api.multi
|
|
||||||
def action_move_create(self):
|
|
||||||
res = super(AccountInvoice, self).action_move_create()
|
|
||||||
for inv in self:
|
|
||||||
self._cr.execute(
|
|
||||||
"UPDATE account_move_line SET name= "
|
|
||||||
"CASE WHEN name='/' THEN %s "
|
|
||||||
"ELSE %s||' - '||name END "
|
|
||||||
"WHERE move_id=%s", (inv.number, inv.number, inv.move_id.id))
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
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')
|
|
||||||
|
|
||||||
|
|
||||||
class AccountJournal(models.Model):
|
|
||||||
_inherit = 'account.journal'
|
|
||||||
|
|
||||||
@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))
|
|
||||||
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
|
|
||||||
|
|
||||||
# Also search on start of 'code', not only on 'name'
|
|
||||||
@api.model
|
|
||||||
def name_search(
|
|
||||||
self, name='', args=None, operator='ilike', limit=80):
|
|
||||||
if args is None:
|
|
||||||
args = []
|
|
||||||
if name:
|
|
||||||
jrls = self.search(
|
|
||||||
[('code', '=ilike', name + '%')] + args, limit=limit)
|
|
||||||
if jrls:
|
|
||||||
return jrls.name_get()
|
|
||||||
return super(AccountJournal, self).name_search(
|
|
||||||
name=name, args=args, operator=operator, limit=limit)
|
|
||||||
|
|
||||||
@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))
|
|
||||||
|
|
||||||
|
|
||||||
class AccountAccount(models.Model):
|
|
||||||
_inherit = 'account.account'
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def name_get(self):
|
|
||||||
if self._context.get('account_account_show_code_only'):
|
|
||||||
res = []
|
|
||||||
for record in self:
|
|
||||||
res.append((record.id, record.code))
|
|
||||||
return res
|
|
||||||
else:
|
|
||||||
return super(AccountAccount, self).name_get()
|
|
||||||
|
|
||||||
# https://github.com/odoo/odoo/issues/23040
|
|
||||||
def fix_bank_account_types(self):
|
|
||||||
aao = self.env['account.account']
|
|
||||||
companies = self.env['res.company'].search([])
|
|
||||||
if len(companies) > 1 and self.env.user.id != SUPERUSER_ID:
|
|
||||||
raise UserError(
|
|
||||||
"In multi-company setups, you should run this "
|
|
||||||
"script as admin user")
|
|
||||||
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 = aao
|
|
||||||
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 = aao.search([
|
|
||||||
('user_type_id', '=', bank_type.id)], order='company_id, code')
|
|
||||||
for account in aao.search([('user_type_id', '=', bank_type.id)]):
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
class AccountAnalyticAccount(models.Model):
|
|
||||||
_inherit = 'account.analytic.account'
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def name_get(self):
|
|
||||||
if self._context.get('analytic_account_show_code_only'):
|
|
||||||
res = []
|
|
||||||
for record in self:
|
|
||||||
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)]})
|
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|
||||||
@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)):
|
|
||||||
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)):
|
|
||||||
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
|
|
||||||
self.amount_currency and
|
|
||||||
float_is_zero(self.credit, precision_digits=prec) and
|
|
||||||
float_is_zero(self.debit, precision_digits=prec)):
|
|
||||||
date = self.date or None
|
|
||||||
amount_company_currency = self.currency_id.with_context(
|
|
||||||
date=date).compute(
|
|
||||||
self.amount_currency, self.env.user.company_id.currency_id)
|
|
||||||
precision = self.env['decimal.precision'].precision_get('Account')
|
|
||||||
if float_compare(
|
|
||||||
amount_company_currency, 0,
|
|
||||||
precision_digits=precision) == -1:
|
|
||||||
self.debit = amount_company_currency * -1
|
|
||||||
else:
|
|
||||||
self.credit = amount_company_currency
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
@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
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
# in the following scenario : move line 'x' has been "guessed" by OpenERP
|
|
||||||
# to be reconciled with a statement line 'Y' at the end of the bank
|
|
||||||
# statement, but it is a mistake because it should be reconciled with
|
|
||||||
# statement line 'B' at the beginning of the bank statement
|
|
||||||
# When the user is on statement line 'B', he tries to select
|
|
||||||
# move line 'x', but it can't find it... because it is already "reserved"
|
|
||||||
# by the guess of OpenERP for statement line 'Y' ! To solve this problem,
|
|
||||||
# the user must go to statement line 'Y' and unselect move line 'x'
|
|
||||||
# and then come back on statement line 'B' and select move line 'A'...
|
|
||||||
# but non super-expert users can't do that because it is impossible to
|
|
||||||
# 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
|
|
||||||
|
|
||||||
@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:
|
|
||||||
action.update({
|
|
||||||
'views': False,
|
|
||||||
'view_id': False,
|
|
||||||
'view_mode': 'form,tree',
|
|
||||||
'res_id': self.journal_entry_ids[0].id,
|
|
||||||
})
|
|
||||||
return action
|
|
||||||
else:
|
|
||||||
raise UserError(_(
|
|
||||||
'No journal entry linked to this bank statement line.'))
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
|
||||||
'''This method is inspired by the method get_fiscal_position()
|
|
||||||
in odoo/addons/account/partner.py : it uses the same algo
|
|
||||||
but without a real partner.
|
|
||||||
Returns a recordset of fiscal position, or False'''
|
|
||||||
domains = [[
|
|
||||||
('auto_apply', '=', True),
|
|
||||||
('vat_required', '=', vat_subjected),
|
|
||||||
('company_id', '=', company_id)]]
|
|
||||||
if vat_subjected:
|
|
||||||
domains += [[
|
|
||||||
('auto_apply', '=', True),
|
|
||||||
('vat_required', '=', False),
|
|
||||||
('company_id', '=', company_id)]]
|
|
||||||
|
|
||||||
for domain in domains:
|
|
||||||
if country_id:
|
|
||||||
fps = self.search(
|
|
||||||
domain + [('country_id', '=', country_id)], limit=1)
|
|
||||||
if fps:
|
|
||||||
return fps[0]
|
|
||||||
|
|
||||||
fps = self.search(
|
|
||||||
domain +
|
|
||||||
[('country_group_id.country_ids', '=', country_id)],
|
|
||||||
limit=1)
|
|
||||||
if fps:
|
|
||||||
return fps[0]
|
|
||||||
|
|
||||||
fps = self.search(
|
|
||||||
domain +
|
|
||||||
[('country_id', '=', None), ('country_group_id', '=', None)],
|
|
||||||
limit=1)
|
|
||||||
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...
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py
|
|
||||||
index 8ed1e48..615da43 100644
|
|
||||||
--- a/addons/account/models/account_bank_statement.py
|
|
||||||
+++ b/addons/account/models/account_bank_statement.py
|
|
||||||
@@ -563,7 +563,13 @@ class AccountBankStatementLine(models.Model):
|
|
||||||
"""
|
|
||||||
# Blue lines = payment on bank account not assigned to a statement yet
|
|
||||||
reconciliation_aml_accounts = [self.journal_id.default_credit_account_id.id, self.journal_id.default_debit_account_id.id]
|
|
||||||
- domain_reconciliation = ['&', '&', ('statement_id', '=', False), ('account_id', 'in', reconciliation_aml_accounts), ('payment_id','<>', False)]
|
|
||||||
+ # AKRETION HACK 11/7/2017
|
|
||||||
+ # Remove ('payment_id','<>', False) in order to allow to select move lines
|
|
||||||
+ # generated from payment orders or check deposit
|
|
||||||
+ # but I add ('journal_id', '=', self.journal_id.id) to exclude the
|
|
||||||
+ # opening entry of the first fiscal year
|
|
||||||
+ #domain_reconciliation = ['&', '&', ('statement_id', '=', False), ('account_id', 'in', reconciliation_aml_accounts), ('payment_id','<>', False)]
|
|
||||||
+ domain_reconciliation = ['&', '&', ('statement_id', '=', False), ('account_id', 'in', reconciliation_aml_accounts), ('journal_id', '=', self.journal_id.id)]
|
|
||||||
|
|
||||||
# Black lines = unreconciled & (not linked to a payment or open balance created by statement
|
|
||||||
domain_matching = [('reconciled', '=', False)]
|
|
||||||
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
|
|
||||||
index b60ffbe..6c27c57 100644
|
|
||||||
--- a/addons/account/models/account_move.py
|
|
||||||
+++ b/addons/account/models/account_move.py
|
|
||||||
@@ -599,6 +599,7 @@ class AccountMoveLine(models.Model):
|
|
||||||
domain = expression.AND([domain, [('id', 'not in', excluded_ids)]])
|
|
||||||
if str:
|
|
||||||
str_domain = [
|
|
||||||
+ '|', ('account_id.code', '=ilike', str + '%'),
|
|
||||||
'|', ('move_id.name', 'ilike', str),
|
|
||||||
'|', ('move_id.ref', 'ilike', str),
|
|
||||||
'|', ('date_maturity', 'like', str),
|
|
||||||
diff --git a/addons/account/static/src/js/account_reconciliation_widgets.js b/addons/account/static/src/js/account_reconciliation_widgets.js
|
|
||||||
index 453bd41..48c396e 100644
|
|
||||||
--- a/addons/account/static/src/js/account_reconciliation_widgets.js
|
|
||||||
+++ b/addons/account/static/src/js/account_reconciliation_widgets.js
|
|
||||||
@@ -76,7 +76,7 @@ var abstractReconciliation = Widget.extend(ControlPanelMixin, {
|
|
||||||
this.model_res_users = new Model("res.users");
|
|
||||||
this.model_tax = new Model("account.tax");
|
|
||||||
this.model_presets = new Model("account.reconcile.model");
|
|
||||||
- this.max_move_lines_displayed = 5;
|
|
||||||
+ this.max_move_lines_displayed = 15;
|
|
||||||
// Number of reconciliations loaded initially and by clicking 'show more'
|
|
||||||
this.num_reconciliations_fetched_in_batch = 10;
|
|
||||||
this.animation_speed = 100; // "Blocking" animations
|
|
||||||
@@ -1755,7 +1755,7 @@ var bankStatementReconciliationLine = abstractReconciliationLine.extend({
|
|
||||||
relation: "res.partner",
|
|
||||||
string: _t("Partner"),
|
|
||||||
type: "many2one",
|
|
||||||
- domain: [['parent_id','=',false], '|', ['customer','=',true], ['supplier','=',true]],
|
|
||||||
+ domain: [['parent_id','=',false]], // AKRETION HACK 26/6/2017 allow all parent partners
|
|
||||||
help: "",
|
|
||||||
readonly: false,
|
|
||||||
required: true,
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py
|
|
||||||
index 4374528..aea1361 100644
|
|
||||||
--- a/addons/account/models/account_bank_statement.py
|
|
||||||
+++ b/addons/account/models/account_bank_statement.py
|
|
||||||
@@ -1008,7 +1008,7 @@ class AccountBankStatementLine(models.Model):
|
|
||||||
#record the move name on the statement line to be able to retrieve it in case of unreconciliation
|
|
||||||
self.write({'move_name': move.name})
|
|
||||||
payment.write({'payment_reference': move.name})
|
|
||||||
- elif self.move_name:
|
|
||||||
- raise UserError(_('Operation not allowed. Since your statement line already received a number, you cannot reconcile it entirely with existing journal entries otherwise it would make a gap in the numbering. You should book an entry and make a regular revert of it in case you want to cancel it.'))
|
|
||||||
+ #elif self.move_name:
|
|
||||||
+ # raise UserError(_('Operation not allowed. Since your statement line already received a number, you cannot reconcile it entirely with existing journal entries otherwise it would make a gap in the numbering. You should book an entry and make a regular revert of it in case you want to cancel it.'))
|
|
||||||
counterpart_moves.assert_balanced()
|
|
||||||
return counterpart_moves
|
|
||||||
@@ -1,482 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="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).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<!-- INVOICE -->
|
|
||||||
<record id="invoice_supplier_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.supplier.invoice.form</field>
|
|
||||||
<field name="model">account.invoice</field>
|
|
||||||
<field name="inherit_id" ref="account.invoice_supplier_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="fiscal_position_id" position="attributes">
|
|
||||||
<attribute name="widget">selection</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="invoice_line_ids" position="before">
|
|
||||||
<button name="delete_lines_qty_zero" states="draft" string="⇒ Delete lines qty=0" type="object" class="oe_link oe_right" groups="account.group_account_invoice"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="invoice_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.invoice.form</field>
|
|
||||||
<field name="model">account.invoice</field>
|
|
||||||
<field name="inherit_id" ref="account.invoice_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="fiscal_position_id" position="attributes">
|
|
||||||
<attribute name="widget">selection</attribute>
|
|
||||||
</field>
|
|
||||||
<!-- move sent field and make it visible -->
|
|
||||||
<field name="sent" position="replace"/>
|
|
||||||
<field name="move_id" position="before">
|
|
||||||
<field name="sent"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="invoice_tree" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.invoice_tree</field>
|
|
||||||
<field name="model">account.invoice</field>
|
|
||||||
<field name="inherit_id" ref="account.invoice_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="reference" position="attributes">
|
|
||||||
<attribute name="invisible">not context.get('type') in ('in_invoice', 'in_refund')</attribute>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_invoice_filter" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.invoice.search</field>
|
|
||||||
<field name="model">account.invoice</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<filter name="late" position="after">
|
|
||||||
<separator/>
|
|
||||||
<filter name="to_send" string="To Send" domain="[('sent', '=', False), ('state', 'in', ('open', 'paid'))]"/>
|
|
||||||
<filter name="sent" string="Sent" domain="[('sent', '=', True)]"/>
|
|
||||||
<separator/>
|
|
||||||
<filter name="no_attachment" string="Missing Attachment" domain="[('has_attachment', '=', False)]"/>
|
|
||||||
</filter>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Having a menu entry on invoice lines is often very usefull for odoo user:
|
|
||||||
they can search in their lines, etc...
|
|
||||||
So I enhance the generic views and add actions, but I don't add menu entries here ;
|
|
||||||
the creation of the corresponding menu entry should be done in the customer-specifc
|
|
||||||
module -->
|
|
||||||
<record id="view_invoice_line_tree" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.invoice_line_tree</field>
|
|
||||||
<field name="model">account.invoice.line</field>
|
|
||||||
<field name="inherit_id" ref="account.view_invoice_line_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="name" position="before">
|
|
||||||
<field name="partner_id" invisible="not context.get('show_invoice_fields')"/>
|
|
||||||
<field name="date_invoice" invisible="not context.get('show_invoice_fields')"/>
|
|
||||||
<field name="invoice_number" invisible="not context.get('show_invoice_fields')"/>
|
|
||||||
</field>
|
|
||||||
<field name="currency_id" position="after">
|
|
||||||
<field name="state" invisible="not context.get('show_invoice_fields')"/>
|
|
||||||
<field name="invoice_type" invisible="1"/>
|
|
||||||
</field>
|
|
||||||
<field name="quantity" position="attributes">
|
|
||||||
<attribute name="sum">1</attribute>
|
|
||||||
</field>
|
|
||||||
<xpath expr="/tree" position="attributes">
|
|
||||||
<attribute name="decoration-info">state == 'draft'</attribute>
|
|
||||||
<attribute name="decoration-muted">state == 'cancel'</attribute>
|
|
||||||
<attribute name="edit">0</attribute>
|
|
||||||
<attribute name="create">0</attribute>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_invoice_line_search" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.invoice_line_search</field>
|
|
||||||
<field name="model">account.invoice.line</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<search string="Search Invoice Lines">
|
|
||||||
<field name="partner_id"/>
|
|
||||||
<field name="product_id"/>
|
|
||||||
<field name="account_id"/>
|
|
||||||
<field name="invoice_number"/>
|
|
||||||
<field name="name"/>
|
|
||||||
<filter name="out_invoice" string="Customer Invoices"
|
|
||||||
domain="[('invoice_type', '=', 'out_invoice')]"/>
|
|
||||||
<filter name="out_refund" string="Customer Refunds"
|
|
||||||
domain="[('invoice_type', '=', 'out_refund')]"/>
|
|
||||||
<filter name="in_invoice" string="Supplier Invoices"
|
|
||||||
domain="[('invoice_type', '=', 'in_invoice')]"/>
|
|
||||||
<filter name="in_refund" string="Supplier Refunds"
|
|
||||||
domain="[('invoice_type', '=', 'in_refund')]"/>
|
|
||||||
<separator/>
|
|
||||||
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]"/>
|
|
||||||
<filter name="unpaid" string="Not Paid" domain="[('state', '=', 'open')]"/>
|
|
||||||
<filter name="paid" string="Paid" domain="[('state', '=', 'paid')]"/>
|
|
||||||
|
|
||||||
<group string="Group By" name="groupby">
|
|
||||||
<filter name="partner_groupby" string="Partner"
|
|
||||||
context="{'group_by': 'partner_id'}"/>
|
|
||||||
<filter name="date_groupby" string="Invoice Date"
|
|
||||||
context="{'group_by': 'date_invoice'}"/>
|
|
||||||
<filter name="product_groupby" string="Product"
|
|
||||||
context="{'group_by': 'product_id'}"/>
|
|
||||||
<filter name="account_groupby" string="Account"
|
|
||||||
context="{'group_by': 'account_id'}"/>
|
|
||||||
</group>
|
|
||||||
</search>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="out_invoice_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Customer Invoice Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', '=', 'out_invoice')]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="out_refund_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Customer Refund Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', '=', 'out_refund')]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="out_invoice_refund_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Customer Invoice Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', 'in', ('out_invoice', 'out_refund'))]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="in_invoice_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Supplier Invoice Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', '=', 'in_invoice')]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="in_refund_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Supplier Refund Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', '=', 'in_refund')]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="in_invoice_refund_line_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Supplier Invoice Lines</field>
|
|
||||||
<field name="res_model">account.invoice.line</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
<field name="domain">[('invoice_type', 'in', ('in_invoice', 'in_refund'))]</field>
|
|
||||||
<field name="context">{'show_invoice_fields': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_invoice_report_search" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.invoice.report.search</field>
|
|
||||||
<field name="model">account.invoice.report</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_invoice_report_search"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="categ_id" position="after">
|
|
||||||
<field name="product_id"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<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="date"/>
|
|
||||||
<field name="commercial_partner_id"/>
|
|
||||||
<field name="type"/>
|
|
||||||
<field name="product_id"/>
|
|
||||||
<field name="product_qty" sum="1"/>
|
|
||||||
<field name="price_total" sum="1"/>
|
|
||||||
<field name="state"/>
|
|
||||||
<field name="currency_id" invisible="1"/>
|
|
||||||
<field name="company_id" groups="base.group_multi_company"/>
|
|
||||||
</tree>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account.action_account_invoice_report_all_supp" model="ir.actions.act_window">
|
|
||||||
<field name="view_mode">pivot,graph,tree</field>
|
|
||||||
<field name="context">{'search_default_current':1, 'search_default_supplier':1, 'search_default_year': 1}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account.action_account_invoice_report_all" model="ir.actions.act_window">
|
|
||||||
<field name="view_mode">pivot,graph,tree</field>
|
|
||||||
<field name="context">{'search_default_current':1, 'search_default_customer':1, 'search_default_year': 1}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_invoice_report_pivot" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.invoice.report.pivot</field>
|
|
||||||
<field name="model">account.invoice.report</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_invoice_report_pivot"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="/pivot" position="attributes">
|
|
||||||
<attribute name="disable_linking"></attribute>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_invoice_tax_form" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.invoice.tax.form</field>
|
|
||||||
<field name="model">account.invoice.tax</field>
|
|
||||||
<field name="inherit_id" ref="account.view_invoice_tax_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="name" position="after">
|
|
||||||
<field name="tax_id"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- model account.move.line / Journal Items -->
|
|
||||||
<record id="account.action_account_moves_all_a" model="ir.actions.act_window">
|
|
||||||
<field name="limit">200</field>
|
|
||||||
<!-- Win space, because there are already many columns -->
|
|
||||||
<field name="context">{'journal_show_code_only': True}</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- remove base.group_no_one on Journal Items-->
|
|
||||||
<record id="account.menu_action_account_moves_all" model="ir.ui.menu">
|
|
||||||
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- accountant must be able to access the Adviser section ! -->
|
|
||||||
<record id="account.menu_finance_entries" model="ir.ui.menu">
|
|
||||||
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- model account.move / Journal Entries -->
|
|
||||||
<record id="account.action_move_journal_line" model="ir.actions.act_window">
|
|
||||||
<field name="limit">200</field>
|
|
||||||
<field name="context">{}</field> <!-- Don't filter by default on misc journal -->
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_move_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.account_move_form</field>
|
|
||||||
<field name="model">account.move</field>
|
|
||||||
<field name="inherit_id" ref="account.view_move_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="ref" position="after">
|
|
||||||
<field name="default_move_line_name"/>
|
|
||||||
</field>
|
|
||||||
<xpath expr="//field[@name='line_ids']" position="attributes">
|
|
||||||
<attribute name="context">{'line_ids': line_ids, 'journal_id': journal_id, 'default_name': default_move_line_name}</attribute>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='date_maturity']" position="after">
|
|
||||||
<field name="full_reconcile_id"/>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_move_line_filter" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.account_move_line_search</field>
|
|
||||||
<field name="model">account.move.line</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_move_line_filter"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="partner_id" position="after">
|
|
||||||
<field name="full_reconcile_id" />
|
|
||||||
</field>
|
|
||||||
<filter name="unreconciled" position="before">
|
|
||||||
<filter name="reconciled" string="Fully Reconciled" domain="[('full_reconcile_id', '!=', False)]"/>
|
|
||||||
<!-- <filter name="partial_reconciled" string="Partially Reconciled" domain="[('reconcile_partial_id', '!=', False)]"/> -->
|
|
||||||
</filter>
|
|
||||||
<filter name="unreconciled" position="attributes">
|
|
||||||
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
|
|
||||||
</filter>
|
|
||||||
<field name="name" position="attributes">
|
|
||||||
<attribute name="string">Name or Reference</attribute>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_move_line_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.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">
|
|
||||||
<field name="quantity" position="after">
|
|
||||||
<field name="product_id" />
|
|
||||||
</field>
|
|
||||||
<field name="move_id" position="after">
|
|
||||||
<field name="invoice_id"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_move_line_tree" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.account_move_line_tree</field>
|
|
||||||
<field name="model">account.move.line</field>
|
|
||||||
<field name="inherit_id" ref="account.view_move_line_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<!-- Move reconcile_id to a better position -->
|
|
||||||
<field name="full_reconcile_id" position="replace"/>
|
|
||||||
<field name="credit" position="after">
|
|
||||||
<field name="full_reconcile_id"/>
|
|
||||||
</field>
|
|
||||||
<field name="date_maturity" position="after">
|
|
||||||
<button name="show_account_move_form" type="object" icon="fa-arrows-h" string="Show Journal Entry"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_search" model="ir.ui.view">
|
|
||||||
<field name="name">account.account.search</field>
|
|
||||||
<field name="model">account.account</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_search"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<!-- The native "name" filter uses a domain ['|', ('name','ilike',self), ('code','=like',str(self)+'%')]
|
|
||||||
This is good because it uses '=like' on 'code', but sometimes there are digits in account names,
|
|
||||||
so you get additionnal unexpected accounts in the result of the search -->
|
|
||||||
<field name="name" position="after">
|
|
||||||
<field name="code" filter_domain="[('code', '=like', str(self)+'%')]" string="Code"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_type_tree" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.account_type_tree</field>
|
|
||||||
<field name="model">account.account.type</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_type_tree" />
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="type" position="after">
|
|
||||||
<field name="include_initial_balance" />
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_account_journal_search" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.journal.search</field>
|
|
||||||
<field name="model">account.journal</field>
|
|
||||||
<field name="inherit_id" ref="account.view_account_journal_search"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<filter name="dashboard" position="after">
|
|
||||||
<group name="groupby" string="Group By">
|
|
||||||
<filter name="type_groupby" string="Type" context="{'group_by': 'type'}"/>
|
|
||||||
</group>
|
|
||||||
</filter>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_bank_statement_form" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.bank.statement.form</field>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='bank_account_id']" position="after">
|
|
||||||
<!-- The cancel button is provided by the account_cancel module, but we don't want to depend on it -->
|
|
||||||
<button name="show_account_move" type="object"
|
|
||||||
string="View Account Move" icon="fa fa-arrow-right"
|
|
||||||
attrs="{'invisible': [('journal_entry_ids', '=', [])]}"/>
|
|
||||||
</xpath>
|
|
||||||
<field name="date" position="after">
|
|
||||||
<field name="start_date"/>
|
|
||||||
<field name="end_date"/>
|
|
||||||
</field>
|
|
||||||
<field name="date" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_bank_statement_tree" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.bank.statement.tree</field>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="date" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="journal_id" position="after">
|
|
||||||
<field name="start_date"/>
|
|
||||||
<field name="end_date"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="view_bank_statement_search" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.bank.statement.search</field>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_search"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="date" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</field>
|
|
||||||
<field name="date" position="after">
|
|
||||||
<field name="start_date"/>
|
|
||||||
<field name="end_date"/>
|
|
||||||
</field>
|
|
||||||
<filter context="{'group_by': 'date'}" position="attributes">
|
|
||||||
<attribute name="invisible">1</attribute>
|
|
||||||
</filter>
|
|
||||||
<filter context="{'group_by': 'date'}" position="after">
|
|
||||||
<filter name="start_date_groupby" string="Start Date"
|
|
||||||
context="{'group_by': 'start_date'}"/>
|
|
||||||
<filter name="end_date_groupby" string="End Date"
|
|
||||||
context="{'group_by': 'end_date'}"/>
|
|
||||||
</filter>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- ACCOUNT TAX GROUP -->
|
|
||||||
<!-- in the account module, there is nothing for account.tax.group : no form/tree view, no menu... -->
|
|
||||||
<record id="account_tax_group_form" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.tax.group.form</field>
|
|
||||||
<field name="model">account.tax.group</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form string="Tax Group">
|
|
||||||
<group name="main">
|
|
||||||
<field name="name"/>
|
|
||||||
<field name="sequence" invisible="1"/>
|
|
||||||
</group>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_tax_group_tree" model="ir.ui.view">
|
|
||||||
<field name="name">usability.account.tax.group.tree</field>
|
|
||||||
<field name="model">account.tax.group</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<tree string="Tax Groups">
|
|
||||||
<field name="sequence" widget="handle"/>
|
|
||||||
<field name="name"/>
|
|
||||||
</tree>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="account_tax_group_action" model="ir.actions.act_window">
|
|
||||||
<field name="name">Tax Groups</field>
|
|
||||||
<field name="res_model">account.tax.group</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<menuitem id="account_tax_group_menu" action="account_tax_group_action" parent="account.account_account_menu" sequence="2"/>
|
|
||||||
|
|
||||||
<!-- Remove menu entry "Accounting > Configuration > Accounting > Bank Accounts"
|
|
||||||
(account.journal filtered on type = 'bank' with special tree and form view)
|
|
||||||
because it is useless and confusing -->
|
|
||||||
<record id="account.menu_action_account_bank_journal_form" model="ir.ui.menu">
|
|
||||||
<field name="groups_id" eval="[(6, 0, [ref('base_usability.group_nobody')])]"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Duplicate the menu "Sales > Configuration > Contacts > Bank Accounts"
|
|
||||||
under "Accounting > Configuration", because most users will try to find it there -->
|
|
||||||
<menuitem id="bank_account_account_config_menu" name="Bank Accounts" parent="account.menu_finance_configuration" sequence="9"/>
|
|
||||||
|
|
||||||
<menuitem id="res_bank_account_config_menu" action="base.action_res_bank_form" parent="bank_account_account_config_menu" sequence="10"/>
|
|
||||||
|
|
||||||
<menuitem id="res_partner_bank_account_config_menu" action="base.action_res_partner_bank_account_form" parent="bank_account_account_config_menu" sequence="20"/>
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import models, fields
|
|
||||||
|
|
||||||
|
|
||||||
class ResPartner(models.Model):
|
|
||||||
_inherit = 'res.partner'
|
|
||||||
|
|
||||||
invoice_warn = fields.Selection(track_visibility='onchange')
|
|
||||||
property_account_position_id = fields.Many2one(
|
|
||||||
track_visibility='onchange')
|
|
||||||
@@ -1,26 +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>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="view_partner_property_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.res.partner.form</field>
|
|
||||||
<field name="model">res.partner</field>
|
|
||||||
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="property_account_position_id" position="attributes">
|
|
||||||
<attribute name="widget">selection</attribute>
|
|
||||||
</field>
|
|
||||||
<group name="accounting_entries" position="attributes">
|
|
||||||
<attribute name="groups">account.group_account_user</attribute>
|
|
||||||
</group>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,24 +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>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="view_category_property_form" model="ir.ui.view">
|
|
||||||
<field name="name">account_usability.product.category.form</field>
|
|
||||||
<field name="model">product.category</field>
|
|
||||||
<field name="inherit_id" ref="account.view_category_property_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<!-- On product form view, the group for Invoicing tab is limited to account.group_account_invoice... but on product category form, it is limited to account.group_account_manager -> we fix this and also use account.group_account_invoice -->
|
|
||||||
<group name="account_property" position="attributes">
|
|
||||||
<attribute name="groups">account.group_account_invoice</attribute>
|
|
||||||
</group>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.5 KiB |
@@ -1,4 +0,0 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import account_invoice_mark_sent
|
|
||||||
from . import account_move_reversal
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import models
|
|
||||||
import logging
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoiceMarkSent(models.TransientModel):
|
|
||||||
_name = 'account.invoice.mark.sent'
|
|
||||||
_description = 'Mark invoices as sent'
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
assert self.env.context.get('active_model') == 'account.invoice',\
|
|
||||||
'Source model must be invoices'
|
|
||||||
assert self.env.context.get('active_ids'), 'No invoices selected'
|
|
||||||
invoices = self.env['account.invoice'].search([
|
|
||||||
('id', 'in', self.env.context.get('active_ids')),
|
|
||||||
('state', 'in', ('open', 'paid'))])
|
|
||||||
invoices.write({'sent': True})
|
|
||||||
logger.info('Marking invoices with ID %s as sent', invoices.ids)
|
|
||||||
return
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright 2017-2018 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_mark_sent_form" model="ir.ui.view">
|
|
||||||
<field name="name">account.invoice.mark.sent.form</field>
|
|
||||||
<field name="model">account.invoice.mark.sent</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form string="Mark invoices as sent">
|
|
||||||
<p>
|
|
||||||
This wizard will mark as <i>sent</i> all the selected invoices in open or paid state.
|
|
||||||
</p>
|
|
||||||
<footer>
|
|
||||||
<button type="object" name="run" string="Mark as Sent" class="btn-primary"/>
|
|
||||||
<button special="cancel" string="Cancel" class="oe_link"/>
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<act_window id="account_invoice_mark_sent_action"
|
|
||||||
multi="True"
|
|
||||||
key2="client_action_multi"
|
|
||||||
name="Mark as Sent"
|
|
||||||
res_model="account.invoice.mark.sent"
|
|
||||||
src_model="account.invoice"
|
|
||||||
view_mode="form"
|
|
||||||
target="new"
|
|
||||||
groups="account.group_account_invoice" />
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import api, fields, models
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
|
|
||||||
|
|
||||||
class AccountMoveReversal(models.TransientModel):
|
|
||||||
_inherit = 'account.move.reversal'
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _default_date(self):
|
|
||||||
date = None
|
|
||||||
if (
|
|
||||||
self._context.get('active_model') == 'account.move' and
|
|
||||||
self._context.get('active_id')):
|
|
||||||
move = self.env['account.move'].browse(self._context['active_id'])
|
|
||||||
date_dt = fields.Date.from_string(move.date) +\
|
|
||||||
relativedelta(days=1)
|
|
||||||
date = fields.Date.to_string(date_dt)
|
|
||||||
return date
|
|
||||||
|
|
||||||
date = fields.Date(default=_default_date)
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import printing
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Aeroo Report to Printer 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': 'Aeroo Report to Printer',
|
|
||||||
'version': '0.1',
|
|
||||||
'category': 'Aeroo',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Connect aeroo_report to base_report_to_printer',
|
|
||||||
'description': """
|
|
||||||
Aeroo Report to Printer
|
|
||||||
=======================
|
|
||||||
|
|
||||||
There is a module *report_aeroo_direct_print* in https://github.com/aeroo/aeroo_reports that adds support for CUPS printing, but it's not as mature and clean as the OCA module *base_report_to_printer* from https://github.com/OCA/report-print-send.
|
|
||||||
|
|
||||||
And I want to use the best of both world : the best reporting engine (Aeroo) with the best CUPS printing module (base_report_to_printer). So I developped this small glue module.
|
|
||||||
|
|
||||||
You will find some sample code to use this module in the comments of the main Python file.
|
|
||||||
|
|
||||||
WARNING: you need this PR for base_report_to_printer to use this module: https://github.com/OCA/report-print-send/pull/39
|
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
|
||||||
""",
|
|
||||||
'author': 'Akretion',
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': [
|
|
||||||
'base_report_to_printer',
|
|
||||||
'report_aeroo',
|
|
||||||
'base_other_report_engines',
|
|
||||||
],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Aeroo Report to Printer 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, _
|
|
||||||
from openerp.exceptions import Warning as UserError
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class PrintingPrinter(models.Model):
|
|
||||||
_inherit = 'printing.printer'
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def aeroo_print_document(self, report_name, object_id, copies=1):
|
|
||||||
'''
|
|
||||||
Send an aeroo report to CUPS server for printing
|
|
||||||
|
|
||||||
Usage example :
|
|
||||||
|
|
||||||
Add this button in an inherit of the view 'stock.view_picking_form':
|
|
||||||
<button name="print_delivery" type="object" states="done"
|
|
||||||
string="Print 2 copies"/>
|
|
||||||
|
|
||||||
Add this code in the StockPicking class that inherit 'stock.picking'
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def print_delivery(self):
|
|
||||||
if not self.env.user.printing_printer_id:
|
|
||||||
raise UserError(_(
|
|
||||||
"Missing 'Default Printer' in your preferences"))
|
|
||||||
self.env.user.printing_printer_id.aeroo_print_document(
|
|
||||||
'stock.report_picking', self.id, copies=2)
|
|
||||||
'''
|
|
||||||
self.ensure_one()
|
|
||||||
report = self.env['ir.actions.report.xml']._lookup_report(report_name)
|
|
||||||
report_xml = self.env['report']._get_report_from_name(report_name)
|
|
||||||
data = {
|
|
||||||
'model': report_xml.model,
|
|
||||||
'id': object_id,
|
|
||||||
'report_type': 'aeroo',
|
|
||||||
}
|
|
||||||
logger.info(
|
|
||||||
'Request printing aeroo report %s model %s ID %d in %d copies',
|
|
||||||
report_name, data['model'], data['id'], copies)
|
|
||||||
aeroo_report_content, aeroo_report_format = report.create(
|
|
||||||
self.env.cr, self.env.uid, [object_id],
|
|
||||||
data, context=dict(self.env.context))
|
|
||||||
if aeroo_report_format in ('pdf', 'raw'):
|
|
||||||
self.print_document(
|
|
||||||
report_name, aeroo_report_content, aeroo_report_format, copies)
|
|
||||||
else:
|
|
||||||
raise UserError(_(
|
|
||||||
"Format '%s' is not supported for printing")
|
|
||||||
% aeroo_report_format)
|
|
||||||
return True
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from . import attribute
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
# © 2016 Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
||||||
|
|
||||||
{
|
|
||||||
'name': 'Attribute Usability',
|
|
||||||
'version': '8.0.0.0.0',
|
|
||||||
'category': 'Product',
|
|
||||||
'summary': "Attribute views improved",
|
|
||||||
'description': """
|
|
||||||
- Create filter dynamically for each attributes in attribute values search view
|
|
||||||
- Add a form view to Attribute and Attribute Value views
|
|
||||||
|
|
||||||
Contributors: David BEAL
|
|
||||||
""",
|
|
||||||
'author': 'Akretion',
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
'depends': [
|
|
||||||
'product',
|
|
||||||
],
|
|
||||||
'data': [
|
|
||||||
'view.xml',
|
|
||||||
],
|
|
||||||
'installable': False,
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
# © 2016 David BEAL @ Akretion
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
||||||
|
|
||||||
from openerp import models, api
|
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
|
|
||||||
class ProductAtribute(models.Model):
|
|
||||||
_inherit = 'product.attribute'
|
|
||||||
_order = 'sequence ASC'
|
|
||||||
|
|
||||||
|
|
||||||
class ProductAttributeValue(models.Model):
|
|
||||||
_inherit = 'product.attribute.value'
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _get_attributes_to_filter(self):
|
|
||||||
""" Inherit if you want reduce the list """
|
|
||||||
return [(x.id, x.name)
|
|
||||||
for x in self.env['product.attribute'].search(
|
|
||||||
[], order='name DESC')]
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _customize_attribute_filters(self, my_filter):
|
|
||||||
""" Inherit if you to customize search filter display"""
|
|
||||||
return {
|
|
||||||
'string': "%s" % my_filter[1],
|
|
||||||
'help': 'Filtering by Attribute',
|
|
||||||
'domain': "[('attribute_id','=', %s)]" % my_filter[0]}
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def fields_view_get(self, view_id=None, view_type='form',
|
|
||||||
toolbar=False, submenu=False):
|
|
||||||
""" customize xml output
|
|
||||||
"""
|
|
||||||
res = super(ProductAttributeValue, self).fields_view_get(
|
|
||||||
view_id=view_id, view_type=view_type, toolbar=toolbar,
|
|
||||||
submenu=submenu)
|
|
||||||
if view_type == 'search':
|
|
||||||
filters_to_create = self._get_attributes_to_filter()
|
|
||||||
doc = etree.XML(res['arch'])
|
|
||||||
for my_filter in filters_to_create:
|
|
||||||
elm = etree.Element(
|
|
||||||
'filter', **self._customize_attribute_filters(my_filter))
|
|
||||||
doc[0].addprevious(elm)
|
|
||||||
res['arch'] = etree.tostring(doc, pretty_print=True)
|
|
||||||
return res
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Translation of Odoo Server.
|
|
||||||
# This file contains the translation of the following modules:
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Odoo Server 8.0\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2016-03-16 16:14+0000\n"
|
|
||||||
"PO-Revision-Date: 2016-03-16 16:14+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"
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Translation of Odoo Server.
|
|
||||||
# This file contains the translation of the following modules:
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Odoo Server 8.0\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2016-03-16 16:10+0000\n"
|
|
||||||
"PO-Revision-Date: 2016-03-16 16:10+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"
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 936 B |
@@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<record id="product.variants_action" model="ir.actions.act_window">
|
|
||||||
<field name="res_model">product.attribute.value</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="product.attribute_action" model="ir.actions.act_window">
|
|
||||||
<field name="res_model">product.attribute</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- After installation of the module, open the adhoc menu -->
|
|
||||||
<record id="action_client_attribute_usabi_menu" model="ir.actions.client">
|
|
||||||
<field name="name">Open Attribute Usability Menu</field>
|
|
||||||
<field name="tag">reload</field>
|
|
||||||
<field name="params" eval="{'menu_id': ref('product.menu_variants_action')}"/>
|
|
||||||
</record>
|
|
||||||
<record id="base.open_menu" model="ir.actions.todo">
|
|
||||||
<field name="action_id" ref="action_client_attribute_usabi_menu"/>
|
|
||||||
<field name="state">open</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import company
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2014-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': 'Base Company Extension',
|
|
||||||
'version': '10.0.1.0.0',
|
|
||||||
'category': 'Partner',
|
|
||||||
'license': 'AGPL-3',
|
|
||||||
'summary': 'Adds capital and title on company',
|
|
||||||
'description': """
|
|
||||||
Base Company Extension
|
|
||||||
======================
|
|
||||||
|
|
||||||
This module adds 2 fields on the Company :
|
|
||||||
|
|
||||||
* *Capital Amount*
|
|
||||||
|
|
||||||
* *Legal Form*
|
|
||||||
""",
|
|
||||||
'author': 'Akretion',
|
|
||||||
'website': 'http://www.akretion.com',
|
|
||||||
# I depend on base_usability only for _report_company_legal_name()
|
|
||||||
'depends': ['base_usability'],
|
|
||||||
'data': ['company_view.xml'],
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# © 2014-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).
|
|
||||||
|
|
||||||
from odoo import models, fields
|
|
||||||
|
|
||||||
|
|
||||||
class ResCompany(models.Model):
|
|
||||||
_inherit = "res.company"
|
|
||||||
|
|
||||||
capital_amount = fields.Monetary(string='Capital Amount')
|
|
||||||
# in v9, title is only for contacts, not for companies
|
|
||||||
legal_type = fields.Char(
|
|
||||||
string="Legal Type", help="Type of Company, e.g. SARL, SAS, ...")
|
|
||||||
|
|
||||||
def _report_company_legal_name(self):
|
|
||||||
self.ensure_one()
|
|
||||||
if self.legal_type:
|
|
||||||
name = u'%s %s' % (self.name, self.legal_type)
|
|
||||||
else:
|
|
||||||
name = self.name
|
|
||||||
return name
|
|
||||||
|
|
||||||
_sql_constraints = [(
|
|
||||||
'capital_amount_positive',
|
|
||||||
'CHECK (capital_amount >= 0)',
|
|
||||||
"The value of the field 'Capital Amount' must be positive."
|
|
||||||
)]
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
© 2014-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).
|
|
||||||
-->
|
|
||||||
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<record id="view_company_form" model="ir.ui.view">
|
|
||||||
<field name="name">company.extension.form</field>
|
|
||||||
<field name="model">res.company</field>
|
|
||||||
<field name="inherit_id" ref="base.view_company_form" />
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="company_registry" position="after">
|
|
||||||
<field name="capital_amount"/>
|
|
||||||
<field name="legal_type"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import ir_mail_server
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user