OLD | NEW |
1 #This file is part of Tryton. The COPYRIGHT file at the top level of | 1 #This file is part of Tryton. The COPYRIGHT file at the top level of |
2 #this repository contains the full copyright notices and license terms. | 2 #this repository contains the full copyright notices and license terms. |
3 from trytond.model import ModelView, ModelSQL, fields | 3 from trytond.model import ModelView, ModelSQL, fields |
4 from trytond.wizard import Wizard | 4 from trytond.wizard import Wizard |
5 import datetime | 5 import datetime |
6 | 6 |
7 | 7 |
8 class Template(ModelSQL, ModelView): | 8 class Template(ModelSQL, ModelView): |
9 _name = "product.template" | 9 _name = "product.template" |
10 | 10 |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 where_vals = args | 363 where_vals = args |
364 else: | 364 else: |
365 where_clause = " IN (" + \ | 365 where_clause = " IN (" + \ |
366 ",".join(('%s',) * len(location_ids)) + ") " | 366 ",".join(('%s',) * len(location_ids)) + ") " |
367 where_vals = location_ids[:] | 367 where_vals = location_ids[:] |
368 | 368 |
369 if move_query: | 369 if move_query: |
370 where_clause += " AND " + move_query + " " | 370 where_clause += " AND " + move_query + " " |
371 where_vals += move_val | 371 where_vals += move_val |
372 | 372 |
| 373 product_template_join = "" |
373 if product_ids: | 374 if product_ids: |
374 where_clause += "AND product in (" + \ | 375 where_clause += "AND product in (" + \ |
375 ",".join(('%s',) * len(product_ids)) + ")" | 376 ",".join(('%s',) * len(product_ids)) + ")" |
376 where_vals += product_ids | 377 where_vals += product_ids |
| 378 else: |
| 379 where_clause += "AND product_template.active = %s" |
| 380 where_vals.append(True) |
| 381 product_template_join = \ |
| 382 "JOIN product_product "\ |
| 383 "ON (stock_move.product = product_product.id) "\ |
| 384 "JOIN product_template "\ |
| 385 "ON (product_product.template = "\ |
| 386 "product_template.id) "\ |
| 387 |
377 | 388 |
378 if context.get('stock_destinations'): | 389 if context.get('stock_destinations'): |
379 destinations = context.get('stock_destinations') | 390 destinations = context.get('stock_destinations') |
380 dest_clause_from = " AND from_location in (" | 391 dest_clause_from = " AND from_location in (" |
381 dest_clause_from += ",".join(('%s',) * len(destinations)) | 392 dest_clause_from += ",".join(('%s',) * len(destinations)) |
382 dest_clause_from += ") " | 393 dest_clause_from += ") " |
383 dest_clause_to = " AND to_location in (" | 394 dest_clause_to = " AND to_location in (" |
384 dest_clause_to += ",".join(('%s',) * len(destinations)) | 395 dest_clause_to += ",".join(('%s',) * len(destinations)) |
385 dest_clause_to += ") " | 396 dest_clause_to += ") " |
386 dest_vals = destinations | 397 dest_vals = destinations |
387 | 398 |
388 else: | 399 else: |
389 dest_clause_from = dest_clause_to ="" | 400 dest_clause_from = dest_clause_to ="" |
390 dest_vals = [] | 401 dest_vals = [] |
391 | 402 |
392 select_clause = \ | 403 select_clause = \ |
393 "SELECT location, product, uom, sum(quantity) AS quantity "\ | 404 "SELECT location, product, uom, sum(quantity) AS quantity "\ |
394 "FROM ( "\ | 405 "FROM ( "\ |
395 "SELECT to_location AS location, product, uom, "\ | 406 "SELECT to_location AS location, product, uom, "\ |
396 "sum(quantity) AS quantity "\ | 407 "sum(quantity) AS quantity "\ |
397 "FROM stock_move "\ | 408 "FROM stock_move " + product_template_join + \ |
398 "WHERE (%s) " \ | 409 "WHERE (%s) " \ |
399 "AND to_location %s "\ | 410 "AND to_location %s "\ |
400 "GROUP BY to_location, product ,uom "\ | 411 "GROUP BY to_location, product ,uom "\ |
401 "UNION "\ | 412 "UNION "\ |
402 "SELECT from_location AS location, product, uom, "\ | 413 "SELECT from_location AS location, product, uom, "\ |
403 "-sum(quantity) AS quantity "\ | 414 "-sum(quantity) AS quantity "\ |
404 "FROM stock_move "\ | 415 "FROM stock_move " + product_template_join + \ |
405 "WHERE (%s) " \ | 416 "WHERE (%s) " \ |
406 "AND from_location %s "\ | 417 "AND from_location %s "\ |
407 "GROUP BY from_location, product, uom "\ | 418 "GROUP BY from_location, product, uom "\ |
408 ") AS T GROUP BY T.location, T.product, T.uom" | 419 ") AS T GROUP BY T.location, T.product, T.uom" |
409 | 420 |
410 cursor.execute(select_clause % ( | 421 cursor.execute(select_clause % ( |
411 state_date_clause, where_clause + dest_clause_from, | 422 state_date_clause, where_clause + dest_clause_from, |
412 state_date_clause, where_clause + dest_clause_to), | 423 state_date_clause, where_clause + dest_clause_to), |
413 state_date_vals + where_vals + dest_vals + \ | 424 state_date_vals + where_vals + dest_vals + \ |
414 state_date_vals + where_vals + dest_vals) | 425 state_date_vals + where_vals + dest_vals) |
415 raw_lines = cursor.fetchall() | 426 raw_lines = cursor.fetchall() |
416 | 427 |
417 res = {} | 428 res = {} |
418 res_location_ids = [] | 429 res_location_ids = [] |
419 uom_ids = [] | 430 uom_ids = [] |
420 res_product_ids = [] | 431 res_product_ids = [] |
421 for line in raw_lines: | 432 for line in raw_lines: |
422 for id_list, position in ((res_location_ids, 0), (uom_ids, 2), | 433 for id_list, position in ((res_location_ids, 0), (uom_ids, 2), |
423 (res_product_ids, 1)): | 434 (res_product_ids, 1)): |
424 if line[position] not in id_list: | 435 if line[position] not in id_list: |
425 id_list.append(line[position]) | 436 id_list.append(line[position]) |
426 | 437 |
427 if not product_ids: | 438 if not product_ids: |
428 product_ids = self.pool.get("product.product").search( | 439 product_ids = res_product_ids |
429 cursor, user, [], context=context) | |
430 uom_by_id = dict([(x.id, x) for x in uom_obj.browse( | 440 uom_by_id = dict([(x.id, x) for x in uom_obj.browse( |
431 cursor, user, uom_ids, context=context)]) | 441 cursor, user, uom_ids, context=context)]) |
432 default_uom = dict((x.id, x.default_uom) for x in product_obj.browse( | 442 default_uom = dict((x.id, x.default_uom) for x in product_obj.browse( |
433 cursor, user, product_ids, context=context)) | 443 cursor, user, product_ids, context=context)) |
434 | 444 |
435 for line in raw_lines: | 445 for line in raw_lines: |
436 location, product, uom, quantity = line | 446 location, product, uom, quantity = line |
437 key = (location, product) | 447 key = (location, product) |
438 res.setdefault(key, 0.0) | 448 res.setdefault(key, 0.0) |
439 res[key] += uom_obj.compute_qty(cursor, user, uom_by_id[uom], | 449 res[key] += uom_obj.compute_qty(cursor, user, uom_by_id[uom], |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 486 |
477 # Round quantities | 487 # Round quantities |
478 for location, product in res: | 488 for location, product in res: |
479 key = (location, product) | 489 key = (location, product) |
480 res[key] = uom_obj.compute_qty(cursor, user, default_uom[product], | 490 res[key] = uom_obj.compute_qty(cursor, user, default_uom[product], |
481 res[key], default_uom[product], round=True, | 491 res[key], default_uom[product], round=True, |
482 context=context) | 492 context=context) |
483 | 493 |
484 # Complete result with missing products if asked | 494 # Complete result with missing products if asked |
485 if not skip_zero: | 495 if not skip_zero: |
486 keys = ((l,p) for l in location_ids for p in product_ids) | 496 # Search for all products, even if not linked with moves |
| 497 all_product_ids = self.pool.get("product.product").search( |
| 498 cursor, user, [], context=context) |
| 499 keys = ((l,p) for l in location_ids for p in all_product_ids) |
487 for location_id, product_id in keys: | 500 for location_id, product_id in keys: |
488 if (location_id, product_id) not in res: | 501 if (location_id, product_id) not in res: |
489 res[(location_id, product_id)] = 0.0 | 502 res[(location_id, product_id)] = 0.0 |
490 | 503 |
491 if wh_to_add: | 504 if wh_to_add: |
492 for wh, storage in wh_to_add.iteritems(): | 505 for wh, storage in wh_to_add.iteritems(): |
493 for product in product_ids: | 506 for product in product_ids: |
494 if (storage, product) in res: | 507 if (storage, product) in res: |
495 res[(wh, product)] = res[(storage, product)] | 508 res[(wh, product)] = res[(storage, product)] |
496 if storage in storage_to_remove: | 509 if storage in storage_to_remove: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 | 567 |
555 model_data_ids = model_data_obj.search(cursor, user, [ | 568 model_data_ids = model_data_obj.search(cursor, user, [ |
556 ('fs_id', '=', 'act_location_quantity_tree'), | 569 ('fs_id', '=', 'act_location_quantity_tree'), |
557 ('module', '=', 'stock'), | 570 ('module', '=', 'stock'), |
558 ('inherit', '=', False), | 571 ('inherit', '=', False), |
559 ], limit=1, context=context) | 572 ], limit=1, context=context) |
560 model_data = model_data_obj.browse(cursor, user, model_data_ids[0], | 573 model_data = model_data_obj.browse(cursor, user, model_data_ids[0], |
561 context=context) | 574 context=context) |
562 res = act_window_obj.read(cursor, user, model_data.db_id, context=contex
t) | 575 res = act_window_obj.read(cursor, user, model_data.db_id, context=contex
t) |
563 | 576 |
564 ctx = {} | 577 if context == None: context = {} |
565 ctx['product'] = data['id'] | 578 context['product'] = data['id'] |
566 if data['form']['forecast_date']: | 579 if data['form']['forecast_date']: |
567 ctx['stock_date_end'] = data['form']['forecast_date'] | 580 context['stock_date_end'] = data['form']['forecast_date'] |
568 else: | 581 else: |
569 ctx['stock_date_end'] = datetime.date.max | 582 context['stock_date_end'] = datetime.date.max |
570 res['context'] = str(ctx) | 583 res['context'] = str(context) |
571 | 584 |
572 return res | 585 return res |
573 | 586 |
574 OpenLocation() | 587 OpenLocation() |
OLD | NEW |