[MERGE] account check printing fixes and refactoring

- Use account_check_printing as the basis for other modules to add actual
check printing facilities
- Some usability fixes
This commit is contained in:
Arthur Maniet
2015-08-10 14:36:09 +02:00
18 changed files with 127 additions and 61 deletions
+3 -3
View File
@@ -57,9 +57,9 @@ file_filter = addons/account_chart/i18n/<lang>.po
source_file = addons/account_chart/i18n/account_chart.pot
source_lang = en
[odoo-9.account_check_writing]
file_filter = addons/account_check_writing/i18n/<lang>.po
source_file = addons/account_check_writing/i18n/account_check_writing.pot
[odoo-9.account_check_printing]
file_filter = addons/account_check_printing/i18n/<lang>.po
source_file = addons/account_check_printing/i18n/account_check_printing.pot
source_lang = en
[odoo-9.account_followup]
-3
View File
@@ -69,9 +69,6 @@ class AccountConfigSettings(models.TransientModel):
period_lock_date = fields.Date(string="Lock Date for Non-Advisers", related='company_id.period_lock_date', help="Only users with the 'Adviser' role can edit accounts prior to and inclusive of this date. Use it for period locking inside an open fiscal year, for example.")
fiscalyear_lock_date = fields.Date(string="Lock Date", related='company_id.fiscalyear_lock_date', help="No users, including Advisers, can edit accounts prior to and inclusive of this date. Use it for fiscal year locking for example.")
module_account_check_writing = fields.Boolean(string='Pay your vendors by check',
help='This allows you to check writing and printing.\n'
'-This installs the module account_check_writing.')
module_account_accountant = fields.Boolean(string='Full accounting features: journals, legal statements, chart of accounts, etc.',
help="""If you do not check this box, you will be able to do invoicing & payments,
but not accounting (Journal Items, Chart of Accounts, ...)""")
-4
View File
@@ -163,10 +163,6 @@
domain="[('type_tax_use', 'in', ('purchase', 'all')), ('company_id', '=', company_id)]"
class="oe_inline"/>
</div>
<div>
<field name="module_account_check_writing" class="oe_inline"/>
<label for="module_account_check_writing"/>
</div>
</div>
</group>
<separator string="Bank &amp; Cash"/>
@@ -3,3 +3,5 @@
import account_journal
import account_journal_dashboard
import account_payment
import wizard
@@ -1,24 +1,23 @@
# -*- coding: utf-8 -*-
{
'name': 'Check Writing',
'name': 'Check Printing Base',
'version': '1.0',
'author': 'Odoo SA',
'category': 'Generic Modules/Accounting',
'summary': 'Keep Track of Checks Payments',
'category': 'Hidden/Dependency',
'summary': 'Check printing commons',
'description': """
Check Writing
=============
This module allows to register your payments by check in odoo.
You can also print checks by installing a module that adds country-specific check printing.
This module offers the basic functionalities to make payments by printing checks.
It must be used as a dependency for modules that provide country-specific check templates.
The check settings are located in the accounting journals configuration page.
""",
'website': 'https://www.odoo.com/page/accounting',
'depends' : ['account_accountant'],
'data': [
'data/check_writing.xml',
'data/check_printing.xml',
'views/account_journal_dashboard_view.xml',
'views/account_journal_view.xml',
'views/account_payment_view.xml',
'wizard/print_pre_numbered_checks.xml'
],
'installable': True,
'auto_install': False,
@@ -8,8 +8,8 @@ class AccountJournal(models.Model):
@api.one
@api.depends('outbound_payment_method_ids')
def _compute_check_writing_payment_method_selected(self):
self.check_writing_payment_method_selected = any(pm.code == 'check_writing' for pm in self.outbound_payment_method_ids)
def _compute_check_printing_payment_method_selected(self):
self.check_printing_payment_method_selected = any(pm.code == 'check_printing' for pm in self.outbound_payment_method_ids)
@api.one
@api.depends('check_manual_sequencing')
@@ -32,8 +32,8 @@ class AccountJournal(models.Model):
help="Checks numbering sequence.")
check_next_number = fields.Integer('Next Check Number', compute='_get_check_next_number', inverse='_set_check_next_number',
help="Sequence number of the next printed check.")
check_writing_payment_method_selected = fields.Boolean(compute='_compute_check_writing_payment_method_selected',
help="Technical feature used to know whether check writing was enabled as payment method.")
check_printing_payment_method_selected = fields.Boolean(compute='_compute_check_printing_payment_method_selected',
help="Technical feature used to know whether check printing was enabled as payment method.")
@api.model
def create(self, vals):
@@ -60,18 +60,18 @@ class AccountJournal(models.Model):
def _default_outbound_payment_methods(self):
methods = super(AccountJournal, self)._default_outbound_payment_methods()
return methods + self.env.ref('account_check_writing.account_payment_method_check_writing')
return methods + self.env.ref('account_check_printing.account_payment_method_check')
@api.model
def _enable_check_writing_on_bank_journals(self):
""" Enables check writing payment method and add a check sequence on bank journals.
def _enable_check_printing_on_bank_journals(self):
""" Enables check printing payment method and add a check sequence on bank journals.
Called upon module installation via data file.
"""
check_writing = self.env.ref('account_check_writing.account_payment_method_check_writing')
check_printing = self.env.ref('account_check_printing.account_payment_method_check')
bank_journals = self.search([('type', '=', 'bank')])
for bank_journal in bank_journals:
check_sequence = self._create_check_sequence({'name': bank_journal.name, 'company_id': bank_journal.company_id.id})
bank_journal.write({
'outbound_payment_method_ids': [(4, check_writing.id, None)],
'outbound_payment_method_ids': [(4, check_printing.id, None)],
'check_sequence_id': check_sequence.id,
})
@@ -9,7 +9,7 @@ class account_journal(models.Model):
def get_journal_dashboard_datas(self):
domain_checks_to_print = [
('journal_id', '=', self.id),
('payment_method_id.code', '=', 'check_writing'),
('payment_method_id.code', '=', 'check_printing'),
('state','=','posted')
]
return dict(
@@ -30,6 +30,6 @@ class account_journal(models.Model):
journal_id=self.id,
default_journal_id=self.id,
default_payment_type='outbound',
default_payment_method_id=self.env.ref('account_check_writing.account_payment_method_check_writing').id,
default_payment_method_id=self.env.ref('account_check_printing.account_payment_method_check').id,
),
}
@@ -37,7 +37,7 @@ class account_register_payments(models.TransientModel):
def get_payment_vals(self):
res = super(account_register_payments, self).get_payment_vals()
if self.payment_method_id == self.env.ref('account_check_writing.account_payment_method_check_writing'):
if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
res.update({
'check_amount_in_words': self.check_amount_in_words,
'check_manual_sequencing': self.check_manual_sequencing,
@@ -74,7 +74,7 @@ class account_payment(models.Model):
def _check_communication(self, payment_method_id, communication):
super(account_payment, self)._check_communication(payment_method_id, communication)
if payment_method_id == self.env.ref('account_check_writing.account_payment_method_check_writing').id:
if payment_method_id == self.env.ref('account_check_printing.account_payment_method_check').id:
if not communication:
return
if len(communication) > 60:
@@ -82,20 +82,20 @@ class account_payment(models.Model):
@api.model
def create(self, vals):
if vals['payment_method_id'] == self.env.ref('account_check_writing.account_payment_method_check_writing').id\
if vals['payment_method_id'] == self.env.ref('account_check_printing.account_payment_method_check').id\
and vals.get('check_manual_sequencing'):
sequence = self.env['account.journal'].browse(vals['journal_id']).check_sequence_id
vals.update({'check_number': sequence.next_by_id()})
return super(account_payment, self.sudo()).create(vals)
@api.multi
def send_checks(self):
def print_checks(self):
""" Check that the recordset is valid, set the payments state to sent and call print_checks() """
# Since this method can be called via a client_action_multi, we need to make sure the received records are what we expect
self = self.filtered(lambda r: r.payment_method_id.code == 'check_writing' and r.state != 'reconciled')
self = self.filtered(lambda r: r.payment_method_id.code == 'check_printing' and r.state != 'reconciled')
if len(self) == 0:
raise UserError(_("Payments to print as a checks must have 'Check Writing' selected as payment method and "
raise UserError(_("Payments to print as a checks must have 'Check' selected as payment method and "
"not have already been reconciled"))
if any(payment.journal_id != self[0].journal_id for payment in self):
raise UserError(_("In order to print multiple checks at once, they must belong to the same bank journal."))
@@ -103,9 +103,34 @@ class account_payment(models.Model):
self.filtered(lambda r: r.state == 'draft').post()
self.write({'state': 'sent'})
return self.print_checks()
if not self[0].journal_id.check_manual_sequencing:
# The wizard asks for the number printed on the first pre-printed check
# so payments are attributed the number of the check the'll be printed on.
last_printed_check = self.search([
('journal_id', '=', self[0].journal_id.id),
('check_number', '!=', 0)], order="check_number desc", limit=1)
next_check_number = last_printed_check and last_printed_check.check_number + 1 or 1
return {
'name': _('Print Pre-numbered Checks'),
'type': 'ir.actions.act_window',
'res_model': 'print.prenumbered.checks',
'view_type': 'form',
'view_mode': 'form',
'target': 'new',
'context': {
'payment_ids': self.ids,
'default_next_check_number': next_check_number,
}
}
else:
return self.do_print_checks()
@api.multi
def print_checks(self):
def unmark_sent(self):
self.write({'state': 'posted'})
@api.multi
def do_print_checks(self):
""" This method is a hook for l10n_xx_check_printing modules to implement actual check printing capabilities """
pass
raise UserError(_("There is no check layout configured.\nMake sure the proper check printing module is installed"
" and its configuration (in company settings > 'Configuration' tab) is correct."))
@@ -2,29 +2,29 @@
<openerp>
<data noupdate="1">
<record id="account_payment_method_check_writing" model="account.payment.method">
<record id="account_payment_method_check" model="account.payment.method">
<field name="name">Check</field>
<field name="code">check_writing</field>
<field name="code">check_printing</field>
<field name="payment_type">outbound</field>
</record>
<function model="account.journal" name="_enable_check_writing_on_bank_journals"/>
<function model="account.journal" name="_enable_check_printing_on_bank_journals"/>
<record model="ir.actions.server" id="action_account_send_checks">
<record model="ir.actions.server" id="action_account_print_checks">
<field name="name">Print Checks</field>
<field name="model_id" ref="account.model_account_payment"/>
<field name="code">
if context.get('active_model') == 'account.payment' and context.get('active_ids'):
action = self.pool['account.payment'].send_checks(cr, uid, context['active_ids'], context=context)
action = self.pool['account.payment'].print_checks(cr, uid, context['active_ids'], context=context)
</field>
</record>
<record model="ir.values" id="account_send_checks">
<record model="ir.values" id="account_print_checks">
<field name="model_id" ref="account.model_account_payment" />
<field name="name">Print Checks</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.server,' +str(ref('action_account_send_checks'))" />
<field name="value" eval="'ir.actions.server,' +str(ref('action_account_print_checks'))" />
<field name="key">action</field>
<field name="model">account.payment</field>
</record>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -1,7 +1,7 @@
from openerp.addons.account.tests.account_test_classes import AccountingTestCase
import time
class TestCheckWriting(AccountingTestCase):
class TestCheckPrinting(AccountingTestCase):
def setUp(self):
super(TestCheckWriting, self).setUp()
@@ -11,13 +11,14 @@ class TestCheckWriting(AccountingTestCase):
self.partner_axelor = self.env.ref("base.res_partner_13")
self.product = self.env.ref("product.product_product_4")
self.payment_method_check = self.env.ref("account_check_writing.account_payment_method_check_writing")
self.payment_method_check = self.env.ref("account_check_printing.account_payment_method_check")
self.account_payable = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1)
self.account_expenses = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_expenses').id)], limit=1)
self.bank = self.env['res.partner.bank'].create({'acc_number': '0123456789', 'bank_name': 'Test Bank', 'company_id': self.env.user.company_id.id})
self.bank_journal = self.bank.journal_id
self.bank_journal.check_manual_sequencing = True
def create_invoice(self, amount=100, is_refund=False):
invoice = self.invoice_model.create({
@@ -54,5 +55,5 @@ class TestCheckWriting(AccountingTestCase):
def test_send_check(self):
# Create a payment and 'send' the check
payment = self.create_payment(self.create_invoice())
payment.send_checks()
payment.print_checks()
self.assertEqual(payment.state, 'sent')
@@ -7,8 +7,8 @@
<field name="inherit_id" ref="account.view_account_journal_form" />
<field name="arch" type="xml">
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
<group string="Check Writing" attrs="{'invisible': [('check_writing_payment_method_selected', '=', False)]}">
<field name="check_writing_payment_method_selected" invisible="1"/>
<group string="Check Printing" attrs="{'invisible': [('check_printing_payment_method_selected', '=', False)]}">
<field name="check_printing_payment_method_selected" invisible="1"/>
<field name="check_sequence_id" invisible="1"/>
<field name="check_manual_sequencing"/>
<field name="check_next_number" attrs="{'invisible': [('check_manual_sequencing', '=', False)]}"/>
@@ -7,14 +7,15 @@
<field name="inherit_id" ref="account.view_account_payment_form" />
<field name="arch" type="xml">
<xpath expr="//button[@name='post']" position="before">
<button name="send_checks" class="oe_highlight" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_writing'), ('state', 'not in', ('posted', 'sent'))]}" string="Send Check" type="object"/>
<button name="print_checks" class="oe_highlight" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_printing'), ('state', '!=', 'posted')]}" string="Print Check" type="object"/>
<button name="unmark_sent" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_printing'), ('state', '!=', 'sent')]}" string="Unmark Sent" type="object"/>
</xpath>
<xpath expr="//div[@name='amount_div']" position="after">
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_writing')], 'readonly': [('state', '!=', 'draft')]}"/>
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_printing')], 'readonly': [('state', '!=', 'draft')]}" groups="base.group_no_one"/>
</xpath>
<xpath expr="//field[@name='communication']" position="after">
<field name="check_manual_sequencing" invisible="1"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_writing'), ('check_number', '=', 0)]}"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_printing'), ('check_number', '=', 0)]}"/>
</xpath>
</field>
</record>
@@ -25,11 +26,11 @@
<field name="inherit_id" ref="account.view_account_payment_invoice_form" />
<field name="arch" type="xml">
<xpath expr="//div[@name='amount_div']" position="after">
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_writing')]}"/>
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_printing')]}" groups="base.group_no_one"/>
</xpath>
<xpath expr="//field[@name='communication']" position="after">
<field name="check_manual_sequencing" invisible="1"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_writing'), ('check_manual_sequencing', '=', False)]}"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_printing'), ('check_manual_sequencing', '=', False)]}"/>
</xpath>
</field>
</record>
@@ -40,22 +41,22 @@
<field name="inherit_id" ref="account.view_account_payment_from_invoices" />
<field name="arch" type="xml">
<xpath expr="//field[@name='amount']" position="after">
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_writing')]}"/>
<field name="check_amount_in_words" attrs="{'invisible': [('payment_method_code', '!=', 'check_printing')]}" groups="base.group_no_one"/>
</xpath>
<xpath expr="//field[@name='communication']" position="after">
<field name="check_manual_sequencing" invisible="1"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_writing'), ('check_manual_sequencing', '=', False)]}"/>
<field name="check_number" attrs="{'invisible': ['|', ('payment_method_code', '!=', 'check_printing'), ('check_manual_sequencing', '=', False)]}"/>
</xpath>
</field>
</record>
<record id="view_payment_check_writing_search" model="ir.ui.view">
<field name="name">account.payment.check.writing.search</field>
<record id="view_payment_check_printing_search" model="ir.ui.view">
<field name="name">account.payment.check.printing.search</field>
<field name="model">account.payment</field>
<field name="inherit_id" ref="account.view_account_payment_search"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='state_sent']" position="before">
<filter string="Checks To Send" domain="[('payment_method_id.code', '=', 'check_writing'), ('state','=','posted')]" name="checks_to_send"/>
<filter string="Checks To Print" domain="[('payment_method_id.code', '=', 'check_printing'), ('state','=','posted')]" name="checks_to_send"/>
</xpath>
</field>
</record>
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import print_pre_numbered_checks
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models
class print_pre_numbered_checks(models.TransientModel):
_name = 'print.prenumbered.checks'
_description = 'Print Pre-numbered Checks'
next_check_number = fields.Integer('Next Check Number', required=True)
@api.multi
def print_checks(self):
check_number = self.next_check_number
payments = self.env['account.payment'].browse(self.env.context['payment_ids'])
for payment in payments:
payment.check_number = check_number
check_number += 1
return payments.do_print_checks()
@@ -0,0 +1,25 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="print_pre_numbered_checks_view" model="ir.ui.view">
<field name="name">Print Pre-numbered Checks</field>
<field name="model">print.prenumbered.checks</field>
<field name="arch" type="xml">
<form string="Print Pre-numbered Checks">
<p>Please enter the number of the first pre-printed check that you are about to print on.</p>
<p>This will allow to save on payments the number of the corresponding check.</p>
<group>
<field name="next_check_number"/>
</group>
<footer>
<button name="print_checks" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
</data>
</openerp>
@@ -1 +0,0 @@
from . import test_check_writing