2021-08-26 20:16:55 +02:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
2022-01-18 22:23:18 +01:00
import copy
2021-12-29 17:41:02 +01:00
from datetime import date , datetime , timedelta
2021-08-28 18:27:55 +02:00
from decimal import Decimal
2021-08-26 20:16:55 +02:00
from trytond . model import fields , ModelView
from trytond . pool import Pool , PoolMeta
from trytond . pyson import Eval , Not , Bool
2023-12-04 01:28:55 +01:00
from trytond . wizard import Wizard , StateView , StateReport , Button , StateTransition
2021-08-26 20:16:55 +02:00
from trytond . report import Report
from trytond . transaction import Transaction
2023-12-04 01:28:55 +01:00
from trytond . pyson import Eval , Equal , If , In
2023-10-24 21:58:28 +02:00
2021-08-26 20:16:55 +02:00
STATES = { ' invisible ' : ( Eval ( ' type ' ) != ' goods ' ) }
STATES_MOVE = {
' readonly ' : Eval ( ' state ' ) . in_ ( [ ' cancel ' , ' assigned ' , ' done ' ] ) ,
}
2021-09-23 15:15:13 +02:00
class Lot ( metaclass = PoolMeta ) :
__name__ = ' stock.lot '
active = fields . Boolean ( ' Active ' )
@staticmethod
def default_active ( ) :
return True
2021-08-26 20:16:55 +02:00
class Move ( metaclass = PoolMeta ) :
__name__ = ' stock.move '
2022-08-30 19:18:05 +02:00
description = fields . Char ( ' Description ' )
2021-08-26 20:16:55 +02:00
current_stock = fields . Function ( fields . Float ( ' Current Stock ' ,
depends = [ ' product ' ] ) , ' on_change_with_current_stock ' )
2021-12-09 20:10:33 +01:00
reference = fields . Function ( fields . Char ( ' Reference ' ,
depends = [ ' product ' ] , help = ' reference of product ' ) , ' get_reference ' )
2021-08-26 20:16:55 +02:00
2021-09-25 07:02:37 +02:00
@fields.depends ( ' current_stock ' )
2021-08-26 20:16:55 +02:00
def on_change_product ( self , name = None ) :
super ( Move , self ) . on_change_product ( )
self . current_stock = self . on_change_with_current_stock ( )
2021-12-09 20:10:33 +01:00
@fields.depends ( ' product ' )
def get_reference ( self , name = None ) :
reference = None
if self . product and hasattr ( self . product , ' reference ' ) and self . product . reference :
reference = self . product . reference
return reference
2021-08-26 20:16:55 +02:00
@fields.depends ( ' product ' , ' from_location ' , ' to_location ' )
def on_change_with_current_stock ( self , name = None ) :
res = 0
location = None
2022-01-24 15:57:35 +01:00
if self . from_location and self . from_location . type == ' storage ' and self . from_location . parent :
2021-08-26 20:16:55 +02:00
location = self . from_location . parent . storage_location
2022-01-24 15:57:35 +01:00
elif self . to_location and self . to_location . type == ' storage ' and self . to_location . parent :
2021-08-26 20:16:55 +02:00
location = self . to_location . parent . storage_location
if self . product and location :
context = {
' location_ids ' : [ location . id ] ,
' stock_date_end ' : date . today ( ) ,
}
with Transaction ( ) . set_context ( context ) :
res_dict = self . product . _get_quantity (
2021-09-25 07:02:37 +02:00
[ self . product ] ,
' quantity ' ,
[ location . id ] ,
grouping_filter = ( [ self . product . id ] , )
)
2021-08-26 20:16:55 +02:00
if res_dict . get ( self . product . id ) :
res + = res_dict [ self . product . id ]
2022-02-18 16:22:54 +01:00
return res
2021-08-26 20:16:55 +02:00
2022-02-21 18:27:26 +01:00
@fields.depends ( ' product ' )
def on_change_with_description ( self , name = None ) :
res = ' '
2022-10-11 17:50:04 +02:00
if self . product and self . product . description :
2022-02-21 18:27:26 +01:00
description = self . product . description
res = description . rstrip ( ' \n ' )
return res
2022-04-27 00:20:35 +02:00
@classmethod
def do ( cls , moves ) :
super ( Move , cls ) . do ( moves )
for move in moves :
2023-09-14 22:50:19 +02:00
product = move . product
2022-10-10 23:46:59 +02:00
if not move . description :
move . description = cls . on_change_with_description ( move )
move . save ( )
2022-06-08 00:35:08 +02:00
# remove origin 'stock.inventory.line' for set average cost
if move . origin and move . origin . __name__ in ( ' purchase.line ' ) :
2023-09-14 22:50:19 +02:00
if product . cost_price_method == ' fixed ' :
product . cost_price = move . unit_price
product . save ( )
2022-04-27 00:20:35 +02:00
move . set_average_cost ( )
2023-11-29 15:40:52 +01:00
if hasattr ( product , ' standard_margin ' ) and product . standard_margin and product . standard_margin > 0 and move . product . cost_price > 0 :
template = product . template
percentage_calculation = round ( move . product . cost_price * Decimal ( move . product . standard_margin / 100 ) , 4 )
template . list_price = product . cost_price + percentage_calculation
template . on_change_list_price ( )
template . save ( )
2022-04-27 00:20:35 +02:00
def set_average_cost ( self ) :
AverageCost = Pool ( ) . get ( ' product.average_cost ' )
data = {
" stock_move " : self . id ,
" product " : self . product . id ,
" effective_date " : self . effective_date ,
" cost_price " : self . product . cost_price ,
}
AverageCost . create ( [ data ] )
2021-08-26 20:16:55 +02:00
class MoveByProductStart ( ModelView ) :
' Move By Product Start '
__name__ = ' stock_co.move_by_product.start '
start_date = fields . Date ( ' Start Date ' , required = True )
end_date = fields . Date ( ' End Date ' , required = True )
from_location = fields . Many2One ( ' stock.location ' , ' From Location ' )
to_location = fields . Many2One ( ' stock.location ' , ' To Location ' ,
required = True )
categories = fields . Many2Many ( ' product.category ' , None , None , ' Categories ' )
company = fields . Many2One ( ' company.company ' , ' Company ' ,
required = True )
party = fields . Many2One ( ' party.party ' , ' Party ' )
shipment_draft = fields . Boolean ( ' Shipment Draft ' )
start_time = fields . Time ( ' Start Time ' , )
end_time = fields . Time ( ' End Time ' , states = {
' required ' : Bool ( Eval ( ' start_time ' ) ) ,
' invisible ' : Not ( Bool ( Eval ( ' start_time ' ) ) ) ,
} , depends = [ ' start_time ' ] )
product = fields . Many2One ( ' product.product ' , ' Product ' )
2023-06-28 22:20:27 +02:00
brand = fields . Many2One ( ' product.brand ' , ' Brand ' )
2021-08-26 20:16:55 +02:00
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
@staticmethod
def default_end_date ( ) :
Date_ = Pool ( ) . get ( ' ir.date ' )
return Date_ . today ( )
@staticmethod
def default_start_date ( ) :
Date_ = Pool ( ) . get ( ' ir.date ' )
return Date_ . today ( )
class PrintMoveByProduct ( Wizard ) :
' Move By Product '
__name__ = ' stock_co.print_move_by_product '
start = StateView ( ' stock_co.move_by_product.start ' ,
' stock_co.print_move_by_product_start_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Print ' , ' print_ ' , ' tryton-print ' , default = True ) ,
] )
print_ = StateReport ( ' stock_co.move_by_product ' )
def do_print_ ( self , action ) :
category_ids = [ ]
from_location_id = None
brand_id = None
party_id = None
start_time = None
end_time = None
if self . start . from_location :
from_location_id = self . start . from_location . id
if self . start . categories :
category_ids = [ acc . id for acc in self . start . categories ]
2023-06-28 22:20:27 +02:00
if self . start . brand :
2021-08-26 20:16:55 +02:00
brand_id = self . start . brand . id
if self . start . party :
party_id = self . start . party . id
if self . start . start_time :
start_time = self . start . start_time
if self . start . end_time :
end_time = self . start . end_time
data = {
' company ' : self . start . company . id ,
' from_location ' : from_location_id ,
' to_location ' : self . start . to_location . id ,
' start_date ' : self . start . start_date ,
' end_date ' : self . start . end_date ,
' categories ' : category_ids ,
' brand ' : brand_id ,
' party ' : party_id ,
' shipment_draft ' : self . start . shipment_draft ,
' start_time ' : start_time ,
' end_time ' : end_time ,
' product ' : self . start . product . id if self . start . product else None
}
return action , data
def transition_print_ ( self ) :
return ' end '
class MoveByProduct ( Report ) :
' Move By Product Report '
__name__ = ' stock_co.move_by_product '
@classmethod
def get_context ( cls , records , header , data ) :
report_context = super ( ) . get_context ( records , header , data )
pool = Pool ( )
Company = pool . get ( ' company.company ' )
Move = pool . get ( ' stock.move ' )
Location = pool . get ( ' stock.location ' )
Party = pool . get ( ' party.party ' )
Category = pool . get ( ' product.template-product.category ' )
company = Company ( data [ ' company ' ] )
from_location = None
brand_name = ' '
party_name = ' '
start_date = None
end_date = None
categories = Category . search ( [ ( ' category ' , ' in ' , data [ ' categories ' ] ) ] )
products_ids = [ c . template . id for c in categories ]
dom_products = [ ]
if data [ ' start_time ' ] :
start_date = datetime . combine ( data [ ' start_date ' ] , data [ ' start_time ' ] )
end_date = datetime . combine ( data [ ' end_date ' ] , data [ ' end_time ' ] )
_start_date = Company . convert_timezone ( start_date , True )
_end_date = Company . convert_timezone ( end_date , True )
dom_products . append (
( ' to_location.id ' , ' = ' , data [ ' to_location ' ] ) ,
( ' create_date ' , ' >= ' , _start_date ) ,
( ' create_date ' , ' <= ' , _end_date )
)
else :
start_date = data [ ' start_date ' ]
end_date = data [ ' end_date ' ]
dom_products . extend ( [
( ' to_location ' , ' = ' , data [ ' to_location ' ] ) ,
[ ' AND ' ,
[ ' OR ' , [
( ' planned_date ' , ' >= ' , start_date ) ,
( ' planned_date ' , ' <= ' , end_date ) ,
] , [
( ' effective_date ' , ' >= ' , start_date ) ,
( ' effective_date ' , ' <= ' , end_date ) ,
] ,
] ]
] )
if data [ ' shipment_draft ' ] :
dom_products . append ( ( ' state ' , ' = ' , ' draft ' ) )
if data [ ' from_location ' ] :
dom_products . append (
( ' from_location.id ' , ' = ' , data [ ' from_location ' ] ) ,
)
from_location = Location ( data [ ' from_location ' ] )
if data [ ' categories ' ] :
if products_ids :
dom_products . append (
( ' product.template ' , ' in ' , products_ids )
)
else :
dom_products . append (
( ' product.template.account_category ' , ' in ' , data [ ' categories ' ] )
)
if data [ ' brand ' ] :
2022-12-21 22:51:11 +01:00
Brand = pool . get ( ' product.brand ' )
2021-08-26 20:16:55 +02:00
dom_products . append (
( ' product.template.brand ' , ' = ' , data [ ' brand ' ] ) ,
)
brand_name = Brand ( data [ ' brand ' ] ) . name
if data [ ' party ' ] :
dom_products . append (
( ' invoice_lines.invoice.party ' , ' = ' , data [ ' party ' ] ) ,
)
party_name = Party ( data [ ' party ' ] ) . name
if data [ ' product ' ] :
dom_products . append (
( ' product ' , ' = ' , data [ ' product ' ] ) ,
)
moves = Move . search ( [ dom_products ] )
products = { }
2023-07-04 23:25:22 +02:00
Location = pool . get ( ' stock.location ' )
location = Location ( data [ ' to_location ' ] )
2021-08-26 20:16:55 +02:00
for move in moves :
product = move . product
amount = move . quantity * float ( product . cost_price )
2023-07-04 23:25:22 +02:00
origin = None
2023-09-23 19:39:30 +02:00
id_dict = product . id
2023-07-04 23:25:22 +02:00
if location . type == ' customer ' :
2023-09-23 19:39:30 +02:00
id_dict = move . origin . sale . party . name + str ( product . id )
2023-07-04 23:25:22 +02:00
origin = move . origin . sale . party . name if move . origin else None
2021-08-26 20:16:55 +02:00
try :
2023-09-23 19:39:30 +02:00
row = products [ id_dict ]
row [ 4 ] . append ( move . quantity )
row [ 6 ] . append ( amount )
2021-08-26 20:16:55 +02:00
except Exception as e :
template = product . template
brand = template . brand and template . brand . name
category = template . account_category and template . account_category . name
2023-07-04 23:25:22 +02:00
effective_date = move . effective_date
2023-09-23 19:39:30 +02:00
products [ id_dict ] = [
2021-08-26 20:16:55 +02:00
product . code ,
2023-07-04 23:25:22 +02:00
origin ,
2021-08-26 20:16:55 +02:00
product . rec_name ,
template . default_uom . symbol ,
[ move . quantity ] ,
product . cost_price ,
[ amount ] ,
category ,
brand ,
template . list_price ,
2023-07-04 23:25:22 +02:00
effective_date ,
2021-08-26 20:16:55 +02:00
]
2023-09-23 19:39:30 +02:00
2021-08-26 20:16:55 +02:00
report_context [ ' records ' ] = products . values ( )
report_context [ ' from_location ' ] = from_location
2023-07-04 23:25:22 +02:00
report_context [ ' to_location ' ] = location
report_context [ ' customer_location ' ] = location . type == ' customer '
2021-08-26 20:16:55 +02:00
report_context [ ' start_date ' ] = start_date
report_context [ ' end_date ' ] = end_date
report_context [ ' company ' ] = company
report_context [ ' brand_name ' ] = brand_name
report_context [ ' party_name ' ] = party_name
return report_context
class WarehouseStockStart ( ModelView ) :
' Warehouse Stock Start '
__name__ = ' stock_co.warehouse_stock.start '
company = fields . Many2One ( ' company.company ' , ' Company ' , required = True )
locations = fields . Many2Many ( ' stock.location ' , None , None , " Locations " ,
domain = [
( ' type ' , ' in ' , [ ' storage ' , ' customer ' ] ) ,
( ' active ' , ' = ' , True )
] , required = True )
to_date = fields . Date ( ' To Date ' , required = True )
only_minimal_level = fields . Boolean ( ' Only Minimal Level ' )
group_by_location = fields . Boolean ( ' Group By Location ' )
2022-01-12 15:35:56 +01:00
group_by_supplier = fields . Boolean ( ' Group By Supplier ' )
2021-08-26 20:16:55 +02:00
category = fields . Many2One ( ' product.category ' , ' Category ' )
2022-01-12 15:35:56 +01:00
suppliers = fields . Many2Many ( ' party.party ' , None , None , " Suppliers " ,
domain = [
( ' active ' , ' = ' , True )
] )
2021-09-24 05:16:20 +02:00
zero_quantity = fields . Boolean ( ' Zero Quantity ' )
2021-08-26 20:16:55 +02:00
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
@staticmethod
def default_to_date ( ) :
Date_ = Pool ( ) . get ( ' ir.date ' )
return Date_ . today ( )
class WarehouseStock ( Wizard ) :
' Warehouse Stock '
__name__ = ' stock_co.warehouse_stock '
start = StateView ( ' stock_co.warehouse_stock.start ' ,
' stock_co.warehouse_stock_start_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Print ' , ' print_ ' , ' tryton-ok ' , default = True ) ,
] )
print_ = StateReport ( ' stock_co.warehouse_stock.report ' )
def do_print_ ( self , action ) :
category_id = None
if self . start . category :
category_id = self . start . category . id
data = {
' company ' : self . start . company . id ,
' locations ' : [ l . id for l in self . start . locations ] ,
' location_names ' : ' , ' . join ( [ l . name for l in self . start . locations ] ) ,
' only_minimal_level ' : self . start . only_minimal_level ,
' group_by_location ' : self . start . group_by_location ,
2022-01-12 15:35:56 +01:00
' group_by_supplier ' : self . start . group_by_supplier ,
2021-09-24 05:16:20 +02:00
' zero_quantity ' : self . start . zero_quantity ,
2021-08-26 20:16:55 +02:00
' to_date ' : self . start . to_date ,
' category ' : category_id ,
2022-01-12 15:35:56 +01:00
' suppliers ' : [ l . id for l in self . start . suppliers ] ,
2021-08-26 20:16:55 +02:00
}
return action , data
class WarehouseReport ( Report ) :
' Warehouse Report '
__name__ = ' stock_co.warehouse_stock.report '
@classmethod
def get_context ( cls , records , header , data ) :
report_context = super ( ) . get_context ( records , header , data )
pool = Pool ( )
Company = pool . get ( ' company.company ' )
Product = pool . get ( ' product.product ' )
OrderPoint = pool . get ( ' stock.order_point ' )
Location = pool . get ( ' stock.location ' )
ids_location = data [ ' locations ' ]
locations = Location . browse ( data [ ' locations ' ] )
2023-03-27 15:44:21 +02:00
Move = pool . get ( ' stock.move ' )
2021-08-26 20:16:55 +02:00
dom_products = [
( ' active ' , ' = ' , True ) ,
( ' template.active ' , ' = ' , True ) ,
( ' type ' , ' = ' , ' goods ' ) ,
( ' consumable ' , ' = ' , False ) ,
]
stock_context = {
' stock_date_end ' : data [ ' to_date ' ] ,
' locations ' : ids_location ,
}
if data [ ' category ' ] :
dom_products . append ( [ ' AND ' , [ ' OR ' , [
( ' account_category ' , ' = ' , data [ ' category ' ] ) ,
] , [
( ' categories ' , ' in ' , [ data [ ' category ' ] ] ) ,
] ,
] ] )
2021-09-24 05:16:20 +02:00
if not data [ ' zero_quantity ' ] :
2021-08-26 20:16:55 +02:00
dom_products . append ( [ ( ' quantity ' , ' != ' , 0 ) ] )
if data [ ' only_minimal_level ' ] :
2023-06-22 17:02:19 +02:00
locations = Location . search ( [ ( ' id ' , ' in ' , ids_location ) ] )
location_parents = [ location . parent . id for location in locations ]
order_points_wl = OrderPoint . search ( [
( ' warehouse_location ' , ' in ' , set ( location_parents ) ) ,
2021-08-26 20:16:55 +02:00
( ' type ' , ' = ' , ' purchase ' ) ,
] )
2023-06-22 17:02:19 +02:00
min_quantities = { op . product . id : op . min_quantity for op in order_points_wl }
order_points_sl = OrderPoint . search ( [
( ' storage_location ' , ' in ' , ids_location ) ,
( ' type ' , ' = ' , ' internal ' ) ,
] )
min_quantities . update ( { op . product . id : op . min_quantity for op in order_points_sl } )
2021-08-26 20:16:55 +02:00
products_ids = min_quantities . keys ( )
dom_products . append ( ( ' id ' , ' in ' , products_ids ) )
2022-01-12 15:35:56 +01:00
if data [ ' suppliers ' ] :
2022-01-14 00:00:08 +01:00
dom_products . append ( [ ( ' template.product_suppliers.party ' , ' in ' , data [ ' suppliers ' ] ) ] )
2021-08-26 20:16:55 +02:00
total_amount = 0
2023-01-12 16:59:47 +01:00
total_amount_imp = 0
2021-08-26 20:16:55 +02:00
values = { }
products = [ ]
if data [ ' group_by_location ' ] :
for l in locations :
2023-09-12 00:16:57 +02:00
days = [ ]
2021-08-26 20:16:55 +02:00
stock_context [ ' locations ' ] = [ l . id ]
with Transaction ( ) . set_context ( stock_context ) :
prdts = Product . search ( dom_products , order = [ ( ' code ' , ' ASC ' ) ] )
2022-01-12 15:35:56 +01:00
suppliers = { }
2023-03-27 15:44:21 +02:00
for p in prdts :
move = Move . search ( [
( ' to_location ' , ' = ' , l . id ) ,
( ' product ' , ' = ' , p . id ) ,
2023-04-03 15:31:01 +02:00
( ' state ' , ' = ' , ' done ' ) ,
] , order = [ ( ' effective_date ' , ' DESC ' ) ] )
2023-09-12 00:16:57 +02:00
date_start = move [ 0 ] . effective_date if len ( move ) > 0 else None
2023-03-27 15:44:21 +02:00
date_now = date . today ( )
2023-05-29 16:43:10 +02:00
date_result = date_now - date_start if date_start else 0
days . append ( date_result . days ) if date_start else days . append ( ' error ' )
2022-01-12 15:35:56 +01:00
if data [ ' group_by_supplier ' ] :
for p in prdts :
if not p . template . product_suppliers :
continue
2022-01-14 00:00:08 +01:00
for prod_sup in p . template . product_suppliers :
sup_id = prod_sup . party . id
2022-01-13 18:38:19 +01:00
try :
suppliers [ sup_id ] [ ' products ' ] . append ( p )
2022-05-14 17:09:14 +02:00
suppliers [ sup_id ] [ ' total_amount ' ] . append ( p . amount_cost if p . amount_cost else 0 )
2023-01-12 16:59:47 +01:00
suppliers [ sup_id ] [ ' total_amount_imp ' ] . append ( p . extra_tax * Deciaml ( p . quantity ) if p . extra_tax else 0 )
2022-01-13 18:38:19 +01:00
except :
suppliers [ sup_id ] = { }
suppliers [ sup_id ] [ ' products ' ] = [ p ]
2022-01-14 00:00:08 +01:00
suppliers [ sup_id ] [ ' party ' ] = prod_sup . party
2022-05-14 17:09:14 +02:00
suppliers [ sup_id ] [ ' total_amount ' ] = [ p . amount_cost if p . amount_cost else 0 ]
2023-01-12 16:59:47 +01:00
suppliers [ sup_id ] [ ' total_amount_imp ' ] = [ p . extra_tax * Decimal ( p . quantity ) if p . extra_tax else 0 ]
2022-04-27 00:20:35 +02:00
total_amount = sum ( [ p . amount_cost for p in prdts if p . amount_cost ] )
2023-01-12 16:59:47 +01:00
total_amount_imp = sum ( [ p . extra_tax * Decimal ( p . quantity ) for p in prdts if p . extra_tax ] )
2021-08-26 20:16:55 +02:00
values [ l . id ] = {
' name ' : l . name ,
' products ' : prdts ,
2023-03-27 15:44:21 +02:00
' days ' : days ,
2022-01-12 15:35:56 +01:00
' suppliers ' : suppliers . values ( ) ,
2023-01-12 16:59:47 +01:00
' total_amount ' : total_amount ,
' total_amount_imp ' : total_amount_imp
2021-08-26 20:16:55 +02:00
}
products = values . values ( )
else :
with Transaction ( ) . set_context ( stock_context ) :
products = Product . search ( dom_products , order = [ ( ' code ' , ' ASC ' ) ] )
2022-01-12 15:35:56 +01:00
if data [ ' only_minimal_level ' ] :
products = [ p for p in products if p . quantity < = min_quantities [ p . id ] ]
2022-04-27 00:20:35 +02:00
total_amount = sum ( [ p . amount_cost for p in products if p . amount_cost ] )
2023-01-12 16:59:47 +01:00
total_amount_imp = sum ( [ p . extra_tax * Decimal ( p . quantity ) for p in products if p . extra_tax ] )
2022-01-12 15:35:56 +01:00
suppliers = { }
if data [ ' group_by_supplier ' ] :
for p in products :
if not p . template . product_suppliers :
continue
2022-01-14 00:00:08 +01:00
for prod_sup in p . template . product_suppliers :
sup_id = prod_sup . party . id
2022-01-13 18:38:19 +01:00
try :
suppliers [ sup_id ] [ ' products ' ] . append ( p )
2022-05-14 17:05:15 +02:00
suppliers [ sup_id ] [ ' total_amount ' ] . append ( p . amount_cost if p . amount_cost else 0 )
2023-01-12 16:59:47 +01:00
suppliers [ sup_id ] [ ' total_amount_imp ' ] . append ( p . extra_tax * Decimal ( p . quantity ) if p . extra_tax else 0 )
2022-01-13 18:38:19 +01:00
except :
suppliers [ sup_id ] = { }
suppliers [ sup_id ] [ ' products ' ] = [ p ]
2022-01-14 00:00:08 +01:00
suppliers [ sup_id ] [ ' party ' ] = prod_sup . party
2022-05-14 17:05:15 +02:00
suppliers [ sup_id ] [ ' total_amount ' ] = [ p . amount_cost if p . amount_cost else 0 ]
2023-01-12 16:59:47 +01:00
suppliers [ sup_id ] [ ' total_amount_imp ' ] = [ p . extra_tax * Decimal ( p . quantity ) if p . extra_tax else 0 ]
2022-01-12 15:35:56 +01:00
products = suppliers . values ( )
2021-08-26 20:16:55 +02:00
2021-09-13 20:14:58 +02:00
cursor = Transaction ( ) . connection . cursor ( )
2023-03-27 15:44:21 +02:00
# query = "select distinct on(p.id) p.id, t.name, p.code, s.effective_date from product_product as p right join stock_move as s on p.id=s.product join product_template as t on p.template=t.id where (date_part('day', TIMESTAMP '{}') - date_part('day', s.effective_date))>45 and s.shipment ilike 'stock.shipment.in,%' and state='done' order by p.id, s.effective_date DESC;".format(data['to_date'])
2021-09-13 20:14:58 +02:00
query = " select distinct on(p.id) p.id, t.name, p.code, s.effective_date from product_product as p right join stock_move as s on p.id=s.product join product_template as t on p.template=t.id where s.shipment ilike ' stock.shipment.in, % ' and state= ' done ' order by p.id, s.effective_date DESC; "
2023-03-27 15:44:21 +02:00
2021-09-13 20:14:58 +02:00
cursor . execute ( query )
columns = list ( cursor . description )
result = cursor . fetchall ( )
2021-09-24 05:16:20 +02:00
last_purchase = { }
2021-09-13 20:14:58 +02:00
for row in result :
row_dict = { }
for i , col in enumerate ( columns ) :
row_dict [ col . name ] = row [ i ]
2021-09-24 05:16:20 +02:00
last_purchase [ row [ 0 ] ] = row_dict
2021-09-13 20:14:58 +02:00
2021-08-26 20:16:55 +02:00
report_context [ ' group_by_location ' ] = data [ ' group_by_location ' ]
2022-01-12 15:35:56 +01:00
report_context [ ' group_by_supplier ' ] = data [ ' group_by_supplier ' ]
2021-08-26 20:16:55 +02:00
report_context [ ' records ' ] = products
report_context [ ' total_amount ' ] = total_amount
2023-01-12 16:59:47 +01:00
report_context [ ' total_amount_imp ' ] = total_amount_imp
2021-09-24 05:16:20 +02:00
report_context [ ' last_purchase ' ] = last_purchase
2021-08-26 20:16:55 +02:00
report_context [ ' location ' ] = data [ ' location_names ' ]
report_context [ ' stock_date_end ' ] = data [ ' to_date ' ]
report_context [ ' company ' ] = Company ( data [ ' company ' ] )
return report_context
class PrintProductsStart ( ModelView ) :
' Products Start '
__name__ = ' stock_co.print_products.start '
company = fields . Many2One ( ' company.company ' , ' Company ' , required = True )
category = fields . Many2One ( ' product.category ' , ' Category ' )
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
class PrintProducts ( Wizard ) :
' Warehouse Stock '
__name__ = ' stock_co.print_products '
start = StateView ( ' stock_co.print_products.start ' ,
' stock_co.print_products_start_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Print ' , ' print_ ' , ' tryton-ok ' , default = True ) ,
] )
print_ = StateReport ( ' stock_co.print_products.report ' )
def do_print_ ( self , action ) :
category_id = None
if self . start . category :
category_id = self . start . category . id
data = {
' company ' : self . start . company . id ,
' category ' : category_id ,
}
return action , data
class PrintProductsReport ( Report ) :
' Warehouse Report '
__name__ = ' stock_co.print_products.report '
@classmethod
def get_context ( cls , records , header , data ) :
report_context = super ( ) . get_context ( records , header , data )
pool = Pool ( )
Company = pool . get ( ' company.company ' )
Product = pool . get ( ' product.product ' )
Date_ = Pool ( ) . get ( ' ir.date ' )
dom_products = [
( ' active ' , ' = ' , True ) ,
( ' type ' , ' = ' , ' goods ' ) ,
( ' consumable ' , ' = ' , False ) ,
]
if data [ ' category ' ] :
dom_products . append ( ( ' account_category ' , ' = ' , data [ ' category ' ] ) )
products = Product . search ( dom_products , order = [ ( ' code ' , ' ASC ' ) ] )
report_context [ ' records ' ] = products
report_context [ ' stock_date_end ' ] = Date_ . today ( )
report_context [ ' company ' ] = Company ( data [ ' company ' ] )
return report_context
2021-08-28 18:27:55 +02:00
class WarehouseStockDetailedStart ( ModelView ) :
' Warehouse Stock Detailed Start '
__name__ = ' stock_co.warehouse_stock_detailed.start '
company = fields . Many2One ( ' company.company ' , ' Company ' , required = True )
locations = fields . Many2Many ( ' stock.location ' , None , None , " Locations " ,
domain = [
( ' id ' , ' in ' , Eval ( ' location_storage ' ) ) ,
( ' active ' , ' = ' , True )
] , depends = [ ' location_storage ' ] )
location_storage = fields . One2Many ( ' stock.location ' , None , ' Locations Storage ' )
to_date = fields . Date ( ' To Date ' , required = True )
2022-04-18 20:15:11 +02:00
lot = fields . Boolean ( ' Grouping Lot ' )
2021-08-28 18:27:55 +02:00
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
@staticmethod
def default_to_date ( ) :
Date_ = Pool ( ) . get ( ' ir.date ' )
return Date_ . today ( )
@staticmethod
def default_location_storage ( ) :
Location = Pool ( ) . get ( ' stock.location ' )
locations = Location . search ( [ ( ' type ' , ' = ' , ' warehouse ' ) ] )
2021-12-29 21:48:04 +01:00
return [ l . storage_location . id for l in locations if l . storage_location . id ]
2021-08-28 18:27:55 +02:00
class WarehouseStockDetailed ( Wizard ) :
' Warehouse Stock Detailed '
__name__ = ' stock_co.warehouse_stock_detailed '
start = StateView ( ' stock_co.warehouse_stock_detailed.start ' ,
' stock_co.warehouse_stock_detailed_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Print ' , ' print_ ' , ' tryton-ok ' , default = True ) ,
] )
print_ = StateReport ( ' stock_co.warehouse_stock_detailed.report ' )
def do_print_ ( self , action ) :
location_ids = None
if self . start . locations :
location_ids = [ l . id for l in self . start . locations ]
data = {
' company ' : self . start . company . id ,
' locations ' : location_ids ,
' to_date ' : self . start . to_date ,
2022-04-18 20:15:11 +02:00
' lot ' : self . start . lot ,
2021-08-28 18:27:55 +02:00
}
return action , data
class WarehouseStockDetailedReport ( Report ) :
' Warehouse Stock Detailed Report '
__name__ = ' stock_co.warehouse_stock_detailed.report '
@classmethod
def get_context ( cls , records , header , data ) :
report_context = super ( ) . get_context ( records , header , data )
pool = Pool ( )
Company = pool . get ( ' company.company ' )
Product = pool . get ( ' product.product ' )
Location = pool . get ( ' stock.location ' )
2022-04-18 20:15:11 +02:00
LotbyLocation = pool . get ( ' stock.lots_by_locations ' )
2021-08-28 18:27:55 +02:00
if data [ ' locations ' ] :
ids_location = data [ ' locations ' ]
locations = Location . browse ( ids_location )
else :
locations = Location . search ( [
( ' type ' , ' = ' , ' warehouse ' )
] )
ids_location = [ l . storage_location . id for l in locations if l . storage_location ]
dom_products = [
( ' active ' , ' = ' , True ) ,
( ' template.active ' , ' = ' , True ) ,
( ' type ' , ' = ' , ' goods ' ) ,
( ' consumable ' , ' = ' , False ) ,
]
stock_context = {
' stock_date_end ' : data [ ' to_date ' ] ,
' locations ' : ids_location ,
}
# dom_products.append(('account_category', '=', data['category']))
2021-08-30 22:39:59 +02:00
cursor = Transaction ( ) . connection . cursor ( )
2021-09-23 15:15:13 +02:00
query = " select distinct on(p.id) p.id, t.name, p.code, t.reference, s.effective_date from product_product as p right join stock_move as s on p.id=s.product join product_template as t on p.template=t.id where s.shipment ilike ' stock.shipment.in, % ' and state= ' done ' order by p.id, s.effective_date DESC "
2021-08-30 22:39:59 +02:00
cursor . execute ( query )
columns = list ( cursor . description )
result = cursor . fetchall ( )
2021-09-24 05:16:20 +02:00
last_purchase = { }
2021-08-30 22:39:59 +02:00
for row in result :
row_dict = { }
for i , col in enumerate ( columns ) :
row_dict [ col . name ] = row [ i ]
2021-09-24 05:16:20 +02:00
last_purchase [ row [ 0 ] ] = row_dict
2021-08-30 22:39:59 +02:00
2021-08-28 18:27:55 +02:00
values = [ ]
2021-09-23 15:15:13 +02:00
add_ = values . append
2021-08-28 18:27:55 +02:00
for l in locations :
stock_context [ ' locations ' ] = [ l . id ]
with Transaction ( ) . set_context ( stock_context ) :
prdts = Product . search ( dom_products , order = [ ( ' code ' , ' ASC ' ) ] )
2022-04-18 20:15:11 +02:00
if data [ ' lot ' ] :
prd_ids = [ p . id for p in prdts ]
prdts = LotbyLocation . search ( [ ( ' product ' , ' in ' , prd_ids ) ] )
2021-08-28 18:27:55 +02:00
for p in prdts :
2021-09-23 15:15:13 +02:00
add_ ( {
2021-08-28 18:27:55 +02:00
' parent_name ' : l . parent . name if l . parent else ' ' ,
' name ' : l . name ,
2022-04-18 20:15:11 +02:00
' product ' : p . product if data [ ' lot ' ] else p ,
' lot ' : p if data [ ' lot ' ] else None ,
2021-08-28 18:27:55 +02:00
} )
2021-08-30 22:39:59 +02:00
2021-08-28 18:27:55 +02:00
products = values
report_context [ ' records ' ] = products
report_context [ ' Decimal ' ] = Decimal
2021-09-24 05:16:20 +02:00
report_context [ ' last_purchase ' ] = last_purchase
2021-08-28 18:27:55 +02:00
report_context [ ' stock_date_end ' ] = data [ ' to_date ' ]
report_context [ ' company ' ] = Company ( data [ ' company ' ] )
return report_context
2021-12-29 17:41:02 +01:00
class WarehouseKardexStockStart ( ModelView ) :
' Warehouse Kardex Stock Start '
__name__ = ' stock_co.warehouse_kardex_stock.start '
company = fields . Many2One ( ' company.company ' , ' Company ' , required = True )
2022-02-07 23:48:18 +01:00
locations = fields . Many2Many ( ' stock.location ' , None , None , " Location " ,
2021-12-29 17:41:02 +01:00
domain = [
( ' type ' , ' in ' , [ ' warehouse ' ] ) ,
( ' active ' , ' = ' , True )
] , required = True )
from_date = fields . Date ( ' From Date ' , required = True )
to_date = fields . Date ( ' To Date ' , required = True )
2023-10-24 21:58:28 +02:00
detail_by_product = fields . Boolean ( ' Detail By Product ' )
2021-12-29 17:41:02 +01:00
categories = fields . Many2Many ( ' product.category ' , None , None , ' Categories ' )
2023-10-24 21:58:28 +02:00
products = fields . Many2Many ( ' product.product ' , None , None , ' Products ' ,
domain = [
( ' active ' , ' = ' , True ) ,
( ' template.active ' , ' = ' , True ) ,
( ' type ' , ' = ' , ' goods ' ) ,
( ' consumable ' , ' = ' , False ) ,
( ' quantity ' , ' != ' , 0 ) ,
] ,
states = { ' required ' : Eval ( ' detail_by_product ' , True ) } ,
depends = [ ' detail_by_product ' ] )
2021-12-29 17:41:02 +01:00
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
@staticmethod
def default_to_date ( ) :
Date_ = Pool ( ) . get ( ' ir.date ' )
return Date_ . today ( )
class WarehouseKardexStock ( Wizard ) :
' Warehouse Kardex Stock '
__name__ = ' stock_co.warehouse_kardex_stock '
start = StateView ( ' stock_co.warehouse_kardex_stock.start ' ,
' stock_co.warehouse_kardex_stock_start_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Print ' , ' print_ ' , ' tryton-ok ' , default = True ) ,
] )
print_ = StateReport ( ' stock_co.warehouse_kardex_stock.report ' )
def do_print_ ( self , action ) :
data = {
' company ' : self . start . company . id ,
2022-02-07 23:48:18 +01:00
# 'location': self.start.location.id,
2021-12-29 17:41:02 +01:00
' from_date ' : self . start . from_date ,
' to_date ' : self . start . to_date ,
2023-10-24 21:58:28 +02:00
' detail_by_product ' : self . start . detail_by_product ,
2021-12-29 17:41:02 +01:00
' categories ' : [ l . id for l in self . start . categories ] ,
2022-02-07 23:48:18 +01:00
' locations ' : [ l . id for l in self . start . locations ] ,
2023-10-24 21:58:28 +02:00
' products ' : [ l . id for l in self . start . products ] ,
2021-12-29 17:41:02 +01:00
}
return action , data
class WarehouseKardexReport ( Report ) :
' Warehouse Kardex Report '
__name__ = ' stock_co.warehouse_kardex_stock.report '
@classmethod
def get_context ( cls , records , header , data ) :
report_context = super ( ) . get_context ( records , header , data )
pool = Pool ( )
Company = pool . get ( ' company.company ' )
Product = pool . get ( ' product.product ' )
Location = pool . get ( ' stock.location ' )
2022-02-07 23:48:18 +01:00
warehouses = Location . browse ( data [ ' locations ' ] )
id_locations = [ w . storage_location . id for w in warehouses if w . storage_location ]
2021-12-29 17:41:02 +01:00
dom_products = [
( ' active ' , ' = ' , True ) ,
( ' template.active ' , ' = ' , True ) ,
( ' type ' , ' = ' , ' goods ' ) ,
( ' consumable ' , ' = ' , False ) ,
2022-04-08 21:25:14 +02:00
( ' quantity ' , ' != ' , 0 ) ,
2021-12-29 17:41:02 +01:00
]
if data [ ' categories ' ] :
dom_products . append ( [ ' AND ' , [ ' OR ' , [
( ' account_category ' , ' in ' , data [ ' categories ' ] ) ,
] , [
( ' categories ' , ' in ' , data [ ' categories ' ] ) ,
] ,
] ] )
stock_context_start = {
' stock_date_end ' : ( data [ ' from_date ' ] - timedelta ( 1 ) ) ,
2022-02-07 23:48:18 +01:00
' locations ' : id_locations ,
2021-12-29 17:41:02 +01:00
}
stock_context_end = {
' stock_date_end ' : data [ ' to_date ' ] ,
2022-02-07 23:48:18 +01:00
' locations ' : id_locations ,
2021-12-29 17:41:02 +01:00
}
2022-01-18 22:23:18 +01:00
products = { }
2023-10-28 17:36:36 +02:00
products_detail = [ ]
2023-10-24 21:58:28 +02:00
fields_names = [ ' code ' , ' name ' , ' brand ' , ' reference ' , ' quantity ' ]
2022-01-18 22:23:18 +01:00
# products = {p['id']: p for p in products_start}
# type = {'input': f'and from_location != {output_location} and to_location = {id_location}',
# 'input_dif': f'and from_location = {id_location} and to_location = {input_location}',
# 'output': f'and from_location = {id_location} and to_location != {output_location}',
# 'output_dif': f'and from_location = {output_location} and to_location = {id_location}'
# }
2022-02-07 23:48:18 +01:00
tup_locations = str ( tuple ( id_locations ) ) . replace ( ' , ' , ' ' ) if len (
id_locations ) == 1 else str ( tuple ( id_locations ) )
2022-01-18 22:23:18 +01:00
type = {
2022-02-07 23:48:18 +01:00
' input ' : f ' and to_location in { tup_locations } ' ,
' output ' : f ' and from_location in { tup_locations } ' ,
2022-01-18 22:23:18 +01:00
}
2021-12-29 17:41:02 +01:00
moves = { }
2023-10-24 21:58:28 +02:00
if not data [ ' detail_by_product ' ] :
with Transaction ( ) . set_context ( stock_context_start ) :
products_start = Product . search_read ( dom_products , fields_names = fields_names , order = [ ( ' code ' , ' ASC ' ) ] )
with Transaction ( ) . set_context ( stock_context_end ) :
products_end = Product . search_read ( dom_products , fields_names = fields_names , order = [ ( ' code ' , ' ASC ' ) ] )
for p in products_start :
cls . set_value ( p , ' start ' , products )
for p in products_end :
cls . set_value ( p , ' end ' , products )
for k , v in type . items ( ) :
clause = v
2023-10-26 18:17:27 +02:00
query = f """ select s.product as id, p.code, t.name, t.reference, sum(s.quantity) as quantity from stock_move as s
join product_product as p on p . id = s . product
join product_template as t on p . template = t . id
where effective_date > = ' { str(data[ ' from_date ' ])} '
and effective_date < = ' { str(data[ ' to_date ' ])} '
{ clause }
group by s . product , p . code , t . name , t . reference ; """
moves = cls . query_to_dict ( query )
for m , v in moves . items ( ) :
cls . set_value ( v , k , products )
2022-01-18 22:23:18 +01:00
2023-10-24 21:58:28 +02:00
else :
2023-10-28 17:36:36 +02:00
for product in data [ ' products ' ] :
query = f """ select p.id as pid, p.code, t.name, pb.name as brand, t.reference, s.effective_date,
SPLIT_PART ( s . origin , ' , ' , 1 ) as model ,
SPLIT_PART ( s . origin , ' , ' , 2 ) as line_id ,
s . id as move_id , s . quantity as quantity
2023-10-26 18:17:27 +02:00
from stock_move as s
2023-10-28 17:36:36 +02:00
INNER JOIN product_product as p on p . id = s . product
INNER JOIN product_template as t on p . template = t . id
INNER JOIN product_brand as pb on pb . id = t . brand
2023-10-31 22:08:40 +01:00
where s . effective_date > = ' { str(data[ ' from_date ' ])} '
and s . effective_date < = ' { str(data[ ' to_date ' ])} '
2023-10-28 17:36:36 +02:00
AND p . id IN ( { product } )
ORDER BY s . effective_date ASC , p . id ASC
"""
2023-10-31 22:08:40 +01:00
# and (s.origin LIKE '%purchase.line%' or s.origin LIKE '%sale.line%')
2023-11-21 23:13:00 +01:00
start , end = cls . get_balances ( Product , product , data [ ' from_date ' ] - timedelta ( days = 1 ) , id_locations )
2023-10-28 17:36:36 +02:00
products_detail . append ( cls . query_to_dict_detail ( query , end ) )
2022-02-07 23:48:18 +01:00
wh_name = ' '
for l in warehouses :
2023-10-24 21:58:28 +02:00
wh_name + = ( l . name + ' , ' )
2022-01-18 22:23:18 +01:00
report_context [ ' products ' ] = products . values ( )
2023-10-28 17:36:36 +02:00
report_context [ ' products_detail ' ] = products_detail
2023-10-24 21:58:28 +02:00
report_context [ ' detail_by_product ' ] = data [ ' detail_by_product ' ]
2022-02-07 23:48:18 +01:00
report_context [ ' warehouse ' ] = wh_name
2021-12-29 17:41:02 +01:00
report_context [ ' company ' ] = Company ( data [ ' company ' ] )
return report_context
2022-01-18 22:23:18 +01:00
@classmethod
def set_value ( cls , p , key , products ) :
defaults = {
' start ' : 0 ,
' input ' : 0 ,
' output ' : 0 ,
' end ' : 0
}
try :
products [ p [ ' id ' ] ] . update ( {
key : p [ ' quantity ' ]
} )
except :
products [ p [ ' id ' ] ] = copy . deepcopy ( defaults )
products [ p [ ' id ' ] ] . update ( {
' code ' : p [ ' code ' ] ,
' name ' : p [ ' name ' ] ,
' reference ' : p [ ' reference ' ] ,
key : p [ ' quantity ' ]
} )
2023-10-24 21:58:28 +02:00
@classmethod
2023-10-28 17:36:36 +02:00
def set_value_detail ( cls , p , key , Product , id_locations ) :
2023-10-26 22:59:40 +02:00
start , end = cls . get_balances ( Product , p [ ' pid ' ] , p [ ' effective_date ' ] , id_locations )
2023-10-24 21:58:28 +02:00
@classmethod
def get_balances ( cls , Product , id , effective_data , locations ) :
dom_products = [ ( ' id ' , ' = ' , id ) ]
fields_names = [ ' code ' , ' name ' , ' brand ' , ' reference ' , ' quantity ' ]
products = { }
stock_context = {
' stock_date_end ' : effective_data - timedelta ( 1 ) ,
' locations ' : locations ,
}
stock_context_end = {
' stock_date_end ' : effective_data ,
' locations ' : locations ,
}
with Transaction ( ) . set_context ( stock_context ) :
2023-10-26 18:17:27 +02:00
products_start = Product . search_read ( dom_products , fields_names = fields_names )
2023-10-24 21:58:28 +02:00
with Transaction ( ) . set_context ( stock_context_end ) :
2023-10-26 18:17:27 +02:00
products_end = Product . search_read ( dom_products , fields_names = fields_names )
2023-10-24 21:58:28 +02:00
for p in products_start :
cls . set_value ( p , ' start ' , products )
for p in products_end :
cls . set_value ( p , ' end ' , products )
return products [ id ] [ ' start ' ] , products [ id ] [ ' end ' ]
2021-12-29 17:41:02 +01:00
@classmethod
def query_to_dict ( cls , query ) :
cursor = Transaction ( ) . connection . cursor ( )
cursor . execute ( query )
columns = list ( cursor . description )
result = cursor . fetchall ( )
res_dict = { }
for row in result :
row_dict = { }
for i , col in enumerate ( columns ) :
row_dict [ col . name ] = row [ i ]
res_dict [ row [ 0 ] ] = row_dict
return res_dict
2023-10-28 17:36:36 +02:00
@classmethod
def query_to_dict_detail ( cls , query , end ) :
pool = Pool ( )
SaleLine = pool . get ( ' sale.line ' )
PurchaseLine = pool . get ( ' purchase.line ' )
2023-10-31 22:08:40 +01:00
StockMove = pool . get ( ' stock.move ' )
2023-10-28 17:36:36 +02:00
cursor = Transaction ( ) . connection . cursor ( )
cursor . execute ( query )
result = cursor . fetchall ( )
sale_line_ids = [ ]
purchase_line_ids = [ ]
2023-10-31 22:08:40 +01:00
stock_inventory_id = [ ]
2023-10-28 17:36:36 +02:00
for row in result :
if row [ 6 ] == ' sale.line ' :
sale_line_ids . append ( row [ 7 ] )
2023-10-31 22:08:40 +01:00
elif row [ 6 ] == ' purchase.line ' :
2023-10-28 17:36:36 +02:00
purchase_line_ids . append ( row [ 7 ] )
2023-10-31 22:08:40 +01:00
elif row [ 6 ] == ' stock.inventory ' :
stock_inventory_id . append ( row [ 7 ] )
sale_lines = SaleLine . search_read ( [ ( ' id ' , ' in ' , sale_line_ids ) ] , fields_names = [ ' sale.party.name ' , ' sale.number ' , ' unit_price ' , ' quantity ' ] )
sale_lines_dict = { sl [ ' id ' ] : ( sl [ ' sale. ' ] [ ' party. ' ] [ ' name ' ] , sl [ ' sale. ' ] [ ' number ' ] , sl [ ' unit_price ' ] , sl [ ' quantity ' ] ) for sl in sale_lines }
purchase_lines = PurchaseLine . search_read ( [ ( ' id ' , ' in ' , purchase_line_ids ) ] , fields_names = [ ' purchase.party.name ' , ' purchase.number ' , ' unit_price ' , ' quantity ' ] )
purchase_lines_dict = { pl [ ' id ' ] : ( pl [ ' purchase. ' ] [ ' party. ' ] [ ' name ' ] , pl [ ' purchase. ' ] [ ' number ' ] , pl [ ' unit_price ' ] , pl [ ' quantity ' ] ) for pl in purchase_lines }
2023-10-28 17:36:36 +02:00
res = [ ]
balance = end
cost_price = 0
for row in result :
qty_input = 0
qty_output = 0
list_price = 0
party = ' '
number = ' '
2023-10-31 22:08:40 +01:00
add_item = False
2023-11-21 23:13:00 +01:00
print ( row [ 8 ] , row [ 0 ] , ' origens ' )
2023-10-28 17:36:36 +02:00
if row [ 6 ] == ' sale.line ' :
2023-11-21 23:13:00 +01:00
print ( ' paso por if ' )
2023-10-31 22:08:40 +01:00
party , number , list_price , qty_output = sale_lines_dict [ int ( row [ 7 ] ) ]
2023-10-28 17:36:36 +02:00
balance - = qty_output
2023-10-31 22:08:40 +01:00
add_item = True
elif row [ 6 ] == ' purchase.line ' :
# qty_input = row[9]
party , number , cost_price , qty_input = purchase_lines_dict [ int ( row [ 7 ] ) ]
2023-10-28 17:36:36 +02:00
balance + = qty_input
2023-10-31 22:08:40 +01:00
add_item = True
else :
move = StockMove ( row [ 8 ] )
2023-11-21 23:13:00 +01:00
print ( ' paso por else ' )
2023-11-21 14:46:02 +01:00
if move and ( move . from_location . type == ' lost_found ' or move . from_location . type == ' customer ' or move . from_location . type == ' supplier ' ) :
2023-10-31 22:08:40 +01:00
qty_input = row [ 9 ]
balance + = qty_input
add_item = True
if add_item :
value = {
' product ' : row [ 2 ] ,
' code ' : row [ 1 ] ,
' brand ' : row [ 3 ] ,
' reference ' : row [ 4 ] ,
' effective_date ' : row [ 5 ] ,
' party ' : party ,
' number ' : number ,
' end_balance ' : balance ,
' input ' : qty_input ,
' output ' : qty_output ,
' list_price ' : list_price ,
' cost_price ' : cost_price ,
}
res . append ( value )
2023-10-28 17:36:36 +02:00
return res
2023-12-04 01:28:55 +01:00
class CreateOrderPointStart ( ModelView ) :
' Create Order Point Start '
__name__ = ' stock_co.create_order_point.start '
category = fields . Many2One ( ' product.category ' , ' Category ' , required = True ,
domain = [ ( ' accounting ' , ' = ' , False ) ] )
warehouse_location = fields . Many2One ( ' stock.location ' ,
' Warehouse Location ' , select = True ,
domain = [ ( ' type ' , ' = ' , ' warehouse ' ) ] ,
states = {
' invisible ' : Not ( Equal ( Eval ( ' type ' ) , ' purchase ' ) ) ,
' required ' : Equal ( Eval ( ' type ' ) , ' purchase ' ) ,
} ,
depends = [ ' type ' ] )
storage_location = fields . Many2One ( ' stock.location ' , ' Storage Location ' ,
select = True ,
domain = [ ( ' type ' , ' = ' , ' storage ' ) ] ,
states = {
' invisible ' : Not ( Equal ( Eval ( ' type ' ) , ' internal ' ) ) ,
' required ' : Equal ( Eval ( ' type ' ) , ' internal ' ) ,
} ,
depends = [ ' type ' ] )
location = fields . Function ( fields . Many2One ( ' stock.location ' , ' Location ' ) ,
' get_location ' , searcher = ' search_location ' )
provisioning_location = fields . Many2One (
' stock.location ' , ' Provisioning Location ' ,
domain = [ ( ' type ' , ' in ' , [ ' storage ' , ' view ' ] ) ] ,
states = {
' invisible ' : Not ( Equal ( Eval ( ' type ' ) , ' internal ' ) ) ,
' required ' : ( ( Eval ( ' type ' ) == ' internal ' )
& ( Eval ( ' min_quantity ' , None ) != None ) ) , # noqa: E711
} ,
depends = [ ' type ' , ' min_quantity ' ] )
overflowing_location = fields . Many2One (
' stock.location ' , ' Overflowing Location ' ,
domain = [ ( ' type ' , ' in ' , [ ' storage ' , ' view ' ] ) ] ,
states = {
' invisible ' : Eval ( ' type ' ) != ' internal ' ,
' required ' : ( ( Eval ( ' type ' ) == ' internal ' )
& ( Eval ( ' max_quantity ' , None ) != None ) ) , # noqa: E711
} ,
depends = [ ' type ' , ' max_quantity ' ] )
type = fields . Selection (
[ ( ' internal ' , ' Internal ' ) ,
( ' purchase ' , ' Purchase ' ) ] ,
' Type ' , select = True , required = True )
min_quantity = fields . Float ( ' Minimal Quantity ' ,
digits = ( 16 , Eval ( ' unit_digits ' , 2 ) ) ,
states = {
# required for purchase and production types
' required ' : Eval ( ' type ' ) != ' internal ' ,
} ,
domain = [ ' OR ' ,
( ' min_quantity ' , ' = ' , None ) ,
( ' min_quantity ' , ' <= ' , Eval ( ' target_quantity ' , 0 ) ) ,
] ,
depends = [ ' unit_digits ' , ' target_quantity ' , ' type ' ] )
target_quantity = fields . Float ( ' Target Quantity ' , required = True ,
digits = ( 16 , Eval ( ' unit_digits ' , 2 ) ) ,
domain = [
[ ' OR ' ,
( ' min_quantity ' , ' = ' , None ) ,
( ' target_quantity ' , ' >= ' , Eval ( ' min_quantity ' , 0 ) ) ,
] ,
[ ' OR ' ,
( ' max_quantity ' , ' = ' , None ) ,
( ' target_quantity ' , ' <= ' , Eval ( ' max_quantity ' , 0 ) ) ,
] ,
] ,
depends = [ ' unit_digits ' , ' min_quantity ' , ' max_quantity ' ] )
max_quantity = fields . Float ( ' Maximal Quantity ' ,
digits = ( 16 , Eval ( ' unit_digits ' , 2 ) ) ,
states = {
' invisible ' : Eval ( ' type ' ) != ' internal ' ,
} ,
domain = [ ' OR ' ,
( ' max_quantity ' , ' = ' , None ) ,
( ' max_quantity ' , ' >= ' , Eval ( ' target_quantity ' , 0 ) ) ,
] ,
depends = [ ' unit_digits ' , ' type ' , ' target_quantity ' ] )
company = fields . Many2One ( ' company.company ' , ' Company ' , required = True ,
domain = [
( ' id ' , If ( In ( ' company ' , Eval ( ' context ' , { } ) ) , ' = ' , ' != ' ) ,
Eval ( ' context ' , { } ) . get ( ' company ' , - 1 ) ) ,
] )
unit = fields . Function ( fields . Many2One ( ' product.uom ' , ' Unit ' ) , ' get_unit ' )
unit_digits = fields . Function ( fields . Integer ( ' Unit Digits ' ) ,
' get_unit_digits ' )
@staticmethod
def default_company ( ) :
return Transaction ( ) . context . get ( ' company ' )
@staticmethod
def default_type ( ) :
return " purchase "
class CreateOrderPoint ( Wizard ) :
' Create Order Point '
__name__ = ' stock_co.create_order_point '
start = StateView ( ' stock_co.create_order_point.start ' ,
' stock_co.create_order_point_start_view_form ' , [
Button ( ' Cancel ' , ' end ' , ' tryton-cancel ' ) ,
Button ( ' Ok ' , ' accept ' , ' tryton-ok ' , default = True ) ,
] )
accept = StateTransition ( )
def transition_accept ( self ) :
pool = Pool ( )
OrderPoint = pool . get ( ' stock.order_point ' )
Product = pool . get ( ' product.product ' )
order_points = [ ]
type = self . start . type
company = self . start . company
warehouse_location = self . start . warehouse_location
min_quantity = self . start . min_quantity
target_quantity = self . start . target_quantity
products = Product . search ( [ ( ' categories ' , ' in ' , [ self . start . category ] ) ] )
print ( products )
for product in products :
order_points . append ( {
' type ' : type ,
' company ' : company ,
' warehouse_location ' : warehouse_location . id ,
' product ' : product . id ,
' min_quantity ' : min_quantity ,
' target_quantity ' : target_quantity ,
} )
OrderPoint . create ( order_points )
return ' end '