1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
23
from osv import fields
25
DEFAULTENCODING = 'utf8'
28
REFHEADER = ['Project', 'Rev']
32
MAQUINADICT = {'type': 'product',
33
'supply_method': 'produce',
36
'category': 'Maquina'}
38
MODULODICT = {'type': 'product',
39
'supply_method': 'produce',
42
'category': 'Maquina'}
49
map(set.__setitem__, mylist, [])
52
def xls2list(fname, worksheet=1,encoding=DEFAULTENCODING):
53
from pyExcelerator import parse_xls
54
data = parse_xls(fname, encoding)
55
sheet_name=data[worksheet-1][0].encode(encoding)
56
values = data[worksheet-1][1]
60
for row_idx, col_idx in sorted(values.keys()):
61
row_idx_max = max(row_idx,row_idx_max)
62
col_idx_max = max(col_idx,col_idx_max)
63
v = values[(row_idx, col_idx)]
64
if isinstance(v, unicode):
65
v = v.encode(encoding, 'backslashreplace')
66
vdict[(row_idx,col_idx)] = v
68
for row in range(row_idx_max+1):
70
for col in range(col_idx_max+1):
71
if (row,col) not in vdict:
73
vlist[row].append(vdict[(row,col)])
76
def getAllWorksheets(fname, encoding=DEFAULTENCODING):
77
from pyExcelerator import parse_xls
79
for i in range(len(parse_xls(fname, encoding))):
80
WorkSheetList.append(xls2list(fname, i+1, encoding))
83
def getCols(mylist, colnumlist):
87
for colnum in colnumlist:
88
myrow.append(row[colnum])
92
def cleanWorkSheetList(wslist):
95
while ws[0].count(None) == len(ws[0]):
98
mycol = getCols(ws, [startcol])
99
while mycol.count([None]) == len(mycol):
101
mycol = getCols(ws, [startcol])
102
outlist.append([x[startcol:] for x in ws])
105
class product_product(osv.osv):
106
_inherit = "product.product"
107
_columns = {'equitek_docnum': fields.char('Document Number', size=128)
111
class category_relation(osv.osv):
112
_name = 'category.relation'
113
_columns = {'key': fields.char('Key', size=10),
114
'category_id': fields.many2one('product.category', 'Category')
118
class bom_file(osv.osv):
119
_inherit = 'ir.attachment'
122
def _getModuleList(self, wslist):
125
modlist.append("%s-%03i" %tuple(ws[0][2:4]))
128
def _getBOMData(self, cr, uid, myid, context=None):
129
import base64, os, time
130
mydata = base64.standard_b64decode(self.browse(cr, uid, myid).datas)
131
oldumask = os.umask(077)
132
tmpfname = ('/tmp/xlsfile_%.6f' %(time.time(), )).replace('.', '_') + '.xls'
133
open(tmpfname, 'w').write(mydata)
134
WorkSheetList = getAllWorksheets(tmpfname)
136
return cleanWorkSheetList(WorkSheetList)
138
def getOldModules(self, cr, uid, attachid):
139
wslist = self._getBOMData(cr, uid, attachid)
141
prod_obj = self.pool.get('product.product')
143
mycols = getCols(ws, [PROJECTCOLUMN, REVCOLUMN])
144
modulename = "%s-%03i" %tuple(mycols[0])
145
modlist = prod_obj.search(cr, uid, [('default_code', '=', modulename)])
146
if len(modlist) == 1:
147
oldprodlist.append(modlist[0])
148
elif len(modlist) > 1:
149
raise Exception, "Multiple existing modules: %s" %(modulename, )
150
return uniquify(oldprodlist)
152
def getNewModules(self, cr, uid, attachid):
153
wslist = self._getBOMData(cr, uid, attachid)
155
prod_obj = self.pool.get('product.product')
157
mycols = getCols(ws, [PROJECTCOLUMN, REVCOLUMN])
158
modulename = "%s-%03i" %tuple(mycols[0])
159
modlist = prod_obj.search(cr, uid, [('default_code', '=', modulename)])
160
if len(modlist) == 0:
161
newprodlist.append(prodname)
162
elif len(modlist) > 1:
163
raise Exception, "Multiple existing modules: %s" %(modulename, )
164
return uniquify(newprodlist)
166
def importBOM(self, cr, uid, attachid):
167
wslist = self._getBOMData(cr, uid, attachid)
168
prod_obj = self.pool.get('product.product')
171
MainProdName = ws[0][0]
173
docnum, project, rev, description, qty, variant = row[1:7]
176
def _addProductFromRow(self, cr, uid, row):
177
mycode = "%s-%03i" %tuple(row[2:4])
180
mydict['default_code'] = mycode
181
mydict['name'] = mydescr
182
mydict['description'] = mydescr
183
mydict['equitek_docnum'] = row[1]
184
if row[6] and row[6] != "NA":
185
mydict['variants'] = row[6]
186
#### Falta: agregar category de acuerdo a category_relation
187
prod_obj = self.pool.get('product.product')
188
return prod_obj.create(cr, uid, mydict)
190
def getPMList(self, cr, uid, ws):
191
wslist = self._getBOMData(cr, uid, attachid)
193
for ws in wslist[1:]:
195
if ('find' in dir(row[1])) and (row[1].find(PMPREFIX) == 0):
196
pmlist.append("%s-%03i" %tuple(row[2:4]))
199
def altaMaquina(self, cr, uid, wslist):
202
mycode = "%s-%03i" %tuple(myws[0][2:4])
204
prod_obj = self.pool.get('product.product')
205
if len(prod_obj.search(cr, uid, [('default_code', '=', mycode)])):
206
maqid = prod_obj.search(cr, uid, [('default_code', '=', mycode)])[0]
210
mydict['default_code'] = mycode
211
mydict['name'] = mydescr
212
mydict['description'] = mydescr
213
maqid = prod_obj.create(cr, uid, mydict)
214
result['maquina_id'] = maqid
215
modlist = self._getModuleList(wslist[1:])
216
uomid = self.pool.get('product.uom').search(cr, uid, [('name', '=', UOMNAME)])[0]
217
bom_obj = self.pool.get('mrp.bom')
219
bomdict['product_id'] = maqid
220
bomdict['name'] = 'Lista de mat. ' + mycode
221
bomdict['product_uom'] = uomid
222
bomdict['bom_id'] = False
223
bomid = bom_obj.create(cr, uid, bomdict)
224
result['bom_id'] = bomid
226
mycode = "%s-%03i" %tuple(row[2:4])
227
if mycode in modlist:
228
###### Si el modulo está incluido en los worksheets anexos suponemos que es un modulo nuevo
229
if len(prod_obj.search(cr, uid, [('default_code', '=', mycode)])):
230
raise Exception, "El módulo %s ya existe" %(mycode, )
232
mymoduleid = self._addProductFromRow(cr, uid, row)
234
bomdict['product_id'] = mymoduleid
235
bomdict['product_uom'] = uomid
236
bomdict['bom_id'] = bomid
237
bomdict['name'] = mycode
238
mybomid = bom_obj.create(cr, uid, bomdict)
240
###### Si no está incluido suponemos que el módulo ya existe (y que tiene su bom, etc).
241
res = prod_obj.search(cr, uid, [('default_code', '=', mycode)])
245
raise Exception, "El módulo %s no está dado de alta y no está incluido en el archivo a importar" %(mycode, )
247
raise Exception, "Más de un módulo %s dado de alta." %(mycode, )
248
prod_brw = prod_obj.browse(cr, uid, mymoduleid)
250
bomdict['product_id'] = mymoduleid
251
bomdict['product_uom'] = uomid #### Debería ser el uom del template correspondiente al producto
252
bomdict['bom_id'] = bomid
253
bomdict['name'] = mycode
254
mybomid = bom_obj.create(cr, uid, bomdict)
257
def _addModuleFromWS(self, cr, uid, ws):
259
mycode = "%s-%03i" %tuple(ws[0][2:4])
260
prod_obj = self.pool.get('product.product')
261
bom_obj = self.pool.get('mrp.bom')
262
product_id = prod_obj.search(cr, uid, [('default_code', '=', mycode)])[0]
263
result['module_product_id'] = product_id
264
uomid = self.pool.get('product.uom').search(cr, uid, [('name', '=', UOMNAME)])[0]
266
bomdict['product_id'] = product_id
267
bomdict['product_uom'] = uomid
268
bomdict['bom_id'] = False
269
bomdict['name'] = 'Lista de material para módulo ' + mycode
270
bomid = bom_obj.create(cr, uid, bomdict)
271
result['module_bom_id'] = bomid
272
result['bom_pmlist'] = []
274
myprod_code = "%s-%03i" %tuple(row[2:4])
275
myproduct_idlist = prod_obj.search(cr, uid, [('default_code', '=', myprod_code)])
277
if not len(myproduct_idlist):
278
myproduct_id = self._addProductFromRow(cr, uid, row)
281
myproduct_id = myproduct_idlist[0]
283
if ('find' in dir(row[1])) and (row[1].find(PMPREFIX) == 0):
284
result['bom_pmlist'].append(myproduct_id)
286
bomdict['product_id'] = myproduct_id
287
bomdict['bom_id'] = bomid
288
bomdict['product_uom'] = uomid
289
bomdict['product_qty'] = row[5]
290
bomdict['name'] = mydescr
291
mybomid = bom_obj.create(cr, uid, bomdict)
292
if len(row) >= 8 and row[7]:
294
prod_obj.write(cr, uid, [myproduct_id], {'variants': False})
296
res = prod_obj.search(cr, uid, [('default_code', '=', row[6])])
298
raise osv.except_osv(('Error !'), ('El producto %s no existe.' %(row[6], )))
299
bomdict['product_id'] = res[0]
300
bomdict['bom_id'] = mybomid
301
bomdict['product_uom'] = uomid
302
bomdict['product_qty'] = row[7]
303
bomdict['name'] = row[6]
304
mysubbomid = bom_obj.create(cr, uid, bomdict)
308
def importMaquina(self, cr, uid, attachid):
310
oldlist = self.getOldModules(cr, uid, attachid)
311
wslist = self._getBOMData(cr, uid, attachid)
312
maqdict = self.altaMaquina(cr, uid, wslist)
313
main_bomid = maqdict['bom_id']
315
for ws in wslist[1:]:
316
bomdata.append(self._addModuleFromWS(cr, uid, ws))
317
return (main_bomid, oldlist, bomdata)