~openerp-commiter/openobject-addons/6.0-opw-4801-dhs

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    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 fields, osv

from tools.translate import _

class hr_timesheet_invoice_factor(osv.osv):
    _name = "hr_timesheet_invoice.factor"
    _description = "Invoice Rate"
    _columns = {
        'name': fields.char('Internal name', size=128, required=True, translate=True),
        'customer_name': fields.char('Name', size=128, help="Label for the customer"),
        'factor': fields.float('Discount (%)', required=True, help="Discount in percentage"),
    }
    _defaults = {
        'factor': lambda *a: 0.0,
    }

hr_timesheet_invoice_factor()


class account_analytic_account(osv.osv):
    def _invoiced_calc(self, cr, uid, ids, name, arg, context=None):
        obj_invoice = self.pool.get('account.invoice')
        res = {}

        cr.execute('SELECT account_id as account_id, l.invoice_id '
                'FROM hr_analytic_timesheet h LEFT JOIN account_analytic_line l '
                    'ON (h.line_id=l.id) '
                    'WHERE l.account_id = ANY(%s)', (ids,))
        account_to_invoice_map = {}
        for rec in cr.dictfetchall():
            account_to_invoice_map.setdefault(rec['account_id'], []).append(rec['invoice_id'])

        for account in self.browse(cr, uid, ids, context=context):
            invoice_ids = filter(None, list(set(account_to_invoice_map.get(account.id, []))))
            for invoice in obj_invoice.browse(cr, uid, invoice_ids, context=context):
                res.setdefault(account.id, 0.0)
                res[account.id] += invoice.amount_untaxed
        for id in ids:
            res[id] = round(res.get(id, 0.0),2)

        return res

    _inherit = "account.analytic.account"
    _columns = {
        'pricelist_id': fields.many2one('product.pricelist', 'Sale Pricelist',
            help="The product to invoice is defined on the employee form, the price will be deduced by this pricelist on the product."),
        'amount_max': fields.float('Max. Invoice Price'),
        'amount_invoiced': fields.function(_invoiced_calc, method=True, string='Invoiced Amount',
            help="Total invoiced"),
        'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Reinvoice Costs',
            help="Fill this field if you plan to automatically generate invoices based " \
            "on the costs in this analytic account: timesheets, expenses, ..." \
            "You can configure an automatic invoice rate on analytic accounts."),
    }
    _defaults = {
        'pricelist_id': lambda self, cr, uid, ctx: ctx.get('pricelist_id', False),
    }
    
    def set_close(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state':'close'}, context=context)
    
    def set_cancel(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
    
    def set_open(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state':'open'}, context=context)
      
    def set_pending(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state':'pending'}, context=context)

account_analytic_account()


class account_analytic_line(osv.osv):
    _inherit = 'account.analytic.line'
    _columns = {
        'invoice_id': fields.many2one('account.invoice', 'Invoice', ondelete="set null"),
        'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Type of Invoicing', help="It allows to set the discount while making invoice"),
    }

    def unlink(self, cursor, user, ids, context=None):
        return super(account_analytic_line,self).unlink(cursor, user, ids,
                context=context)

    def write(self, cr, uid, ids, vals, context=None):
        self._check_inv(cr, uid, ids, vals)
        return super(account_analytic_line,self).write(cr, uid, ids, vals,
                context=context)

    def _check_inv(self, cr, uid, ids, vals):
        select = ids
        if isinstance(select, (int, long)):
            select = [ids]
        if ( not vals.has_key('invoice_id')) or vals['invoice_id' ] == False:
            for line in self.browse(cr, uid, select):
                if line.invoice_id:
                    raise osv.except_osv(_('Error !'),
                        _('You can not modify an invoiced analytic line!'))
        return True

    def copy(self, cursor, user, obj_id, default=None, context=None):
        if default is None:
            default = {}
        default = default.copy()
        default.update({'invoice_id': False})
        return super(account_analytic_line, self).copy(cursor, user, obj_id,
                default, context=context)

account_analytic_line()


class hr_analytic_timesheet(osv.osv):
    _inherit = "hr.analytic.timesheet"
    def on_change_account_id(self, cr, uid, ids, account_id):
        res = {}
        if not account_id:
            return res
        res.setdefault('value',{})
        acc = self.pool.get('account.analytic.account').browse(cr, uid, account_id)
        st = acc.to_invoice.id
        res['value']['to_invoice'] = st or False
        if acc.state=='pending':
            res['warning'] = {
                'title': 'Warning',
                'message': 'The analytic account is in pending state.\nYou should not work on this account !'
            }
        return res

    def copy(self, cursor, user, obj_id, default=None, context=None):
        if default is None:
            default = {}
        default = default.copy()
        default.update({'invoice_id': False})
        return super(hr_analytic_timesheet, self).copy(cursor, user, obj_id,
                default, context=context)

hr_analytic_timesheet()

class account_invoice(osv.osv):
    _inherit = "account.invoice"

    def _get_analytic_lines(self, cr, uid, id):
        iml = super(account_invoice, self)._get_analytic_lines(cr, uid, id)

        inv = self.browse(cr, uid, [id])[0]
        if inv.type == 'in_invoice':
            obj_analytic_account = self.pool.get('account.analytic.account')
            for il in iml:
                if il['account_analytic_id']:
		    # *-* browse (or refactor to avoid read inside the loop)
                    to_invoice = obj_analytic_account.read(cr, uid, [il['account_analytic_id']], ['to_invoice'])[0]['to_invoice']
                    if to_invoice:
                        il['analytic_lines'][0][2]['to_invoice'] = to_invoice[0]
        return iml

account_invoice()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: