1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2004-2011 Pexego (<www.pexego.es>). All Rights Reserved
6
# $Omar Castiñeira Saavedra$
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
##############################################################################
23
"""inherits fromk stock_move for checks blocked prodlots"""
25
from osv import osv, fields
26
from tools.translate import _
28
class stock_move(osv.osv):
29
"""inherits fromk stock_move for checks blocked prodlots"""
30
_inherit = "stock.move"
32
def get_move_type(self, cr, uid, ids, context=None):
33
"""add new move types"""
34
if context is None: context = {}
36
res = super(stock_move, self).get_move_type(cr, uid, ids, context=context)
38
for move in self.browse(cr, uid, ids, context=context):
39
if move.location_dest_id.usage == 'elimination':
40
res[move.id] = _('WASTE')
41
elif move.picking_id.type == 'return':
42
res[move.id] = _('RETURN')
46
def get_moves_in_location(self, cr, uid, location_id, prodlot_id, qty = 0.0, id = False):
47
"""returns the move in location"""
48
moves = super(stock_move, self).get_moves_in_location(cr, uid, location_id, prodlot_id, qty=qty, id=id)
52
for move in self.browse(cr, uid, moves):
53
if move.location_dest_id.usage == 'elimination':
54
ids_to_remove.append(move.id)
55
ids = list(set(moves) - set(ids_to_remove))
60
def _default_location_destination(self, cr, uid, context=None):
61
""" Gets default address of partner for destination location
62
@return: Address id or False
67
if context.get('move_line', []):
68
if context['move_line'][0]:
69
if isinstance(context['move_line'][0], (tuple, list)):
70
return context['move_line'][0][2] and context['move_line'][0][2].get('location_dest_id',False)
72
move_list = self.pool.get('stock.move').read(cr, uid, context['move_line'][0], ['location_dest_id'])
73
return move_list and move_list['location_dest_id'][0] or False
75
if context.get('address_out_id', False):
76
property_out = self.pool.get('res.partner.address').browse(cr, uid, context['address_out_id'], context).partner_id.property_stock_customer
77
return property_out and property_out.id or False
78
if context.get('address_return_id', False):
79
property_out = self.pool.get('res.partner.address').browse(cr, uid, context['address_return_id'], context).partner_id.property_stock_returns
80
return property_out and property_out.id or False
84
def _default_location_source(self, cr, uid, context=None):
85
""" Gets default address of partner for source location
86
@return: Address id or False
91
if context.get('move_line', []):
93
return context['move_line'][0][2]['location_id']
97
if context.get('address_in_id', False):
98
part_obj_add = self.pool.get('res.partner.address').browse(cr, uid, context['address_in_id'], context=context)
99
if part_obj_add.partner_id:
100
return part_obj_add.partner_id.property_stock_supplier.id
101
if context.get('customer_address_id', False):
102
part_obj_add = self.pool.get('res.partner.address').browse(cr, uid, context['customer_address_id'], context=context)
103
if part_obj_add.partner_id:
104
return part_obj_add.partner_id.property_stock_customer.id
108
def _check_prodlot_blocked(self, cr, uid, ids):
109
"""checks if prodlot is blocked and is trying move"""
110
for move in self.browse(cr, uid, ids):
111
if move.prodlot_id and move.prodlot_id.blocked and move.state in ['assigned', 'done'] and move.location_dest_id.usage != 'elimination':
116
'towaste': fields.boolean('Eliminated', readonly=True),
120
'location_id': _default_location_source,
121
'location_dest_id': _default_location_destination,
124
_constraints = [(_check_prodlot_blocked, _('Cannot move a blocked production lot to internal or customer location'), ['blocked'])
127
def eval_onchange_lot_value(self, cr, uid, res, prodlot_id=False):
128
"""check prodlot_id in on_dhanges value"""
129
prodlot = prodlot_id or ((res.get('value') and res['value'].get('prodlot_id')) and res['value']['prodlot_id'] or False)
130
if res.get('warning', False):
133
obj_prodlot_id = self.pool.get('stock.production.lot').browse(cr, uid, prodlot)
134
if obj_prodlot_id.in_alert:
136
'title': _('Production Lot in Alert!'),
137
'message': _('This production lot is on alert because any of its compounds are in poor conditions.'),
139
return {'warning': res['warning'], 'value': res.get('value') and res['value'] or {}}
140
elif obj_prodlot_id.blocked:
142
'title': _('Production Lot Blocked!'),
143
'message': _('This production lot is blocked because it is poor conditions.'),
145
return {'warning': res['warning'], 'value': res.get('value') and res['value'].update({'prodlot_id': None}) or {'prodlot_id': None}}
148
def onchange_lot_id(self, cr, uid, ids, prodlot_id=False, product_qty=False, loc_id=False, product_id=False, uom_id=False, context=None):
149
"""overwrites this event for shows a warning if the production lot selected is on alert"""
150
if context is None: context = {}
151
if not prodlot_id or not loc_id:
154
res = super(stock_move, self).onchange_lot_id(cr, uid, ids, prodlot_id = prodlot_id, product_qty = product_qty, loc_id = loc_id, product_id=product_id, uom_id=uom_id, context = context)
155
return self.eval_onchange_lot_value(cr, uid, res, prodlot_id)
157
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False, address_id=False, prod_qty=0.0, prodlot_id=False):
158
"""Extends this event checking prodlot obtained"""
159
res = super(stock_move, self).onchange_product_id(cr, uid, ids, prod_id, loc_id, loc_dest_id, address_id)
161
return self.eval_onchange_lot_value(cr, uid, res)
163
def onchange_location_id(self, cr, uid, ids, product_id = False, location_id = False, dummy = False, product_qty=False, product_uom_id=False):
164
"""event fires when changes the location, checks the location and return a default production lot for this location"""
165
res = super(stock_move, self).onchange_location_id(cr, uid, ids,product_id,location_id,dummy,product_qty,product_uom_id)
167
return self.eval_onchange_lot_value(cr, uid, res)
169
def action_done(self, cr, uid, ids, context=None):
170
"""overwrites this method for that to waste product be marked that eliminated"""
171
for move in self.browse(cr, uid, ids):
172
if move.location_dest_id.id == move.product_id.product_tmpl_id.property_waste.id:
173
self.write(cr, uid, [move.id], {'towaste': True})
174
return super(stock_move, self).action_done(cr, uid, ids, context)