~openerp-mongolian/openerp-mongolization/7.0

« back to all changes in this revision

Viewing changes to l10n_mn_purchase/wizard/.svn/text-base/purchase_expenses.py.svn-base

  • Committer: Unurjartal Ts
  • Date: 2013-06-17 09:33:42 UTC
  • mfrom: (1.1.2 openerp-mongolization)
  • Revision ID: unuruu25@gmail.com-20130617093342-w2o2hbtz5qg8ioli
ShineERP custom modules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    ShineERP, Enterprise Management Solution    
 
5
#    Copyright (C) 2007-2012 ShineERP Co.,ltd (<http://www.erp.mn>). All Rights Reserved
 
6
#
 
7
#    Address : Suhkbaatar District, National ITPark, ShineERP LLC
 
8
#    Email : info@erp.mn
 
9
#    Phone : 976 + 11-318043
 
10
#
 
11
##############################################################################
 
12
 
 
13
from osv import fields, osv
 
14
from tools.translate import _
 
15
from lxml import etree
 
16
import decimal_precision as dp
 
17
import time
 
18
 
 
19
class purchase_import_expenses_option(osv.osv_memory):
 
20
    _name = 'purchase.import.expenses.option'
 
21
    _description = "Purchase Add Expenses Option"
 
22
    
 
23
    _columns = {
 
24
        'option': fields.selection([('exists','Import from existing invoice'),('create','Create and import new expense')],
 
25
                            'Option', required=True)
 
26
    }
 
27
 
 
28
    _defaults = {
 
29
        'option': 'create'
 
30
    }
 
31
    
 
32
    def next(self, cr, uid, ids, context={}):
 
33
        data = self.read(cr, uid, ids[0], context=context)
 
34
        if data['option'] == 'create':
 
35
            return {
 
36
                'name': _('Add Expenses'),
 
37
                'view_type': 'form',
 
38
                'view_mode': 'form',
 
39
                'res_model': 'purchase.import.expenses',
 
40
                'type': 'ir.actions.act_window',
 
41
                'target': 'new',
 
42
                'context': context
 
43
            }
 
44
        else :
 
45
            return {
 
46
                'name': _('Add Expenses'),
 
47
                'view_type': 'form',
 
48
                'view_mode': 'form',
 
49
                'res_model': 'purchase.import.expenses.from.invoice',
 
50
                'type': 'ir.actions.act_window',
 
51
                'target': 'new',
 
52
                'context': context
 
53
            }
 
54
    
 
55
purchase_import_expenses_option()
 
56
 
 
57
class purchase_import_expenses(osv.osv_memory):
 
58
    _name = "purchase.import.expenses"
 
59
    _description = "Purchase Add Expenses"
 
60
    
 
61
    PORTION_SELECTION = [
 
62
        ('weight','Weight'),
 
63
        ('volume','Volume'),
 
64
        ('price','Unit Price'),
 
65
        ('subtotal','SubTotal')
 
66
    ]
 
67
    
 
68
    _columns = {
 
69
        'name': fields.char('Description', size=256),
 
70
        'product_id': fields.many2one('product.product', 'Expense', domain=[('type','=','service')],
 
71
            help="Select a service product to include extra costs for this purchase order."),
 
72
        'purchase_lines': fields.many2many('purchase.order.line', 'purchase_lines_import_rel', 'wiz_id', 'line_id', 'To be included lines'),
 
73
        'portion_method': fields.selection(PORTION_SELECTION, 'Portion Method', required=True),
 
74
        'taxes_id': fields.many2many('account.tax', 'purchase_order_import_taxe', 'line_id', 'tax_id', 'Taxes'),
 
75
        'amount': fields.float('Expense Amount', digits_compute=dp.get_precision('Purchase Price'), required=True),
 
76
        'currency_id': fields.many2one('res.currency', 'Currency'),
 
77
        'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account'),
 
78
        'expense_partner_id': fields.many2one('res.partner', 'Associated Partner', help="This expense will be invoiced from selected partner."),
 
79
        'not_included': fields.boolean('This expense is VAT'),
 
80
        'date_planned': fields.date('Scheduled Date'),
 
81
        'notes': fields.text('Note')
 
82
    }
 
83
    
 
84
    def product_id_change(self, cr, uid, ids, product, context={}):
 
85
        if not product:
 
86
            return {'value': {'taxes_id': []}}
 
87
        prod = self.pool.get('product.product').browse(cr, uid, product)
 
88
        
 
89
        taxes_id = map(lambda x: x.id, prod.supplier_taxes_id)
 
90
        if context.get('active_id', False) and len(taxes_id) > 0 :
 
91
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'])
 
92
            taxes = self.pool.get('account.tax').browse(cr, uid, taxes_id)
 
93
            if order.fiscal_position :
 
94
                taxes_id = self.pool.get('account.fiscal.position').map_tax(cr, uid, order.fiscal_position, taxes)
 
95
        
 
96
        prod_name = self.pool.get('product.product').name_get(cr, uid, [prod.id])[0][1]
 
97
        return {'value':{
 
98
            'taxes_id': taxes_id,
 
99
            'name':prod_name,
 
100
            'invoice_id':False,
 
101
            'amount': 0
 
102
        }}
 
103
    
 
104
    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
 
105
        res = super(purchase_import_expenses, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
 
106
        if context is None:
 
107
            context = {}
 
108
        if context.get('active_model', 'ir.ui.menu') == self._name:
 
109
            doc = etree.XML(res['arch'])
 
110
            nodes = doc.xpath("//field[@name='purchase_lines']")
 
111
            for node in nodes:
 
112
                node.set('domain', "[('order_id','=',%s),('is_extra_expense','=',False)]" % context['active_id'])
 
113
            res['arch'] = etree.tostring(doc)
 
114
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'], context=context)
 
115
            selection = [(order.company_id.currency_id.id, order.company_id.currency_id.name)]
 
116
            if order.pricelist_id.currency_id.id <> order.company_id.currency_id.id:
 
117
                selection.append( (order.pricelist_id.currency_id.id, order.pricelist_id.currency_id.name) )
 
118
            res['fields']['currency_id']['selection'] = selection
 
119
            
 
120
        return res
 
121
    
 
122
    def _get_currency(self, cr, uid, context={}):
 
123
        if context.get('active_id', False) :
 
124
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'])
 
125
            return order.company_id.currency_id.id
 
126
        raise osv.except_osv('BUG!', u'active_id context-оор ĐľŃ€Đ¶ Đ¸Ń€ŃŤŃ…гүй Đ±Đ°ĐąĐ˝Đ°.')
 
127
    
 
128
    def _get_date_planned(self, cr, uid, context={}):
 
129
        if context.get('active_id', False) :
 
130
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'])
 
131
            return order.date_order or time.strftime('%Y-%m-%d')
 
132
    
 
133
    _defaults = {
 
134
        'portion_method': 'subtotal',
 
135
        'currency_id': _get_currency,
 
136
        'not_included': False,
 
137
        'date_planned': _get_date_planned
 
138
    }
 
139
    
 
140
    def make_portion(self, cr, uid, method, lines, amount, context={}):
 
141
        portion_dict = {}
 
142
        total = 0.0
 
143
        if method == 'price' :
 
144
            for line in lines :
 
145
                total += line.price_unit
 
146
            coff = 0
 
147
            if total :
 
148
                coff = amount / total
 
149
            for line in lines :
 
150
                portion_dict[line.id] = (line.price_unit * coff) / line.product_qty
 
151
        elif method == 'subtotal' :
 
152
            for line in lines :
 
153
                total += line.price_unit * line.product_qty
 
154
            coff = 0
 
155
            if total :
 
156
                coff = amount / total
 
157
            for line in lines :
 
158
                portion_dict[line.id] = line.price_unit * coff
 
159
        elif method == 'volume' :
 
160
            for line in lines :
 
161
                total += (line.product_id.volume or 1) * line.product_qty
 
162
            coff = 0
 
163
            if total :
 
164
                coff = amount / total
 
165
            for line in lines :
 
166
                portion_dict[line.id] = (line.product_id.volume or 1) * coff
 
167
        elif method == 'weight' :
 
168
            for line in lines :
 
169
                total += (line.product_id.weight_net or 1) * line.product_qty
 
170
            coff = 0
 
171
            if total :
 
172
                coff = amount / total
 
173
            for line in lines :
 
174
                portion_dict[line.id] = (line.product_id.weight_net or 1) * coff
 
175
        else :
 
176
            pass
 
177
        
 
178
        return portion_dict
 
179
 
 
180
    def make_expenses(self, cr, uid, ids, context={}):
 
181
        purchase_obj = self.pool.get('purchase.order')
 
182
        purchase_line_obj = self.pool.get('purchase.order.line')
 
183
        purchase_line_exp_obj = self.pool.get('purchase.order.line.expenses')
 
184
        currency_obj = self.pool.get('res.currency')
 
185
        
 
186
        order = purchase_obj.browse(cr, uid, context['active_id'])
 
187
        form = self.browse(cr, uid, ids[0])
 
188
        
 
189
        selected_lines = form.purchase_lines
 
190
        if not selected_lines :
 
191
            selected_lines = [line for line in order.order_line if not line.is_extra_expense]
 
192
        portion_dict = self.make_portion(cr, uid, form.portion_method, selected_lines, form.amount, context=context)
 
193
        
 
194
        line_state = 'draft'
 
195
        for line in order.order_line:
 
196
            line_state = line.state
 
197
            break
 
198
        
 
199
        new_line_id = purchase_line_obj.create(cr, uid, {'order_id' : order.id,
 
200
                    'name': form.name,
 
201
                    'product_id': form.product_id.id,
 
202
                    'product_uom': form.product_id.uom_id.id,
 
203
                    'product_qty': 1,
 
204
                    'account_analytic_id':form.account_analytic_id.id,
 
205
                    'price_unit': form.amount,
 
206
                    'base_price': form.amount,
 
207
                    'taxes_id': [(6, 0, map(lambda x: x.id, form.taxes_id))],
 
208
                    'date_planned': form.date_planned,
 
209
                    'is_extra_expense': True,
 
210
                    'portion_method': form.portion_method,
 
211
                    'expense_partner_id': form.expense_partner_id.id,
 
212
                    'not_included': form.not_included,
 
213
                    'expense_currency_id': form.currency_id.id,
 
214
                    'notes': form.notes,
 
215
                    'state':line_state}, 
 
216
        context=context)
 
217
        purchase_obj.write(cr, uid, order.id, {'partner_id':1}, context=context)
 
218
        for line in selected_lines :
 
219
            purchase_line_exp_obj.create(cr, uid, {
 
220
                    'base_line' : new_line_id,
 
221
                    'target_line': line.id,
 
222
                    'amount': portion_dict[line.id]
 
223
            }, context=context)
 
224
        
 
225
        return {'type': 'ir.actions.act_window_close'}
 
226
 
 
227
purchase_import_expenses()
 
228
 
 
229
class purchase_import_expenses_from_invoice(osv.osv_memory):
 
230
    _inherit = 'purchase.import.expenses'
 
231
    _name = 'purchase.import.expenses.from.invoice'
 
232
    
 
233
    _columns = {
 
234
        'invoice_id': fields.many2one('account.invoice', 'Invoice', required=True),
 
235
        'company_id': fields.many2one('res.company', 'Company', required=True)
 
236
    }
 
237
    
 
238
    def _get_company(self, cr, uid, context={}):
 
239
        if context.get('active_id', False) :
 
240
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'])
 
241
            return order.company_id.id
 
242
    
 
243
    _defaults = {
 
244
        'company_id': _get_company
 
245
    }
 
246
    
 
247
    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
 
248
        res = super(purchase_import_expenses_from_invoice, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
 
249
        if context is None:
 
250
            context = {}
 
251
        if context and context['active_model'] <> 'ir.ui.menu':
 
252
            doc = etree.XML(res['arch'])
 
253
            nodes = doc.xpath("//field[@name='purchase_lines']")
 
254
            for node in nodes:
 
255
                node.set('domain', "[('order_id','=',%s),('is_extra_expense','=',False)]" % context['active_id'])
 
256
            res['arch'] = etree.tostring(doc)
 
257
 
 
258
            order = self.pool.get('purchase.order').browse(cr, uid, context['active_id'], context=context)
 
259
            selection = [(order.company_id.currency_id.id, order.company_id.currency_id.name)]
 
260
            if order.pricelist_id.currency_id.id <> order.company_id.currency_id.id:
 
261
                selection.append( (order.pricelist_id.currency_id.id, order.pricelist_id.currency_id.name) )
 
262
            res['fields']['currency_id']['selection'] = selection
 
263
            
 
264
        return res
 
265
    
 
266
    def invoice_id_change(self, cr, uid, ids, invoice, company, context={}):
 
267
        if not invoice:
 
268
            return {'value': {'amount':0,'currency_id':False}}
 
269
        currency_obj = self.pool.get('res.currency')
 
270
        invoice = self.pool.get('account.invoice').browse(cr, uid, invoice, context=context)
 
271
        name = (len(invoice.invoice_line) > 0 and invoice.invoice_line[0].name) or False
 
272
        currency_id = invoice.currency_id.id
 
273
        company = self.pool.get('res.company').browse(cr, uid, company, context=context)
 
274
        if company.currency_id.id <> currency_id:
 
275
            invoice.amount_total = currency_obj.compute(cr, uid, currency_id,
 
276
                    company.currency_id.id, invoice.amount_total, context={'date':invoice.date_invoice})
 
277
            currency_id = company.currency_id.id
 
278
        self.pool.get('account.invoice').write(cr, uid, [invoice.id], {'is_extra_expense':True})
 
279
        return {'value': {
 
280
            'amount': invoice.amount_total, 
 
281
            'currency_id':  currency_id,
 
282
            'date_planned': invoice.date_invoice,
 
283
            'product_id': False,
 
284
            'expense_partner_id': False,
 
285
            'name': name
 
286
        }}
 
287
    
 
288
    def make_expenses(self, cr, uid, ids, context={}):
 
289
        purchase_obj = self.pool.get('purchase.order')
 
290
        purchase_line_obj = self.pool.get('purchase.order.line')
 
291
        purchase_line_exp_obj = self.pool.get('purchase.order.line.expenses')
 
292
        currency_obj = self.pool.get('res.currency')
 
293
        
 
294
        order = purchase_obj.browse(cr, uid, context['active_id'])
 
295
        form = self.browse(cr, uid, ids[0])
 
296
        
 
297
        selected_lines = form.purchase_lines
 
298
        if not selected_lines :
 
299
            selected_lines = [line for line in order.order_line if not line.is_extra_expense]
 
300
        
 
301
        for inv in order.invoice_ids:
 
302
            if inv.id == form.invoice_id.id :
 
303
                raise osv.except_osv(_('Warning!'), _('This invioce already related in this purchase order!'))
 
304
        amount = form.invoice_id.amount_total
 
305
        if order.company_id.currency_id.id <> form.invoice_id.currency_id.id:
 
306
            amount = currency_obj.compute(cr, uid, form.invoice_id.currency_id.id,
 
307
                order.company_id.currency_id.id, amount, context={'date':form.invoice_id.date_invoice})
 
308
        date_planned = form.invoice_id.date_invoice
 
309
        currency_id = order.company_id.currency_id.id
 
310
        product_id = False
 
311
        name = '/'
 
312
        for l in form.invoice_id.invoice_line:
 
313
            if l.product_id :
 
314
                product_id = l.product_id.id
 
315
                name = l.name
 
316
        partner_id = form.invoice_id.partner_id.id
 
317
        
 
318
        portion_dict = self.make_portion(cr, uid, form.portion_method, selected_lines, amount, context=context)
 
319
        
 
320
        
 
321
        uom = False
 
322
        if product_id :
 
323
            uom = self.pool.get('product.product').read(cr, uid, product_id, ['uom_id'])['uom_id'][0]
 
324
        expense_val = {
 
325
                    'order_id' : order.id,
 
326
                    'name': name,
 
327
                    'product_id': product_id,
 
328
                    'product_uom': uom,
 
329
                    'product_qty': 1,
 
330
                    'price_unit': amount,
 
331
                    'base_price': amount,
 
332
                    'date_planned': date_planned,
 
333
                    'is_extra_expense': True,
 
334
                    'portion_method': form.portion_method,
 
335
                    'expense_partner_id': partner_id,
 
336
                    'not_included': form.not_included,
 
337
                    'expense_currency_id': currency_id
 
338
        }
 
339
        
 
340
        expense_val['invoice_lines'] = [(6,0,map(lambda x:x.id, form.invoice_id.invoice_line))]
 
341
        expense_val['invoiced'] = True
 
342
        purchase_obj.write(cr, uid, order.id, {'invoice_ids': [(4, form.invoice_id.id)]}, context=context)
 
343
        
 
344
        line_state = 'draft'
 
345
        for line in order.order_line:
 
346
            line_state = line.state
 
347
            break
 
348
        expense_val['state'] = line_state
 
349
        new_line_id = purchase_line_obj.create(cr, uid, expense_val, context=context)
 
350
 
 
351
        for line in selected_lines :
 
352
            purchase_line_exp_obj.create(cr, uid, {
 
353
                    'base_line' : new_line_id,
 
354
                    'target_line': line.id,
 
355
                    'amount': portion_dict[line.id]
 
356
            }, context=context)
 
357
 
 
358
        return {'type': 'ir.actions.act_window_close'}
 
359
    
 
360
    def create(self, cr, uid, vals, context=None):
 
361
        seq = 0
 
362
        if 'amount' not in vals:
 
363
            invoice = self.pool.get('account.invoice').browse(cr, uid, vals['invoice_id'], context=context)
 
364
            vals.update({'amount': invoice.amount_total})
 
365
        return super(purchase_import_expenses_from_invoice, self).create(cr, uid, vals, context=context)
 
366
 
 
367
 
 
368
purchase_import_expenses_from_invoice()
 
369
 
 
370
class purchase_remove_expenses(osv.TransientModel):
 
371
    _name = 'purchase.remove.expenses'
 
372
    _description = 'Remove Expenses'
 
373
    
 
374
    _columns = {
 
375
        'extra_expense_ids': fields.many2many('purchase.order.line','wizard_extra_expense_rel', 'wizard_id','expense_id', 'Extra Expense'),
 
376
    }
 
377
    
 
378
    def default_get(self, cr, uid, fields, context=None):
 
379
 
 
380
        if context is None:
 
381
            context = {}
 
382
        res = super(purchase_remove_expenses, self).default_get(cr, uid, fields, context=context)
 
383
        if context.get('active_model',False) == 'purchase.order':
 
384
            record_id = context and context.get('active_id', False) or False
 
385
            purchase_obj = self.pool.get('purchase.order')
 
386
            order = purchase_obj.browse(cr, uid, record_id, context=context)
 
387
            extra_ids = []
 
388
            for line in order.order_line:
 
389
                if not line.is_extra_expense or line.invoiced:
 
390
                    continue
 
391
                extra_ids.append(line.id)
 
392
            if extra_ids:
 
393
                res['extra_expense_ids'] = extra_ids
 
394
        return res
 
395
    
 
396
    def fields_view_get(self, cr, uid, view_id=None, view_type='form',
 
397
                        context=None, toolbar=False, submenu=False):
 
398
        res = super(purchase_remove_expenses, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
 
399
        if context is None:
 
400
            context = {}
 
401
        if context.get('active_model',False):
 
402
            active_model = context.get('active_model')
 
403
            if  active_model != 'purchase.order':
 
404
                return res
 
405
            
 
406
            record_id = context and context.get('active_id', False)
 
407
            purchase_obj = self.pool.get('purchase.order')
 
408
            order = purchase_obj.browse(cr, uid, record_id, context=context)
 
409
            domain = "[]"
 
410
            extra_ids = []
 
411
            for line in order.order_line:
 
412
                if line.is_extra_expense:
 
413
                    extra_ids.append(line.id)
 
414
            if extra_ids:
 
415
                domain = "[('id','in',("+','.join(map(str,extra_ids))+"))]"
 
416
            else:
 
417
                domain = "[('id','in',False)]"
 
418
            doc = etree.XML(res['arch'])
 
419
            nodes = doc.xpath("//field[@name='extra_expense_ids']")
 
420
            for node in nodes:
 
421
                node.set('domain', domain)
 
422
            res['arch'] = etree.tostring(doc)
 
423
        return res
 
424
 
 
425
    def remove_expenses(self, cr, uid, ids, context=None):
 
426
        if context is None:
 
427
            context = {}
 
428
        if context.get('active_id',False):
 
429
            record_id = context and context.get('active_id', False)
 
430
            purchase_obj = self.pool.get('purchase.order')
 
431
            purchase_line_obj = self.pool.get('purchase.order.line')
 
432
            order = purchase_obj.browse(cr, uid, record_id, context=context)
 
433
            st = self.browse(cr, uid, ids[0], context=context)
 
434
            todo_remove = []
 
435
            ex_ids = []
 
436
            for ex in st.extra_expense_ids:
 
437
                ex_ids.append(ex.id)
 
438
            todo_remove = purchase_line_obj.search(cr, uid, [('order_id','=',order.id),('is_extra_expense','=',True),('id','<>',ex_ids)])
 
439
            if todo_remove:
 
440
                purchase_line_obj.unlink(cr, uid, todo_remove, context=context)
 
441
 
 
442
        return {'type': 'ir.actions.act_window_close'}
 
443
 
 
444
purchase_remove_expenses()