~technofluid-team/openobject-addons/technofluid_multiple_installations

« back to all changes in this revision

Viewing changes to account/project/project.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) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
 
4
#
 
5
# $Id$
 
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
import time
 
31
import operator
 
32
 
 
33
from osv import fields
 
34
from osv import osv
 
35
 
 
36
#
 
37
# Model definition
 
38
#
 
39
 
 
40
class account_analytic_account(osv.osv):
 
41
        _name = 'account.analytic.account'
 
42
 
 
43
        def _credit_calc(self, cr, uid, ids, name, arg, context={}):
 
44
                res = {}
 
45
                for account in self.browse(cr, uid, ids):
 
46
                        node_balance = reduce(operator.add, [-line.amount for line in account.line_ids if line.amount<0], 0)
 
47
                        child_balance = reduce(operator.add, [child.credit for child in account.child_ids], 0)
 
48
                        res[account.id] = node_balance + child_balance
 
49
                for id in ids:
 
50
                        res[id] = round(res.get(id, 0.0),2)
 
51
                return res
 
52
 
 
53
        def _debit_calc(self, cr, uid, ids, name, arg, context={}):
 
54
                res = {}
 
55
                for account in self.browse(cr, uid, ids):
 
56
                        node_balance = reduce(operator.add, [line.amount for line in account.line_ids if line.amount>0], 0)
 
57
                        child_balance = reduce(operator.add, [child.debit for child in account.child_ids], 0)
 
58
                        res[account.id] = node_balance + child_balance
 
59
                for id in ids:
 
60
                        res[id] = round(res.get(id, 0.0),2)
 
61
                return res
 
62
 
 
63
        def _balance_calc(self, cr, uid, ids, name, arg, context={}):
 
64
                res = {}
 
65
                for account in self.browse(cr, uid, ids):
 
66
                        node_balance = reduce(operator.add, [line.amount for line in account.line_ids], 0)
 
67
                        child_balance = reduce(operator.add, [child.balance for child in account.child_ids], 0)
 
68
                        res[account.id] = node_balance + child_balance
 
69
                for id in ids:
 
70
                        res[id] = round(res.get(id, 0.0),2)
 
71
                return res
 
72
 
 
73
        def _quantity_calc(self, cr, uid, ids, name, arg, context={}):
 
74
                res = {}
 
75
                for account in self.browse(cr, uid, ids):
 
76
                        node_balance = reduce(operator.add, [line.unit_amount for line in account.line_ids], 0)
 
77
                        child_balance = reduce(operator.add, [child.quantity for child in account.child_ids], 0)
 
78
                        res[account.id] = node_balance + child_balance
 
79
                for id in ids:
 
80
                        res[id] = round(res.get(id, 0.0),2)
 
81
                return res
 
82
 
 
83
        def name_get(self, cr, uid, ids, context={}):
 
84
                if not len(ids):
 
85
                        return []
 
86
                reads = self.read(cr, uid, ids, ['name','parent_id'], context)
 
87
                res = []
 
88
                for record in reads:
 
89
                        name = record['name']
 
90
                        if record['parent_id']:
 
91
                                name = record['parent_id'][1]+' / '+name
 
92
                        res.append((record['id'], name))
 
93
                return res
 
94
 
 
95
        def _complete_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
 
96
                res = self.name_get(cr, uid, ids)
 
97
                return dict(res)
 
98
 
 
99
 
 
100
        _columns = {
 
101
                'name' : fields.char('Account name', size=64, required=True),
 
102
                'complete_name': fields.function(_complete_name_calc, method=True, type='char', string='Account Name'),
 
103
                'code' : fields.char('Account code', size=8),
 
104
                'active' : fields.boolean('Active'),
 
105
                'type': fields.selection([('view','View'), ('normal','Normal')], 'type'),
 
106
                'description' : fields.text('Description'),
 
107
                'parent_id': fields.many2one('account.analytic.account', 'Parent Cost account', select=True),
 
108
                'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Childs Accounts'),
 
109
                'line_ids': fields.one2many('account.analytic.line', 'account_id', 'Analytic entries'),
 
110
                'balance' : fields.function(_balance_calc, method=True, type='float', string='Balance'),
 
111
                'debit' : fields.function(_debit_calc, method=True, type='float', string='Balance'),
 
112
                'credit' : fields.function(_credit_calc, method=True, type='float', string='Balance'),
 
113
                'quantity': fields.function(_quantity_calc, method=True, type='float', string='Quantity'),
 
114
                'quantity_max': fields.float('Maximal quantity'),
 
115
                'partner_id' : fields.many2one('res.partner', 'Associated partner'),
 
116
                'contact_id' : fields.many2one('res.partner.address', 'Contact'),
 
117
                'date_start': fields.date('Date Start'),
 
118
                'date': fields.date('Date End'),
 
119
                'stats_ids': fields.one2many('report.hr.timesheet.invoice.journal', 'account_id', string='Statistics', readonly=True),
 
120
        }
 
121
 
 
122
        _defaults = {
 
123
                'active' : lambda *a : True,
 
124
                'type' : lambda *a : 'normal',
 
125
        }
 
126
 
 
127
        _order = 'parent_id desc,code'
 
128
 
 
129
        def create(self, cr, uid, vals, ctx={}):
 
130
                parent_id = vals.get('parent_id', 0)
 
131
                if ('code' not in vals or not vals['code']) and not parent_id:
 
132
                        vals['code'] = self.pool.get('ir.sequence').get(cr, uid, 'account.analytic.account')
 
133
                elif parent_id:
 
134
                        parent = self.read(cr, uid, [parent_id], ['parent_id'])[0]
 
135
                        childs = self.search(cr, uid, [('parent_id', '=', parent_id), ('active', '=', 1)]) + self.search(cr, uid, [('parent_id', '=', parent_id), ('active', '=', 0)])
 
136
                        vals['code'] = '%03d' % (len(childs) + 1,)
 
137
                return super(account_analytic_account, self).create(cr, uid, vals, ctx)
 
138
 
 
139
 
 
140
        def on_change_parent(self, cr, uid, id, parent_id):
 
141
                if not parent_id:
 
142
                        return {'value': {'code': False, 'partner_id': ''}}
 
143
                parent = self.read(cr, uid, [parent_id], ['partner_id'])[0]
 
144
                childs = self.search(cr, uid, [('parent_id', '=', parent_id), ('active', '=', 1)]) + self.search(cr, uid, [('parent_id', '=', parent_id), ('active', '=', 0)])
 
145
                numchild = len(childs)
 
146
                if parent['partner_id']:
 
147
                        partner = parent['partner_id'][0]
 
148
                else:
 
149
                        partner = False
 
150
                return {'value' : {'code' : '%03d' % (numchild + 1,), 'partner_id' : partner}}
 
151
 
 
152
        def name_search(self, cr, uid, name, args=[], operator='ilike', context={}):
 
153
                codes = name.split('.')
 
154
                codes.reverse()
 
155
                parent_code = False
 
156
                while codes:
 
157
                        current_code = codes.pop()
 
158
                        account = self.search(cr, uid, [('parent_id', '=', parent_code), ('code', '=', current_code)]+args)
 
159
                        if account:
 
160
                                parent_code = account[0]
 
161
                        else:
 
162
                                account = self.search(cr, uid, [('name', 'ilike', '%%%s%%' % name)]+args)
 
163
                                break
 
164
                return self.name_get(cr, uid, account)
 
165
 
 
166
account_analytic_account()
 
167
 
 
168
 
 
169
class account_analytic_journal(osv.osv):
 
170
        _name = 'account.analytic.journal'
 
171
        _columns = {
 
172
                'name' : fields.char('Journal name', size=64, required=True),
 
173
                'code' : fields.char('Journal code', size=8),
 
174
                'active' : fields.boolean('Active'),
 
175
                'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When a document (eg: an invoice) needs to create analytic entries, Tiny ERP will look for a matching journal of the same type."),
 
176
                'line_ids' : fields.one2many('account.analytic.line', 'journal_id', 'Lines'),
 
177
        }
 
178
        _defaults = {
 
179
                'active': lambda *a: True,
 
180
                'type': lambda *a: 'general',
 
181
        }
 
182
account_analytic_journal()
 
183
        
 
184
class account_analytic_line(osv.osv):
 
185
        _name = 'account.analytic.line'
 
186
        _columns = {
 
187
                'name' : fields.char('Description', size=128, required=True),
 
188
                'date' : fields.date('Date', required=True),
 
189
                'amount' : fields.float('Amount', required=True),
 
190
                'unit_amount' : fields.float('Quantity'),
 
191
                'product_uom_id' : fields.many2one('product.uom', 'UoM'),
 
192
                'product_id' : fields.many2one('product.product', 'Product'),
 
193
                'account_id' : fields.many2one('account.analytic.account', 'Analytic Account', required=True, ondelete='cascade', select=True),
 
194
                'general_account_id' : fields.many2one('account.account', 'General account', required=True, ondelete='cascade'),
 
195
                'move_id' : fields.many2one('account.move.line', 'General entry', ondelete='cascade', select=True),
 
196
                'journal_id' : fields.many2one('account.analytic.journal', 'Analytic journal', required=True, ondelete='cascade', select=True),
 
197
                'code' : fields.char('Code', size=8),
 
198
                'user_id' : fields.many2one('res.users', 'User',),
 
199
        }
 
200
                
 
201
        _defaults = {
 
202
                'date': lambda *a: time.strftime('%Y-%m-%d'),
 
203
        }
 
204
        _order = 'date'
 
205
        
 
206
        def on_change_unit_amount(self, cr, uid, id, prod_id, unit_amount, unit=False, context={}):
 
207
                if unit_amount and prod_id:
 
208
                        rate = 1
 
209
                        if unit:
 
210
                                uom_id = self.pool.get('product.uom')
 
211
                                hunit = uom_id.browse(cr, uid, unit)
 
212
                                rate = hunit.factor
 
213
                        uom_id = self.pool.get('product.product')
 
214
                        prod = uom_id.browse(cr, uid, prod_id)
 
215
                        a = prod.product_tmpl_id.property_account_expense
 
216
                        if not a:
 
217
                                a = prod.categ_id.property_account_expense_categ
 
218
                        return {'value' : {'amount' : -round(unit_amount * prod.standard_price * rate,2), 'general_account_id':a[0]}}
 
219
                return {}
 
220
 
 
221
account_analytic_line()
 
222
 
 
223
class timesheet_invoice(osv.osv):
 
224
        _name = "report.hr.timesheet.invoice.journal"
 
225
        _description = "Analytic account costs and revenues"
 
226
        _auto = False
 
227
        _columns = {
 
228
                'name': fields.date('Month', readonly=True),
 
229
                'account_id':fields.many2one('account.analytic.account', 'Analytic Account', readonly=True, relate=True, select=True),
 
230
                'journal_id': fields.many2one('account.analytic.journal', 'Journal', readonly=True),
 
231
                'quantity': fields.float('Quantities', readonly=True),
 
232
                'cost': fields.float('Credit', readonly=True),
 
233
                'revenue': fields.float('Debit', readonly=True)
 
234
        }
 
235
        _order = 'name desc, account_id'
 
236
        def init(self, cr):
 
237
                #cr.execute("""
 
238
                #create or replace view report_hr_timesheet_invoice_journal as (
 
239
                #       select
 
240
                #               min(l.id) as id,
 
241
                #               substring(l.create_date for 7)||'-01' as name,
 
242
                #               sum(greatest(-l.amount,0)) as cost,
 
243
                #               sum(greatest(l.amount,0)) as revenue,
 
244
                #               sum(l.unit_amount*u.factor) as quantity,
 
245
                #               journal_id,
 
246
                #               account_id
 
247
                #       from account_analytic_line l
 
248
                #               left join product_uom u on (u.id=l.product_uom_id)
 
249
                #       group by
 
250
                #               substring(l.create_date for 7),
 
251
                #               journal_id,
 
252
                #               account_id
 
253
                #)""")
 
254
                cr.execute("""
 
255
                create or replace view report_hr_timesheet_invoice_journal as (
 
256
                        select
 
257
                                min(l.id) as id,
 
258
                                substring(l.create_date for 7)||'-01' as name,
 
259
                                sum(
 
260
                                        CASE WHEN -l.amount>0 THEN 0 ELSE -l.amount
 
261
                                        END
 
262
                                ) as cost,
 
263
                                sum(
 
264
                                        CASE WHEN l.amount>0 THEN l.amount ELSE 0
 
265
                                        END
 
266
                                ) as revenue,
 
267
                                sum(l.unit_amount*u.factor) as quantity,
 
268
                                journal_id,
 
269
                                account_id
 
270
                        from account_analytic_line l
 
271
                                left join product_uom u on (u.id=l.product_uom_id)
 
272
                        group by
 
273
                                substring(l.create_date for 7),
 
274
                                journal_id,
 
275
                                account_id
 
276
                )""")
 
277
timesheet_invoice()
 
278