[IMP] account_check_deposit: black, isort

This commit is contained in:
ps-tubtim
2020-03-24 11:11:14 +07:00
committed by Víctor Martínez
parent f31e014d6d
commit 800a963aaf
13 changed files with 614 additions and 482 deletions

View File

@@ -6,29 +6,24 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Account Check Deposit',
'version': '12.0.1.0.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Manage deposit of checks to the bank',
'author': "Odoo Community Association (OCA),"
"Akretion,"
"Tecnativa",
'website': 'https://github.com/OCA/account-financial-tools/tree/12.0/'
'account_check_deposit',
'depends': [
'account',
"name": "Account Check Deposit",
"version": "13.0.1.0.0",
"category": "Accounting",
"license": "AGPL-3",
"summary": "Manage deposit of checks to the bank",
"author": "Akretion, Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-financial-tools",
"depends": ["account"],
"development_status": "Mature",
"data": [
"security/ir.model.access.csv",
"security/check_deposit_security.xml",
"data/sequence.xml",
"views/account_deposit_view.xml",
"views/account_move_line_view.xml",
"views/res_config_settings_views.xml",
"report/report.xml",
"report/report_checkdeposit.xml",
],
'development_status': 'Mature',
'data': [
'security/ir.model.access.csv',
'security/check_deposit_security.xml',
'data/sequence.xml',
'views/account_deposit_view.xml',
'views/account_move_line_view.xml',
'views/res_config_settings_views.xml',
'report/report.xml',
'report/report_checkdeposit.xml',
],
'installable': True,
"installable": True,
}

View File

@@ -1,18 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
© 2012-2019 Akretion (http://www.akretion.com/)
@author: Benoît GUILLOT <benoit.guillot@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo noupdate="1">
<record id="seq_account_check_deposit" model="ir.sequence">
<field name="name">Account Check Deposit</field>
<field name="code">account.check.deposit</field>
<field name="prefix">DEP</field>
<field name="padding">3</field>
<field name="company_id" eval="False"/>
<field name="company_id" eval="False" />
</record>
</odoo>

View File

@@ -7,19 +7,23 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
import odoo.addons.decimal_precision as dp
from odoo.exceptions import ValidationError, UserError
class AccountCheckDeposit(models.Model):
_name = "account.check.deposit"
_description = "Account Check Deposit"
_order = 'deposit_date desc'
_order = "deposit_date desc"
@api.depends(
'company_id', 'currency_id', 'check_payment_ids.debit',
'check_payment_ids.amount_currency',
'move_id.line_ids.reconciled')
"company_id",
"currency_id",
"check_payment_ids.debit",
"check_payment_ids.amount_currency",
"move_id.line_ids.reconciled",
)
def _compute_check_deposit(self):
for deposit in self:
total = 0.0
@@ -40,62 +44,94 @@ class AccountCheckDeposit(models.Model):
reconcile = True
deposit.total_amount = total
deposit.is_reconcile = reconcile
deposit.currency_none_same_company_id =\
currency_none_same_company_id
deposit.currency_none_same_company_id = currency_none_same_company_id
deposit.check_count = count
name = fields.Char(string='Name', size=64, readonly=True, default='/')
name = fields.Char(string="Name", size=64, readonly=True, default="/")
check_payment_ids = fields.One2many(
'account.move.line', 'check_deposit_id', string='Check Payments',
states={'done': [('readonly', '=', True)]})
comodel_name="account.move.line",
inverse_name="check_deposit_id",
string="Check Payments",
states={"done": [("readonly", "=", True)]},
)
deposit_date = fields.Date(
string='Deposit Date', required=True,
states={'done': [('readonly', '=', True)]},
default=fields.Date.context_today)
string="Deposit Date",
required=True,
states={"done": [("readonly", "=", True)]},
default=fields.Date.context_today,
)
journal_id = fields.Many2one(
'account.journal', string='Journal',
domain=[('type', '=', 'bank'), ('bank_account_id', '=', False)],
required=True, states={'done': [('readonly', '=', True)]})
comodel_name="account.journal",
string="Journal",
domain=[("type", "=", "bank"), ("bank_account_id", "=", False)],
required=True,
states={"done": [("readonly", "=", True)]},
)
journal_default_account_id = fields.Many2one(
'account.account', related='journal_id.default_debit_account_id',
string='Default Debit Account of the Journal')
comodel_name="account.account",
related="journal_id.default_debit_account_id",
string="Default Debit Account of the Journal",
)
currency_id = fields.Many2one(
'res.currency', string='Currency', required=True,
states={'done': [('readonly', '=', True)]})
comodel_name="res.currency",
string="Currency",
required=True,
states={"done": [("readonly", "=", True)]},
)
currency_none_same_company_id = fields.Many2one(
'res.currency', compute='_compute_check_deposit', store=True,
string='Currency (False if same as company)')
comodel_name="res.currency",
compute="_compute_check_deposit",
store=True,
string="Currency (False if same as company)",
)
state = fields.Selection(
[
('draft', 'Draft'),
('done', 'Done'),
], string='Status', default='draft', readonly=True)
selection=[("draft", "Draft"), ("done", "Done")],
string="Status",
default="draft",
readonly=True,
)
move_id = fields.Many2one(
'account.move', string='Journal Entry', readonly=True)
comodel_name="account.move", string="Journal Entry", readonly=True
)
bank_journal_id = fields.Many2one(
'account.journal', string='Bank Account', required=True,
comodel_name="account.journal",
string="Bank Account",
required=True,
domain="[('company_id', '=', company_id), ('type', '=', 'bank'), "
"('bank_account_id', '!=', False)]",
states={'done': [('readonly', '=', True)]})
states={"done": [("readonly", "=", True)]},
)
line_ids = fields.One2many(
'account.move.line', related='move_id.line_ids',
string='Lines', readonly=True)
comodel_name="account.move.line",
related="move_id.line_ids",
string="Lines",
readonly=True,
)
company_id = fields.Many2one(
'res.company', string='Company', required=True,
states={'done': [('readonly', '=', True)]},
default=lambda self: self.env['res.company']._company_default_get())
comodel_name="res.company",
string="Company",
required=True,
states={"done": [("readonly", "=", True)]},
default=lambda self: self.env["res.company"]._company_default_get(),
)
total_amount = fields.Float(
compute='_compute_check_deposit',
string="Total Amount", readonly=True, store=True,
digits=dp.get_precision('Account'))
compute="_compute_check_deposit",
string="Total Amount",
readonly=True,
store=True,
digits=dp.get_precision("Account"),
)
check_count = fields.Integer(
compute='_compute_check_deposit', readonly=True, store=True,
string="Number of Checks")
compute="_compute_check_deposit",
readonly=True,
store=True,
string="Number of Checks",
)
is_reconcile = fields.Boolean(
compute='_compute_check_deposit', readonly=True, store=True,
string="Reconcile")
compute="_compute_check_deposit", readonly=True, store=True, string="Reconcile"
)
@api.constrains('currency_id', 'check_payment_ids', 'company_id')
@api.constrains("currency_id", "check_payment_ids", "company_id")
def _check_deposit(self):
for deposit in self:
deposit_currency = deposit.currency_id
@@ -103,30 +139,45 @@ class AccountCheckDeposit(models.Model):
for line in deposit.check_payment_ids:
if line.currency_id:
raise ValidationError(
_("The check with amount %s and reference '%s' "
_(
"The check with amount %s and reference '%s' "
"is in currency %s but the deposit is in "
"currency %s.") % (
line.debit, line.ref or '',
"currency %s."
)
% (
line.debit,
line.ref or "",
line.currency_id.name,
deposit_currency.name))
deposit_currency.name,
)
)
else:
for line in deposit.check_payment_ids:
if line.currency_id != deposit_currency:
raise ValidationError(
_("The check with amount %s and reference '%s' "
_(
"The check with amount %s and reference '%s' "
"is in currency %s but the deposit is in "
"currency %s.") % (
line.debit, line.ref or '',
"currency %s."
)
% (
line.debit,
line.ref or "",
line.currency_id.name,
deposit_currency.name))
deposit_currency.name,
)
)
def unlink(self):
for deposit in self:
if deposit.state == 'done':
if deposit.state == "done":
raise UserError(
_("The deposit '%s' is in valid state, so you must "
"cancel it before deleting it.")
% deposit.name)
_(
"The deposit '%s' is in valid state, so you must "
"cancel it before deleting it."
)
% deposit.name
)
return super(AccountCheckDeposit, self).unlink()
def backtodraft(self):
@@ -138,78 +189,87 @@ class AccountCheckDeposit(models.Model):
if line.reconciled:
line.remove_move_reconcile()
deposit.move_id.unlink()
deposit.write({'state': 'draft'})
deposit.write({"state": "draft"})
return True
@api.model
def create(self, vals):
if vals.get('name', '/') == '/':
vals['name'] = self.env['ir.sequence'].\
with_context(ir_sequence_date=vals.get('deposit_date')).\
next_by_code('account.check.deposit')
if vals.get("name", "/") == "/":
vals["name"] = (
self.env["ir.sequence"]
.with_context(ir_sequence_date=vals.get("deposit_date"))
.next_by_code("account.check.deposit")
)
return super(AccountCheckDeposit, self).create(vals)
@api.model
def _prepare_account_move_vals(self, deposit):
if (
deposit.company_id.check_deposit_offsetting_account ==
'bank_account'):
if deposit.company_id.check_deposit_offsetting_account == "bank_account":
journal_id = deposit.bank_journal_id.id
else:
journal_id = deposit.journal_id.id
move_vals = {
'journal_id': journal_id,
'date': deposit.deposit_date,
'ref': _('Check Deposit %s') % deposit.name,
"journal_id": journal_id,
"date": deposit.deposit_date,
"ref": _("Check Deposit %s") % deposit.name,
}
return move_vals
@api.model
def _prepare_move_line_vals(self, line):
assert (line.debit > 0), 'Debit must have a value'
assert line.debit > 0, "Debit must have a value"
return {
'name': _('Check Deposit - Ref. Check %s') % line.ref,
'credit': line.debit,
'debit': 0.0,
'account_id': line.account_id.id,
'partner_id': line.partner_id.id,
'currency_id': line.currency_id.id or False,
'amount_currency': line.amount_currency * -1,
"name": _("Check Deposit - Ref. Check %s") % line.ref,
"credit": line.debit,
"debit": 0.0,
"account_id": line.account_id.id,
"partner_id": line.partner_id.id,
"currency_id": line.currency_id.id or False,
"amount_currency": line.amount_currency * -1,
}
@api.model
def _prepare_counterpart_move_lines_vals(
self, deposit, total_debit, total_amount_currency):
self, deposit, total_debit, total_amount_currency
):
company = deposit.company_id
if not company.check_deposit_offsetting_account:
raise UserError(_(
"You must configure the 'Check Deposit Offsetting Account' "
"on the Accounting Settings page"))
if company.check_deposit_offsetting_account == 'bank_account':
raise UserError(
_(
"You must configure the 'Check Deposit Offsetting Account' "
"on the Accounting Settings page"
)
)
if company.check_deposit_offsetting_account == "bank_account":
if not deposit.bank_journal_id.default_debit_account_id:
raise UserError(_(
"Missing 'Default Debit Account' on bank journal '%s'")
% deposit.bank_journal_id.name)
raise UserError(
_("Missing 'Default Debit Account' on bank journal '%s'")
% deposit.bank_journal_id.name
)
account_id = deposit.bank_journal_id.default_debit_account_id.id
elif company.check_deposit_offsetting_account == 'transfer_account':
elif company.check_deposit_offsetting_account == "transfer_account":
if not company.check_deposit_transfer_account_id:
raise UserError(_(
"Missing 'Check Deposit Offsetting Account' on the "
"company '%s'.") % company.name)
raise UserError(
_(
"Missing 'Check Deposit Offsetting Account' on the "
"company '%s'."
)
% company.name
)
account_id = company.check_deposit_transfer_account_id.id
return {
'name': _('Check Deposit %s') % deposit.name,
'debit': total_debit,
'credit': 0.0,
'account_id': account_id,
'partner_id': False,
'currency_id': deposit.currency_none_same_company_id.id or False,
'amount_currency': total_amount_currency,
"name": _("Check Deposit %s") % deposit.name,
"debit": total_debit,
"credit": 0.0,
"account_id": account_id,
"partner_id": False,
"currency_id": deposit.currency_none_same_company_id.id or False,
"amount_currency": total_amount_currency,
}
def validate_deposit(self):
am_obj = self.env['account.move']
move_line_obj = self.env['account.move.line']
am_obj = self.env["account.move"]
move_line_obj = self.env["account.move.line"]
for deposit in self:
move_vals = self._prepare_account_move_vals(deposit)
move = am_obj.create(move_vals)
@@ -220,37 +280,42 @@ class AccountCheckDeposit(models.Model):
total_debit += line.debit
total_amount_currency += line.amount_currency
line_vals = self._prepare_move_line_vals(line)
line_vals['move_id'] = move.id
line_vals["move_id"] = move.id
move_line = move_line_obj.with_context(
check_move_validity=False).create(line_vals)
check_move_validity=False
).create(line_vals)
to_reconcile_lines.append(line + move_line)
# Create counter-part
counter_vals = self._prepare_counterpart_move_lines_vals(
deposit, total_debit, total_amount_currency)
counter_vals['move_id'] = move.id
deposit, total_debit, total_amount_currency
)
counter_vals["move_id"] = move.id
move_line_obj.create(counter_vals)
if deposit.company_id.check_deposit_post_move:
move.post()
deposit.write({'state': 'done', 'move_id': move.id})
deposit.write({"state": "done", "move_id": move.id})
for reconcile_lines in to_reconcile_lines:
reconcile_lines.reconcile()
return True
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
if self.company_id:
bank_journals = self.env['account.journal'].search([
('company_id', '=', self.company_id.id),
('type', '=', 'bank'),
('bank_account_id', '!=', False)])
bank_journals = self.env["account.journal"].search(
[
("company_id", "=", self.company_id.id),
("type", "=", "bank"),
("bank_account_id", "!=", False),
]
)
if len(bank_journals) == 1:
self.bank_journal_id = bank_journals[0]
else:
self.bank_journal_id = False
@api.onchange('journal_id')
@api.onchange("journal_id")
def onchange_journal_id(self):
if self.journal_id:
if self.journal_id.currency_id:
@@ -259,7 +324,6 @@ class AccountCheckDeposit(models.Model):
self.currency_id = self.journal_id.company_id.currency_id
def get_report(self):
report = self.env.ref(
'account_check_deposit.report_account_check_deposit')
report = self.env.ref("account_check_deposit.report_account_check_deposit")
action = report.report_action(self)
return action

View File

@@ -13,7 +13,5 @@ class AccountMoveLine(models.Model):
_inherit = "account.move.line"
check_deposit_id = fields.Many2one(
'account.check.deposit',
string='Check Deposit',
copy=False,
comodel_name="account.check.deposit", string="Check Deposit", copy=False,
)

View File

@@ -9,15 +9,21 @@ from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
_inherit = "res.company"
check_deposit_offsetting_account = fields.Selection([
('bank_account', 'Bank Account'),
('transfer_account', 'Transfer Account'),
], string='Check Deposit Offsetting Account', default='bank_account')
check_deposit_offsetting_account = fields.Selection(
selection=[
("bank_account", "Bank Account"),
("transfer_account", "Transfer Account"),
],
string="Check Deposit Offsetting Account",
default="bank_account",
)
check_deposit_transfer_account_id = fields.Many2one(
'account.account', string='Transfer Account for Check Deposits',
ondelete='restrict', copy=False,
domain=[('reconcile', '=', True), ('deprecated', '=', False)])
check_deposit_post_move = fields.Boolean(
string='Post Move for Check Deposits')
comodel_name="account.account",
string="Transfer Account for Check Deposits",
ondelete="restrict",
copy=False,
domain=[("reconcile", "=", True), ("deprecated", "=", False)],
)
check_deposit_post_move = fields.Boolean(string="Post Move for Check Deposits")

View File

@@ -6,16 +6,14 @@ from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
_inherit = "res.config.settings"
check_deposit_offsetting_account = fields.Selection(
readonly=False,
related='company_id.check_deposit_offsetting_account',
related="company_id.check_deposit_offsetting_account", readonly=False
)
check_deposit_transfer_account_id = fields.Many2one(
related='company_id.check_deposit_transfer_account_id',
readonly=False,
related="company_id.check_deposit_transfer_account_id", readonly=False
)
check_deposit_post_move = fields.Boolean(
related='company_id.check_deposit_post_move', readonly=False,
related="company_id.check_deposit_post_move", readonly=False
)

View File

@@ -1,20 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright (C) 2014-2019 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __manifest__.py
-->
<odoo>
<report id="report_account_check_deposit"
model="account.check.deposit"
string="Check Deposit"
report_type="qweb-pdf"
name="account_check_deposit.report_checkdeposit"
file="account_check_deposit.report_checkdeposit"
print_report_name="'check_deposit-%s%s' % (object.name, object.state == 'draft' and '-draft' or '')"
<report
id="report_account_check_deposit"
model="account.check.deposit"
string="Check Deposit"
report_type="qweb-pdf"
name="account_check_deposit.report_checkdeposit"
file="account_check_deposit.report_checkdeposit"
print_report_name="'check_deposit-%s%s' % (object.name, object.state == 'draft' and '-draft' or '')"
/>
</odoo>

View File

@@ -1,89 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright (C) 2014-2019 Akretion (www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __manifest__.py
-->
<odoo>
<template id="report_checkdeposit">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.internal_layout">
<div class="page">
<h1>Check Deposit n°<span t-field="o.name"/></h1>
<h3>Bank:</h3>
<p><span t-field="o.bank_journal_id.bank_account_id.bank_id.name"/><br/>
<span t-field="o.bank_journal_id.bank_account_id.bank_id.street"/><br/>
<span t-field="o.bank_journal_id.bank_account_id.bank_id.zip"/> <span t-field="o.bank_journal_id.bank_account_id.bank_id.city"/></p>
<h3>Beneficiary:</h3>
<div t-field="o.company_id.partner_id"
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
<p><b>Bank Account Number to Credit:</b> <span t-field="o.bank_journal_id.bank_account_id.acc_number"/></p>
<p><b>Check Currency:</b> <span t-field="o.currency_id.name"/></p>
<p><b>Transfer Date:</b> <span t-field="o.deposit_date"/></p>
<p><b>Number of checks:</b> <span t-field="o.check_count"/></p>
<h3>List of checks:</h3>
<table class="table table-condensed">
<thead>
<tr>
<th>Date</th>
<th>Reference</th>
<th>Debtor</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<t t-foreach="o.check_payment_ids" t-as="move_line">
<tr>
<td><span t-field="move_line.date"/></td>
<td><span t-field="move_line.ref"/></td>
<td><span t-field="move_line.partner_id.name"/></td>
<td>
<t t-if="o.currency_id == o.company_id.currency_id">
<span t-field="move_line.debit"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
<template id="report_checkdeposit">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.internal_layout">
<div class="page">
<h1>Check Deposit n°<span t-field="o.name" /></h1>
<h3>Bank:</h3>
<p>
<span
t-field="o.bank_journal_id.bank_account_id.bank_id.name"
/>
<br />
<span
t-field="o.bank_journal_id.bank_account_id.bank_id.street"
/>
<br />
<span
t-field="o.bank_journal_id.bank_account_id.bank_id.zip"
/>
<span
t-field="o.bank_journal_id.bank_account_id.bank_id.city"
/>
</p>
<h3>Beneficiary:</h3>
<div
t-field="o.company_id.partner_id"
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'
/>
<p>
<b>Bank Account Number to Credit:</b>
<span
t-field="o.bank_journal_id.bank_account_id.acc_number"
/>
</p>
<p>
<b>Check Currency:</b>
<span t-field="o.currency_id.name" />
</p>
<p>
<b>Transfer Date:</b>
<span t-field="o.deposit_date" />
</p>
<p>
<b>Number of checks:</b>
<span t-field="o.check_count" />
</p>
<h3>List of checks:</h3>
<table class="table table-condensed">
<thead>
<tr>
<th>Date</th>
<th>Reference</th>
<th>Debtor</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<t t-foreach="o.check_payment_ids" t-as="move_line">
<tr>
<td>
<span t-field="move_line.date" />
</td>
<td>
<span t-field="move_line.ref" />
</td>
<td>
<span t-field="move_line.partner_id.name" />
</td>
<td>
<t
t-if="o.currency_id == o.company_id.currency_id"
>
<span
t-field="move_line.debit"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'
/>
</t>
<t
t-if="o.currency_id != o.company_id.currency_id"
>
<span
t-field="move_line.amount_currency"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'
/>
</t>
</td>
</tr>
</t>
<tr>
<td />
<td />
<td>
<b>Total:</b>
</td>
<td>
<b>
<span
t-field="o.total_amount"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'
/>
</b>
</td>
</tr>
</tbody>
</table>
</div>
</t>
<t t-if="o.currency_id != o.company_id.currency_id">
<span t-field="move_line.amount_currency"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</t>
</td>
</tr>
</t>
<tr>
<td></td>
<td></td>
<td><b>Total:</b></td>
<td><b><span t-field="o.total_amount" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/></b></td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</t>
</template>
</t>
</t>
</template>
</odoo>

View File

@@ -1,17 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright (C) 2014-2019 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __manifest__.py
-->
<odoo noupdate="1">
<record id="check_deposit_rule" model="ir.rule">
<field name="name">Check Deposit multi-company</field>
<field name="model_id" ref="model_account_check_deposit"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
<field name="model_id" ref="model_account_check_deposit" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record>
</odoo>

View File

@@ -2,29 +2,28 @@
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.addons.account.tests.account_test_classes\
import AccountingTestCase
import time
from odoo.addons.account.tests.account_test_classes import AccountingTestCase
class TestPayment(AccountingTestCase):
def setUp(self):
super(TestPayment, self).setUp()
self.register_payments_model = self.env['account.register.payments']
self.payment_model = self.env['account.payment']
self.journal_model = self.env['account.journal']
self.account_account_model = self.env['account.account']
self.invoice_model = self.env['account.invoice']
self.invoice_line_model = self.env['account.invoice.line']
self.acc_bank_stmt_model = self.env['account.bank.statement']
self.acc_bank_stmt_line_model = self.env['account.bank.statement.line']
self.res_partner_bank_model = self.env['res.partner.bank']
self.check_deposit_model = self.env['account.check.deposit']
self.register_payments_model = self.env["account.register.payments"]
self.payment_model = self.env["account.payment"]
self.journal_model = self.env["account.journal"]
self.account_model = self.env["account.account"]
self.invoice_model = self.env["account.invoice"]
self.invoice_line_model = self.env["account.invoice.line"]
self.acc_bank_stmt_model = self.env["account.bank.statement"]
self.acc_bank_stmt_line_model = self.env["account.bank.statement.line"]
self.res_partner_bank_model = self.env["res.partner.bank"]
self.check_deposit_model = self.env["account.check.deposit"]
self.partner_agrolait = self.env.ref("base.res_partner_2")
self.currency_eur_id = self.env.ref("base.EUR").id
self.main_company = self.env.ref('base.main_company')
self.main_company = self.env.ref("base.main_company")
self.env.cr.execute(
"""UPDATE res_company SET currency_id = %s
WHERE id = %s""",
@@ -32,123 +31,141 @@ class TestPayment(AccountingTestCase):
)
self.product = self.env.ref("product.product_product_4")
self.payment_method_manual_in = self.env.ref(
"account.account_payment_method_manual_in")
"account.account_payment_method_manual_in"
)
self.payment_method_manual_out = self.env.ref(
"account.account_payment_method_manual_out")
"account.account_payment_method_manual_out"
)
# check if those accounts exist otherwise create them
self.account_receivable = self.account_account_model.search(
[('code', '=', '411100')], limit=1)
self.account_receivable = self.account_model.search(
[("code", "=", "411100")], limit=1
)
if not self.account_receivable:
self.account_receivable = self.account_account_model.create(
{"code": '411100',
"name": "Debtors - (test)",
"reconcile": True,
"user_type_id":
self.ref('account.data_account_type_receivable')
})
self.account_receivable = self.account_model.create(
{
"code": "411100",
"name": "Debtors - (test)",
"reconcile": True,
"user_type_id": self.ref("account.data_account_type_receivable"),
}
)
self.account_revenue = self.account_account_model.search(
[('code', '=', '707100')], limit=1)
self.account_revenue = self.account_model.search(
[("code", "=", "707100")], limit=1
)
if not self.account_revenue:
self.account_revenue = self.account_account_model.create(
{"code": '707100',
"name": "Product Sales - (test)",
"user_type_id":
self.ref('account.data_account_type_revenue')
})
self.account_revenue = self.account_model.create(
{
"code": "707100",
"name": "Product Sales - (test)",
"user_type_id": self.ref("account.data_account_type_revenue"),
}
)
self.received_check_account_id = self.account_account_model.search(
[('code', '=', '511200')], limit=1)
self.received_check_account_id = self.account_model.search(
[("code", "=", "511200")], limit=1
)
if self.received_check_account_id:
if not self.received_check_account_id.reconcile:
self.received_check_account_id.reconcile = True
else:
self.received_check_account_id = self.account_account_model.create(
{"code": '511200',
"name": "Received check - (test)",
"reconcile": True,
"user_type_id":
self.ref('account.data_account_type_liquidity')
})
self.main_company.check_deposit_account_id = \
self.account_account_model.search(
[('code', '=', '511201')], limit=1)
self.received_check_account_id = self.account_model.create(
{
"code": "511200",
"name": "Received check - (test)",
"reconcile": True,
"user_type_id": self.ref("account.data_account_type_liquidity"),
}
)
self.main_company.check_deposit_account_id = self.account_model.search(
[("code", "=", "511201")], limit=1
)
if not self.main_company.check_deposit_account_id:
self.main_company.check_deposit_account_id = \
self.account_account_model.create(
{"code": '511201',
"name": "Check deposited in bank - (test)",
"reconcile": True,
"user_type_id":
self.ref('account.data_account_type_liquidity')
})
self.bank_account_id = self.account_account_model.search(
[('code', '=', '512001')], limit=1)
self.main_company.check_deposit_account_id = self.account_model.create(
{
"code": "511201",
"name": "Check deposited in bank - (test)",
"reconcile": True,
"user_type_id": self.ref("account.data_account_type_liquidity"),
}
)
self.bank_account_id = self.account_model.search(
[("code", "=", "512001")], limit=1
)
if not self.bank_account_id:
self.bank_account_id = self.account_account_model.create(
{"code": '512001',
"name": "Bank - (test)",
"reconcile": True,
"user_type_id":
self.ref('account.data_account_type_liquidity')
})
self.bank_account_id = self.account_model.create(
{
"code": "512001",
"name": "Bank - (test)",
"reconcile": True,
"user_type_id": self.ref("account.data_account_type_liquidity"),
}
)
self.check_journal = self.journal_model.search(
[('code', '=', 'CHK')], limit=1)
self.check_journal = self.journal_model.search([("code", "=", "CHK")], limit=1)
if not self.check_journal:
self.check_journal = self.journal_model.create(
{'name': 'received check', 'type': 'bank', 'code': 'CHK'})
self.check_journal.default_debit_account_id = \
self.received_check_account_id
self.check_journal.default_credit_account_id = \
self.received_check_account_id
self.bank_journal = self.journal_model.search(
[('code', '=', 'BNK1')], limit=1)
{"name": "received check", "type": "bank", "code": "CHK"}
)
self.check_journal.default_debit_account_id = self.received_check_account_id
self.check_journal.default_credit_account_id = self.received_check_account_id
self.bank_journal = self.journal_model.search([("code", "=", "BNK1")], limit=1)
if not self.bank_journal:
self.bank_journal = self.journal_model.create(
{'name': 'Bank', 'type': 'bank', 'code': 'BNK1'})
{"name": "Bank", "type": "bank", "code": "BNK1"}
)
self.bank_journal.default_debit_account_id = self.bank_account_id
self.bank_journal.default_credit_account_id = self.bank_account_id
self.partner_bank_id = self.res_partner_bank_model.search(
[('partner_id', '=', self.main_company.partner_id.id)], limit=1)
[("partner_id", "=", self.main_company.partner_id.id)], limit=1
)
if not self.partner_bank_id:
self.partner_bank_id = self.res_partner_bank_model.create(
{"acc_number": 'SI56 1910 0000 0123 438 584',
"partner_id": self.main_company.partner_id.id,
})
{
"acc_number": "SI56 1910 0000 0123 438 584",
"partner_id": self.main_company.partner_id.id,
}
)
self.bank_journal.bank_account_id = self.partner_bank_id.id
def create_invoice(self, amount=100, inv_type='out_invoice', currency_id=None):
def create_invoice(self, amount=100, inv_type="out_invoice", currency_id=None):
""" Returns an open invoice """
invoice = self.invoice_model.create({
'partner_id': self.partner_agrolait.id,
'currency_id': currency_id,
'name': inv_type == 'out_invoice' and
'invoice to client' or 'invoice to supplier',
'account_id': self.account_receivable.id,
'type': inv_type,
'date_invoice': time.strftime('%Y-%m-%d'),
})
self.invoice_line_model.create({
'product_id': self.product.id,
'quantity': 1,
'price_unit': amount,
'invoice_id': invoice.id,
'name': 'something',
'account_id': self.account_revenue.id,
})
invoice = self.invoice_model.create(
{
"partner_id": self.partner_agrolait.id,
"currency_id": currency_id,
"name": inv_type == "out_invoice"
and "invoice to client"
or "invoice to supplier",
"account_id": self.account_receivable.id,
"type": inv_type,
"date_invoice": time.strftime("%Y-%m-%d"),
}
)
self.invoice_line_model.create(
{
"product_id": self.product.id,
"quantity": 1,
"price_unit": amount,
"invoice_id": invoice.id,
"name": "something",
"account_id": self.account_revenue.id,
}
)
invoice.action_invoice_open()
return invoice
def create_check_deposit(self, move_lines):
""" Returns an validated check deposit """
check_deposit = self.check_deposit_model.create({
'journal_id': self.bank_journal.id,
'bank_journal_id': self.bank_journal.id,
'deposit_date': time.strftime('%Y-%m-%d'),
'currency_id': self.currency_eur_id,
})
check_deposit = self.check_deposit_model.create(
{
"journal_id": self.bank_journal.id,
"bank_journal_id": self.bank_journal.id,
"deposit_date": time.strftime("%Y-%m-%d"),
"currency_id": self.currency_eur_id,
}
)
for move_line in move_lines:
move_line.check_deposit_id = check_deposit
check_deposit.validate_deposit()
@@ -157,38 +174,35 @@ class TestPayment(AccountingTestCase):
def test_full_payment_process(self):
""" Create a payment for on invoice by check,
post it and create check deposit"""
inv_1 = self.create_invoice(
amount=100, currency_id=self.currency_eur_id)
inv_2 = self.create_invoice(
amount=200, currency_id=self.currency_eur_id)
inv_1 = self.create_invoice(amount=100, currency_id=self.currency_eur_id)
inv_2 = self.create_invoice(amount=200, currency_id=self.currency_eur_id)
ctx = {
'active_model': 'account.invoice',
'active_ids': [
inv_1.id,
inv_2.id]}
register_payments = self.register_payments_model.with_context(
ctx).create({
'payment_date': time.strftime('%Y-%m-%d'),
'journal_id': self.check_journal.id,
'payment_method_id': self.payment_method_manual_in.id,
})
ctx = {"active_model": "account.invoice", "active_ids": [inv_1.id, inv_2.id]}
register_payments = self.register_payments_model.with_context(ctx).create(
{
"payment_date": time.strftime("%Y-%m-%d"),
"journal_id": self.check_journal.id,
"payment_method_id": self.payment_method_manual_in.id,
}
)
register_payments.create_payments()
payment = self.payment_model.search([], order="id desc", limit=1)
self.assertAlmostEquals(payment.amount, 300)
self.assertEqual(payment.state, 'posted')
self.assertEqual(inv_1.state, 'paid')
self.assertEqual(inv_2.state, 'paid')
self.assertEqual(payment.state, "posted")
self.assertEqual(inv_1.state, "paid")
self.assertEqual(inv_2.state, "paid")
check_aml = payment.move_line_ids.filtered(
lambda r: r.account_id == self.received_check_account_id)
lambda r: r.account_id == self.received_check_account_id
)
check_deposit = self.create_check_deposit([check_aml])
liquidity_aml = check_deposit.move_id.line_ids.filtered(
lambda r: r.account_id != self.received_check_account_id)
lambda r: r.account_id != self.received_check_account_id
)
self.assertEqual(check_deposit.total_amount, 300)
self.assertEqual(liquidity_aml.debit, 300)
self.assertEqual(check_deposit.move_id.state, 'draft')
self.assertEqual(check_deposit.state, 'done')
self.assertEqual(check_deposit.move_id.state, "draft")
self.assertEqual(check_deposit.state, "done")

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright (C) 2012-2015 Akretion (http://www.akretion.com/)
@author: Benoît GUILLOT <benoit.guillot@akretion.com>
@@ -6,81 +6,96 @@
@author: Alexis de Lattre <alexis.delattre@akretion.com>
Copyright 2018 Tecnativa - Pedro M. Baeza
-->
<odoo>
<record id="account_check_deposit_view_form" model="ir.ui.view">
<field name="model">account.check.deposit</field>
<field name="arch" type="xml">
<form>
<header>
<button name="validate_deposit"
states="draft"
string="Validate"
type="object" class="oe_highlight"/>
<button name="backtodraft"
states="done"
string="Back to Draft"
type="object"/>
<button name="get_report" string="Print" type="object"/>
<field name="state"
widget="statusbar"
statusbar_visible="draft,done"/>
<button
name="validate_deposit"
states="draft"
string="Validate"
type="object"
class="oe_highlight"
/>
<button
name="backtodraft"
states="done"
string="Back to Draft"
type="object"
/>
<button name="get_report" string="Print" type="object" />
<field
name="state"
widget="statusbar"
statusbar_visible="draft,done"
/>
</header>
<sheet>
<div class="oe_title">
<label string="Check Deposit" for="name"/>
<label string="Check Deposit" for="name" />
<h1>
<field name="name"/>
<field name="name" />
</h1>
</div>
<group name="main">
<group name="left">
<field name="deposit_date"/>
<field name="journal_id"
widget="selection"/>
<field name="journal_default_account_id"
invisible="1"/>
<field name="currency_id"
groups="base.group_multi_currency"/>
<field name="bank_journal_id" widget="selection"/>
<field name="deposit_date" />
<field name="journal_id" widget="selection" />
<field name="journal_default_account_id" invisible="1" />
<field
name="currency_id"
groups="base.group_multi_currency"
/>
<field name="bank_journal_id" widget="selection" />
</group>
<group name="right">
<field name="company_id"
groups="base.group_multi_company"/>
<field name="currency_none_same_company_id"
invisible="1"/>
<field name="check_count"/>
<field name="total_amount" widget="monetary"
options="{'currency_field': 'currency_id'}"/>
<field name="move_id"/>
<field
name="company_id"
groups="base.group_multi_company"
/>
<field name="currency_none_same_company_id" invisible="1" />
<field name="check_count" />
<field
name="total_amount"
widget="monetary"
options="{'currency_field': 'currency_id'}"
/>
<field name="move_id" />
</group>
</group>
<group string="Check Payments" name="check_payments">
<field name="check_payment_ids" nolabel="1"
widget="many2many"
domain="[('reconciled', '=', False),
<field
name="check_payment_ids"
nolabel="1"
widget="many2many"
domain="[('reconciled', '=', False),
('debit', '>', 0),
('check_deposit_id', '=', False),
('currency_id', '=', currency_none_same_company_id),
('account_id', '=', journal_default_account_id)]"
context="{'currency': currency_id,
'journal_id': journal_id}">
context="{'currency': currency_id,
'journal_id': journal_id}"
>
<tree>
<field name="date"/>
<field name="date_maturity"/>
<field name="move_id"/>
<field name="journal_id"/>
<field name="name"/>
<field name="ref"/>
<field name="partner_id"/>
<field name="account_id"/>
<field name="debit" sum="Total Debit"/>
<field name="credit" sum="Total Credit"/>
<field name="name"/>
<field name="amount_currency" readonly="True"
groups="base.group_multi_currency"/>
<field name="full_reconcile_id"/>
<field name="date" />
<field name="date_maturity" />
<field name="move_id" />
<field name="journal_id" />
<field name="name" />
<field name="ref" />
<field name="partner_id" />
<field name="account_id" />
<field name="debit" sum="Total Debit" />
<field name="credit" sum="Total Credit" />
<field name="name" />
<field
name="amount_currency"
readonly="True"
groups="base.group_multi_currency"
/>
<field name="full_reconcile_id" />
</tree>
</field>
</group>
@@ -88,59 +103,70 @@
</form>
</field>
</record>
<record id="account_check_deposit_view_tree" model="ir.ui.view">
<field name="name">account.check.deposit.tree</field>
<field name="model">account.check.deposit</field>
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'">
<field name="name"/>
<field name="deposit_date"/>
<field name="journal_id"/>
<field name="bank_journal_id"/>
<field name="check_count"/>
<field name="total_amount"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="is_reconcile"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state"/>
<field name="name" />
<field name="deposit_date" />
<field name="journal_id" />
<field name="bank_journal_id" />
<field name="check_count" />
<field name="total_amount" />
<field name="currency_id" groups="base.group_multi_currency" />
<field name="is_reconcile" />
<field name="company_id" groups="base.group_multi_company" />
<field name="state" />
</tree>
</field>
</record>
<record id="view_check_deposit_search" model="ir.ui.view">
<field name="name">account.check.deposit.search</field>
<field name="model">account.check.deposit</field>
<field name="arch" type="xml">
<search>
<field name="name" string="Checks Deposit"/>
<filter name="draft" string="Draft"
domain="[('state', '=', 'draft')]"/>
<filter name="done" string="Done"
domain="[('state', '=', 'done')]"/>
<field name="name" string="Checks Deposit" />
<filter
name="draft"
string="Draft"
domain="[('state', '=', 'draft')]"
/>
<filter name="done" string="Done" domain="[('state', '=', 'done')]" />
<group string="Group By" name="groupby">
<filter name="date_groupby" string="Deposit Date"
context="{'group_by': 'deposit_date'}"/>
<filter name="journal_groupby" string="Journal"
context="{'group_by': 'journal_id'}"/>
<filter name="currency_groupby" string="Currency"
context="{'group_by': 'currency_id'}"/>
<filter name="bank_journal_id_groupby" string="Bank Account"
context="{'group_by': 'bank_journal_id'}"/>
<filter
name="date_groupby"
string="Deposit Date"
context="{'group_by': 'deposit_date'}"
/>
<filter
name="journal_groupby"
string="Journal"
context="{'group_by': 'journal_id'}"
/>
<filter
name="currency_groupby"
string="Currency"
context="{'group_by': 'currency_id'}"
/>
<filter
name="bank_journal_id_groupby"
string="Bank Account"
context="{'group_by': 'bank_journal_id'}"
/>
</group>
</search>
</field>
</record>
<record id="action_check_deposit_tree" model="ir.actions.act_window">
<field name="name">Checks Deposits</field>
<field name="res_model">account.check.deposit</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem action="action_check_deposit_tree"
id="menu_check_deposit_tree"
parent="account.menu_finance_entries"
sequence="20"/>
<menuitem
action="action_check_deposit_tree"
id="menu_check_deposit_tree"
parent="account.menu_finance_entries"
sequence="20"
/>
</odoo>

View File

@@ -1,13 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2015 Akretion - Alexis de Lattre
Copyright 2018 Tecnativa - Pedro M. Baeza
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="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form" />
@@ -17,5 +14,4 @@
</field>
</field>
</record>
</odoo>

View File

@@ -1,48 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2015 Akretion - Alexis de Lattre
Copyright 2018 Tecnativa - Pedro M. Baeza
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.account_check_deposit</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="inherit_id" ref="account.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='bank_cash']" position="after">
<h2>Check Deposits</h2>
<div class="row mt16 o_settings_container" id="account_check_deposit">
<div class="col-xs-12 col-md-6 o_setting_box" id="account_check_deposit_offsetting_account">
<div class="o_setting_left_pane"/>
<div
class="col-xs-12 col-md-6 o_setting_box"
id="account_check_deposit_offsetting_account"
>
<div class="o_setting_left_pane" />
<div class="o_setting_right_pane">
<label for="check_deposit_offsetting_account"/>
<div class="content-group">
<field name="check_deposit_offsetting_account" class="o_light_label mt16" widget="radio"/>
<label for="check_deposit_offsetting_account" />
<div class="content-group">
<field
name="check_deposit_offsetting_account"
class="o_light_label mt16"
widget="radio"
/>
</div>
</div>
</div>
<div class="col-xs-12 col-md-6 o_setting_box" attrs="{'invisible': ['|', ('has_chart_of_accounts', '=', False), ('check_deposit_offsetting_account', '!=', 'transfer_account')]}" id="account_check_deposit_transfer_account_id">
<div class="o_setting_left_pane"/>
<div
class="col-xs-12 col-md-6 o_setting_box"
attrs="{'invisible': ['|', ('has_chart_of_accounts', '=', False), ('check_deposit_offsetting_account', '!=', 'transfer_account')]}"
id="account_check_deposit_transfer_account_id"
>
<div class="o_setting_left_pane" />
<div class="o_setting_right_pane">
<label for="check_deposit_transfer_account_id"/>
<field name="check_deposit_transfer_account_id" class="oe_inline"
context="{'default_reconcile': True}"
<label for="check_deposit_transfer_account_id" />
<field
name="check_deposit_transfer_account_id"
class="oe_inline"
context="{'default_reconcile': True}"
/>
</div>
</div>
<div class="col-xs-12 col-md-6 o_setting_box" id="account_check_deposit_post_move">
<div
class="col-xs-12 col-md-6 o_setting_box"
id="account_check_deposit_post_move"
>
<div class="o_setting_left_pane">
<field name="check_deposit_post_move" />
</div>
<div class="o_setting_right_pane">
<label for="check_deposit_post_move"/>
<label for="check_deposit_post_move" />
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>