~pexego/openobject-addons/6.1-pexego-sale_commission

« back to all changes in this revision

Viewing changes to stock_block_prodlots/block_prodlot_case.py

  • Committer: Omar (pexego)
  • Date: 2012-07-27 08:40:22 UTC
  • Revision ID: omar@pexego.es-20120727084022-qp3ludpr3vsuyuf6
[ADD] Traceability modules ported to 6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2011 Pexego (<www.pexego.es>). All Rights Reserved
 
6
#    $Omar Castiñeira Saavedra$
 
7
#
 
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.
 
12
#
 
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.
 
17
#
 
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/>.
 
20
#
 
21
##############################################################################
 
22
 
 
23
"""reasons to block production lots"""
 
24
 
 
25
from osv import osv, fields
 
26
import netsvc
 
27
import time
 
28
from tools.translate import _
 
29
 
 
30
class block_prodlot_cases(osv.osv):
 
31
    """reasons to block production lots"""
 
32
    _name = "block.prodlot.cases"
 
33
    _description = "Blockade cases"
 
34
 
 
35
    _columns = {
 
36
            'name': fields.char('Name', size=64, required=True, states={'confirm':[('readonly', True)]}),
 
37
            'description': fields.text('Description', required=True),
 
38
            'blocked_prodlots_ids': fields.many2many('stock.production.lot', 'blocked_prodlots_cases_ids', 'case_id', 'blocked_prodlot', 'Blocked Prodlots', states={'confirm':[('readonly', True)]}),
 
39
            'parent_block_prodlot': fields.many2one('stock.production.lot', 'Blockade Root', required=True, ondelete="set null", states={'confirm':[('readonly', True)]}),
 
40
            'state': fields.selection([('in_review', 'In Review'), ('confirm', 'Confirm'), ('cancelled', 'Cancelled')], 'State', required=True, readonly=True)
 
41
        }
 
42
 
 
43
    _defaults = {
 
44
            'state': 'in_review'
 
45
        }
 
46
 
 
47
    def send_blockade_case_notification(self, cr, uid, case_id, state = 'in_review'):
 
48
        """send a notification to Production Lots / Blockade Notifications users for blockade cases"""
 
49
        group_id = self.pool.get('res.groups').search(cr, uid, [('name', '=', 'Production Lots / Blockade Notifications')])
 
50
 
 
51
        if group_id:
 
52
            group_id = self.pool.get('res.groups').browse(cr, uid, group_id[0])
 
53
            
 
54
            obj_case_id = self.browse(cr, uid, case_id)
 
55
            #get a string comma list from object case prodlots collection
 
56
            # pylint: disable-msg=W0141
 
57
            lots_affected_names = u','.join(map(str, map(lambda x:x.name, obj_case_id.blocked_prodlots_ids)))
 
58
 
 
59
            if state == 'in_review':
 
60
                message = _("New production lots in review, will raise a warning meanwhile be in this state.\n\nLots names: %s\n\nBlockade Description: %s\n\n \
 
61
                        Blockade was raised from production_lot: %s.") % (lots_affected_names, obj_case_id.description, obj_case_id.parent_block_prodlot.name)
 
62
            else:
 
63
                message = _("New production lots blocked. Now not can you use this prodlots definitely.\n\nLots names: %s\n\nBlockade Description: %s\n\n \
 
64
                        Blockade was raised from production_lot: %s.") % (lots_affected_names, obj_case_id.description, obj_case_id.parent_block_prodlot.name)
 
65
 
 
66
            for user in group_id.user_ids:
 
67
                self.pool.get('res.request').create(cr, uid, {
 
68
                        'name': _("Blockade Case %s: %s") % (obj_case_id.id, obj_case_id.name),
 
69
                        'body': message,
 
70
                        'state': 'waiting',
 
71
                        'act_from': uid,
 
72
                        'act_to': user.id,
 
73
                        'ref_doc1': 'block.prodlot.cases,%d' % (obj_case_id.id,),
 
74
                        'priority': '2'
 
75
                    })
 
76
 
 
77
            return True
 
78
 
 
79
        return False
 
80
 
 
81
    def confirm_blockade_case(self, cr, uid, ids, context = None):
 
82
        """confirm blockade case and block definitely prodlots in alert affected by case"""
 
83
        if context is None: context = {}
 
84
 
 
85
        if isinstance(ids, (int, long)):
 
86
            ids = [ids]
 
87
 
 
88
        for obj_block_prodlot_case_id in self.browse(cr, uid, ids):
 
89
            created_move_ids = []
 
90
            for obj_blocked_prodlot_id in obj_block_prodlot_case_id.blocked_prodlots_ids:
 
91
                #searches if prodlots have other blockade cases that interrumpt his blockade
 
92
                cr.execute("select * from blocked_prodlots_cases_ids inner join block_prodlot_cases on id = case_id \
 
93
                    where blocked_prodlot = %s and case_id != %s and state not in ('confirm','cancelled')", (obj_blocked_prodlot_id.id, obj_block_prodlot_case_id.id))
 
94
 
 
95
                #if prodlot have another blockade cases in review it cannot block
 
96
                if cr.rowcount:
 
97
                    continue
 
98
 
 
99
                obj_real_report_prodlots_ids = self.pool.get('stock.report.prodlots').search(cr, uid, [('prodlot_id', '=', obj_blocked_prodlot_id.id),('qty','>',0)])
 
100
 
 
101
                for obj_real_report_prodlots_id in self.pool.get('stock.report.prodlots').browse(cr, uid, obj_real_report_prodlots_ids):
 
102
 
 
103
                    if obj_real_report_prodlots_id.location_id.usage not in ('internal'):
 
104
                        continue
 
105
 
 
106
                    move_id = self.pool.get('stock.move').create(cr, uid, {
 
107
                                'product_uom': obj_real_report_prodlots_id.product_id.uom_id.id,
 
108
                                'date' : time.strftime("%Y-%m-%d"),
 
109
                                'date_expected' : time.strftime("%Y-%m-%d"),
 
110
                                'prodlot_id': obj_blocked_prodlot_id.id,
 
111
                                'product_qty': obj_real_report_prodlots_id.qty,
 
112
                                'location_id': obj_real_report_prodlots_id.location_id.id,
 
113
                                'product_id': obj_real_report_prodlots_id.product_id.id,
 
114
                                'name': _("BLOCK: ") + obj_real_report_prodlots_id.prodlot_id.name + obj_real_report_prodlots_id.location_id.name,
 
115
                                'state': 'draft',
 
116
                                'location_dest_id': obj_real_report_prodlots_id.product_id.product_tmpl_id.property_waste.id
 
117
                                })
 
118
 
 
119
                    created_move_ids.append(move_id)
 
120
 
 
121
                #for update block and in_alert store attribute
 
122
                self.pool.get('stock.production.lot').write(cr, uid, [obj_blocked_prodlot_id.id], {'date': time.strftime("%Y-%m-%d %H:%M:%S")})
 
123
 
 
124
            if created_move_ids:
 
125
                picking_id = self.pool.get('stock.picking').create(cr, uid, {
 
126
                                                    'origin': _("BLOCKCASE:") + str(obj_block_prodlot_case_id.id),
 
127
                                                    'state': 'draft',
 
128
                                                    'type': 'internal',
 
129
                                                    'move_type': 'direct',
 
130
                                                    })
 
131
 
 
132
                self.pool.get('stock.move').write(cr, uid, created_move_ids, {'picking_id': picking_id})
 
133
 
 
134
                wf_service = netsvc.LocalService("workflow")
 
135
                wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
 
136
 
 
137
            self.write(cr, uid, [obj_block_prodlot_case_id.id], {
 
138
                                                        'state': 'confirm'
 
139
                                                        })
 
140
 
 
141
            #send block notification to users
 
142
            self.send_blockade_case_notification(cr, uid, obj_block_prodlot_case_id.id, 'confirm')
 
143
 
 
144
            #for update block and in_alert store attribute
 
145
            self.pool.get('stock.production.lot').write(cr, uid, [x.id for x in obj_block_prodlot_case_id.blocked_prodlots_ids], {})
 
146
        return True
 
147
 
 
148
    def cancel_blockade_case(self, cr, uid, ids, context = None):
 
149
        """cancelled blockade cases"""
 
150
        if context is None: context = {}
 
151
        self.write(cr, uid, ids, {'state': 'cancelled'})
 
152
        for obj_block_prodlot_case_id in self.browse(cr, uid, ids):
 
153
            self.pool.get('stock.production.lot').write(cr, uid, [x.id for x in obj_block_prodlot_case_id.blocked_prodlots_ids], {})
 
154
        return True
 
155
 
 
156
    def write(self, cr, uid, ids, vals, context = None):
 
157
        """overwrites write method for update production lots when case updating"""
 
158
        if context is None: context = {}
 
159
        moves_to_update = []
 
160
 
 
161
        if isinstance(ids, (int, long)):
 
162
            ids = [ids]
 
163
 
 
164
        for obj_case_id in self.browse(cr, uid, ids):
 
165
            moves_to_update = list(set(moves_to_update + [x.id for x in obj_case_id.blocked_prodlots_ids]))
 
166
 
 
167
        res = super(block_prodlot_cases, self).write(cr, uid, ids, vals, context)
 
168
 
 
169
        self.pool.get('stock.production.lot').write(cr, uid, moves_to_update, {})
 
170
 
 
171
        return res
 
172
 
 
173
    def create(self, cr, uid, vals, context = None):
 
174
        """overwrites this method to send notification informative with context of in alert prodlots and case"""
 
175
        if context is None: context = {}
 
176
        case_id = super(block_prodlot_cases, self).create(cr, uid, vals, context=context)
 
177
 
 
178
        #send in_review notification
 
179
        self.send_blockade_case_notification(cr, uid, case_id, 'in_review')
 
180
 
 
181
        return case_id
 
182
 
 
183
    def unlink(self, cr, uid, ids, context = None):
 
184
        """overwrites unlink function to update prodlots_state"""
 
185
        if context is None: context = {}
 
186
        affected_lots = []
 
187
        
 
188
        for blockade_case_id in self.browse(cr, uid, ids):
 
189
            if blockade_case_id.state == 'confirm':
 
190
                raise osv.except_osv(_("Warning!"), _("Can't delete confirmed blockade case."))
 
191
 
 
192
            affected_lots.extend([x.id for x in blockade_case_id.blocked_prodlots_ids])
 
193
 
 
194
        res = super(block_prodlot_cases, self).unlink(cr, uid, ids, context = context)
 
195
 
 
196
        if affected_lots:
 
197
            self.pool.get('stock.production.lot').write(cr, uid, affected_lots, {})
 
198
 
 
199
        return res
 
200
 
 
201
block_prodlot_cases()
 
202
 
 
203
class stock_production_lot(osv.osv):
 
204
    """inherit object to add many2many relationship with block.prodlot.cases"""
 
205
    _inherit = "stock.production.lot"
 
206
 
 
207
    _columns = {
 
208
            'blocked_prodlots_cases_ids': fields.many2many('block.prodlot.cases', 'blocked_prodlots_cases_ids', 'blocked_prodlot', 'case_id', "Blockade Cases"),
 
209
    }
 
210
 
 
211
stock_production_lot()