forked from Mapan/odoo17e
151 lines
6.8 KiB
Python
151 lines
6.8 KiB
Python
import uuid
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.tools.sql import column_exists, create_column
|
|
|
|
|
|
class AccountMove(models.Model):
|
|
_inherit = 'account.move'
|
|
|
|
l10n_de_datev_main_account_id = fields.Many2one('account.account', compute='_get_datev_account', store=True)
|
|
|
|
def _auto_init(self):
|
|
if column_exists(self.env.cr, "account_move", "l10n_de_datev_main_account_id"):
|
|
return super()._auto_init()
|
|
|
|
cr = self.env.cr
|
|
create_column(cr, "account_move", "l10n_de_datev_main_account_id", "int4")
|
|
# If move has an invoice, return invoice's account_id
|
|
cr.execute(
|
|
"""
|
|
UPDATE account_move
|
|
SET l10n_de_datev_main_account_id = r.aid
|
|
FROM (
|
|
SELECT l.move_id mid,
|
|
FIRST_VALUE(l.account_id) OVER(PARTITION BY l.move_id ORDER BY l.id DESC) aid
|
|
FROM account_move_line l
|
|
JOIN account_move m
|
|
ON m.id = l.move_id
|
|
JOIN account_account a
|
|
ON a.id = l.account_id
|
|
WHERE m.move_type in ('out_invoice', 'out_refund', 'in_refund', 'in_invoice', 'out_receipt', 'in_receipt')
|
|
AND a.account_type in ('asset_receivable', 'liability_payable')
|
|
) r
|
|
WHERE id = r.mid
|
|
""")
|
|
|
|
# If move belongs to a bank journal, return the journal's account (debit/credit should normally be the same)
|
|
cr.execute(
|
|
"""
|
|
UPDATE account_move
|
|
SET l10n_de_datev_main_account_id = r.aid
|
|
FROM (
|
|
SELECT m.id mid,
|
|
j.default_account_id aid
|
|
FROM account_move m
|
|
JOIN account_journal j
|
|
ON m.journal_id = j.id
|
|
WHERE j.type = 'bank'
|
|
AND j.default_account_id IS NOT NULL
|
|
) r
|
|
WHERE id = r.mid
|
|
AND l10n_de_datev_main_account_id IS NULL
|
|
""")
|
|
|
|
# If the move is an automatic exchange rate entry, take the gain/loss account set on the exchange journal
|
|
cr.execute("""
|
|
UPDATE account_move m
|
|
SET l10n_de_datev_main_account_id = r.aid
|
|
FROM (
|
|
SELECT l.move_id AS mid,
|
|
l.account_id AS aid
|
|
FROM account_move_line l
|
|
JOIN account_move m
|
|
ON l.move_id = m.id
|
|
JOIN account_journal j
|
|
ON m.journal_id = j.id
|
|
JOIN res_company c
|
|
ON c.currency_exchange_journal_id = j.id
|
|
WHERE j.type='general'
|
|
AND l.account_id = j.default_account_id
|
|
GROUP BY l.move_id,
|
|
l.account_id
|
|
HAVING count(*)=1
|
|
) r
|
|
WHERE id = r.mid
|
|
AND l10n_de_datev_main_account_id IS NULL
|
|
""")
|
|
|
|
# Look for an account used a single time in the move, that has no originator tax
|
|
query = """
|
|
UPDATE account_move m
|
|
SET l10n_de_datev_main_account_id = r.aid
|
|
FROM (
|
|
SELECT l.move_id AS mid,
|
|
min(l.account_id) AS aid
|
|
FROM account_move_line l
|
|
WHERE {}
|
|
GROUP BY move_id
|
|
HAVING count(*)=1
|
|
) r
|
|
WHERE id = r.mid
|
|
AND m.l10n_de_datev_main_account_id IS NULL
|
|
"""
|
|
cr.execute(query.format("l.debit > 0"))
|
|
cr.execute(query.format("l.credit > 0"))
|
|
cr.execute(query.format("l.debit > 0 AND l.tax_line_id IS NULL"))
|
|
cr.execute(query.format("l.credit > 0 AND l.tax_line_id IS NULL"))
|
|
|
|
return super()._auto_init()
|
|
|
|
@api.depends('journal_id', 'line_ids', 'journal_id.default_account_id')
|
|
def _get_datev_account(self):
|
|
for move in self:
|
|
move.l10n_de_datev_main_account_id = value = False
|
|
# If move has an invoice, return invoice's account_id
|
|
if move.is_invoice(include_receipts=True):
|
|
payment_term_lines = move.line_ids.filtered(
|
|
lambda line: line.account_id.account_type in ('asset_receivable', 'liability_payable'))
|
|
if payment_term_lines:
|
|
move.l10n_de_datev_main_account_id = payment_term_lines[0].account_id
|
|
continue
|
|
# If move belongs to a bank journal, return the journal's account (debit/credit should normally be the same)
|
|
if move.journal_id.type == 'bank' and move.journal_id.default_account_id:
|
|
move.l10n_de_datev_main_account_id = move.journal_id.default_account_id
|
|
continue
|
|
# If the move is an automatic exchange rate entry, take the gain/loss account set on the exchange journal
|
|
elif move.journal_id.type == 'general' and move.journal_id == self.env.company.currency_exchange_journal_id:
|
|
lines = move.line_ids.filtered(lambda r: r.account_id == move.journal_id.default_account_id)
|
|
|
|
if len(lines) == 1:
|
|
move.l10n_de_datev_main_account_id = lines.account_id
|
|
continue
|
|
|
|
# Look for an account used a single time in the move, that has no originator tax
|
|
aml_debit = self.env['account.move.line']
|
|
aml_credit = self.env['account.move.line']
|
|
for aml in move.line_ids:
|
|
if aml.debit > 0:
|
|
aml_debit += aml
|
|
if aml.credit > 0:
|
|
aml_credit += aml
|
|
if len(aml_debit.account_id) == 1:
|
|
value = aml_debit.account_id
|
|
elif len(aml_credit.account_id) == 1:
|
|
value = aml_credit.account_id
|
|
else:
|
|
aml_debit_wo_tax_accounts = [a.account_id for a in aml_debit if not a.tax_line_id]
|
|
aml_credit_wo_tax_accounts = [a.account_id for a in aml_credit if not a.tax_line_id]
|
|
if len(aml_debit_wo_tax_accounts) == 1:
|
|
value = aml_debit_wo_tax_accounts[0]
|
|
elif len(aml_credit_wo_tax_accounts) == 1:
|
|
value = aml_credit_wo_tax_accounts[0]
|
|
move.l10n_de_datev_main_account_id = value
|
|
|
|
def _l10n_de_datev_get_guid(self):
|
|
""" Get the unique identifier for the move based on the db UUID and the move id """
|
|
self.ensure_one()
|
|
dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid')
|
|
guid = uuid.uuid5(namespace=uuid.UUID(dbuuid), name=str(self.id))
|
|
return str(guid)
|