[IMP] pre-commit: first run on whole repo

This commit is contained in:
Kevin Khao
2021-11-26 18:54:38 +03:00
parent a04b8980e1
commit 167aefee13
289 changed files with 6020 additions and 4170 deletions

View File

@@ -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

View File

@@ -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!",
)
]

View File

@@ -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

View File

@@ -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

View File

@@ -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')

View File

@@ -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

View File

@@ -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

View File

@@ -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
)

View File

@@ -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)