1
# -*- coding: utf-8 -*-
3
# File: wizard/import_n_split.py
4
# Module: ons_autosplit_picking
6
# Created by cyp@open-net.ch
8
# Copyright (c) 2011 Open-Net Ltd. All rights reserved.
9
##############################################################################
11
# OpenERP, Open Source Management Solution
12
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
14
# This program is free software: you can redistribute it and/or modify
15
# it under the terms of the GNU Affero General Public License as
16
# published by the Free Software Foundation, either version 3 of the
17
# License, or (at your option) any later version.
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 Affero General Public License for more details.
24
# You should have received a copy of the GNU Affero General Public License
25
# along with this program. If not, see <http://www.gnu.org/licenses/>.
27
##############################################################################
29
from osv import osv, fields
33
from tools.translate import _
36
class import_n_split(osv.osv_memory):
37
"""Import and split a picking's details"""
39
_name = 'ons.import_n_split'
40
_description = 'Import and split the details of a picking'
42
'prodlot': 'prodlot_id',
43
'tracking': 'tracking_id',
47
'csv_file': fields.binary('Select an CSV File', filters='*.csv', required=True),
50
def fields_view_get(self, cr, uid, view_id=None, view_type='form',
51
context=None, toolbar=False, submenu=False):
52
""" Changes the view dynamically
53
@param self: The object pointer.
54
@param cr: A database cursor
55
@param uid: ID of the user currently logged in
56
@param context: A standard dictionary
57
@return: New arch of view.
59
res = super(import_n_split, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
60
record_id = context and context.get('active_id', False) or False
61
assert record_id,'Active ID not found'
62
pick_obj = self.pool.get('stock.picking')
63
pick = pick_obj.browse(cr, uid, record_id, context=context)
65
# Forget if there's not exactely one stock move
66
if len(pick.move_lines) != 1:
68
res['arch'] = """<form string="File to import">
69
<label string="%s" colspan="4"/>
70
<separator string="" colspan="4"/>
71
<group col="4" colspan="4">
72
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
74
</form>""" % _('You can use this wizard on pickings with one and only one move.')
78
def do_it(self, cr, uid, ids, context=None):
81
@param self: The object pointer
82
@param cr: the current row, from the database cursor,
83
@param uid: the current user’s ID for security checks,
84
@param ids: List of IDs
85
@param context: A standard dictionary for contextual values
87
@return : an empty dictionary.
90
# Here is an example of could be in csv_content
91
# "Qty","prodlot","tracking"
92
# 1,"CNSTP08207030","085511020291554209"
93
# 1,"CNSTP08207030","085511021411014209"
94
# 1,"CNSTP08207030","085511021431334209"
95
# 1,"CNSTP08207030","085511022150614209"
96
# 1,"CNSTP08207030","085511022160244209"
97
# 1,"CNSTP08207031","085511022160804209"
98
# 1,"CNSTP08207031","085511110101200210"
99
# 1,"CNSTP08207031","085511110120020210"
100
# 1,"CNSTP08207031","085511110120740210"
101
# 1,"CNSTP08207031","085511110130070210"
102
# 1,"CNSTP08207031","085511110160080210"
103
# 1,"CNSTP08207031","085511110300360210"
109
obj = self.browse(cr, uid, id, context=context)
110
csv_content = base64.decodestring(obj.csv_file).split('\n')
112
# This will facilitate the decoding of the CSV content
113
lines = csv.reader(csv_content, delimiter=',')
114
fields = lines.next()
116
# Here we clean somewhat the list of lines so that we have an idea of how many lines there are
118
while(i < len(csv_content)):
119
if len(csv_content[i].strip()) < 1:
123
csv_count = len(csv_content) - 1
125
move_obj = self.pool.get('stock.move')
126
pick_obj = self.pool.get('stock.picking')
127
prodlot_obj = self.pool.get('stock.production.lot')
128
tracking_obj = self.pool.get('stock.tracking')
130
record_id = context and context.get('active_id', False) or False
131
assert record_id,'Active ID not found'
132
pick = pick_obj.browse(cr, uid, record_id, context=context)
133
if len(pick.move_lines) != 1:
136
for move in pick.move_lines:
137
if move.product_qty != csv_count:
138
msg = _( 'The quantity (%d) does not correspond to the number of lines (%d) of the CSV file.' ) % ( move.product_qty, csv_count )
139
raise osv.except_osv( 'Error!', msg )
141
# In the future, it may be replaced by one of the CSV's column
143
new_uos_qty = new_qty / move.product_qty * move.product_uos_qty
145
# loop through the CSV lines
150
# Setup the columns and their values
151
for col in self.columns_to_fields.keys():
152
if col not in fields:
154
val = line[ fields.index(col) ]
158
'product_id': move.product_id.id,
160
prodlot_ids = prodlot_obj.search(cr, uid, [('ref','=',val)], context=context)
161
if not prodlot_ids or len(prodlot_ids) < 1:
162
prodlot_id = prodlot_obj.create(cr, uid, prodlot_vals, context=context)
164
prodlot_id = prodlot_ids[0]
166
vals[self.columns_to_fields[col]] = prodlot_id
167
elif col == 'tracking':
171
tracking_ids = tracking_obj.search(cr, uid, [('serial','=',val)], context=context)
172
if not tracking_ids or len(tracking_ids) < 1:
173
tracking_id = tracking_obj.create(cr, uid, tracking_vals, context=context)
175
tracking_id = tracking_ids[0]
177
vals[self.columns_to_fields[col]] = tracking_id
178
elif hasattr(move,self.columns_to_fields[col]):
179
vals[self.columns_to_fields[col]] = val
180
if prodlot_id and tracking_id:
181
tracking_obj.write(cr, uid, [tracking_id], {'prodlot_id':prodlot_id}, context=context)
182
vals.update({'product_qty' : new_qty, 'product_uos_qty': new_uos_qty, 'state':move.state})
185
move_obj.write(cr, uid, move.id, vals, context=context)
187
new_obj = move_obj.copy(cr, uid, move.id, vals)
190
return {'type': 'ir.actions.act_window_close'}