~unifield-team/unifield-wm/us-826

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2011 TeMPO Consulting, MSF. All Rights Reserved
#    Developer: Olivier DOSSMANN
#
#    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 <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import osv
from osv import fields
from tools.translate import _

class wizard_down_payment(osv.osv_memory):
    _name = 'wizard.down.payment'
    _description = 'Down payment'

    _columns = {
        'register_line_id': fields.many2one('account.bank.statement.line', string="Register line", readonly=True, required=True),
        'purchase_id': fields.many2one('purchase.order', string="Purchase Order", readonly=True, required=False, 
            states={'draft': [('readonly', False), ('required', True)]}),
        'state': fields.selection([('draft', 'Draft'), ('closed', 'Closed')], string="State", required=True),
        'currency_id': fields.many2one('res.currency', string="Register line currency", required=True, readonly=True),
        'partner_id': fields.many2one('res.partner', string="Register line 3rd party", required=True, readonly=True),
    }

    _defaults = {
        'state': lambda *a: 'closed',
    }

    def check_register_line_and_po(self, cr, uid, absl_id, po_id, context=None):
        """
        Verify that register line amount is not superior to (PO total_amount - all used down payments - open/paid invoices).
        Check partner on register line AND PO (should be equal)
        """
        # Some verifications
        if not absl_id or not po_id:
            return False
        if not context:
            context = {}
        if isinstance(absl_id, list):
            absl_id = absl_id[0]
        if isinstance(po_id, list):
            po_id = po_id[0]
        # Prepare some values
        po_obj = self.pool.get('purchase.order')
        po = po_obj.read(cr, uid, po_id, ['partner_id', 'down_payment_ids', 'amount_total'])
        absl = self.pool.get('account.bank.statement.line').browse(cr, uid, absl_id)
        # Verify that PO partner is the same as down payment partner
        if not absl.partner_id:
            raise osv.except_osv(_('Warning'), _('Third Party is mandatory for down payments!'))
        if po.get('partner_id', [False])[0] != absl.partner_id.id:
            raise osv.except_osv(_('Error'), _('Third party from Down payment and Purchase Order are different!'))
        total = po.get('amount_total', 0.0)
        for dp in po_obj.read(cr, uid, po.get('down_payment_ids', []), ['amount_currency', 'down_payment_amount']):
            move_ids = [x.id or None for x in absl.move_ids]
            operator = 'in'
            if len(move_ids) == 1:
                operator = '='
            move_line_ids = self.pool.get('account.move.line').search(cr, uid, [('account_id', '=', absl.account_id.id), 
                ('move_id', operator, move_ids)])
            if dp.get('id') not in move_line_ids:
                total -= (dp.get('amount_currency', 0.0) - dp.get('down_payment_amount', 0.0))
        # Cut away open and paid invoice linked to this PO
        invoice_ids = self.pool.get('account.invoice').search(cr, uid, [('purchase_ids', 'in', [po_id]), ('state', 'in', ['paid', 'open'])])
        for inv in self.pool.get('account.invoice').read(cr, uid, invoice_ids, ['amount_total']):
            total -= inv.get('amount_total', 0.0)
        if (-1 * absl.amount) > total:
            raise osv.except_osv(_('Warning'), 
                _('Maximum amount should be: %s. Register line amount is higher than (PO - unexpended DPs - open/paid INV).') % (total))
        return True

    def button_validate(self, cr, uid, ids, context=None):
        """
        Validate the wizard to remember which PO have been selected from this register line.
        """
        # Some verifications
        if not context:
            context = {}
        if isinstance(ids, (int, long)):
            ids = [ids]
        # Browse all wizards
        for wiz in self.browse(cr, uid, ids, context=context):
            # Some verifications
            if not wiz.register_line_id:
                raise osv.except_osv(_('Warning'), _('Please select a Register Line before.'))
            if not wiz.purchase_id:
                raise osv.except_osv(_('Warning'), _('Please choose a Purchase Order.'))
            # Verify that the PO is not invoiced
            if wiz.purchase_id.invoiced:
                raise osv.except_osv(_('Error'), _('You cannot add Down Payment on an invoiced PO.'))
            # Verify that the register line amount is not superior to (PO amount - all its down_payments (draft, temp and hard posted))
            self.check_register_line_and_po(cr, uid, wiz.register_line_id.id, wiz.purchase_id.id, context=context)
            # Write result to register line
            self.pool.get('account.bank.statement.line').write(cr, uid, [wiz.register_line_id.id], {'down_payment_id': wiz.purchase_id.id}, context=context)
        return {'type' : 'ir.actions.act_window_close'}

wizard_down_payment()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: