Files
enterprise-addons/documents_account/models/account_move.py
T

140 lines
6.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class AccountMove(models.Model):
_name = 'account.move'
_inherit = ['account.move', 'documents.unlink.mixin']
suspense_statement_line_id = fields.Many2one(
comodel_name='account.bank.statement.line',
string="Request document from a bank statement line",
index='btree_not_null',
)
has_documents = fields.Boolean(string='Has Documents', compute='_compute_has_documents')
@api.depends('attachment_ids')
def _compute_has_documents(self):
result = self.env['documents.document']._read_group(
domain=[('res_model', '=', self._name), ('res_id', 'in', self.ids)],
groupby=['res_id'],
)
has_documents_ids = {r[0] for r in result}
for move in self:
move.has_documents = move.id in has_documents_ids
def write(self, vals):
main_attachment_id = vals.get('message_main_attachment_id')
new_documents = [False] * len(self)
journals_changed = [('journal_id' in vals and move.journal_id.id != vals['journal_id']) for move in self]
moves_with_updated_partner = self.filtered(
lambda move: vals.get('partner_id', move.partner_id.id) != move.partner_id.id
)
for i, move in enumerate(self):
if main_attachment_id and not move.env.context.get('no_document') and move.move_type != 'entry':
previous_attachment_id = move.message_main_attachment_id.id
if previous_attachment_id == main_attachment_id:
continue
document = False
if previous_attachment_id:
# Search also in previous_attachment_ids to handle the case where
# the attachment is not the main one due to versioning
document = (
move.env["documents.document"]
.sudo()
.search([
"|",
("attachment_id", "=", previous_attachment_id),
("previous_attachment_ids", "in", previous_attachment_id),
], limit=1)
)
if document:
document.attachment_id = main_attachment_id
else:
new_documents[i] = True
res = super().write(vals)
for new_document, journal_changed, move in zip(new_documents, journals_changed, self):
if (new_document or journal_changed) and move.message_main_attachment_id:
move._update_or_create_document(move.message_main_attachment_id.id)
for move in moves_with_updated_partner:
move._sync_partner_on_document()
return res
def button_reconcile_with_st_line(self):
""" When using the "Reconciliation Request" next activity on the statement line's chatter, the invoice is linked
to this statement line through the 'suspense_statement_line_id' field.
When checking this link on your invoice, you are able to click on a button triggering this method opening the
bank reconciliation widget for this specific statement line to easily match it with the current invoice.
:return: An action opening the bank reconciliation widget.
"""
self.ensure_one()
st_line = self.suspense_statement_line_id
rec_pay_lines = self.line_ids.filtered(lambda x: x.account_id.account_type in ('asset_receivable', 'liability_payable'))
default_todo_command = ','.join(['add_new_amls'] + [str(x) for x in rec_pay_lines.ids])
return self.env['account.bank.statement.line']._action_open_bank_reconciliation_widget(
default_context={
'search_default_journal_id': st_line.journal_id.id,
'search_default_statement_id': st_line.statement_id.id,
'default_journal_id': st_line.journal_id.id,
'default_st_line_id': st_line.id,
'default_todo_command': default_todo_command,
},
)
def _update_or_create_document(self, attachment_id):
super()._update_or_create_document(attachment_id)
if not self.env['ir.attachment'].browse(attachment_id).res_model:
return
setting = self.env['documents.account.folder.setting'].sudo().search(
[('journal_id', '=', self.journal_id.id),
('company_id', '=', self.company_id.id)], limit=1)
if setting:
Documents_sudo = self.env['documents.document'].sudo()
doc_sudo = Documents_sudo.with_context(active_test=False).search(
[('attachment_id', '=', attachment_id)], limit=1)
values = {
'active': True, # if archived, unarchive it
'folder_id': setting.folder_id.id,
'partner_id': self.partner_id.id or doc_sudo.partner_id.id,
'owner_id': self.create_uid.active and self.create_uid.id,
'tag_ids': [(4, tag.id) for tag in setting.tag_ids],
}
if doc_sudo:
doc_sudo.write(values)
else:
# backward compatibility with documents that may be not
# registered as attachments yet
values.update({
"attachment_id": attachment_id,
"company_id": self.company_id.id,
})
doc_sudo.create(values)
def _sync_partner_on_document(self):
for move in self:
if not move.message_main_attachment_id:
continue
doc = self.env['documents.document'].sudo().search([('attachment_id', '=', move.message_main_attachment_id.id)], limit=1)
if not doc or doc.partner_id == move.partner_id:
continue
doc.partner_id = move.partner_id
def action_view_documents_account_move(self):
self.ensure_one()
domain = [('res_model', '=', self._name), ('res_id', '=', self.id)]
documents = self.env['documents.document'].search(domain)
default_user_folder_id = (
documents[0].user_folder_id
if len(set(documents.mapped('user_folder_id'))) == 1
else False
)
return {
**self.env['ir.actions.actions']._for_xml_id('documents.document_action_preference'),
'domain': domain,
'context': {'searchpanel_default_user_folder_id': default_user_folder_id},
}