[IMP] pre-commit: first run on whole repo
This commit is contained in:
@@ -3,36 +3,36 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'Account Usability',
|
||||
'version': '14.0.1.0.0',
|
||||
'category': 'Accounting & Finance',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Small usability enhancements in account module',
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': [
|
||||
'account',
|
||||
'base_view_inheritance_extension',
|
||||
'base_usability', # needed only to access base_usability.group_nobody
|
||||
# in v12, I may create a module only for group_nobody
|
||||
],
|
||||
'data': [
|
||||
'views/account_account_type.xml',
|
||||
'views/account_account.xml',
|
||||
'views/account_bank_statement.xml',
|
||||
'views/account_invoice_report.xml',
|
||||
'views/account_journal.xml',
|
||||
'views/account_move.xml',
|
||||
'views/account_menu.xml',
|
||||
'views/account_tax.xml',
|
||||
'views/product.xml',
|
||||
'views/res_config_settings.xml',
|
||||
'views/res_partner.xml',
|
||||
'views/account_report.xml',
|
||||
'wizard/account_invoice_mark_sent_view.xml',
|
||||
'wizard/account_group_generate_view.xml',
|
||||
'wizard/account_payment_register_views.xml',
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
'installable': True,
|
||||
"name": "Account Usability",
|
||||
"version": "14.0.1.0.0",
|
||||
"category": "Accounting & Finance",
|
||||
"license": "AGPL-3",
|
||||
"summary": "Small usability enhancements in account module",
|
||||
"author": "Akretion",
|
||||
"website": "https://github.com/OCA/odoo-usability",
|
||||
"depends": [
|
||||
"account",
|
||||
"base_view_inheritance_extension",
|
||||
"base_usability", # needed only to access base_usability.group_nobody
|
||||
# in v12, I may create a module only for group_nobody
|
||||
],
|
||||
"data": [
|
||||
"views/account_account_type.xml",
|
||||
"views/account_account.xml",
|
||||
"views/account_bank_statement.xml",
|
||||
"views/account_invoice_report.xml",
|
||||
"views/account_journal.xml",
|
||||
"views/account_move.xml",
|
||||
"views/account_menu.xml",
|
||||
"views/account_tax.xml",
|
||||
"views/product.xml",
|
||||
"views/res_config_settings.xml",
|
||||
"views/res_partner.xml",
|
||||
"views/account_report.xml",
|
||||
"wizard/account_invoice_mark_sent_view.xml",
|
||||
"wizard/account_group_generate_view.xml",
|
||||
"wizard/account_payment_register_views.xml",
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ index 2dd1f9cef83..62275fca65e 100644
|
||||
+ 'analytic_account_id': write_off_line_vals.get('analytic_account_id'),
|
||||
})
|
||||
return line_vals_list
|
||||
|
||||
|
||||
@@ -699,6 +700,7 @@ class AccountPayment(models.Model):
|
||||
'name': writeoff_lines[0].name,
|
||||
'amount': writeoff_amount * sign,
|
||||
@@ -29,7 +29,7 @@ index 3fc91f716ad..35636774c7e 100644
|
||||
+ writeoff_analytic_account_id = fields.Many2one('account.analytic.account', string="Difference Analytic Account", copy=False, domain="[('company_id', '=', company_id)]")
|
||||
writeoff_label = fields.Char(string='Journal Item Label', default='Write-Off',
|
||||
help='Change label of the counterpart that will hold the payment difference')
|
||||
|
||||
|
||||
@@ -422,6 +423,7 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
'name': self.writeoff_label,
|
||||
'amount': self.payment_difference,
|
||||
@@ -37,7 +37,7 @@ index 3fc91f716ad..35636774c7e 100644
|
||||
+ 'analytic_account_id': self.writeoff_analytic_account_id.id or False,
|
||||
}
|
||||
return payment_vals
|
||||
|
||||
|
||||
diff --git a/addons/account/wizard/account_payment_register_views.xml b/addons/account/wizard/account_payment_register_views.xml
|
||||
index 16eec30e265..b9386567baa 100644
|
||||
--- a/addons/account/wizard/account_payment_register_views.xml
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, models
|
||||
import logging
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccountAccount(models.Model):
|
||||
_inherit = 'account.account'
|
||||
_inherit = "account.account"
|
||||
|
||||
@api.depends('name', 'code')
|
||||
@api.depends("name", "code")
|
||||
def name_get(self):
|
||||
if self._context.get('account_account_show_code_only'):
|
||||
if self._context.get("account_account_show_code_only"):
|
||||
res = []
|
||||
for record in self:
|
||||
res.append((record.id, record.code))
|
||||
@@ -24,36 +25,42 @@ class AccountAccount(models.Model):
|
||||
# https://github.com/odoo/odoo/issues/23040
|
||||
# TODO mig to v14 ?
|
||||
def fix_bank_account_types(self):
|
||||
aao = self.env['account.account']
|
||||
companies = self.env['res.company'].search([])
|
||||
aao = self.env["account.account"]
|
||||
companies = self.env["res.company"].search([])
|
||||
if len(companies) > 1:
|
||||
self = self.sudo()
|
||||
logger.info("START the script 'fix bank and cash account types'")
|
||||
bank_type = self.env.ref('account.data_account_type_liquidity')
|
||||
asset_type = self.env.ref('account.data_account_type_current_assets')
|
||||
journals = self.env['account.journal'].search(
|
||||
[('type', 'in', ('bank', 'cash'))], order='company_id')
|
||||
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]:
|
||||
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)
|
||||
"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')
|
||||
accounts = aao.search(
|
||||
[("user_type_id", "=", bank_type.id)], order="company_id, code"
|
||||
)
|
||||
for account in accounts:
|
||||
if account not in journal_accounts_bank_type:
|
||||
account.user_type_id = asset_type.id
|
||||
logger.info(
|
||||
'Company %s: Account %s updated to Current Asset type',
|
||||
account.company_id.display_name, account.code)
|
||||
"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
|
||||
|
||||
@@ -6,10 +6,10 @@ from odoo import models
|
||||
|
||||
|
||||
class AccountAnalyticAccount(models.Model):
|
||||
_inherit = 'account.analytic.account'
|
||||
_inherit = "account.analytic.account"
|
||||
|
||||
def name_get(self):
|
||||
if self._context.get('analytic_account_show_code_only'):
|
||||
if self._context.get("analytic_account_show_code_only"):
|
||||
res = []
|
||||
for record in self:
|
||||
res.append((record.id, record.code or record.name))
|
||||
@@ -17,8 +17,11 @@ class AccountAnalyticAccount(models.Model):
|
||||
else:
|
||||
return super().name_get()
|
||||
|
||||
_sql_constraints = [(
|
||||
'code_company_unique',
|
||||
'unique(code, company_id)',
|
||||
'An analytic account with the same code already '
|
||||
'exists in the same company!')]
|
||||
_sql_constraints = [
|
||||
(
|
||||
"code_company_unique",
|
||||
"unique(code, company_id)",
|
||||
"An analytic account with the same code already "
|
||||
"exists in the same company!",
|
||||
)
|
||||
]
|
||||
|
||||
@@ -7,18 +7,19 @@ from odoo.tools.misc import format_date
|
||||
|
||||
|
||||
class AccountBankStatement(models.Model):
|
||||
_inherit = 'account.bank.statement'
|
||||
_inherit = "account.bank.statement"
|
||||
|
||||
start_date = fields.Date(
|
||||
compute='_compute_dates', string='Start Date', readonly=True,
|
||||
store=True)
|
||||
compute="_compute_dates", string="Start Date", readonly=True, store=True
|
||||
)
|
||||
end_date = fields.Date(
|
||||
compute='_compute_dates', string='End Date', readonly=True,
|
||||
store=True)
|
||||
compute="_compute_dates", string="End Date", readonly=True, store=True
|
||||
)
|
||||
hide_bank_statement_balance = fields.Boolean(
|
||||
related='journal_id.hide_bank_statement_balance', readonly=True)
|
||||
related="journal_id.hide_bank_statement_balance", readonly=True
|
||||
)
|
||||
|
||||
@api.depends('line_ids.date')
|
||||
@api.depends("line_ids.date")
|
||||
def _compute_dates(self):
|
||||
for st in self:
|
||||
dates = [line.date for line in st.line_ids]
|
||||
@@ -30,26 +31,31 @@ class AccountBankStatement(models.Model):
|
||||
if stmt.hide_bank_statement_balance:
|
||||
continue
|
||||
else:
|
||||
super(AccountBankStatement, stmt)._check_balance_end_real_same_as_computed()
|
||||
super(
|
||||
AccountBankStatement, stmt
|
||||
)._check_balance_end_real_same_as_computed()
|
||||
return True
|
||||
|
||||
@api.depends('name', 'start_date', 'end_date')
|
||||
@api.depends("name", "start_date", "end_date")
|
||||
def name_get(self):
|
||||
res = []
|
||||
for statement in self:
|
||||
name = "%s (%s => %s)" % (
|
||||
statement.name,
|
||||
statement.start_date and format_date(self.env, statement.start_date) or '',
|
||||
statement.end_date and format_date(self.env, statement.end_date) or '')
|
||||
statement.start_date
|
||||
and format_date(self.env, statement.start_date)
|
||||
or "",
|
||||
statement.end_date and format_date(self.env, statement.end_date) or "",
|
||||
)
|
||||
res.append((statement.id, name))
|
||||
return res
|
||||
|
||||
|
||||
class AccountBankStatementLine(models.Model):
|
||||
_inherit = 'account.bank.statement.line'
|
||||
_inherit = "account.bank.statement.line"
|
||||
# Native order is:
|
||||
# _order = 'statement_id desc, sequence, id desc'
|
||||
_order = 'statement_id desc, date 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
|
||||
@@ -80,12 +86,14 @@ class AccountBankStatementLine(models.Model):
|
||||
|
||||
def show_account_move(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('account.action_move_line_form').read()[0]
|
||||
action = self.env.ref("account.action_move_line_form").read()[0]
|
||||
# Note: this action is on account.move, not account.move.line !
|
||||
action.update({
|
||||
'views': False,
|
||||
'view_id': False,
|
||||
'view_mode': 'form,tree',
|
||||
'res_id': self.move_id.id,
|
||||
})
|
||||
action.update(
|
||||
{
|
||||
"views": False,
|
||||
"view_id": False,
|
||||
"view_mode": "form,tree",
|
||||
"res_id": self.move_id.id,
|
||||
}
|
||||
)
|
||||
return action
|
||||
|
||||
@@ -6,11 +6,11 @@ from odoo import api, models
|
||||
|
||||
|
||||
class AccountIncoterms(models.Model):
|
||||
_inherit = 'account.incoterms'
|
||||
_inherit = "account.incoterms"
|
||||
|
||||
@api.depends('code', 'name')
|
||||
@api.depends("code", "name")
|
||||
def name_get(self):
|
||||
res = []
|
||||
for rec in self:
|
||||
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
|
||||
res.append((rec.id, "[%s] %s" % (rec.code, rec.name)))
|
||||
return res
|
||||
|
||||
@@ -6,22 +6,22 @@ from odoo import api, fields, models
|
||||
|
||||
|
||||
class AccountJournal(models.Model):
|
||||
_inherit = 'account.journal'
|
||||
_inherit = "account.journal"
|
||||
|
||||
hide_bank_statement_balance = fields.Boolean(
|
||||
string='Hide Bank Statement Balance',
|
||||
string="Hide Bank Statement Balance",
|
||||
help="You may want to enable this option when your bank "
|
||||
"journal is generated from a bank statement file that "
|
||||
"doesn't handle start/end balance (QIF for instance) and "
|
||||
"you don't want to enter the start/end balance manually: it "
|
||||
"will prevent the display of wrong information in the accounting "
|
||||
"dashboard and on bank statements.")
|
||||
"dashboard and on bank statements.",
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
'name', 'currency_id', 'company_id', 'company_id.currency_id', 'code')
|
||||
@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'):
|
||||
if self._context.get("journal_show_code_only"):
|
||||
for journal in self:
|
||||
res.append((journal.id, journal.code))
|
||||
return res
|
||||
@@ -29,12 +29,14 @@ class AccountJournal(models.Model):
|
||||
for journal in self:
|
||||
name = "[%s] %s" % (journal.code, journal.name)
|
||||
if (
|
||||
journal.currency_id and
|
||||
journal.currency_id != journal.company_id.currency_id):
|
||||
journal.currency_id
|
||||
and journal.currency_id != journal.company_id.currency_id
|
||||
):
|
||||
name = "%s (%s)" % (name, journal.currency_id.name)
|
||||
res.append((journal.id, name))
|
||||
return res
|
||||
|
||||
|
||||
# @api.constrains('default_credit_account_id', 'default_debit_account_id')
|
||||
# def _check_account_type_on_bank_journal(self):
|
||||
# bank_acc_type = self.env.ref('account.data_account_type_liquidity')
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import float_is_zero
|
||||
from odoo.tools.misc import format_date
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = 'account.move'
|
||||
_inherit = "account.move"
|
||||
|
||||
# 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)]})
|
||||
ref = fields.Char(states={"posted": [("readonly", True)]})
|
||||
date = fields.Date(tracking=True)
|
||||
invoice_date_due = fields.Date(tracking=True)
|
||||
invoice_payment_term_id = fields.Many2one(tracking=True)
|
||||
@@ -22,51 +22,63 @@ class AccountMove(models.Model):
|
||||
fiscal_position_id = fields.Many2one(tracking=True)
|
||||
amount_total = fields.Monetary(tracking=True)
|
||||
# for invoice report
|
||||
has_discount = fields.Boolean(
|
||||
compute='_compute_has_discount', readonly=True)
|
||||
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)
|
||||
compute="_compute_has_attachment",
|
||||
search="_search_has_attachment",
|
||||
readonly=True,
|
||||
)
|
||||
sale_dates = fields.Char(
|
||||
compute="_compute_sales_dates", readonly=True,
|
||||
compute="_compute_sales_dates",
|
||||
readonly=True,
|
||||
help="This information appears on invoice qweb report "
|
||||
"(you may use it for your own report)")
|
||||
"(you may use it for your own report)",
|
||||
)
|
||||
|
||||
def _compute_has_discount(self):
|
||||
prec = self.env['decimal.precision'].precision_get('Discount')
|
||||
prec = self.env["decimal.precision"].precision_get("Discount")
|
||||
for inv in self:
|
||||
has_discount = False
|
||||
for line in inv.invoice_line_ids:
|
||||
if not line.display_type and not float_is_zero(line.discount, precision_digits=prec):
|
||||
if not line.display_type and 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']
|
||||
iao = self.env["ir.attachment"]
|
||||
for move in self:
|
||||
if iao.search_count([
|
||||
('res_model', '=', 'account.move'),
|
||||
('res_id', '=', move.id),
|
||||
('type', '=', 'binary'),
|
||||
('company_id', '=', move.company_id.id)]):
|
||||
if iao.search_count(
|
||||
[
|
||||
("res_model", "=", "account.move"),
|
||||
("res_id", "=", move.id),
|
||||
("type", "=", "binary"),
|
||||
("company_id", "=", move.company_id.id),
|
||||
]
|
||||
):
|
||||
move.has_attachment = True
|
||||
else:
|
||||
move.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.move'),
|
||||
('type', '=', 'binary'),
|
||||
('res_id', '!=', False)], ['res_id'])
|
||||
if operator == "=":
|
||||
search_res = self.env["ir.attachment"].search_read(
|
||||
[
|
||||
("res_model", "=", "account.move"),
|
||||
("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', list(att_inv_ids))]
|
||||
att_inv_ids[att["res_id"]] = True
|
||||
res = [("id", value and "in" or "not in", list(att_inv_ids))]
|
||||
return res
|
||||
|
||||
# when you have an invoice created from a lot of sale orders, the 'name'
|
||||
@@ -81,10 +93,10 @@ class AccountMove(models.Model):
|
||||
name = old_re[1]
|
||||
if name and len(name) > 100:
|
||||
# nice cut
|
||||
name = '%s ...' % ', '.join(name.split(', ')[:3])
|
||||
name = "%s ..." % ", ".join(name.split(", ")[:3])
|
||||
# if not enough, hard cut
|
||||
if len(name) > 120:
|
||||
name = '%s ...' % old_re[1][:120]
|
||||
name = "%s ..." % old_re[1][:120]
|
||||
res.append((old_re[0], name))
|
||||
return res
|
||||
|
||||
@@ -94,23 +106,26 @@ class AccountMove(models.Model):
|
||||
# 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 !
|
||||
# TODO mig to v12
|
||||
# def action_move_create(self):
|
||||
# res = super().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
|
||||
# TODO mig to v12
|
||||
# def action_move_create(self):
|
||||
# res = super().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.move.line'].search([
|
||||
('display_type', '=', False),
|
||||
('move_id', 'in', self.ids),
|
||||
('quantity', '=', 0)])
|
||||
lines = self.env["account.move.line"].search(
|
||||
[
|
||||
("display_type", "=", False),
|
||||
("move_id", "in", self.ids),
|
||||
("quantity", "=", 0),
|
||||
]
|
||||
)
|
||||
lines.unlink()
|
||||
return True
|
||||
|
||||
@@ -120,24 +135,27 @@ class AccountMove(models.Model):
|
||||
res = []
|
||||
has_sections = False
|
||||
subtotal = 0.0
|
||||
sign = self.move_type == 'out_refund' and -1 or 1
|
||||
sign = self.move_type == "out_refund" and -1 or 1
|
||||
# Warning: the order of invoice line is forced in the view
|
||||
# <tree editable="bottom" default_order="sequence, date desc, move_name desc, id"
|
||||
# it's not the same as the _order in the class AccountMoveLine
|
||||
lines = self.env['account.move.line'].search([('exclude_from_invoice_tab', '=', False), ('move_id', '=', self.id)], order="sequence, date desc, move_name desc, id")
|
||||
lines = self.env["account.move.line"].search(
|
||||
[("exclude_from_invoice_tab", "=", False), ("move_id", "=", self.id)],
|
||||
order="sequence, date desc, move_name desc, id",
|
||||
)
|
||||
for line in lines:
|
||||
if line.display_type == 'line_section':
|
||||
if line.display_type == "line_section":
|
||||
# insert line
|
||||
if has_sections:
|
||||
res.append({'subtotal': subtotal})
|
||||
res.append({"subtotal": subtotal})
|
||||
subtotal = 0.0 # reset counter
|
||||
has_sections = True
|
||||
else:
|
||||
if not line.display_type:
|
||||
subtotal += line.price_subtotal * sign
|
||||
res.append({'line': line})
|
||||
res.append({"line": line})
|
||||
if has_sections: # insert last subtotal line
|
||||
res.append({'subtotal': subtotal})
|
||||
res.append({"subtotal": subtotal})
|
||||
# res:
|
||||
# [
|
||||
# {'line': account_invoice_line(1) with display_type=='line_section'},
|
||||
@@ -149,44 +167,55 @@ class AccountMove(models.Model):
|
||||
return res
|
||||
|
||||
def _compute_sales_dates(self):
|
||||
""" French law requires to set sale order dates into invoice
|
||||
returned string: "sale1 (date1), sale2 (date2) ..."
|
||||
"""French law requires to set sale order dates into invoice
|
||||
returned string: "sale1 (date1), sale2 (date2) ..."
|
||||
"""
|
||||
for inv in self:
|
||||
sales = inv.invoice_line_ids.mapped(
|
||||
'sale_line_ids').mapped('order_id')
|
||||
dates = ["%s (%s)" % (
|
||||
x.name, format_date(inv.env, self.date_order))
|
||||
for x in sales]
|
||||
sales = inv.invoice_line_ids.mapped("sale_line_ids").mapped("order_id")
|
||||
dates = [
|
||||
"%s (%s)" % (x.name, format_date(inv.env, self.date_order))
|
||||
for x in sales
|
||||
]
|
||||
inv.sale_dates = ", ".join(dates)
|
||||
|
||||
# allow to manually create moves not only in general journals,
|
||||
# but also in cash journal and check journals (= bank journals not linked to a bank account)
|
||||
@api.depends('company_id', 'invoice_filter_type_domain')
|
||||
@api.depends("company_id", "invoice_filter_type_domain")
|
||||
def _compute_suitable_journal_ids(self):
|
||||
for move in self:
|
||||
if move.invoice_filter_type_domain:
|
||||
super(AccountMove, move)._compute_suitable_journal_ids()
|
||||
else:
|
||||
company_id = move.company_id.id or self.env.company.id
|
||||
domain = expression.AND([
|
||||
[('company_id', '=', company_id)],
|
||||
expression.OR([
|
||||
[('type', 'in', ('general', 'cash'))],
|
||||
[('type', '=', 'bank'), ('bank_account_id', '=', False)]
|
||||
])
|
||||
])
|
||||
move.suitable_journal_ids = self.env['account.journal'].search(domain)
|
||||
domain = expression.AND(
|
||||
[
|
||||
[("company_id", "=", company_id)],
|
||||
expression.OR(
|
||||
[
|
||||
[("type", "in", ("general", "cash"))],
|
||||
[
|
||||
("type", "=", "bank"),
|
||||
("bank_account_id", "=", False),
|
||||
],
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
move.suitable_journal_ids = self.env["account.journal"].search(domain)
|
||||
|
||||
def button_draft(self):
|
||||
super().button_draft()
|
||||
# Delete attached pdf invoice
|
||||
try:
|
||||
report_invoice = self.env['ir.actions.report']._get_report_from_name('account.report_invoice')
|
||||
report_invoice = self.env["ir.actions.report"]._get_report_from_name(
|
||||
"account.report_invoice"
|
||||
)
|
||||
except IndexError:
|
||||
report_invoice = False
|
||||
if report_invoice and report_invoice.attachment:
|
||||
for move in self.filtered(lambda x: x.move_type in ('out_invoice', 'out_refund')):
|
||||
for move in self.filtered(
|
||||
lambda x: x.move_type in ("out_invoice", "out_refund")
|
||||
):
|
||||
# The pb is that the filename is dynamic and related to move.state
|
||||
# in v12, the feature was native and they used that kind of code:
|
||||
# with invoice.env.do_in_draft():
|
||||
@@ -194,22 +223,25 @@ class AccountMove(models.Model):
|
||||
# attachment = self.env.ref('account.account_invoices').retrieve_attachment(invoice)
|
||||
# But do_in_draft() doesn't exists in v14
|
||||
# If you know how we could do that, please update the code below
|
||||
attachment = self.env['ir.attachment'].search([
|
||||
('name', '=', self._get_invoice_attachment_name()),
|
||||
('res_id', '=', move.id),
|
||||
('res_model', '=', self._name),
|
||||
('type', '=', 'binary'),
|
||||
], limit=1)
|
||||
attachment = self.env["ir.attachment"].search(
|
||||
[
|
||||
("name", "=", self._get_invoice_attachment_name()),
|
||||
("res_id", "=", move.id),
|
||||
("res_model", "=", self._name),
|
||||
("type", "=", "binary"),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
if attachment:
|
||||
attachment.unlink()
|
||||
|
||||
def _get_invoice_attachment_name(self):
|
||||
self.ensure_one()
|
||||
return '%s.pdf' % (self.name and self.name.replace('/', '_') or 'INV')
|
||||
return "%s.pdf" % (self.name and self.name.replace("/", "_") or "INV")
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = 'account.move.line'
|
||||
_inherit = "account.move.line"
|
||||
# Native order:
|
||||
# _order = "date desc, move_name desc, id"
|
||||
# Problem: when you manually create a journal entry, the
|
||||
@@ -220,34 +252,42 @@ class AccountMoveLine(models.Model):
|
||||
# In the 'account' module, we have related stored field for:
|
||||
# name (move_name), date, ref, state (parent_state),
|
||||
# journal_id, company_id, payment_id, statement_line_id,
|
||||
account_reconcile = fields.Boolean(related='account_id.reconcile')
|
||||
full_reconcile_id = fields.Many2one(string='Full Reconcile')
|
||||
matched_debit_ids = fields.One2many(string='Partial Reconcile Debit')
|
||||
matched_credit_ids = fields.One2many(string='Partial Reconcile Credit')
|
||||
account_reconcile = fields.Boolean(related="account_id.reconcile")
|
||||
full_reconcile_id = fields.Many2one(string="Full Reconcile")
|
||||
matched_debit_ids = fields.One2many(string="Partial Reconcile Debit")
|
||||
matched_credit_ids = fields.One2many(string="Partial Reconcile Credit")
|
||||
reconcile_string = fields.Char(
|
||||
compute='_compute_reconcile_string', string='Reconcile', store=True)
|
||||
compute="_compute_reconcile_string", string="Reconcile", store=True
|
||||
)
|
||||
# for optional display in tree view
|
||||
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||
product_barcode = fields.Char(
|
||||
related="product_id.barcode", string="Product Barcode"
|
||||
)
|
||||
|
||||
def show_account_move_form(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('account.action_move_line_form').read()[0]
|
||||
action.update({
|
||||
'res_id': self.move_id.id,
|
||||
'view_id': False,
|
||||
'views': False,
|
||||
'view_mode': 'form,tree',
|
||||
})
|
||||
action = self.env.ref("account.action_move_line_form").read()[0]
|
||||
action.update(
|
||||
{
|
||||
"res_id": self.move_id.id,
|
||||
"view_id": False,
|
||||
"views": False,
|
||||
"view_mode": "form,tree",
|
||||
}
|
||||
)
|
||||
return action
|
||||
|
||||
@api.depends(
|
||||
'full_reconcile_id', 'matched_debit_ids', 'matched_credit_ids')
|
||||
@api.depends("full_reconcile_id", "matched_debit_ids", "matched_credit_ids")
|
||||
def _compute_reconcile_string(self):
|
||||
for line in self:
|
||||
rec_str = False
|
||||
if line.full_reconcile_id:
|
||||
rec_str = line.full_reconcile_id.name
|
||||
else:
|
||||
rec_str = ', '.join([
|
||||
'a%d' % pr.id for pr in line.matched_debit_ids + line.matched_credit_ids])
|
||||
rec_str = ", ".join(
|
||||
[
|
||||
"a%d" % pr.id
|
||||
for pr in line.matched_debit_ids + line.matched_credit_ids
|
||||
]
|
||||
)
|
||||
line.reconcile_string = rec_str
|
||||
|
||||
@@ -17,7 +17,8 @@ class AccountPartialReconcile(models.Model):
|
||||
# Prefix for full rec: 'A' (upper case)
|
||||
# Prefix for partial rec: 'a' (lower case)
|
||||
amount_fmt = formatLang(
|
||||
self.env, rec.amount, currency_obj=rec.company_currency_id)
|
||||
name = 'a%d (%s)' % (rec.id, amount_fmt)
|
||||
self.env, rec.amount, currency_obj=rec.company_currency_id
|
||||
)
|
||||
name = "a%d (%s)" % (rec.id, amount_fmt)
|
||||
res.append((rec.id, name))
|
||||
return res
|
||||
|
||||
@@ -2,44 +2,61 @@
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo import _, api, fields, models
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
_inherit = "product.template"
|
||||
|
||||
# DON'T put store=True on those fields, because they are company dependent
|
||||
sale_price_type = fields.Selection(
|
||||
'_sale_purchase_price_type_sel', compute='_compute_sale_price_type',
|
||||
string='Sale Price Type', compute_sudo=False, readonly=True)
|
||||
"_sale_purchase_price_type_sel",
|
||||
compute="_compute_sale_price_type",
|
||||
string="Sale Price Type",
|
||||
compute_sudo=False,
|
||||
readonly=True,
|
||||
)
|
||||
purchase_price_type = fields.Selection(
|
||||
'_sale_purchase_price_type_sel', compute='_compute_purchase_price_type',
|
||||
string='Purchase Price Type', compute_sudo=False, readonly=True)
|
||||
"_sale_purchase_price_type_sel",
|
||||
compute="_compute_purchase_price_type",
|
||||
string="Purchase Price Type",
|
||||
compute_sudo=False,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _sale_purchase_price_type_sel(self):
|
||||
return [('incl', _('Tax incl.')), ('excl', _('Tax excl.'))]
|
||||
return [("incl", _("Tax incl.")), ("excl", _("Tax excl."))]
|
||||
|
||||
@api.depends('taxes_id')
|
||||
@api.depends("taxes_id")
|
||||
def _compute_sale_price_type(self):
|
||||
for pt in self:
|
||||
sale_price_type = 'incl'
|
||||
if pt.taxes_id and all([not t.price_include for t in pt.taxes_id if t.amount_type == 'percent']):
|
||||
sale_price_type = 'excl'
|
||||
sale_price_type = "incl"
|
||||
if pt.taxes_id and all(
|
||||
[not t.price_include for t in pt.taxes_id if t.amount_type == "percent"]
|
||||
):
|
||||
sale_price_type = "excl"
|
||||
pt.sale_price_type = sale_price_type
|
||||
|
||||
@api.depends('supplier_taxes_id')
|
||||
@api.depends("supplier_taxes_id")
|
||||
def _compute_purchase_price_type(self):
|
||||
for pt in self:
|
||||
purchase_price_type = 'incl'
|
||||
if pt.supplier_taxes_id and all([not t.price_include for t in pt.supplier_taxes_id if t.amount_type == 'percent']):
|
||||
purchase_price_type = 'excl'
|
||||
purchase_price_type = "incl"
|
||||
if pt.supplier_taxes_id and all(
|
||||
[
|
||||
not t.price_include
|
||||
for t in pt.supplier_taxes_id
|
||||
if t.amount_type == "percent"
|
||||
]
|
||||
):
|
||||
purchase_price_type = "excl"
|
||||
pt.purchase_price_type = purchase_price_type
|
||||
|
||||
|
||||
class ProductSupplierinfo(models.Model):
|
||||
_inherit = 'product.supplierinfo'
|
||||
_inherit = "product.supplierinfo"
|
||||
|
||||
# DON'T put store=True on those fields, because they are company dependent
|
||||
purchase_price_type = fields.Selection(
|
||||
related='product_tmpl_id.purchase_price_type', related_sudo=False)
|
||||
related="product_tmpl_id.purchase_price_type", related_sudo=False
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
_inherit = "res.partner"
|
||||
|
||||
invoice_warn = fields.Selection(tracking=True)
|
||||
property_account_position_id = fields.Many2one(tracking=True)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
This modules adds the following functions:
|
||||
|
||||
* Add an *Overdue* filter on invoice search view (this feature was previously
|
||||
* 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.
|
||||
* disable reconciliation "guessing"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<template id="report_invoice_document" inherit_id="account.report_invoice_document">
|
||||
<xpath expr="//div[@name='origin']/p" position="replace">
|
||||
<p class="m-0" t-field="o.sale_dates"/>
|
||||
<p class="m-0" t-field="o.sale_dates" />
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,35 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2021 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
|
||||
<record id="view_account_form" model="ir.ui.view">
|
||||
<field name="name">account.account.form</field>
|
||||
<field name="model">account.account</field>
|
||||
<field name="inherit_id" ref="account.view_account_form"/>
|
||||
<field name="inherit_id" ref="account.view_account_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="deprecated" position="before">
|
||||
<field name="reconcile" attrs="{'invisible': ['|', ('internal_type','=','liquidity'), ('internal_group', '=', 'off_balance')]}"/>
|
||||
<field
|
||||
name="reconcile"
|
||||
attrs="{'invisible': ['|', ('internal_type','=','liquidity'), ('internal_group', '=', 'off_balance')]}"
|
||||
/>
|
||||
</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="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
|
||||
name="code"
|
||||
filter_domain="[('code', '=like', str(self)+'%')]"
|
||||
string="Code"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_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="arch" type="xml">
|
||||
<field name="type" position="after">
|
||||
<field name="include_initial_balance" optional="show"/>
|
||||
<field name="include_initial_balance" optional="show" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,45 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
|
||||
<record id="view_bank_statement_form" model="ir.ui.view">
|
||||
<field name="name">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="inherit_id" ref="account.view_bank_statement_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='line_ids']/tree/button[@name='button_undo_reconciliation']" position="after">
|
||||
<field name="move_id" invisible="1"/>
|
||||
<button name="show_account_move" type="object"
|
||||
title="View Journal Entry" icon="fa-arrow-right"/>
|
||||
<xpath
|
||||
expr="//field[@name='line_ids']/tree/button[@name='button_undo_reconciliation']"
|
||||
position="after"
|
||||
>
|
||||
<field name="move_id" invisible="1" />
|
||||
<button
|
||||
name="show_account_move"
|
||||
type="object"
|
||||
title="View Journal Entry"
|
||||
icon="fa-arrow-right"
|
||||
/>
|
||||
</xpath>
|
||||
<field name="date" position="after">
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="hide_bank_statement_balance" invisible="1"/>
|
||||
<field name="start_date" />
|
||||
<field name="end_date" />
|
||||
<field name="hide_bank_statement_balance" invisible="1" />
|
||||
</field>
|
||||
<field name="date" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</field>
|
||||
<label for="balance_start" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
</label>
|
||||
<label for="balance_end_real" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
</label>
|
||||
<xpath expr="//field[@name='balance_start']/.." position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='balance_end_real']/.." position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
</xpath>
|
||||
<group name="sale_total" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('hide_bank_statement_balance', '=', True)]}</attribute>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
@@ -47,14 +63,14 @@
|
||||
<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="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 name="start_date" />
|
||||
<field name="end_date" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -62,7 +78,7 @@
|
||||
<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="inherit_id" ref="account.view_bank_statement_search" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="date" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
@@ -74,14 +90,20 @@
|
||||
<attribute name="invisible">1</attribute>
|
||||
</filter>
|
||||
<field name="date" position="after">
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="start_date" />
|
||||
<field name="end_date" />
|
||||
</field>
|
||||
<filter name="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
|
||||
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>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2018-2020 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>
|
||||
|
||||
|
||||
@@ -13,36 +12,43 @@
|
||||
<field name="model">account.invoice.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Invoices Analysis">
|
||||
<field name="move_id"/>
|
||||
<field name="invoice_date"/>
|
||||
<field name="invoice_date_due"/>
|
||||
<field name="move_type"/>
|
||||
<field name="commercial_partner_id"/>
|
||||
<field name="invoice_user_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="quantity" sum="1"/>
|
||||
<field name="product_uom_id" groups="uom.group_uom"/>
|
||||
<field name="price_subtotal" sum="1"/>
|
||||
<field name="state"/>
|
||||
<field name="move_id" />
|
||||
<field name="invoice_date" />
|
||||
<field name="invoice_date_due" />
|
||||
<field name="move_type" />
|
||||
<field name="commercial_partner_id" />
|
||||
<field name="invoice_user_id" />
|
||||
<field name="product_id" />
|
||||
<field name="quantity" sum="1" />
|
||||
<field name="product_uom_id" groups="uom.group_uom" />
|
||||
<field name="price_subtotal" sum="1" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="account.action_account_invoice_report_all_supp" model="ir.actions.act_window">
|
||||
<field name="context">{'search_default_current': 1, 'search_default_supplier': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
|
||||
<record
|
||||
id="account.action_account_invoice_report_all_supp"
|
||||
model="ir.actions.act_window"
|
||||
>
|
||||
<field
|
||||
name="context"
|
||||
>{'search_default_current': 1, 'search_default_supplier': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
|
||||
</record>
|
||||
|
||||
<record id="account.action_account_invoice_report_all" model="ir.actions.act_window">
|
||||
<field name="context">{'search_default_current': 1, 'search_default_customer': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
|
||||
<field
|
||||
name="context"
|
||||
>{'search_default_current': 1, 'search_default_customer': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
|
||||
</record>
|
||||
|
||||
<record id="view_account_invoice_report_pivot" model="ir.ui.view">
|
||||
<field name="name">usability.account.invoice.report</field>
|
||||
<field name="model">account.invoice.report</field>
|
||||
<field name="inherit_id" ref="account.view_account_invoice_report_pivot"/>
|
||||
<field name="inherit_id" ref="account.view_account_invoice_report_pivot" />
|
||||
<field name="arch" type="xml">
|
||||
<pivot position="attributes">
|
||||
<attribute name="disable_linking"></attribute>
|
||||
<attribute name="disable_linking" />
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_account_journal_form" model="ir.ui.view">
|
||||
<field name="name">usability.account.journal.form</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.view_account_journal_form"/>
|
||||
<field name="inherit_id" ref="account.view_account_journal_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="bank_statements_source" position="after">
|
||||
<field name="hide_bank_statement_balance" groups="account.group_account_readonly"/>
|
||||
<field
|
||||
name="hide_bank_statement_balance"
|
||||
groups="account.group_account_readonly"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -21,13 +23,15 @@
|
||||
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
|
||||
<field name="name">usability.account.journal.dashboard</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="kanban_dashboard" position="after">
|
||||
<field name="hide_bank_statement_balance"/>
|
||||
<field name="hide_bank_statement_balance" />
|
||||
</field>
|
||||
<xpath expr="//div[@name='latest_statement']/.." position="attributes">
|
||||
<attribute name="t-if">dashboard.has_at_least_one_statement and dashboard.account_balance != dashboard.last_balance and !record.hide_bank_statement_balance.raw_value</attribute>
|
||||
<attribute
|
||||
name="t-if"
|
||||
>dashboard.has_at_least_one_statement and dashboard.account_balance != dashboard.last_balance and !record.hide_bank_statement_balance.raw_value</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -35,10 +39,10 @@
|
||||
<record id="view_account_journal_tree" model="ir.ui.view">
|
||||
<field name="name">usability.account.journal.tree</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.view_account_journal_tree"/>
|
||||
<field name="inherit_id" ref="account.view_account_journal_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="code" optional="show"/>
|
||||
<field name="code" optional="show" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -46,11 +50,15 @@
|
||||
<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">
|
||||
<field name="inherit_id" ref="account.view_account_journal_search" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="inactive" position="after">
|
||||
<group name="groupby" string="Group By">
|
||||
<filter name="type_groupby" string="Type" context="{'group_by': 'type'}"/>
|
||||
<filter
|
||||
name="type_groupby"
|
||||
string="Type"
|
||||
context="{'group_by': 'type'}"
|
||||
/>
|
||||
</group>
|
||||
</filter>
|
||||
</field>
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<!-- Duplicate the menu "Sales > Configuration > Contacts > Bank Accounts"
|
||||
under "Accounting > Configuration", because most users will try to find it there -->
|
||||
<menuitem id="res_bank_account_config_menu" action="base.action_res_bank_form" parent="account.account_banks_menu" sequence="10"/>
|
||||
<menuitem
|
||||
id="res_bank_account_config_menu"
|
||||
action="base.action_res_bank_form"
|
||||
parent="account.account_banks_menu"
|
||||
sequence="10"
|
||||
/>
|
||||
|
||||
<menuitem id="res_partner_bank_account_config_menu" action="base.action_res_partner_bank_account_form" parent="account.account_banks_menu" sequence="20"/>
|
||||
<menuitem
|
||||
id="res_partner_bank_account_config_menu"
|
||||
action="base.action_res_partner_bank_account_form"
|
||||
parent="account.account_banks_menu"
|
||||
sequence="20"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_move_form" model="ir.ui.view">
|
||||
<field name="name">account_usability.account.move.form</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="inherit_id" ref="account.view_move_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="fiscal_position_id" position="attributes">
|
||||
<attribute name="widget">selection</attribute>
|
||||
@@ -22,28 +21,45 @@
|
||||
<attribute name="class">btn-default</attribute>
|
||||
</button>
|
||||
<button name="action_register_payment" position="before">
|
||||
<button name="%(account.account_invoices)d" type="action" string="Print" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
|
||||
<button
|
||||
name="%(account.account_invoices)d"
|
||||
type="action"
|
||||
string="Print"
|
||||
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"
|
||||
/>
|
||||
</button>
|
||||
<button name="preview_invoice" position="attributes">
|
||||
<attribute name="attrs">{'invisible': 1}</attribute>
|
||||
</button>
|
||||
<!-- move sent field and make it visible -->
|
||||
<field name="is_move_sent" position="replace"/>
|
||||
<field name="is_move_sent" position="replace" />
|
||||
<field name="invoice_origin" position="attributes">
|
||||
<attribute name="invisible">0</attribute>
|
||||
</field>
|
||||
<field name="invoice_origin" position="after">
|
||||
<field name="is_move_sent" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
|
||||
<field
|
||||
name="is_move_sent"
|
||||
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"
|
||||
/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='analytic_account_id']" position="attributes">
|
||||
<xpath
|
||||
expr="//field[@name='line_ids']/tree/field[@name='analytic_account_id']"
|
||||
position="attributes"
|
||||
>
|
||||
<attribute name="optional">show</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='tax_tag_ids']" position="after">
|
||||
<field name="matching_number" optional="hide"/>
|
||||
<field name="reconcile_string" optional="show"/>
|
||||
<xpath
|
||||
expr="//field[@name='line_ids']/tree/field[@name='tax_tag_ids']"
|
||||
position="after"
|
||||
>
|
||||
<field name="matching_number" optional="hide" />
|
||||
<field name="reconcile_string" optional="show" />
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='product_id']" position="after">
|
||||
<field name="product_barcode" optional="hide"/>
|
||||
<xpath
|
||||
expr="//field[@name='invoice_line_ids']/tree/field[@name='product_id']"
|
||||
position="after"
|
||||
>
|
||||
<field name="product_barcode" optional="hide" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -51,24 +67,41 @@
|
||||
<record id="view_account_invoice_filter" model="ir.ui.view">
|
||||
<field name="name">account_usability.account.move.search</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
|
||||
<field name="inherit_id" ref="account.view_account_invoice_filter" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="due_date" position="after">
|
||||
<separator/>
|
||||
<filter name="to_send" string="To Send" domain="[('is_move_sent', '=', False), ('state', '=', 'posted'), ('move_type', 'in', ('out_invoice', 'out_refund'))]"/>
|
||||
<filter name="sent" string="Sent" domain="[('is_move_sent', '=', True), ('move_type', 'in', ('out_invoice', 'out_refund'))]"/>
|
||||
<separator/>
|
||||
<filter name="no_attachment" string="Missing Attachment" domain="[('has_attachment', '=', False)]"/>
|
||||
<separator />
|
||||
<filter
|
||||
name="to_send"
|
||||
string="To Send"
|
||||
domain="[('is_move_sent', '=', False), ('state', '=', 'posted'), ('move_type', 'in', ('out_invoice', 'out_refund'))]"
|
||||
/>
|
||||
<filter
|
||||
name="sent"
|
||||
string="Sent"
|
||||
domain="[('is_move_sent', '=', True), ('move_type', 'in', ('out_invoice', 'out_refund'))]"
|
||||
/>
|
||||
<separator />
|
||||
<filter
|
||||
name="no_attachment"
|
||||
string="Missing Attachment"
|
||||
domain="[('has_attachment', '=', False)]"
|
||||
/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_move_line_tree" model="ir.ui.view">
|
||||
<field name="model">account.move.line</field>
|
||||
<field name="inherit_id" ref="account.view_move_line_tree"/>
|
||||
<field name="inherit_id" ref="account.view_move_line_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="matching_number" position="after">
|
||||
<button title="View Journal Entry Form" type="object" name="show_account_move_form" icon="fa-arrow-right"/>
|
||||
<button
|
||||
title="View Journal Entry Form"
|
||||
type="object"
|
||||
name="show_account_move_form"
|
||||
icon="fa-arrow-right"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -76,19 +109,35 @@
|
||||
<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="inherit_id" ref="account.view_account_move_line_filter" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="unposted" position="before">
|
||||
<filter name="current_year" string="Current Year" domain="[('date', '>=', (context_today().strftime('%Y-01-01'))), ('date', '<=', (context_today().strftime('%Y-12-31')))]"/>
|
||||
<filter name="previous_year" string="Previous Year" domain="[('date', '>=', (context_today() + relativedelta(day=1, month=1, years=-1)).strftime('%Y-%m-%d')), ('date', '<=', (context_today() + relativedelta(day=31, month=12, years=-1)).strftime('%Y-%m-%d'))]"/>
|
||||
<separator/>
|
||||
<filter
|
||||
name="current_year"
|
||||
string="Current Year"
|
||||
domain="[('date', '>=', (context_today().strftime('%Y-01-01'))), ('date', '<=', (context_today().strftime('%Y-12-31')))]"
|
||||
/>
|
||||
<filter
|
||||
name="previous_year"
|
||||
string="Previous Year"
|
||||
domain="[('date', '>=', (context_today() + relativedelta(day=1, month=1, years=-1)).strftime('%Y-%m-%d')), ('date', '<=', (context_today() + relativedelta(day=31, month=12, years=-1)).strftime('%Y-%m-%d'))]"
|
||||
/>
|
||||
<separator />
|
||||
</filter>
|
||||
<field name="partner_id" position="after">
|
||||
<field name="reconcile_string" />
|
||||
<field name="debit" filter_domain="['|', ('debit', '=', self), ('credit', '=', self)]" string="Debit or Credit"/>
|
||||
<field
|
||||
name="debit"
|
||||
filter_domain="['|', ('debit', '=', self), ('credit', '=', self)]"
|
||||
string="Debit or Credit"
|
||||
/>
|
||||
</field>
|
||||
<filter name="unreconciled" position="before">
|
||||
<filter name="reconciled" string="Fully Reconciled" domain="[('full_reconcile_id', '!=', False)]"/>
|
||||
<filter
|
||||
name="reconciled"
|
||||
string="Fully Reconciled"
|
||||
domain="[('full_reconcile_id', '!=', False)]"
|
||||
/>
|
||||
</filter>
|
||||
<filter name="unreconciled" position="attributes">
|
||||
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
|
||||
@@ -98,13 +147,17 @@
|
||||
<attribute name="string">Name or Reference</attribute>
|
||||
</field> -->
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="domain">['|', ('parent_id', '=', False), ('is_company', '=', True)]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>['|', ('parent_id', '=', False), ('is_company', '=', True)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="account.action_move_journal_line" model="ir.actions.act_window">
|
||||
<field name="context">{'default_move_type': 'entry', 'view_no_maturity': True}</field>
|
||||
<field
|
||||
name="context"
|
||||
>{'default_move_type': 'entry', 'view_no_maturity': True}</field>
|
||||
<!-- Remove 'search_default_misc_filter': 1 -->
|
||||
</record>
|
||||
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2018-2020 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">
|
||||
<!-- Attach only on customer invoices/refunds -->
|
||||
<field name="attachment">(object.move_type in ('out_invoice', 'out_refund')) and (object.state == 'posted') and ((object.name or 'INV').replace('/','_')+'.pdf')</field>
|
||||
<field
|
||||
name="attachment"
|
||||
>(object.move_type in ('out_invoice', 'out_refund')) and (object.state == 'posted') and ((object.name or 'INV').replace('/','_')+'.pdf')</field>
|
||||
</record>
|
||||
|
||||
<record id="account.account_invoices_without_payment" model="ir.actions.report">
|
||||
<!-- Attach only on customer invoices/refunds -->
|
||||
<field name="attachment">(object.move_type in ('out_invoice', 'out_refund')) and (object.state == 'posted') and ((object.name or 'INV').replace('/','_')+'.pdf')</field>
|
||||
<field
|
||||
name="attachment"
|
||||
>(object.move_type in ('out_invoice', 'out_refund')) and (object.state == 'posted') and ((object.name or 'INV').replace('/','_')+'.pdf')</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_tax_tree" model="ir.ui.view">
|
||||
<field name="model">account.tax</field>
|
||||
<field name="inherit_id" ref="account.view_tax_tree"/>
|
||||
<field name="inherit_id" ref="account.view_tax_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="description" position="after">
|
||||
<field name="price_include" optional="show"/>
|
||||
<field name="price_include" optional="show" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2017-2020 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>
|
||||
|
||||
<!-- In the official account module, on product category and product template,
|
||||
@@ -16,8 +15,10 @@ Here, we set all those fields on account.group_account_invoice
|
||||
<record id="product_template_form_view" model="ir.ui.view">
|
||||
<field name="name">account_usability.product.template.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="priority">100</field> <!-- when you replace a field, it's always better to inherit at the end -->
|
||||
<field name="inherit_id" ref="account.product_template_form_view"/>
|
||||
<field
|
||||
name="priority"
|
||||
>100</field> <!-- when you replace a field, it's always better to inherit at the end -->
|
||||
<field name="inherit_id" ref="account.product_template_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="property_account_income_id" position="attributes">
|
||||
<attribute name="groups">account.group_account_invoice</attribute>
|
||||
@@ -27,9 +28,14 @@ Here, we set all those fields on account.group_account_invoice
|
||||
</field>
|
||||
<field name="list_price" position="replace">
|
||||
<div name="list_price">
|
||||
<field name="list_price" widget='monetary' options="{'currency_field': 'currency_id', 'field_digits': True}" class="oe_inline"/>
|
||||
<label for="sale_price_type" string=" "/>
|
||||
<field name="sale_price_type"/>
|
||||
<field
|
||||
name="list_price"
|
||||
widget='monetary'
|
||||
options="{'currency_field': 'currency_id', 'field_digits': True}"
|
||||
class="oe_inline"
|
||||
/>
|
||||
<label for="sale_price_type" string=" " />
|
||||
<field name="sale_price_type" />
|
||||
</div>
|
||||
</field>
|
||||
</field>
|
||||
@@ -38,7 +44,7 @@ Here, we set all those fields on account.group_account_invoice
|
||||
<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="inherit_id" ref="account.view_category_property_form" />
|
||||
<field name="arch" type="xml">
|
||||
<group name="account_property" position="attributes">
|
||||
<attribute name="groups">account.group_account_invoice</attribute>
|
||||
@@ -49,10 +55,10 @@ Here, we set all those fields on account.group_account_invoice
|
||||
<record id="product_supplierinfo_form_view" model="ir.ui.view">
|
||||
<field name="name">account_usability.product.supplierinfo.form</field>
|
||||
<field name="model">product.supplierinfo</field>
|
||||
<field name="inherit_id" ref="product.product_supplierinfo_form_view"/>
|
||||
<field name="inherit_id" ref="product.product_supplierinfo_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="purchase_price_type"/>
|
||||
<field name="purchase_price_type" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -60,10 +66,10 @@ Here, we set all those fields on account.group_account_invoice
|
||||
<record id="product_supplierinfo_tree_view" model="ir.ui.view">
|
||||
<field name="name">account_usability.product.supplierinfo.tree</field>
|
||||
<field name="model">product.supplierinfo</field>
|
||||
<field name="inherit_id" ref="product.product_supplierinfo_tree_view"/>
|
||||
<field name="inherit_id" ref="product.product_supplierinfo_tree_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="price" position="after">
|
||||
<field name="purchase_price_type" string="Tax"/>
|
||||
<field name="purchase_price_type" string="Tax" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2015-2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">account_usability account config page</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='bank_cash']" position="inside">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" id="transfer_account">
|
||||
<div class="o_setting_left_pane"/>
|
||||
<div class="o_setting_left_pane" />
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="transfer_account_id"/>
|
||||
<label for="transfer_account_id" />
|
||||
<div class="text-muted">
|
||||
Transit account when you transfer money from a bank account of your company to another bank account of your company.
|
||||
</div>
|
||||
<field name="transfer_account_id"/>
|
||||
<field name="transfer_account_id" />
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2017-2020 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="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>
|
||||
<xpath expr="//field[@name='bank_ids']/tree/field[@name='acc_number']" position="after">
|
||||
<field name="acc_type"/>
|
||||
<xpath
|
||||
expr="//field[@name='bank_ids']/tree/field[@name='acc_number']"
|
||||
position="after"
|
||||
>
|
||||
<field name="acc_type" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -2,58 +2,66 @@
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, models, _
|
||||
from odoo import _, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountGroupGenerate(models.TransientModel):
|
||||
_name = 'account.group.generate'
|
||||
_description = 'Generate Account Groups'
|
||||
_name = "account.group.generate"
|
||||
_description = "Generate Account Groups"
|
||||
|
||||
name_prefix = fields.Char(string='Prefix', required=True, default='Comptes')
|
||||
name_prefix = fields.Char(string="Prefix", required=True, default="Comptes")
|
||||
level = fields.Integer(default=2, required=True)
|
||||
|
||||
def run(self):
|
||||
if self.level < 1:
|
||||
raise UserError(_("The level must be >= 1."))
|
||||
ago = self.env['account.group']
|
||||
aao = self.env['account.account']
|
||||
ago = self.env["account.group"]
|
||||
aao = self.env["account.account"]
|
||||
company = self.env.company
|
||||
groups = ago.search([('company_id', '=', company.id)])
|
||||
groups = ago.search([("company_id", "=", company.id)])
|
||||
if groups:
|
||||
raise UserError(_(
|
||||
"%d account groups already exists in company '%s'. This wizard is "
|
||||
"designed to generate account groups from scratch.")
|
||||
% (len(groups), company.display_name))
|
||||
accounts = aao.search([('company_id', '=', company.id)])
|
||||
struct = {'childs': {}}
|
||||
raise UserError(
|
||||
_(
|
||||
"%d account groups already exists in company '%s'. This wizard is "
|
||||
"designed to generate account groups from scratch."
|
||||
)
|
||||
% (len(groups), company.display_name)
|
||||
)
|
||||
accounts = aao.search([("company_id", "=", company.id)])
|
||||
struct = {"childs": {}}
|
||||
for account in accounts:
|
||||
if len(account.code) <= self.level:
|
||||
raise UserError(_(
|
||||
"The code of account '%s' is %d caracters. "
|
||||
"It cannot be inferior to level (%d).")
|
||||
% (account.display_name, len(account.code), self.level))
|
||||
raise UserError(
|
||||
_(
|
||||
"The code of account '%s' is %d caracters. "
|
||||
"It cannot be inferior to level (%d)."
|
||||
)
|
||||
% (account.display_name, len(account.code), self.level)
|
||||
)
|
||||
n = 1
|
||||
parent = struct
|
||||
gparent = False
|
||||
while n <= self.level:
|
||||
group_code = account.code[:n]
|
||||
if group_code not in parent['childs']:
|
||||
new_group = ago.create({
|
||||
'name': '%s %s' % (self.name_prefix or '', group_code),
|
||||
'code_prefix_start': group_code,
|
||||
'parent_id': gparent and gparent.id or False,
|
||||
'company_id': company.id,
|
||||
})
|
||||
parent['childs'][group_code] = {'obj': new_group, 'childs': {}}
|
||||
parent = parent['childs'][group_code]
|
||||
gparent = parent['obj']
|
||||
if group_code not in parent["childs"]:
|
||||
new_group = ago.create(
|
||||
{
|
||||
"name": "%s %s" % (self.name_prefix or "", group_code),
|
||||
"code_prefix_start": group_code,
|
||||
"parent_id": gparent and gparent.id or False,
|
||||
"company_id": company.id,
|
||||
}
|
||||
)
|
||||
parent["childs"][group_code] = {"obj": new_group, "childs": {}}
|
||||
parent = parent["childs"][group_code]
|
||||
gparent = parent["obj"]
|
||||
n += 1
|
||||
account.write({'group_id': gparent.id})
|
||||
account.write({"group_id": gparent.id})
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Account Groups'),
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'account.group',
|
||||
}
|
||||
"type": "ir.actions.act_window",
|
||||
"name": _("Account Groups"),
|
||||
"view_mode": "tree,form",
|
||||
"res_model": "account.group",
|
||||
}
|
||||
return action
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2020 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="account_group_generate_form" model="ir.ui.view">
|
||||
<field name="name">account.group.generate.form</field>
|
||||
<field name="model">account.group.generate</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="arch" type="xml">
|
||||
<form string="Generate account groups">
|
||||
<p>
|
||||
This wizard is designed to auto-generate account groups from the chart of account.
|
||||
</p>
|
||||
<group name="main">
|
||||
<field name="name_prefix"/>
|
||||
<field name="level"/>
|
||||
<field name="name_prefix" />
|
||||
<field name="level" />
|
||||
</group>
|
||||
<footer>
|
||||
<button type="object" name="run" string="Generate" class="btn-primary"/>
|
||||
<button special="cancel" string="Cancel"/>
|
||||
<button
|
||||
type="object"
|
||||
name="run"
|
||||
string="Generate"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<button special="cancel" string="Cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
@@ -34,9 +38,11 @@
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="account_group_generate_menu"
|
||||
<menuitem
|
||||
id="account_group_generate_menu"
|
||||
action="account_group_generate_action"
|
||||
parent="account.account_account_menu"
|
||||
sequence="51"/>
|
||||
sequence="51"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -2,23 +2,29 @@
|
||||
# @author: 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
|
||||
|
||||
from odoo import models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccountInvoiceMarkSent(models.TransientModel):
|
||||
_name = 'account.invoice.mark.sent'
|
||||
_description = 'Mark invoices as sent'
|
||||
_name = "account.invoice.mark.sent"
|
||||
_description = "Mark invoices as sent"
|
||||
|
||||
def run(self):
|
||||
assert self.env.context.get('active_model') == 'account.move',\
|
||||
'Source model must be invoices'
|
||||
assert self.env.context.get('active_ids'), 'No invoices selected'
|
||||
invoices = self.env['account.move'].search([
|
||||
('id', 'in', self.env.context.get('active_ids')),
|
||||
('move_type', 'in', ('out_invoice', 'out_refund')),
|
||||
('state', '=', 'posted')])
|
||||
invoices.write({'is_move_sent': True})
|
||||
logger.info('Marking invoices with ID %s as sent', invoices.ids)
|
||||
assert (
|
||||
self.env.context.get("active_model") == "account.move"
|
||||
), "Source model must be invoices"
|
||||
assert self.env.context.get("active_ids"), "No invoices selected"
|
||||
invoices = self.env["account.move"].search(
|
||||
[
|
||||
("id", "in", self.env.context.get("active_ids")),
|
||||
("move_type", "in", ("out_invoice", "out_refund")),
|
||||
("state", "=", "posted"),
|
||||
]
|
||||
)
|
||||
invoices.write({"is_move_sent": True})
|
||||
logger.info("Marking invoices with ID %s as sent", invoices.ids)
|
||||
return
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2017-2020 Akretion France
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="account_invoice_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">
|
||||
<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.
|
||||
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"/>
|
||||
<button
|
||||
type="object"
|
||||
name="run"
|
||||
string="Mark as Sent"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<button special="cancel" string="Cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class AccountMoveReversal(models.TransientModel):
|
||||
_inherit = 'account.move.reversal'
|
||||
_inherit = "account.move.reversal"
|
||||
|
||||
@api.model
|
||||
def _default_date(self):
|
||||
date_dt = 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'])
|
||||
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 = move.date + relativedelta(days=1)
|
||||
return date_dt
|
||||
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2021 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<!-- When you change the date, it resets the amount via the onchange
|
||||
So, in the view, the date should be BEFORE the amount -->
|
||||
<record id="view_account_payment_register_form" model="ir.ui.view">
|
||||
<field name="model">account.payment.register</field>
|
||||
<field name="inherit_id" ref="account.view_account_payment_register_form"/>
|
||||
<field name="inherit_id" ref="account.view_account_payment_register_form" />
|
||||
<field name="arch" type="xml">
|
||||
<label for="amount" position="before">
|
||||
<field name="payment_date" position="move"/>
|
||||
<field name="payment_date" position="move" />
|
||||
</label>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -6,7 +6,8 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
transfer_account_id = fields.Many2one(
|
||||
related='company_id.transfer_account_id', readonly=False)
|
||||
related="company_id.transfer_account_id", readonly=False
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user