Skip to content
Permalink
Browse files

t

  • Loading branch information...
william-andre committed Mar 18, 2019
1 parent 7764a81 commit 10ec467362602873ffe12581bff979b8613fa3e7
@@ -987,7 +987,7 @@ def action_invoice_re_open(self):

@api.multi
def action_register_payment(self):
return self.env['account.payment'].with_context(active_ids=[self.env.context['params']['id']], active_model='account.invoice').action_register_payment()
return self.env['account.payment'].with_context(active_ids=[self.id], active_model='account.invoice').action_register_payment()

@api.multi
def action_invoice_cancel(self):
@@ -59,7 +59,7 @@ class account_payment(models.Model):
move_reconciled = fields.Boolean(compute="_get_move_reconciled", readonly=True)

state = fields.Selection([('draft', 'Draft'), ('posted', 'Posted'), ('sent', 'Sent'), ('reconciled', 'Reconciled'), ('cancelled', 'Cancelled')], readonly=True, default='draft', copy=False, string="Status")
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money'), ('transfer', 'Internal Transfer')], string='Payment Type', required=True, readonly=True, states={'draft': [('readonly', False)]}) # TODO: transfer only on single payments ?
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money'), ('transfer', 'Internal Transfer')], string='Payment Type', required=True, readonly=True, states={'draft': [('readonly', False)]})
payment_method_id = fields.Many2one('account.payment.method', string='Payment Method Type', required=True, readonly=True, states={'draft': [('readonly', False)]}, oldname="payment_method",
help="Manual: Get paid by cash, check or any other method outside of Odoo.\n"\
"Electronic: Get paid automatically through a payment acquirer by requesting a transaction on a card saved by the customer when buying or subscribing online (payment token).\n"\
@@ -96,7 +96,7 @@ class account_payment(models.Model):
@api.model
def default_get(self, fields):
rec = super(account_payment, self).default_get(fields)
active_ids = self._context.get('active_id')
active_ids = self._context.get('active_ids') or self._context.get('active_id')
active_model = self._context.get('active_model')

# Check for selected invoices ids
@@ -108,6 +108,17 @@ def default_get(self, fields):
# Check all invoices are open
if any(invoice.state != 'open' for invoice in invoices):
raise UserError(_("You can only register payments for open invoices"))

amount = self._compute_payment_amount(invoices, invoices[0].currency_id)
rec.update({
'currency_id': invoices[0].currency_id.id,
'amount': abs(amount),
'payment_type': 'inbound' if amount > 0 else 'outbound',
'partner_id': invoices[0].commercial_partner_id.id,
'partner_type': MAP_INVOICE_TYPE_PARTNER_TYPE[invoices[0].type],
'communication': invoices[0].reference or invoices[0].number,
'invoice_ids': [(6, 0, invoices.ids)],
})
return rec

@api.one
@@ -141,7 +152,7 @@ def _compute_hide_payment_method(self):

@api.depends('invoice_ids', 'amount', 'payment_date', 'currency_id', 'payment_type')
def _compute_payment_difference(self):
for pay in self.filtered(lambda p: p.invoice_ids):
for pay in self.filtered(lambda p: p.invoice_ids and p.state == 'draft'):
payment_amount = -pay.amount if pay.payment_type == 'outbound' else pay.amount
pay.payment_difference = pay._compute_payment_amount() - payment_amount

@@ -161,28 +172,17 @@ def _onchange_journal(self):

# Set payment method domain (restrict to methods enabled for the journal and to selected payment type)
payment_type = self.payment_type in ('outbound', 'transfer') and 'outbound' or 'inbound'
# if i add paypal, empty/useless field appears, can only select in multi

# TODO: check this works https://github.com/odoo/odoo/commit/ec7109c
domain = {'payment_method_id': [('payment_type', '=', payment_type), ('id', 'in', payment_methods_list)]}

if self.env.context.get('active_model') == 'account.invoice':
active_ids = self._context.get('active_ids')
invoices = self.env['account.invoice'].browse(active_ids)
self.amount = abs(self._compute_payment_amount(invoices))

return {'domain': {'payment_method_id': [('payment_type', '=', payment_type), ('id', 'in', payment_methods_list)]}}
return {'domain': domain}
return {}

@api.onchange('invoice_ids')
def _onchange_invoice_ids(self):
# There should be only one invoice_id
self.currency_id = self.invoice_ids[0].currency_id
amount = self._compute_payment_amount(self.invoice_ids)
self.amount = abs(amount)
self.payment_type = 'inbound' if amount > 0 else 'outbound'
self.partner_id = self.invoice_ids[0].commercial_partner_id
self.partner_type = MAP_INVOICE_TYPE_PARTNER_TYPE[self.invoice_ids[0].type]
self.communication = self.invoice_ids[0].reference or self.invoice_ids[0].number

@api.onchange('partner_id')
def _onchange_partner_id(self):
if self.invoice_ids and self.invoice_ids[0].partner_bank_id:
@@ -230,6 +230,8 @@ def _onchange_payment_type(self):
def _compute_journal_domain_and_types(self):
journal_type = ['bank', 'cash']
domain = []
if self.invoice_ids:
domain.append(('company_id', '=', self.invoice_ids[0].company_id.id))
if self.currency_id.is_zero(self.amount) and self.has_invoices:
# In case of payment with 0 amount, allow to select a journal of type 'general' like
# 'Miscellaneous Operations' and set this journal by default.
@@ -247,17 +249,24 @@ def _onchange_amount(self):
jrnl_filters = self._compute_journal_domain_and_types()
journal_types = jrnl_filters['journal_types']
domain_on_types = [('type', 'in', list(journal_types))]
if self.journal_id.type not in journal_types:
if self.invoice_ids:
domain_on_types.append(('company_id', '=', self.invoice_ids[0].company_id.id))
if self.journal_id.type not in journal_types or (self.invoice_ids and self.journal_id.company_id != self.invoice_ids[0].company_id):
self.journal_id = self.env['account.journal'].search(domain_on_types, limit=1)
return {'domain': {'journal_id': jrnl_filters['domain'] + domain_on_types}}

@api.onchange('currency_id')
def _onchange_currency(self):
self.amount = abs(self._compute_payment_amount()) # never check inbound/outbound ?
self.amount = abs(self._compute_payment_amount())

if self.journal_id: # TODO: only return if currency differ?
return

# Set by default the first liquidity journal having this currency if exists.
journal = self.env['account.journal'].search(
[('type', 'in', ('bank', 'cash')), ('currency_id', '=', self.currency_id.id)], limit=1)
domain = [('type', 'in', ('bank', 'cash')), ('currency_id', '=', self.currency_id.id)]
if self.invoice_ids:
domain.append(('company_id', '=', self.invoice_ids[0].company_id.id))
journal = self.env['account.journal'].search(domain, limit=1)
if journal:
return {'value': {'journal_id': journal.id}}

@@ -366,7 +375,7 @@ def action_register_payment(self):
'view_type': 'form',
'view_mode': 'form',
'view_id': len(active_ids) != 1 and self.env.ref('account.view_account_payment_form_multi').id,
'context': {**self.env.context, **{'default_invoice_ids': [(6, False, active_ids)]}},
'context': {**self.env.context, **{'active_model': 'account.invoice', 'active_ids': active_ids}},
'target': len(active_ids) == 1 and 'current' or 'new',
'type': 'ir.actions.act_window',
}
@@ -672,9 +681,26 @@ def default_get(self, fields):
if 'journal_id' not in rec:
rec['journal_id'] = self.env['account.journal'].search([('company_id', '=', self.env.user.company_id.id), ('type', 'in', ('bank', 'cash'))], limit=1).id
if 'payment_method_id' not in rec:
rec['payment_method_id'] = self.env['account.payment.method'].search([], limit=1).id
if invoices[0].type in ('out_invoice', 'in_refund'):
domain = [('payment_type', '=', 'inbound')]
else:
domain = [('payment_type', '=', 'outbound')]
rec['payment_method_id'] = self.env['account.payment.method'].search(domain, limit=1).id
return rec

@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
res = super(payment_register, self).fields_view_get(view_id, view_type, toolbar, submenu)
if 'active_domain' not in self.env.context:
return res

type = [dom[2] for dom in self.env.context['active_domain'] if dom[0] == 'type'][0]
if type in ('out_invoice', 'in_refund'):
res['fields']['payment_method_id']['domain'] = [('payment_type', '=', 'inbound')]
else:
res['fields']['payment_method_id']['domain'] = [('payment_type', '=', 'outbound')]
return res

@api.multi
def _prepare_payment_vals(self, invoices):
'''Create the payment values.
@@ -4,6 +4,19 @@
import time


class group_invoices:
def __init__(self, model, group):
self.model = model
self.group = group

def __enter__(self):
self.previous_state = self.model.env.user.company_id.payment_group_by_partner
self.model.env.user.company_id.payment_group_by_partner = self.group

def __exit__(self, exception_type, exception_value, traceback):
self.model.env.user.company_id.payment_group_by_partner = self.previous_state


@tagged('post_install', '-at_install')
class TestPayment(AccountingTestCase):

@@ -43,19 +56,6 @@ def setUp(self):
self.diff_expense_account = self.env['res.users'].browse(self.env.uid).company_id.expense_currency_exchange_account_id

self.form_payment = Form(self.env['account.payment'])
self.form_payment_register = Form(self.env['account.payment.register'])

class group_invoices:
def __init__(self, model, group):
self.model = model
self.group = group

def __enter__(self):
self.previous_state = self.model.env.user.company_id.payment_group_by_partner
self.model.env.user.company_id.payment_group_by_partner = self.group

def __exit__(self, exception_type, exception_value, traceback):
self.model.env.user.company_id.payment_group_by_partner = self.previous_state

def create_invoice(self, amount=100, type='out_invoice', currency_id=None, partner=None, account_id=None):
""" Returns an open invoice """
@@ -108,7 +108,7 @@ def test_full_payment_process(self):
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
with self.group_invoices(self, True):
with group_invoices(self, True):
register_payments.create_payments()
payment = self.payment_model.search([], order="id desc", limit=1)

@@ -186,7 +186,7 @@ def test_multiple_payments_00(self):
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
with self.group_invoices(self, True):
with group_invoices(self, True):
register_payments.create_payments()
payment_ids = self.payment_model.search([('invoice_ids', 'in', ids)], order="id desc")

@@ -237,7 +237,7 @@ def test_partial_payment(self):
# Test Customer Invoice
inv_1 = self.create_invoice(amount=600)
ids = [inv_1.id]
payment_register = Form(self.env['account.payment'].with_context(default_invoice_ids=ids))
payment_register = Form(self.env['account.payment'].with_context(active_model='account.invoice', active_ids=ids))
with payment_register as pr:
pr.payment_date = time.strftime('%Y') + '-07-15'
pr.journal_id = self.bank_journal_euro
@@ -261,7 +261,7 @@ def test_partial_payment(self):
# Test Vendor Bill
inv_2 = self.create_invoice(amount=500, type='in_invoice', partner=self.partner_china_exp.id)
ids = [inv_2.id]
payment_register = Form(self.env['account.payment'].with_context(default_invoice_ids=ids))
payment_register = Form(self.env['account.payment'].with_context(active_model='account.invoice', active_ids=ids))
with payment_register as pr:
pr.payment_date = time.strftime('%Y') + '-07-15'
pr.journal_id = self.bank_journal_euro
@@ -302,7 +302,7 @@ def test_multiple_receivables(self):
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
with self.group_invoices(self, True):
with group_invoices(self, True):
register_payments.create_payments()
payment_ids = self.payment_model.search([('invoice_ids', 'in', ids)], order="id desc")

@@ -351,7 +351,7 @@ def test_register_payment_group_invoices(self):
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
with self.group_invoices(self, True):
with group_invoices(self, True):
register_payments1.create_payments()
payment_ids1 = self.payment_model.search([('invoice_ids', 'in', ids1)], order="id desc")
self.assertEqual(len(payment_ids1), 3, "3 payments should have been created, one fo each (partner, receivable account).")
@@ -363,7 +363,7 @@ def test_register_payment_group_invoices(self):
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
with self.group_invoices(self, False):
with group_invoices(self, False):
register_payments2.create_payments()
payment_ids2 = self.payment_model.search([('invoice_ids', 'in', ids2)], order="id desc")
self.assertEqual(len(payment_ids2), 4, "Not grouping payments should always create a distinct payment per invoice.")
@@ -159,7 +159,7 @@
<field name="amount"/>
<field name="currency_id" options="{'no_create': True, 'no_open': True}" groups="base.group_multi_currency"/>
</div>
<field name="journal_id" widget="selection" attrs="{'invisible': [('amount', '=', 0)]}"/>
<field name="journal_id" widget="selection" attrs="{'invisible': [('amount', '=', 0), ('state', '!=', 'draft')]}"/>
<field name="destination_journal_id" widget="selection" attrs="{'required': [('payment_type', '=', 'transfer')], 'invisible': [('payment_type', '!=', 'transfer')]}"/>
<field name="hide_payment_method" invisible="1"/>
<field name="payment_method_id" string=" " widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)]}"/>
@@ -203,13 +203,13 @@
<field name="payment_method_id" string=" " widget="radio"/>
</group>
<group>
<field name="journal_id"/>
<field name="journal_id" widget="selection"/>
<field name="payment_date"/>
</group>
</group>
<footer>
<button string="Create Payment" name="create_payments" type="object" class="oe_highlight"/>
<button string="Cancel" class="btn btn-default" special="cancel"/>
<button string="Cancel" class="btn btn-secondary" special="cancel"/>
</footer>
</form>
</field>
@@ -7,6 +7,18 @@

INV_LINES_PER_STUB = 9

class AccountPaymentRegister(models.TransientModel):
_inherit = "account.payment.register"

def _prepare_payment_vals(self, invoices):
res = super(AccountPaymentRegister, self)._prepare_payment_vals(invoices)
if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
currency_id = self.env['res.currency'].browse(res['currency_id'])
res.update({
'check_amount_in_words': currency_id.amount_to_text(res['amount']),
})
return res


class AccountPayment(models.Model):
_inherit = "account.payment"
@@ -38,14 +50,6 @@ def _check_communication(self, payment_method_id, communication):
if len(communication) > 60:
raise ValidationError(_("A check memo cannot exceed 60 characters."))

def _prepare_payment_vals(self, invoices):
res = super(AccountPayment, self)._prepare_payment_vals(invoices)
if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
res.update({
'check_amount_in_words': self.currency_id.amount_to_text(res['amount']),
})
return res

@api.multi
def post(self):
res = super(AccountPayment, self).post()
@@ -50,7 +50,7 @@ def create_invoice(self, amount=100, is_refund=False):
return invoice

def create_payment(self, invoices):
payment_register = Form(self.env['account.payment'].with_context(default_invoice_ids=invoices.ids))
payment_register = Form(self.env['account.payment'].with_context(active_model='account.invoice', active_ids=invoices.ids))
payment_register.payment_date = time.strftime('%Y') + '-07-15'
payment_register.journal_id = self.bank_journal
payment_register.payment_method_id = self.payment_method_check
@@ -62,9 +62,11 @@ def create_payment(self, invoices):
def test_print_check(self):
# Make a payment for 10 invoices and 5 credit notes
invoices = self.env['account.invoice']
for i in range(0,15):
for i in range(0, 15):
invoices |= self.create_invoice(is_refund=(i % 3 == 0))
payment = self.create_payment(invoices)
self.assertEqual(all(payment.mapped('check_amount_in_words')), True, 'The amount in words is not set on all the payments')
self.assertEqual(all(payment.mapped('check_number')), True, 'The check number is not set on all the payments')

# Check the data generated for the report
self.env.ref('base.main_company').write({'account_check_printing_multi_stub': True})
@@ -73,3 +75,16 @@ def test_print_check(self):
self.env.ref('base.main_company').write({'account_check_printing_multi_stub': False})
report_pages = payment._check_get_pages()
self.assertEqual(len(report_pages), 1)

def test_from_register(self):
invoices = self.env['account.invoice']
for i in range(0, 3):
invoices |= self.create_invoice(is_refund=(i % 3 == 0))
payment_register = Form(self.env['account.payment.register'].with_context(active_model='account.invoice', active_ids=invoices.ids))
payment_register.payment_date = time.strftime('%Y') + '-07-15'
payment_register.journal_id = self.bank_journal
payment_register.payment_method_id = self.payment_method_check
domain = payment_register.save().create_payments()['domain']
payment = self.env['account.payment'].search(domain)

self.assertEqual(all(payment.mapped('check_amount_in_words')), True, 'The amount in words is not set on all the payments')

0 comments on commit 10ec467

Please sign in to comment.
You can’t perform that action at this time.