-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproduto_IMP.py
486 lines (444 loc) · 16.9 KB
/
produto_IMP.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# Implementação do módulo {produto} e da classe {ObjProduto}.
import produto
import tabela_generica
import conversao_sql
import identificador
import tabelas
from utils_testes import erro_prog, aviso_prog, mostra
import sys # Para diagnóstico.
# VARIÁVEIS GLOBAIS DO MÓDULO
nome_tb = "produtos"
# Nome da tabela na base de dados.
cache = {}.copy()
# Dicionário que mapeia identificadores para os objetos {ObjProdutos} na memória.
# Todo objeto dessa classe que é criado é acrescentado a esse dicionário,
# a fim de garantir a unicidadde dos objetos.
letra_tb = "P"
# Prefixo dos identificadores de produtos.
colunas = \
( ( 'descr_curta', type("foo"), 'TEXT', False ), # Descricao curta do produto.
( 'descr_media', type("foo"), 'TEXT', False ), # Descricao media do produto.
( 'descr_longa', type("foo"), 'TEXT', False ), # Descricao longa do produto.
( 'palavras', type("foo"), 'TEXT', True ), # Sinônimos e termos relacionados, para busca.
( 'unidade', type("foo"), 'TEXT', False ), # Unidade de venda ('metro', 'caixa', 'peça', etc.).
( 'preco', type(10.5), 'FLOAT', False ), # Preco unitário do produto em reais.
( 'imagem', type("foo"), 'TEXT', False ), # Nome do arquivo da imagem no diretorio 'imagens'.
( 'peso', type(10.5), 'FLOAT', False ), # peso do produto em gramas.
( 'volume', type(10.5), 'FLOAT', False ), # volume do produto em mililitros.
( 'estoque', type(10), 'INTEGER', False ), # Estoque do produto.
( 'oferta', type(True), 'INTEGER', False ), # Produto está em oferta.
( 'variado', type(True), 'INTEGER', False ), # Produto possui variedades.
( 'grupo', type("foo"), 'TEXT', True ), # Identificador de produto do grupo.
( 'variedade', type("foo"), 'TEXT', True ), # Descrição super-curta do produto, relativa ao grupo.
)
# Descrição das colunas da tabela na base de dados.
diags = False
# Quando {True}, mostra comandos e resultados em {stderr}.
class ObjProduto_IMP():
# Definição interna da classe {ObjUsuario}:
def __init__(self, id_produto, atrs):
self.atrs = atrs.copy()
self.id_produto = id_produto
# Implementação das funções:
def inicializa(limpa):
global cache, nome_tb, letra_tb, colunas, diags
if limpa:
tabela_generica.limpa_tabela(nome_tb, colunas)
else:
tabela_generica.cria_tabela(nome_tb, colunas)
def cria(atrs):
global cache, nome_tb, letra_tb, colunas, diags
if diags: mostra(0, "produto_IMP.cria(" + str(atrs) + ") ...")
# Converte atributos para formato SQL.
atrs_SQL = conversao_sql.dict_mem_para_dict_SQL(atrs, colunas, False, tabelas.obj_para_indice)
# Insere na base de dados e obtém o índice na mesma:
prod = tabela_generica.acrescenta(nome_tb, cache, letra_tb, colunas, def_obj, atrs_SQL)
assert type(prod) is produto.ObjProduto
return prod
def obtem_identificador(prod):
global cache, nome_tb, letra_tb, colunas, diags
return prod.id_produto
def obtem_palavras(prod):
global cache, nome_tb, letra_tb, colunas, diags
return prod.palavras
def obtem_indice(prod):
global cache, nome_tb, letra_tb, colunas, diags
return identificador.para_indice(letra_tb, prod.id_produto)
def obtem_preco(prod):
global cache, nome_tb, letra_tb, colunas, diags
return prod.atrs['preco']
def obtem_atributos(prod):
global cache, nome_tb, letra_tb, colunas, diags
return prod.atrs.copy()
def calcula_preco(prod, qtd):
return prod.atrs['preco'] * qtd
def muda_atributos(prod, mods):
global cache, nome_tb, letra_tb, colunas, diags
# Converte valores de formato memória para formato SQL.
mods_SQL = conversao_sql.dict_mem_para_dict_SQL(mods, colunas, True, tabelas.obj_para_indice)
# Modifica atributos na tabela e na memória:
res = tabela_generica.atualiza(nome_tb, cache, letra_tb, colunas, def_obj, prod.id_produto, mods_SQL)
assert res == prod
return
def busca_grupo_por_identificador(id_produto):
global cache, nome_tb, letra_tb, colunas, diags
prods = tabela_generica.busca_por_campo(nome_tb, letra_tb, colunas, 'grupo', id_produto, None)
return map(busca_por_identificador, prods)
def busca_por_identificador(id_produto):
global cache, nome_tb, letra_tb, colunas, diags
prod = tabela_generica.busca_por_identificador(nome_tb, cache, letra_tb, colunas, def_obj, id_produto)
return prod
def busca_por_indice(ind):
global cache, nome_tb, letra_tb, colunas, diags
usr = tabela_generica.busca_por_indice(nome_tb, cache, letra_tb, colunas, def_obj, ind)
return usr
def busca_por_palavra(pal):
global cache, nome_tb, letra_tb, colunas, diags
chaves = ('descr_curta', 'descr_media', 'palavras')
valores = (pal,)
busca_com_and = ' AND ' in pal
if busca_com_and:
valores = pal.split(' AND ')
valores = tuple(valores)
produtos = tabela_generica.busca_por_semelhanca(nome_tb, letra_tb, colunas, chaves, valores)
return produtos
def busca_ofertas():
global cache, nome_tb, letra_tb, colunas, diags
lista_ids=tabela_generica.busca_por_campo(nome_tb, letra_tb, colunas, "oferta", 1, None)
return lista_ids
def busca_por_produtos_semelhantes(pal):
global cache, nome_tb, letra_tb, colunas, diags
chaves = ('palavras',)
valores = (pal,)
produtos = tabela_generica.busca_por_semelhanca(nome_tb, letra_tb, colunas, chaves, valores)
return produtos
def cria_testes():
global cache, nome_tb, letra_tb, colunas, diags
inicializa(True)
lista_atrs = \
[
{
'descr_curta': "Escovador de ouriço",
'variado' : False,
'grupo' : None,
'variedade' : None,
'descr_media': "Escovador para ouriços ou porcos-espinho portátil em aço inox e marfim orgânico, com haste elongável, cabo de força, 20 acessórios, e valise.",
'palavras': 'escovador, animal, ourico, animais, portátil',
'descr_longa':
"""Fabricante: Ouricex LTD<br/>
Origem: Cochinchina<br/>
Modelo: EO-22<br/>
Tensão: 110-230 V<br/>
Potência: 1500 W<br/>
Acessórios: cabo de força de 50 m, 10 pentes finos, 10 pentes grossos, valise em ABS<br/>
Dimensões: 300 x 200 x 3000 mm""",
'preco': 120.50,
'imagem': "155951.png",
'estoque': 500,
'unidade': "1 aparelho",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{
'descr_curta': "Furadeira telepática (x 2)",
'variado' : False,
'grupo' : None,
'variedade' : None,
'descr_media': "Kit com duas furadeiras telepáticas 700 W para canos de até 2 polegadas com acoplador para guarda-chuva e cabo de força",
'palavras': 'furadeira, marcenaria',
'descr_longa':
""""Fabricante: Ferramentas Tres Dedos SA<br/>
Origem: Brasil<br/>
Modelo: FT7T<br/>
Tensão: insuportável<br/>
Potência: 700 W<br/>
Material: Alumínio, policarbonato, chiclete.<br/>
Acessórios: 1 acoplador para guarda-chuvas, 1 jogo de 5 pedais, cabo de força de 2 m.<br/>
Dimensões: 150 x 400 x 250 mm""",
'preco': 420.00,
'imagem': "156931.png",
'estoque': 500,
'unidade': "caixa de 2",
'peso':10.0,
'volume':500.5,
'oferta' : False,
},
{
'descr_curta': "Luva com 8 dedos",
'variado' : True,
'grupo' : None,
'variedade' : None,
'descr_media': "Luva para mão esquerda com 8 dedos, em camurça, com forro de bom-bril",
'palavras': 'luva, inverno',
'descr_longa':
"""Fabricante: United Trash Inc.<br/>
Origem: USA<br/>
Modelo: 8-EB<br/>
Normas: ANSI 2345, ABNT 2019-857<br/>
Material: Camurça artificial 1 mm, lã de aço.<br/>
Tamanho: G<br/>
Peso: 120 g""",
'preco': 19.95,
'imagem': "160519.png",
'estoque': 500,
'unidade': "1 unidade",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{
'descr_curta': "Luva com 8 dedos",
'variado' : False,
'grupo': "P-00000003",
'variedade' : "Tamanho M",
'descr_media': "Luva para mão esquerda com 8 dedos, em camurça, com forro de bom-bril",
'palavras': 'luva, inverno',
'descr_longa':
"""Fabricante: United Trash Inc.<br/>
Origem: USA<br/>
Modelo: 8-EB<br/>
Normas: ANSI 2345, ABNT 2019-857<br/>
Material: Camurça artificial 1 mm, lã de aço.<br/>
Tamanho: G<br/>
Peso: 120 g""",
'preco': 19.95,
'imagem': "160519.png",
'estoque': 500,
'unidade': "1 unidade",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{
'descr_curta': "Luva com 8 dedos",
'variado' : False,
'grupo': "P-00000003",
'variedade' : "Tamanho G",
'descr_media': "Luva para mão esquerda com 8 dedos, em camurça, com forro de bom-bril",
'palavras': 'luva, inverno',
'descr_longa':
"""Fabricante: United Trash Inc.<br/>
Origem: USA<br/>
Modelo: 8-EB<br/>
Normas: ANSI 2345, ABNT 2019-857<br/>
Material: Camurça artificial 1 mm, lã de aço.<br/>
Tamanho: G<br/>
Peso: 120 g""",
'preco': 19.95,
'imagem': "160519.png",
'estoque': 500,
'unidade': "1 unidade",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{
'descr_curta': "Luva com 8 dedos",
'variado' : False,
'grupo': "P-00000003",
'variedade' : "Tamanho P",
'descr_media': "Luva para mão esquerda com 8 dedos, em camurça, com forro de bom-bril",
'palavras': 'luva, inverno',
'descr_longa':
"""Fabricante: United Trash Inc.<br/>
Origem: USA<br/>
Modelo: 8-EB<br/>
Normas: ANSI 2345, ABNT 2019-857<br/>
Material: Camurça artificial 1 mm, lã de aço.<br/>
Tamanho: G<br/>
Peso: 120 g""",
'preco': 19.95,
'imagem': "160519.png",
'estoque': 500,
'unidade': "1 unidade",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{
'descr_curta': "Ferroada",
'variado' : False,
'grupo' : None,
'variedade' : None,
'descr_media': "Espada élfica forjada na cidade de Gondolin.",
'palavras': 'espada, elfo, senhor dos aneis',
'descr_longa':
"""Fabricante: Gondolin Ferreiros SA<br/>
Origem: Gondolin<br/>
Dono Original: Bilbo""",
'preco': 2000.00,
'imagem': "170859.png",
'estoque': 500,
'unidade': "1 espada" ,
'peso':10.0,
'volume':500.5,
'oferta' : False,
},
{
'descr_curta': "Amassador de suspiros",
'variado' : False,
'grupo' : None,
'variedade' : None,
'descr_media': "Amassador de suspiros lânguidos manual com 5 velocidades e 2 temperaturas.",
'palavras': 'amassador, suspiro',
'descr_longa':
"""Fabricante: Produits Ineffables SA<br/>
Origem: França<br/>
Acionamento: manual<br/>
Acessórios: frasco de elixir, estojo, 4 parafusos de fixação com buchas<br/>
Peso: excessivo<br/>
Volume: estridente""",
'preco': 49.99,
'imagem': "136714.png",
'estoque': 20,
'unidade': "1 aparelho",
'peso':10.0,
'volume':500.5,
'oferta' : True,
},
{ 'descr_curta': "Cabideiro",
'variado' : False,
'grupo' : None,
'variedade' : None,
'descr_media': "Cabideiro com capacidade para 420 cabides",
'palavras':'cabide, cabides, roupas, roupa',
'descr_longa':
"""Lindo cabideiro com suporte para 420 cabides, ideal para você, seus pais, filhos, irmãos, tios e cachorros<br/>
Fabricante: Gargah Lar SA""",
'preco': 69.00,
'imagem': "146752.png",
'estoque': 1,
'unidade': "01 (hum) cabideiro",
'peso':10.0,
'volume':500.5,
'oferta' : False,
},
{ 'descr_curta': "Ácido pernóstico",
'variado' : True,
'grupo' : None,
'variedade' : None,
'descr_media': "Ácido pernóstico (H2PeO4) puro ACS para análise",
'palavras':'química,limpeza,elixir',
'descr_longa':
"""Fabricante: Tox Chic SA<br/>
Fórmula: H2PeO4·3H2O<br/>
Pureza: 99.8%<br/>
Padrão: ACS, INPM
""",
'preco': 25.00,
'imagem': "170013-g.png",
'estoque': 50,
'unidade': "frasco",
'peso': 10.0,
'volume': 500.5,
'oferta' : False,
},
{ 'descr_curta': "Ácido pernóstico",
'variado' : False,
'grupo' : "P-00000010",
'variedade' : "200 mL",
'descr_media': "Ácido pernóstico (H2PeO4) puro ACS para análise",
'palavras': None,
'descr_longa':
"""Fórmula: H2PeO4·3H2O<br/>
Pureza: 99.8%<br/>
Padrão: ACS, INPM<br/>
Embalagem: garrafa de vidro com batoque
""",
'preco': 20.00,
'imagem': "170013-1.png",
'estoque': 50,
'unidade': "frasco",
'peso': 300.0,
'volume': 200.5,
'oferta' : False,
},
{ 'descr_curta': "Ácido pernóstico",
'variado' : False,
'grupo' : "P-00000010",
'variedade' : "500 mL",
'descr_media': "Ácido pernóstico (H2PeO4) puro ACS para análise",
'palavras':'química,limpeza,elixir',
'descr_longa':
"""Fórmula: H2PeO4·3H2O<br/>
Pureza: 99.8%<br/>
Padrão: ACS, INPM<br/>
Embalagem: garrafa de vidro com batoque
""",
'preco': 45.00,
'imagem': "170013-2.png",
'estoque': 50,
'unidade': "frasco",
'peso': 650.0,
'volume': 500.5,
'oferta' : True,
},
{ 'descr_curta': "Ácido pernóstico",
'variado' : False,
'grupo' : "P-00000010",
'variedade' : "5 litros",
'descr_media': "Ácido pernóstico (H2PeO4) puro ACS para análise",
'palavras':'química,limpeza,elixir',
'descr_longa':
"""Fórmula: H2PeO4·3H2O<br/>
Pureza: 99.8%<br/>
Padrão: ACS, INPM<br/>
Embalagem: bombona de polietileno com batoque
""",
'preco': 370.00,
'imagem': "170013-3.png",
'estoque': 50,
'unidade': "frasco",
'peso': 7000.0,
'volume': 5000.0,
'oferta' : False,
},
]
for atrs in lista_atrs:
# Acrescenta o produto à base de dados:
prod = cria(atrs)
assert prod != None and type(prod) is produto.ObjProduto
# Mostra na janela de shell:
sys.stderr.write("id = %s \"%s\"" % (produto.obtem_identificador(prod), atrs['descr_curta'],))
if ('grupo' in atrs) and (atrs['grupo'] != None):
sys.stderr.write(" [grupo = %s var = \"%s\"]" % (str(atrs['grupo']), str(atrs['variedade'],)))
sys.stderr.write("\n")
return
# FUNÇÕES INTERNAS
def def_obj(obj, id_produto, atrs_SQL):
"""Se {obj} for {None}, cria um novo objeto da classe {ObjProduto} com
identificador {id_produto} e atributos {atrs_SQL}, tais como extraidos
da tabela de sessoes. O objeto *não* é inserido na base de dados.
Se {obj} não é {None}, deve ser um objeto da classe {ObjProduto}; nesse
caso a função altera os atributos de {obj} conforme especificado em
{atrs_SQL}.
Em qualquer caso, os valores em {atr_SQL} são convertidos para valores
equivalentes na memória."""
global cache, nome_tb, letra_tb, colunas, diags
if diags: mostra(0, "produto_IMP.def_obj(" + str(obj) + ", " + id_produto + ", " + str(atrs_SQL) + ") ...")
if obj == None:
atrs_mem = conversao_sql.dict_SQL_para_dict_mem(atrs_SQL, colunas, False, tabelas.obj_para_indice)
if diags: mostra(2, "criando objeto, atrs_mem = " + str(atrs_mem))
obj = produto.ObjProduto(id_produto, atrs_mem)
else:
assert obj.id_produto == id_produto
# Converte atributos para formato na memória.
mods_mem = conversao_sql.dict_SQL_para_dict_mem(atrs_SQL, colunas, True, tabelas.obj_para_indice)
if diags: mostra(2, "modificando objeto, mods_mem = " + str(mods_mem))
assert type(mods_mem) is dict
if len(mods_mem) > len(obj.atrs):
erro_prog("numero excessivo de atributos a alterar")
for chave, val in mods_mem.items():
if not chave in obj.atrs:
erro_prog("chave '" + chave + "' inválida")
val_velho = obj.atrs[chave]
if not type(val_velho) is type(val):
erro_prog("tipo do campo '" + chave + "' incorreto")
obj.atrs[chave] = val
if diags: mostra(2, "obj = " + str(obj))
return obj
def diagnosticos(val):
global cache, nome_tb, letra_tb, colunas, diags
diags = val
return