1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/l10n_de_reports/models/account_move.py
2024-12-10 09:04:09 +07:00

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)