[MIG] sale_down_payment to v14

This commit is contained in:
Alexis de Lattre
2024-03-15 15:23:43 +01:00
parent 282e7142db
commit b353bb14a5
14 changed files with 205 additions and 109 deletions

View File

@@ -1,3 +1,4 @@
from . import sale
from . import account_move
from . import account_move_line
from . import account_payment

View File

@@ -0,0 +1,26 @@
# Copyright 2023-2024 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class AccountMove(models.Model):
_inherit = 'account.move'
def _post(self, soft=True):
res = super()._post(soft=soft)
amlo = self.env['account.move.line']
for move in self:
if move.state == 'posted' and move.move_type == 'out_invoice':
sales = move.invoice_line_ids.sale_line_ids.order_id
if sales:
mlines = amlo.search([('sale_id', 'in', sales.ids)])
if mlines:
mlines_to_reconcile = move.line_ids.filtered(
lambda line: line.account_id ==
move.commercial_partner_id.property_account_receivable_id)
mlines_to_reconcile |= mlines
mlines_to_reconcile.remove_move_reconcile()
mlines_to_reconcile.reconcile()
return res

View File

@@ -1,4 +1,4 @@
# Copyright 2019 Akretion France (http://www.akretion.com)
# Copyright 2019-2024 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -9,24 +9,23 @@ from odoo.exceptions import ValidationError
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
sale_id = fields.Many2one('sale.order', string='Sale Order')
account_internal_type = fields.Selection(
related='account_id.user_type_id.type', store=True,
string='Account Internal Type')
sale_id = fields.Many2one(
'sale.order', string='Sale Order', check_company=True,
domain="[('partner_invoice_id', 'child_of', partner_id), ('state', '!=', 'cancel'), ('invoice_status', '!=', 'invoiced'), ('company_id', '=', company_id)]")
@api.constrains('sale_id', 'account_id')
def sale_id_check(self):
def _sale_id_check(self):
for line in self:
if line.sale_id and line.account_id.internal_type != 'receivable':
if line.sale_id and line.account_internal_type != 'receivable':
raise ValidationError(_(
"The account move line '%s' is linked to sale order '%s' "
"but it uses account '%s' which is not a receivable "
"account.")
% (line.name,
line.sale_id.name,
% (line.display_name,
line.sale_id.display_name,
line.account_id.display_name))
@api.onchange('account_id')
def sale_advance_payement_account_id_change(self):
if self.sale_id and self.account_id.user_type_id.type != 'receivable':
if self.sale_id and self.account_internal_type != 'receivable':
self.sale_id = False

View File

@@ -1,9 +1,8 @@
# Copyright 2019 Akretion France (http://www.akretion.com)
# Copyright 2019-2024 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
from odoo.tools import float_round
class AccountPayment(models.Model):
@@ -11,49 +10,24 @@ class AccountPayment(models.Model):
sale_id = fields.Many2one('sale.order', string='Sale Order')
def action_validate_invoice_payment(self):
if self.sale_id:
self.post()
else:
return super(AccountPayment, self).\
action_validate_invoice_payment()
def _get_counterpart_move_line_vals(self, invoice=False):
res = super(AccountPayment, self)._get_counterpart_move_line_vals(
invoice=invoice)
if self.sale_id:
res['sale_id'] = self.sale_id.id
return res
class AccountAbstractPayment(models.AbstractModel):
_inherit = "account.abstract.payment"
def default_get(self, fields_list):
res = super(AccountAbstractPayment, self).default_get(fields_list)
def _prepare_move_line_default_vals(self, write_off_line_vals=None):
line_vals_list = super()._prepare_move_line_default_vals(
write_off_line_vals=write_off_line_vals)
# Add to the receivable/payable line
if (
self._context.get('active_model') == 'sale.order' and
self._context.get('active_id')):
so = self.env['sale.order'].browse(self._context['active_id'])
res.update({
'amount': so.amount_total,
'currency_id': so.currency_id.id,
'payment_type': 'inbound',
'partner_id': so.partner_invoice_id.commercial_partner_id.id,
'partner_type': 'customer',
'communication': so.name,
'sale_id': so.id,
})
return res
self.sale_id and
len(line_vals_list) >= 2 and
line_vals_list[1].get('account_id') == self.destination_account_id.id):
line_vals_list[1]['sale_id'] = self.sale_id.id
return line_vals_list
def _compute_payment_amount(self, invoices=None, currency=None):
amount = super(AccountAbstractPayment, self)._compute_payment_amount(
invoices=invoices, currency=currency)
if self.sale_id:
payment_currency = currency
if not payment_currency:
payment_currency = self.sale_id.currency_id
amount = float_round(
self.sale_id.amount_total - self.sale_id.amount_down_payment,
precision_rounding=payment_currency.rounding)
return amount
def action_post(self):
super().action_post()
for pay in self:
if pay.sale_id and pay.payment_type == 'inbound':
pay._sale_down_payment_hook()
def _sale_down_payment_hook(self):
# can be used for notifications
# WAS on account.move.line on v12 ; is on account.payment on v14
self.ensure_one()

View File

@@ -1,4 +1,4 @@
# Copyright 2019 Akretion France (http://www.akretion.com)
# Copyright 2019-2024 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -9,8 +9,8 @@ from odoo.tools import float_round
class SaleOrder(models.Model):
_inherit = 'sale.order'
payment_line_ids = fields.One2many(
'account.move.line', 'sale_id', string='Advance Payments',
payment_ids = fields.One2many(
'account.payment', 'sale_id', string='Advance Payments',
readonly=True)
amount_down_payment = fields.Monetary(
compute='_compute_amount_down_payment', string='Down Payment Amount')
@@ -19,30 +19,20 @@ class SaleOrder(models.Model):
compute='_compute_amount_down_payment', string='Residual')
@api.depends(
'payment_line_ids.credit', 'payment_line_ids.debit',
'payment_line_ids.amount_currency', 'payment_line_ids.currency_id',
'payment_line_ids.date', 'currency_id')
'payment_ids.amount', 'payment_ids.currency_id', 'payment_ids.date',
'payment_ids.state', 'currency_id')
def _compute_amount_down_payment(self):
for sale in self:
down_payment = 0.0
sale_currency = sale.pricelist_id.currency_id
if sale_currency == sale.company_id.currency_id:
for pl in sale.payment_line_ids:
down_payment -= pl.balance
else:
for pl in sale.payment_line_ids:
if (
pl.currency_id and
pl.currency_id == sale_currency and
pl.amount_currency):
down_payment -= pl.amount_currency
else:
down_payment -= sale.company_id.currency_id._convert(
pl.balance, sale_currency, sale.company_id,
pl.date)
sale_currency = sale.currency_id
prec_rounding = sale_currency.rounding or 0.01
for payment in sale.payment_ids:
if payment.payment_type == 'inbound' and payment.state == 'posted':
down_payment += payment.currency_id._convert(
payment.amount, sale_currency, sale.company_id,
payment.date)
down_payment = float_round(
down_payment, precision_rounding=sale.currency_id.rounding)
down_payment, precision_rounding=prec_rounding)
sale.amount_down_payment = down_payment
sale.amount_residual = float_round(
sale.amount_total - down_payment,
precision_rounding=sale.currency_id.rounding)
sale.amount_total - down_payment, precision_rounding=prec_rounding)