|
@ -37,6 +37,9 @@ class AccountPayment(models.Model): |
|
|
_inherit = "account.payment" |
|
|
_inherit = "account.payment" |
|
|
_inherits = {'account.move': 'move_id'} |
|
|
_inherits = {'account.move': 'move_id'} |
|
|
|
|
|
|
|
|
|
|
|
origin_invoice_ids = fields.Many2many('account.move', string='Invoice Origin') |
|
|
|
|
|
to_reconcile_inv = fields.Many2one('account.move.line', string='Reconcile Move Line') |
|
|
|
|
|
|
|
|
def _check_is_approver(self): |
|
|
def _check_is_approver(self): |
|
|
approval = self.env['ir.config_parameter'].sudo().get_param( |
|
|
approval = self.env['ir.config_parameter'].sudo().get_param( |
|
|
'account_payment_approval.payment_approval') |
|
|
'account_payment_approval.payment_approval') |
|
@ -50,16 +53,62 @@ class AccountPayment(models.Model): |
|
|
"""Overwrites the _post() to validate the payment in the 'approved' stage too. |
|
|
"""Overwrites the _post() to validate the payment in the 'approved' stage too. |
|
|
Currently Odoo allows payment posting only in draft stage. |
|
|
Currently Odoo allows payment posting only in draft stage. |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
if self._context.get('active_model') == 'account.move': |
|
|
|
|
|
if self._context.get('active_ids'): |
|
|
|
|
|
if len(self._context.get('active_ids')) == 1: |
|
|
|
|
|
self.write({ |
|
|
|
|
|
'origin_invoice_ids': [(4, self._context.get('active_ids')[0])] |
|
|
|
|
|
}) |
|
|
|
|
|
validation = self._check_payment_approval() |
|
|
|
|
|
if not validation: |
|
|
|
|
|
if self.state in ('waiting_approval'): |
|
|
|
|
|
return True |
|
|
|
|
|
if self.state not in ('draft', 'approved'): |
|
|
|
|
|
raise UserError(_("Only a draft or approved payment can be posted.")) |
|
|
|
|
|
|
|
|
|
|
|
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids): |
|
|
|
|
|
raise ValidationError(_("The payment cannot be processed because the invoice is not open!")) |
|
|
|
|
|
self.move_id._post(soft=False) |
|
|
|
|
|
else: |
|
|
|
|
|
self.move_id._post(soft=False) |
|
|
|
|
|
|
|
|
|
|
|
if len(self._context.get('active_ids')) > 1: |
|
|
|
|
|
|
|
|
|
|
|
for rec in self: |
|
|
|
|
|
validation = rec._check_payment_approval() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else: |
|
|
validation = self._check_payment_approval() |
|
|
validation = self._check_payment_approval() |
|
|
if validation: |
|
|
if not validation: |
|
|
|
|
|
if self.state in ('waiting_approval'): |
|
|
|
|
|
return True |
|
|
if self.state not in ('draft', 'approved'): |
|
|
if self.state not in ('draft', 'approved'): |
|
|
raise UserError(_("Only a draft or approved payment can be posted.")) |
|
|
raise UserError(_("Only a draft or approved payment can be posted.")) |
|
|
|
|
|
|
|
|
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids): |
|
|
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids): |
|
|
raise ValidationError(_("The payment cannot be processed because the invoice is not open!")) |
|
|
raise ValidationError(_("The payment cannot be processed because the invoice is not open!")) |
|
|
self.move_id._post(soft=False) |
|
|
self.move_id._post(soft=False) |
|
|
|
|
|
self.reconcile_move_payment() |
|
|
|
|
|
else: |
|
|
|
|
|
self.move_id._post(soft=False) |
|
|
|
|
|
self.reconcile_move_payment() |
|
|
|
|
|
|
|
|
|
|
|
def reconcile_move_payment(self): |
|
|
|
|
|
if self.to_reconcile_inv: |
|
|
|
|
|
domain = [('account_internal_type', 'in', ('receivable', 'payable')), ('reconciled', '=', False)] |
|
|
|
|
|
payment_lines = self.line_ids.filtered_domain(domain) |
|
|
|
|
|
lines = self.to_reconcile_inv |
|
|
|
|
|
|
|
|
|
|
|
for account in payment_lines.account_id: |
|
|
|
|
|
(payment_lines + lines) \ |
|
|
|
|
|
.filtered_domain([('account_id', '=', account.id), ('reconciled', '=', False)]) \ |
|
|
|
|
|
.reconcile() |
|
|
|
|
|
|
|
|
def _check_payment_approval(self): |
|
|
def _check_payment_approval(self): |
|
|
|
|
|
if not self.state: |
|
|
|
|
|
return True |
|
|
if self.state == "draft": |
|
|
if self.state == "draft": |
|
|
first_approval = self.env['ir.config_parameter'].sudo().get_param( |
|
|
first_approval = self.env['ir.config_parameter'].sudo().get_param( |
|
|
'account_payment_approval.payment_approval') |
|
|
'account_payment_approval.payment_approval') |
|
@ -81,6 +130,7 @@ class AccountPayment(models.Model): |
|
|
}) |
|
|
}) |
|
|
return False |
|
|
return False |
|
|
return True |
|
|
return True |
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
def approve_transfer(self): |
|
|
def approve_transfer(self): |
|
|
if self.is_approver: |
|
|
if self.is_approver: |
|
@ -92,3 +142,54 @@ class AccountPayment(models.Model): |
|
|
self.write({ |
|
|
self.write({ |
|
|
'state': 'rejected' |
|
|
'state': 'rejected' |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AccountPaymentRegister(models.TransientModel): |
|
|
|
|
|
_inherit = 'account.payment.register' |
|
|
|
|
|
|
|
|
|
|
|
def _create_payments(self): |
|
|
|
|
|
self.ensure_one() |
|
|
|
|
|
batches = self._get_batches() |
|
|
|
|
|
edit_mode = self.can_edit_wizard and (len(batches[0]['lines']) == 1 or self.group_payment) |
|
|
|
|
|
to_process = [] |
|
|
|
|
|
|
|
|
|
|
|
if edit_mode: |
|
|
|
|
|
payment_vals = self._create_payment_vals_from_wizard() |
|
|
|
|
|
to_process.append({ |
|
|
|
|
|
'create_vals': payment_vals, |
|
|
|
|
|
'to_reconcile': batches[0]['lines'], |
|
|
|
|
|
'batch': batches[0], |
|
|
|
|
|
}) |
|
|
|
|
|
else: |
|
|
|
|
|
# Don't group payments: Create one batch per move. |
|
|
|
|
|
if not self.group_payment: |
|
|
|
|
|
new_batches = [] |
|
|
|
|
|
for batch_result in batches: |
|
|
|
|
|
for line in batch_result['lines']: |
|
|
|
|
|
new_batches.append({ |
|
|
|
|
|
**batch_result, |
|
|
|
|
|
'lines': line, |
|
|
|
|
|
}) |
|
|
|
|
|
batches = new_batches |
|
|
|
|
|
|
|
|
|
|
|
for batch_result in batches: |
|
|
|
|
|
to_reconcile_inv = batch_result['lines'] |
|
|
|
|
|
to_process.append({ |
|
|
|
|
|
'create_vals': self._create_payment_vals_from_batch(batch_result), |
|
|
|
|
|
'to_reconcile': batch_result['lines'], |
|
|
|
|
|
'batch': batch_result, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
payments = self._init_payments(to_process, edit_mode=edit_mode) |
|
|
|
|
|
self._post_payments(to_process, edit_mode=edit_mode) |
|
|
|
|
|
|
|
|
|
|
|
for item_rec in to_process: |
|
|
|
|
|
item_rec.get('payment').write({ |
|
|
|
|
|
'to_reconcile_inv': item_rec.get('to_reconcile'), |
|
|
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
for rec in payments: |
|
|
|
|
|
if rec.state == 'posted': |
|
|
|
|
|
self._reconcile_payments(to_process, edit_mode=edit_mode) |
|
|
|
|
|
return payments |
|
|