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

« back to all changes in this revision

Viewing changes to msf_partner/partner.py

  • Committer: jf
  • Date: 2012-11-29 13:00:27 UTC
  • mfrom: (1287.9.8 unifield-wm)
  • Revision ID: jfb@tempo-consulting.fr-20121129130027-564r4yns8t5d2v7d
UTP-368 [FIX] Shouldn't be possible to source a non-stockable product to stock in the order sourcing tool (fix unit test)
lp:~unifield-team/unifield-wm/utp-368

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
from msf_partner import PARTNER_TYPE
26
26
import time
27
27
from tools.translate import _
28
 
from lxml import etree
29
28
 
30
29
 
31
30
class res_partner(osv.osv):
119
118
                price_list = self.pool.get('product.product')._get_partner_info_price(cr, uid, product, partner.id, context.get('product_qty', 1.00), pricelist.currency_id.id, time.strftime('%Y-%m-%d'), uom, context=context)
120
119
                if not price_list:
121
120
                    func_currency_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
122
 
                    price = self.pool.get('res.currency').compute(cr, uid, func_currency_id, pricelist.currency_id.id, product.standard_price, round=False, context=context)
 
121
                    price = self.pool.get('res.currency').compute(cr, uid, func_currency_id, pricelist.currency_id.id, product.standard_price, round=True, context=context)
123
122
                    res[partner.id] = {'price_currency': pricelist.currency_id.id,
124
123
                                       'price_unit': price,
125
124
                                       'valide_until_date': False}
126
125
                else:
127
126
                    info_price = partner_price.browse(cr, uid, price_list[0], context=context)
128
127
                    partner_currency_id = pricelist.currency_id.id
129
 
                    price = self.pool.get('res.currency').compute(cr, uid, info_price.currency_id.id, partner_currency_id, info_price.price, round=False, context=context)
 
128
                    price = self.pool.get('res.currency').compute(cr, uid, info_price.currency_id.id, partner_currency_id, info_price.price)
130
129
                    currency = partner_currency_id
131
130
                    # Uncomment the following 2 lines if you want the price in currency of the pricelist.partnerinfo instead of partner default currency
132
131
#                    currency = info_price.currency_id.id
218
217
    _constraints = [
219
218
    ]
220
219
 
221
 
    def get_objects_for_partner(self, cr, uid, ids, context):
222
 
        """
223
 
        According to partner's ids: 
224
 
        return the most important objects linked to him that are not closed or opened
225
 
        """
226
 
        # some verifications
227
 
        if isinstance(ids, (int, long)):
228
 
            ids = [ids]
229
 
        if context is None:
230
 
            context = {}
231
 
        #objects
232
 
        purchase_obj = self.pool.get('purchase.order')
233
 
        sale_obj = self.pool.get('sale.order')
234
 
        account_invoice_obj = self.pool.get('account.invoice') # for Supplier invoice/ Debit Note
235
 
        pick_obj = self.pool.get('stock.picking') # for PICK/ PACK/ PPL/ INCOMING SHIPMENT/ DELIVERY
236
 
        tender_obj = self.pool.get('tender')
237
 
        com_vouch_obj = self.pool.get('account.commitment')# for commitment voucher
238
 
        ship_obj = self.pool.get('shipment')
239
 
 
240
 
        # ids list (the domain are the same as the one used for the action window of the menus)
241
 
        purchase_ids = purchase_obj.search(cr, uid,
242
 
            [('rfq_ok', '=', False), ('partner_id', '=', ids[0]), ('state', 'not in', ['done', 'cancel'])],
243
 
            context=context.update({'purchase_order': True}))
244
 
        rfq_ids = purchase_obj.search(cr, uid, 
245
 
            [('rfq_ok', '=', True), ('partner_id', '=', ids[0]), ('state', 'not in', ['done', 'cancel'])],
246
 
            context=context.update({'request_for_quotation': True}))
247
 
        sale_ids = sale_obj.search(cr, uid,
248
 
            [('procurement_request', '=', False), ('partner_id', '=', ids[0]), ('state', 'not in', ['done', 'cancel'])],
249
 
            context=context)
250
 
        intermission_vouch_in_ids = account_invoice_obj.search(cr, uid, [
251
 
                ('type','=','in_invoice'), ('is_debit_note', '=', False), ('is_inkind_donation', '=', False),
252
 
                ('is_intermission', '=', True), ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
253
 
            ], context = context.update({'type':'in_invoice', 'journal_type': 'intermission'}))
254
 
        nb_intermission_vouch_in_ids = len(intermission_vouch_in_ids)
255
 
 
256
 
        intermission_vouch_out_ids = account_invoice_obj.search(cr, uid, [
257
 
                ('type','=','out_invoice'), ('is_debit_note', '=', False), ('is_inkind_donation', '=', False),
258
 
                ('is_intermission', '=', True), ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
259
 
            ], context = context.update({'type':'out_invoice', 'journal_type': 'intermission'}))
260
 
        nb_intermission_vouch_out_ids = len(intermission_vouch_out_ids)
261
 
 
262
 
        donation_ids = account_invoice_obj.search(cr, uid, [
263
 
                ('type','=','in_invoice'), ('is_debit_note', '=', False), ('is_inkind_donation', '=', True),
264
 
                ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
265
 
            ], context = context.update({'type':'in_invoice', 'journal_type': 'inkind'}))
266
 
        supp_invoice_ids = account_invoice_obj.search(cr, uid, [
267
 
                ('type','=','in_invoice'), ('register_line_ids', '=', False), ('is_inkind_donation', '=', False),
268
 
                ('is_debit_note', "=", False), ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
269
 
            ], context = context.update({'type':'in_invoice', 'journal_type': 'purchase'}))
270
 
        nb_supp_invoice_ids = len(supp_invoice_ids)
271
 
 
272
 
        cust_refunds_ids = account_invoice_obj.search(cr, uid,
273
 
            [('type','=','out_refund'), ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])],
274
 
            context = context.update({'type':'out_refund', 'journal_type': 'sale_refund'}))
275
 
        nb_cust_refunds_ids = len(cust_refunds_ids)
276
 
 
277
 
        debit_note_ids = account_invoice_obj.search(cr, uid, [
278
 
                ('type','=','out_invoice'), ('is_debit_note', '!=', False), ('is_inkind_donation', '=', False),
279
 
                ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
280
 
            ], context = context.update({'type':'out_invoice', 'journal_type': 'sale', 'is_debit_note': True}))
281
 
        nb_debit_note_ids = len(debit_note_ids)
282
 
 
283
 
        stock_transfer_vouch_ids = account_invoice_obj.search(cr, uid, [
284
 
                ('type','=','out_invoice'), ('is_debit_note', '=', False), ('is_inkind_donation', '=', False),
285
 
                ('partner_id', '=', ids[0]), ('state', 'in', ['draft', 'open'])
286
 
            ], context = context.update({'type':'out_invoice', 'journal_type': 'sale'}))
287
 
        incoming_ship_ids = pick_obj.search(cr, uid, [
288
 
                ('state', 'not in', ['done', 'cancel']), ('type', '=', 'in'), ('subtype', '=', 'standard'),
289
 
                '|', ('partner_id', '=', ids[0]), ('partner_id2', '=', ids[0])
290
 
            ], context = context.update({
291
 
                'contact_display': 'partner_address', 'subtype': 'in', 'picking_type': 'incoming_shipment', 'search_default_available':1
292
 
            }))
293
 
        out_ids = pick_obj.search(cr, uid, [
294
 
                ('state', 'not in', ['done', 'cancel']), ('type', '=', 'out'), ('subtype', '=', 'standard'),
295
 
                '|', ('partner_id', '=', ids[0]), ('partner_id2', '=', ids[0])
296
 
            ], context = context.update({
297
 
                'contact_display': 'partner_address', 'search_default_available': 1,'picking_type': 'delivery_order', 'subtype': 'standard'
298
 
            }))
299
 
        pick_ids = pick_obj.search(cr, uid, [
300
 
                ('state', 'not in', ['done', 'cancel']), ('type', '=', 'out'), ('subtype', '=', 'picking'),
301
 
                '|', ('partner_id', '=', ids[0]), ('partner_id2', '=', ids[0])
302
 
            ], context = context.update({
303
 
                'picking_screen':True, 'picking_type': 'picking_ticket', 'test':True, 'search_default_not_empty':1
304
 
            }))
305
 
        ppl_ids = pick_obj.search(cr, uid, [
306
 
                ('state', 'not in', ['done', 'cancel']), ('type', '=', 'out'), ('subtype', '=', 'ppl'),
307
 
                '|', ('partner_id', '=', ids[0]), ('partner_id2', '=', ids[0])
308
 
            ], context=context.update({
309
 
                'contact_display': 'partner_address', 'ppl_screen':True, 'picking_type': 'picking_ticket', 'search_default_available':1
310
 
            }))
311
 
        tender_ids = [tend for tend in tender_obj.search(cr, uid, [('state', '=', 'comparison')]) if ids[0] in tender_obj.read(cr, uid, tend, ['supplier_ids'])['supplier_ids']]
312
 
        com_vouch_ids = com_vouch_obj.search(cr, uid, [('partner_id', '=', ids[0]), ('state', '!=', 'done')], context=context)
313
 
        ship_ids = ship_obj.search(cr, uid,
314
 
            [('state', 'not in', ['done', 'delivered']), '|', ('partner_id', '=', ids[0]), ('partner_id2', '=', ids[0])],
315
 
            context=context)
316
 
        
317
 
        return ', '.join([
318
 
            po['name']+_(' (Purchase)') for po in purchase_obj.read(cr, uid, purchase_ids, ['name'], context) if po['name']]
319
 
            +[rfq['name']+_(' (RfQ)') for rfq in purchase_obj.read(cr, uid, rfq_ids, ['name'], context) if rfq['name']]
320
 
            +[so['name']+_(' (Field Order)') for so in sale_obj.read(cr, uid, sale_ids, ['name'], context) if so['name']]
321
 
            +([int_vouch_in['number']+_(' (Intermission Voucher IN)') for int_vouch_in in account_invoice_obj.read(cr, uid, intermission_vouch_in_ids, ['number'], context) if int_vouch_in['number']]\
322
 
                    or intermission_vouch_in_ids and [str(nb_intermission_vouch_in_ids)+_(' (Number of Intermission Voucher IN)')])
323
 
            +([int_vouch_out['number']+_(' (Intermission Voucher OUT)') for int_vouch_out in account_invoice_obj.read(cr, uid, intermission_vouch_out_ids, ['number'], context) if int_vouch_out['number']]\
324
 
                    or intermission_vouch_out_ids and [str(nb_intermission_vouch_out_ids)+_(' (Number of Intermission Voucher OUT)')])
325
 
            +[donation['name']+_(' (Donation)') for donation in account_invoice_obj.read(cr, uid, donation_ids, ['name'], context) if donation['name']]
326
 
            +([supp_invoice['number']+_(' (Supplier Invoice)') for supp_invoice in account_invoice_obj.read(cr, uid, supp_invoice_ids, ['number'], context) if supp_invoice['number']]\
327
 
                    or supp_invoice_ids and [str(nb_supp_invoice_ids)+_(' (Number of Supplier Invoice)')])
328
 
            +([cust_refunds['number']+_(' (Customer Refunds)') for cust_refunds in account_invoice_obj.read(cr, uid, cust_refunds_ids, ['number'], context) if cust_refunds['number']]\
329
 
                    or cust_refunds_ids and [str(nb_cust_refunds_ids)+_(' (Number of Customer Refunds)')])
330
 
            +[debit_note['number']+_(' (Debit Note)') for debit_note in account_invoice_obj.read(cr, uid, debit_note_ids, ['number'], context) if debit_note['number']]
331
 
            +[st_transf_vouch['number']+_(' (Stock Transfer Voucher)') for st_transf_vouch in account_invoice_obj.read(cr, uid, stock_transfer_vouch_ids, ['number',], context) if st_transf_vouch['number']]
332
 
            +[inc_ship['name']+_(' (Incoming Shipment)') for inc_ship in pick_obj.read(cr, uid, incoming_ship_ids, ['name'], context) if inc_ship['name']]
333
 
            +[out['name']+_(' (OUT)') for out in pick_obj.read(cr, uid, out_ids, ['name'], context) if out['name']]
334
 
            +[pick['name']+_(' (PICK)') for pick in pick_obj.read(cr, uid, pick_ids, ['name'], context) if pick['name']]
335
 
            +[ppl['name']+_(' (PPL)') for ppl in pick_obj.read(cr, uid, ppl_ids, ['name'], context) if ppl['name']]
336
 
            +[tend['name']+_(' (Tender)') for tend in tender_obj.read(cr, uid, tender_ids, ['name'], context) if tend['name']]
337
 
            +[com_vouch['name']+_(' (Commitment Voucher)') for com_vouch in com_vouch_obj.read(cr, uid, com_vouch_ids, ['name'], context) if com_vouch['name']]
338
 
            +[ship['name']+_(' (Shipment)') for ship in ship_obj.read(cr, uid, ship_ids, ['name'], context) if ship['name']]
339
 
        )
340
 
 
341
220
    def write(self, cr, uid, ids, vals, context=None):
342
221
        if isinstance(ids, (int, long)):
343
222
            ids = [ids]
344
223
        if not context:
345
224
            context = {}
346
 
        
347
225
        self._check_main_partner(cr, uid, ids, vals, context=context)
348
226
        bro_uid = self.pool.get('res.users').browse(cr,uid,uid)
349
227
        bro = bro_uid.company_id
354
232
            for field in ['name', 'partner_type', 'customer', 'supplier']:
355
233
                if field in vals:
356
234
                    del vals[field]
357
 
        # [utp-315] avoid deactivating partner that have still open document linked to them
358
 
        if 'active' in vals and vals.get('active') == False:
359
 
            objects_linked_to_partner = self.get_objects_for_partner(cr, uid, ids, context)
360
 
            if objects_linked_to_partner:
361
 
                raise osv.except_osv(_('Warning'),
362
 
                                     _("""The following documents linked to the partner need to be closed before deactivating the partner: %s"""
363
 
                                       ) % (objects_linked_to_partner))
 
235
 
364
236
        return super(res_partner, self).write(cr, uid, ids, vals, context=context)
365
237
 
366
238
    def create(self, cr, uid, vals, context=None):
373
245
                vals['property_stock_supplier'] = msf_supplier[1]
374
246
        return super(res_partner, self).create(cr, uid, vals, context=context)
375
247
    
376
 
    
377
 
    def copy_data(self, cr, uid, id, default=None, context=None):
378
 
        '''
379
 
        Erase some unused data copied from the original object, which sometime could become dangerous, as in UF-1631/1632, 
380
 
        when duplicating a new partner (by button duplicate), or company, it creates duplicated currencies
381
 
        '''
382
 
        if default is None:
383
 
            default = {}
384
 
        if context is None:
385
 
            context = {}
386
 
        fields_to_reset = ['ref_companies'] # reset this value, otherwise the content of the field triggers the creation of a new company
387
 
        to_del = []
388
 
        for ftr in fields_to_reset:
389
 
            if ftr not in default:
390
 
                to_del.append(ftr)
391
 
        res = super(res_partner, self).copy_data(cr, uid, id, default=default, context=context)
392
 
        for ftd in to_del:
393
 
            if ftd in res:
394
 
                del(res[ftd])
395
 
        return res
396
 
 
397
 
    def on_change_active(self, cr, uid, ids, active, context=None):
398
 
        """
399
 
        [utp-315] avoid deactivating partner that have still open document linked to them.
400
 
        """
401
 
        if not active:
402
 
            # some verifications
403
 
            if isinstance(ids, (int, long)):
404
 
                ids = [ids]
405
 
            if context is None:
406
 
                context = {}
407
 
            
408
 
            objects_linked_to_partner = self.get_objects_for_partner(cr, uid, ids, context)
409
 
            if objects_linked_to_partner:
410
 
                return {'value': {'active': True}, 
411
 
                        'warning': {'title': _('Error'), 
412
 
                                    'message': _("Some documents linked to this partner needs to be closed or canceled before deactivating the partner: %s"
413
 
                                                ) % (objects_linked_to_partner,)}}
414
 
        return {}
415
 
 
416
248
    def on_change_partner_type(self, cr, uid, ids, partner_type, sale_pricelist, purchase_pricelist):
417
249
        '''
418
250
        Change the procurement method according to the partner type
488
320
            
489
321
            return new_res
490
322
 
491
 
    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
492
 
        """
493
 
        Show the button "Show inactive" in the partner search view only when we have in the context {'show_button_show_inactive':1}.
494
 
        """
495
 
        if not context:
496
 
            context = {}
497
 
        view = super(res_partner, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
498
 
        if view_type == 'search':
499
 
            if not context or not context.get('show_button_show_inactive', False):
500
 
                tree = etree.fromstring(view['arch'])
501
 
                fields = tree.xpath('//filter[@name="inactive"]')
502
 
                for field in fields:
503
 
                    field.set('invisible', "1")
504
 
                view['arch'] = etree.tostring(tree)
505
 
        return view
506
 
 
507
323
res_partner()
508
324
 
509
325
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: