Rename module sale_advance_payment_management to sale_down_payment

Add field amount_down_payment on sale.order
This commit is contained in:
Alexis de Lattre
2019-11-14 23:02:42 +01:00
parent 83fec9264f
commit 035a3dfd1e
12 changed files with 50 additions and 17 deletions

View File

@@ -0,0 +1,2 @@
from . import models
from . import wizard

View File

@@ -0,0 +1,34 @@
# Copyright 2019 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).
{
'name': 'Sale Down Payment',
'version': '12.0.1.0.0',
'category': 'Sales',
'license': 'AGPL-3',
'summary': 'Link payment to sale orders',
'description': """
Sale Down Payment
=================
This module adds a link between payment and sale orders. It allows to see advanced payment directly on the sale order form view.
After processing a bank statement, you can start a wizard to link unreconciled incoming payments to a sale order.
This module targets B2B companies that don't want to generate a down payment invoice for an advanced payment.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['sale'],
'data': [
'wizard/account_bank_statement_sale_view.xml',
'views/account_bank_statement.xml',
'views/sale.xml',
'views/account_move_line.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,2 @@
from . import sale
from . import account_move_line

View File

@@ -0,0 +1,32 @@
# Copyright 2019 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 api, fields, models, _
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')
@api.constrains('sale_id', 'account_id')
def sale_id_check(self):
for line in self:
if line.sale_id and line.account_id.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.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':
self.sale_id = False

View File

@@ -0,0 +1,39 @@
# Copyright 2019 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 api, fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
payment_line_ids = fields.One2many(
'account.move.line', 'sale_id', string='Advance Payments',
readonly=True)
amount_down_payment = fields.Monetary(
compute='_compute_amount_down_payment', string='Down Payment Amount')
@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')
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.amount_down_payment = down_payment

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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).
-->
<odoo>
<record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">advance_payment.account.bank.statement.form</field>
<field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml">
<button name="check_confirm_bank" position="after">
<button name="%(account_bank_statement_sale_action)d" type="action" string="Link to Quotation/Sale Orders"/>
</button>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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).
-->
<odoo>
<record id="view_move_line_form" model="ir.ui.view">
<field name="name">advance_payment.account.move.line.form</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form"/>
<field name="arch" type="xml">
<field name="invoice_id" position="after">
<field name="sale_id" attrs="{'invisible': [('account_internal_type', '!=', 'receivable')]}" domain="['|', ('partner_id', 'child_of', partner_id), ('partner_invoice_id', 'child_of', partner_id), ('state', '!=', 'cancel'), ('invoice_status', '!=', 'invoiced')]"/>
<field name="account_internal_type" invisible="1"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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).
-->
<odoo>
<record id="view_order_form" model="ir.ui.view">
<field name="name">advance_payment.sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page name="advance_payment" string="Advance Payments">
<field name="payment_line_ids" nolabel="1"/>
</page>
</notebook>
<field name="amount_total" position="after">
<div class="oe_subtotal_footer_separator oe_inline o_td_label">
<label for="amount_down_payment" />
</div>
<field name="amount_down_payment" nolabel="1" class="oe_subtotal_footer_separator"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
from . import account_bank_statement_sale

View File

@@ -0,0 +1,86 @@
# Copyright 2019 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 api, fields, models, _
from odoo.exceptions import UserError
class AccountBankStatementSale(models.TransientModel):
_name = 'account.bank.statement.sale'
_description = 'Account Bank Statement Sale'
statement_id = fields.Many2one('account.bank.statement', readonly=True)
line_ids = fields.One2many(
'account.bank.statement.sale.line', 'wizard_id', string='Lines')
@api.model
def _prepare_line(self, move_line):
vals = {
'move_line_id': move_line.id,
'sale_id': move_line.sale_id.id or False,
'date': move_line.date,
'credit': move_line.credit,
'partner_id': move_line.partner_id.id,
'account_id': move_line.account_id.id,
'name': move_line.name,
'company_currency_id': move_line.company_currency_id.id,
}
return vals
@api.model
def default_get(self, fields_list):
res = super(AccountBankStatementSale, self).default_get(fields_list)
assert self._context.get('active_model') == 'account.bank.statement'
statement_id = self._context.get('active_id')
statement = self.env['account.bank.statement'].browse(statement_id)
res.update({
'line_ids': [],
'statement_id': statement_id,
})
for st_line in statement.line_ids:
if (
st_line.amount > 0 and
st_line.partner_id and
st_line.journal_entry_ids):
for line in st_line.journal_entry_ids:
if (
line.account_id.user_type_id.type == 'receivable'
and
line.partner_id and
not line.full_reconcile_id and
not line.matched_debit_ids and
not line.matched_credit_ids):
lvals = self._prepare_line(line)
res['line_ids'].append((0, 0, lvals))
if not res['line_ids']:
raise UserError(_(
"The bank statement '%s' doesn't contain any processed line "
"with a positive amount which is not reconciled.")
% statement.display_name)
return res
def validate(self):
self.ensure_one()
for line in self.line_ids:
if line.move_line_id.sale_id != line.sale_id:
line.move_line_id.sale_id = line.sale_id.id
class AccountBankStatementSaleLine(models.TransientModel):
_name = 'account.bank.statement.sale.line'
_description = 'Account Bank Statement Sale Lines'
wizard_id = fields.Many2one(
'account.bank.statement.sale', ondelete='cascade')
move_line_id = fields.Many2one(
'account.move.line', string='Move Line', required=True)
date = fields.Date(related='move_line_id.date')
credit = fields.Monetary(
related='move_line_id.credit', currency_field='company_currency_id')
partner_id = fields.Many2one(related='move_line_id.partner_id')
account_id = fields.Many2one(related='move_line_id.account_id')
name = fields.Char(related='move_line_id.name')
company_currency_id = fields.Many2one(
related='move_line_id.company_currency_id')
sale_id = fields.Many2one('sale.order', string='Sale Order')

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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).
-->
<odoo>
<record id="account_bank_statement_sale_form" model="ir.ui.view">
<field name="name">account.bank.statement.sale.form</field>
<field name="model">account.bank.statement.sale</field>
<field name="arch" type="xml">
<form string="Link to Quotation/Sale Orders">
<group name="main" invisible="1">
<field name="statement_id"/>
</group>
<group name="lines">
<field name="line_ids" nolabel="1">
<tree editable="bottom">
<field name="move_line_id" invisible="1"/>
<field name="date"/>
<field name="name"/>
<field name="partner_id"/>
<field name="account_id"/>
<field name="credit"/>
<field name="sale_id" domain="['|', ('partner_id', 'child_of', partner_id), ('partner_invoice_id', 'child_of', partner_id), ('state', '!=', 'cancel'), ('invoice_status', '!=', 'invoiced')]"/>
<field name="company_currency_id" invisible="1"/>
</tree>
</field>
</group>
<footer>
<button name="validate" type="object" string="Validate" class="btn-primary"/>
<button special="cancel" string="Cancel" class="btn-default"/>
</footer>
</form>
</field>
</record>
<record id="account_bank_statement_sale_action" model="ir.actions.act_window">
<field name="name">Link to Quotation/Sale Orders</field>
<field name="res_model">account.bank.statement.sale</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>