diff --git a/account_banking_aggregate_payment/model/export_aggregate.py b/account_banking_aggregate_payment/model/export_aggregate.py new file mode 100644 index 000000000..fb77f105d --- /dev/null +++ b/account_banking_aggregate_payment/model/export_aggregate.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +from openerp.tools.translate import _ +from openerp import netsvc + +class banking_export_aggregate(orm.TransientModel): + _name = 'banking.export.aggregate' + _columns = { + 'payment_order_id': fields.many2one( + 'payment.order', 'Payment order'), + 'reference': fields.char( + 'Reference', size=24), + } + + def reconcile_lines(self, cr, uid, move_line_ids, context=None): + """ + Reconcile move lines lines, really. Talk about core functionality + """ + reconcile_obj = self.pool.get('account.move.reconcile') + account_move_line_obj = self.pool.get('account.move.line') + currency_obj = self.pool.get('res.currency') + lines = account_move_line_obj.browse(cr, uid, move_line_ids, context=context) + + for line in lines[1:]: + if line.account_id != lines[0].account_id: + raise orm.except_orm( + _('Error'), + _('Cannot reconcile between different accounts')) + + if any(lines, + lambda line: line.reconcile_id and line.reconcile_id.line_id): + raise orm.except_orm( + _('Error'), + _('Line is already fully reconciled')) + + currency = lines[0].company_id.currency_id + + partials = [] + line_ids = [] + for line in lines: + if line.id not in line_ids: + line_ids.append(line.id) + if line.reconcile_partial_id: + line_ids += line.reconcile_partial_id.line_partial_ids + if line.reconcile_partial_id.id not in partials: + partials.append(line.reconcile_partial_id.id) + + total = account_move_line_obj.get_balance(cr, uid, line_ids) + is_zero = currency_obj.is_zero(cr, uid, currency, total) + + vals = { + 'type': 'auto', + 'line_id': is_zero and [(6, 0, line_ids)] or [(6, 0, [])], + 'line_partial_ids': is_zero and [(6, 0, [])] or [(6, 0, line_ids)], + } + + if partials: + if len(partials) > 1: + reconcile_obj.unlink( + cr, uid, partials[1:], context=context) + reconcile_obj.write( + cr, uid, partials[0], + vals, context=context) + else: + reconcile_obj.create( + cr, uid, vals, context=context) + + for line_id in line_ids: + netsvc.LocalService("workflow").trg_trigger( + uid, 'account.move.line', line_id, cr) + return True + + def create_aggregate_order(self, cr, uid, ids, context=None): + wiz = self.browse(cr, uid, ids[0], context=context) + account_move_line_obj = self.pool.get('account.move.line') + account_move_obj = self.pool.get('account.move') + payment_order_obj = self.pool.get('payment.order') + payment_order_line_obj = self.pool.get('payment.order.line') + payment_order_ids = context.get('active_ids', []) + if not payment_order_ids: + raise orm.except_orm( + _('Error'), + _('Please select a payment order')) + if len(payment_order_ids) > 1: + raise orm.except_orm( + _('Error'), + _('This operation can only be performed on a single payment order')) + order = payment_order_obj.browse( + cr, uid, payment_order_ids[0], context=context) + if not (order.mode.transfer_journal_id and + order.mode.transfer_account_id): + raise orm.except_orm( + _('Error'), + _('Transfer journal or account are not filled ' + 'in on the payment mode')) + + move_id = account_move_obj.create(cr, uid, { + 'journal_id': order.mode.transfer_journal_id.id, + 'name': 'Aggregate Payment Order', # TODO: get order reference or number + 'reference': 'AGG', # TODO get order reference number or number + }, context=context) + + counter_move_line_ids = [] + for line in order.line_ids: + # basic checks + if not line.move_line_id: + raise orm.except_orm( + _('Error'), + _('No move line provided for line %s') % line.name) + if line.move_line_id.reconcile_id: + raise orm.except_orm( + _('Error'), + _('Move line %s has already been paid/reconciled') % + line.move_line_id.name + ) + + # TODO: take multicurrency into account + + # create the move line on the transfer account + vals = { + 'name': 'Aggregate payment for %s' % ( + line.move_line_id.invoice and + line.move_line_id.invoice.number or + line.move_line_id.name), + 'move_id': move_id, + 'partner_id': line.partner_id and line.partner_id.id or False, + 'account_id': order.mode.transfer_account_id.id, + 'credit': line.amount, + 'debit': 0.0, + 'date': fields.date.context_today(self, cr, uid, context=context), + } + counter_move_line_id = account_move_line_obj.create( + cr, uid, vals, context=context) + counter_move_line_ids.append(counter_move_line_id) + + # create the debit move line on the receivable account + vals.update({ + 'account_id': line.move_line_id.account_id.id, + 'credit': 0.0, + 'debit': line.amount, + }) + reconcile_move_line_id = account_move_line_obj.create( + cr, uid, vals, context=context) + + self.reconcile_lines( + cr, uid, [reconcile_move_line_id, counter_move_line_id], + context=context) + + total = account_move_line_obj.get_balance( + cr, uid, counter_move_line_ids) + + vals = { + 'name': 'Aggregate payment for %s' % ( + line.move_line_id.invoice and + line.move_line_id.invoice.number or + line.move_line_id.name), + 'move_id': move_id, + 'partner_id': order.mode.aggregate_partner_id.id, + 'account_id': order.mode.transfer_account_id.id, + 'credit': 0.0, + 'debit': total, + 'date': fields.date.context_today(self, cr, uid, context=context), + } + aggregate_move_line_id = account_move_line_obj.create( + cr, uid, vals, context=context) + + self.reconcile_lines( + cr, uid, counter_move_line_ids + [aggregate_move_line_id], + context=context) + + # create the credit move line on the aggregate partner + vals.update({ + 'account_id': order.mode.aggregate_partner_id.property_account_payable.id, + 'partner_id': order.mode.aggregate_partner_id.id, + 'credit': total, + 'debit': 0.0, + }) + + payable_move_line = account_move_line_obj.browse( + cr, uid, + account_move_line_obj.create( + cr, uid, vals, context=context), + context=context) + + account_move_obj.post(cr, uid, [move_id], context=context) + + wf_service = netsvc.LocalService('workflow') + wf_service.trg_validate(uid, 'payment.order', order.id, 'sent', cr) + wf_service.trg_validate(uid, 'payment.order', order.id, 'done', cr) + order.refresh() + if order.state != 'done': + raise orm.except_orm( + _('Error'), + _('Payment order workflow does not go into state "done"')) + + payment_order_id = payment_order_obj.create( + cr, uid, { + 'company_id': order.company_id.id, + 'mode': order.mode.aggregate_mode_id.id, + }, context=context) + + payment_order_line_obj.create(cr, uid,{ + 'move_line_id': payable_move_line.id, + 'amount_currency': payable_move_line.amount_to_pay, + 'bank_id': line2bank.get(line.id), # TODO line2bank get it from account_banking + 'order_id': payment_order_id, + 'partner_id': order.mode.aggregate_partner_id.id, + 'communication': False, + 'communication2': payable_move_line.ref, + 'state': 'normal', + 'date': False, + 'currency': (line.journal_id.currency.id or + line.journal_id.company_id.currency_id.id), + }, context=context) + + return ### act_window to payment order{'type': 'ir.actions.act_window_close'} diff --git a/account_banking_aggregate_payment/model/payment_mode.py b/account_banking_aggregate_payment/model/payment_mode.py index cb7ae692c..dc4bf21e8 100644 --- a/account_banking_aggregate_payment/model/payment_mode.py +++ b/account_banking_aggregate_payment/model/payment_mode.py @@ -1,4 +1,4 @@ -o# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution