~technofluid-team/openobject-addons/technofluid_multiple_installations

« back to all changes in this revision

Viewing changes to hr_expense/hr_expense.py

  • Committer: pinky
  • Date: 2006-12-07 13:41:40 UTC
  • Revision ID: pinky-dedd7f8a42bd4557112a0513082691b8590ad6cc
New trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
##############################################################################
 
2
#
 
3
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
 
4
#
 
5
# $Id: hr.py 3751 2006-08-09 13:15:36Z mvd $
 
6
#
 
7
# WARNING: This program as such is intended to be used by professional
 
8
# programmers who take the whole responsability of assessing all potential
 
9
# consequences resulting from its eventual inadequacies and bugs
 
10
# End users who are looking for a ready-to-use solution with commercial
 
11
# garantees and support are strongly adviced to contract a Free Software
 
12
# Service Company
 
13
#
 
14
# This program is Free Software; you can redistribute it and/or
 
15
# modify it under the terms of the GNU General Public License
 
16
# as published by the Free Software Foundation; either version 2
 
17
# of the License, or (at your option) any later version.
 
18
#
 
19
# This program is distributed in the hope that it will be useful,
 
20
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
# GNU General Public License for more details.
 
23
#
 
24
# You should have received a copy of the GNU General Public License
 
25
# along with this program; if not, write to the Free Software
 
26
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
27
#
 
28
##############################################################################
 
29
 
 
30
from mx import DateTime
 
31
import time
 
32
 
 
33
from osv import fields, osv
 
34
 
 
35
def _employee_get(obj,cr,uid,context={}):
 
36
        ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
 
37
        if ids:
 
38
                return ids[0]
 
39
        return False
 
40
 
 
41
class hr_expense_expense(osv.osv):
 
42
        def _amount(self, cr, uid, ids, field_name, arg, context):
 
43
                id_set = ",".join(map(str, ids))
 
44
                cr.execute("SELECT s.id,COALESCE(SUM(l.unit_amount*l.unit_quantity),0) AS amount FROM hr_expense_expense s LEFT OUTER JOIN hr_expense_line l ON (s.id=l.expense_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ")
 
45
                res = dict(cr.fetchall())
 
46
                return res
 
47
 
 
48
        _name = "hr.expense.expense"
 
49
        _description = "Expense"
 
50
        _columns = {
 
51
                'name': fields.char('Expense Sheet', size=128, required=True),
 
52
                'id': fields.integer('Sheet ID', readonly=True),
 
53
                'ref': fields.char('Reference', size=32),
 
54
                'date': fields.date('Date'),
 
55
                'account_id': fields.many2one('account.account', 'Payable Account'),
 
56
                'journal_id': fields.many2one('account.journal', 'Journal'),
 
57
                'analytic_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
 
58
                'employee_id': fields.many2one('hr.employee', 'Employee', required=True),
 
59
                'user_id': fields.many2one('res.users', 'User', required=True),
 
60
                'date_confirm': fields.date('Date Confirmed'),
 
61
                'date_valid': fields.date('Date Valided'),
 
62
                'user_valid': fields.many2one('res.users', 'Validation User'),
 
63
 
 
64
                'account_move_id': fields.many2one('account.move', 'Account Move'),
 
65
                'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines'),
 
66
                'note': fields.text('Note'),
 
67
 
 
68
                # fields.function
 
69
                'amount': fields.function(_amount, method=True, string='Total Amount'),
 
70
                'move_id': fields.many2one('account.move','Accounting Entries'),
 
71
 
 
72
                'state': fields.selection([
 
73
                        ('draft', 'Draft'),
 
74
                        ('confirm', 'Waiting confirmation'),
 
75
                        ('accepted', 'Accepted'),
 
76
                        ('paid', 'Reimbursed'),
 
77
                        ('canceled', 'Canceled')],
 
78
                        'State', readonly=True),
 
79
        }
 
80
        _defaults = {
 
81
                'date' : lambda *a: time.strftime('%Y-%m-%d'),
 
82
                'state': lambda *a: 'draft',
 
83
                'employee_id' : _employee_get,
 
84
                'user_id' : lambda cr,uid,id,c={}: id
 
85
        }
 
86
        def expense_confirm(self, cr, uid, ids, *args):
 
87
                #for exp in self.browse(cr, uid, ids):
 
88
                self.write(cr, uid, ids, {
 
89
                        'state':'confirm',
 
90
                        'date_confirm': time.strftime('%Y-%m-%d')
 
91
                })
 
92
                return True
 
93
 
 
94
        def expense_accept(self, cr, uid, ids, *args):
 
95
                for exp in self.browse(cr, uid, ids):
 
96
                        if not (exp.journal_id and exp.account_id):
 
97
                                raise osv.except_osv('No account or journal defined !', 'You have to define a journal and an account to validate this expense note.')
 
98
                        lines = []
 
99
                        total = 0
 
100
                        for line in exp.line_ids:
 
101
                                if line.product_id:
 
102
                                        acc = line.product_id.product_tmpl_id.property_account_expense
 
103
                                        if not acc:
 
104
                                                acc = line.product_id.categ_id.property_account_expense_categ
 
105
                                        acc = acc[0]
 
106
                                        lines.append({
 
107
                                                'name': line.name,
 
108
                                                'date': line.date_value or time.strftime('%Y-%m-%d'),
 
109
                                                'quantity': line.unit_quantity,
 
110
                                                'ref': line.ref,
 
111
                                                'debit': (line.total_amount>0 and line.total_amount) or 0,
 
112
                                                'credit': (line.total_amount<0 and -line.total_amount) or 0,
 
113
                                                'account_id': acc,
 
114
                                        })
 
115
                                        total += line.total_amount
 
116
                                        if line.analytic_account:
 
117
                                                if not exp.analytic_journal_id:
 
118
                                                        raise osv.except_osv('No analytic journal defined !', 'You have to define an analytic journal to validate this expense note.')
 
119
 
 
120
 
 
121
                                                self.pool.get('account.analytic.line').create(cr, uid, {
 
122
                                                        'name': line.name,
 
123
                                                        'date': line.date_value,
 
124
                                                        'product_id': line.product_id.id,
 
125
                                                        'product_uom_id': line.uom_id.id,
 
126
                                                        'unit_amount': line.unit_quantity,
 
127
                                                        'code': line.ref,
 
128
                                                        'amount': -line.total_amount,
 
129
                                                        'journal_id': exp.analytic_journal_id.id,
 
130
                                                        'general_account_id': acc,
 
131
                                                        'account_id': line.analytic_account.id
 
132
                                                })
 
133
                        move_id = False
 
134
                        if lines:
 
135
                                lines.append({
 
136
                                        'name': exp.name+'['+str(exp.id)+']',
 
137
                                        'date': exp.date or time.strftime('%Y-%m-%d'),
 
138
                                        'ref': exp.ref,
 
139
                                        'debit': (total<0 and -total) or 0,
 
140
                                        'credit': (total>0 and total) or 0,
 
141
                                        'account_id': exp.account_id.id,
 
142
                                })
 
143
                                if exp.journal_id.sequence_id:
 
144
                                        name = self.pool.get('ir.sequence').get_id(cr, uid, exp.journal_id.sequence_id.id)
 
145
                                else:
 
146
                                        name = "EXP "+time.strftime('%Y-%m-%d')
 
147
                                move_id = self.pool.get('account.move').create(cr, uid, {
 
148
                                        'name': name,
 
149
                                        'journal_id': exp.journal_id.id,
 
150
                                        'line_id': map(lambda x: (0,0,x), lines)
 
151
                                })
 
152
                        self.write(cr, uid, [exp.id], {
 
153
                                'move_id': move_id,
 
154
                                'state':'accepted',
 
155
                                'date_valid': time.strftime('%Y-%m-%d'),
 
156
                                'user_valid': uid
 
157
                        })
 
158
                return True
 
159
 
 
160
        def expense_canceled(self, cr, uid, ids, *args):
 
161
                self.write(cr, uid, ids, {'state':'canceled'})
 
162
                return True
 
163
 
 
164
        def expense_paid(self, cr, uid, ids, *args):
 
165
                self.write(cr, uid, ids, {'state':'paid'})
 
166
                return True
 
167
hr_expense_expense()
 
168
 
 
169
 
 
170
class hr_expense_line(osv.osv):
 
171
        _name = "hr.expense.line"
 
172
        _description = "Expense Line"
 
173
        def _amount(self, cr, uid, ids, field_name, arg, context):
 
174
                if not len(ids):
 
175
                        return {}
 
176
                id_set = ",".join(map(str, ids))
 
177
                cr.execute("SELECT l.id,COALESCE(SUM(l.unit_amount*l.unit_quantity),0) AS amount FROM hr_expense_line l WHERE id IN ("+id_set+") GROUP BY l.id ")
 
178
                res = dict(cr.fetchall())
 
179
                return res
 
180
 
 
181
        _columns = {
 
182
                'name': fields.char('Short Description', size=128, required=True),
 
183
                'date_value': fields.date('Date', required=True),
 
184
                'expense_id': fields.many2one('hr.expense.expense', 'Expense', ondelete='cascade', select=True),
 
185
                'total_amount': fields.function(_amount, method=True, string='Total'),
 
186
                'unit_amount': fields.float('Unit Price', readonly=True, states={'draft':[('readonly',False)]}),
 
187
                'unit_quantity': fields.float('Quantities', readonly=True, states={'draft':[('readonly',False)]}),
 
188
                'product_id': fields.many2one('product.product', 'Product', readonly=True, states={'draft':[('readonly',False)]}),
 
189
                'uom_id': fields.many2one('product.uom', 'UoM', readonly=True, states={'draft':[('readonly',False)]}),
 
190
                'description': fields.text('Description'),
 
191
                'analytic_account': fields.many2one('account.analytic.account','Analytic account'),
 
192
                'ref': fields.char('Reference', size=32),
 
193
        }
 
194
        _defaults = {
 
195
                'unit_quantity': lambda *a: 1,
 
196
                'date_value' : lambda *a: time.strftime('%Y-%m-%d'),
 
197
        }
 
198
        def onchange_product_id(self, cr, uid, ids, product_id, uom_id, context={}):
 
199
                v={}
 
200
                if product_id:
 
201
                        product=self.pool.get('product.product').browse(cr,uid,product_id, context=context)
 
202
                        v['name']=product.name
 
203
                        v['unit_amount']=product.standard_price
 
204
                        if not uom_id:
 
205
                                v['uom_id']=product.uom_id.id
 
206
                return {'value':v}
 
207
 
 
208
hr_expense_line()
 
209
 
 
210
# vim:tw=0:noexpandtab