Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
139
Merge Requests
139
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
9ee93048
Commit
9ee93048
authored
Jul 01, 2020
by
Xiaowu Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_trade: customise sale order report
parent
7cb707a2
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
245 additions
and
49 deletions
+245
-49
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderReportSectionList.py
...skins/erp5_trade/OrderModule_getOrderReportSectionList.py
+100
-2
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
...m/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
+145
-47
No files found.
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderReportSectionList.py
View file @
9ee93048
from
Products.ERP5Form.Report
import
ReportSection
from
Products.ERP5Type.DateUtils
import
getIntervalListBetweenDates
from
DateTime
import
DateTime
params
,
stat_columns
,
selection_columns
=
context
.
OrderModule_getOrderReportParameterDict
()
context
.
REQUEST
.
set
(
'stat_columns'
,
stat_columns
)
result
=
[]
request
=
container
.
REQUEST
# list only if user has a login defined
aggregation_level
=
request
.
get
(
'aggregation_level'
)
from_date
=
request
.
get
(
'from_date'
)
to_date
=
request
.
get
(
'at_date'
)
group_by
=
request
.
get
(
'group_by'
)
quantity_unit
=
request
.
get
(
'quantity_unit'
)
simulation_state
=
request
.
get
(
'simulation_state'
,
())
# define some parameter dependings on module
if
"Sale"
in
context
.
getPortalType
():
report_type
=
"sale"
line_portal_type
=
"Sale Order Line"
doc_portal_type
=
"Sale Order"
elif
"Purchase"
in
context
.
getPortalType
():
report_type
=
"purchase"
line_portal_type
=
"Purchase Order Line"
doc_portal_type
=
"Purchase Order"
elif
request
.
get
(
'order_report_document_portal_type'
):
doc_portal_type
=
request
.
get
(
'order_report_document_portal_type'
)
if
doc_portal_type
==
'Purchase Invoice Transaction'
:
line_portal_type
=
'Invoice Line'
report_type
=
'purchase'
elif
doc_portal_type
==
'Sale Invoice Transaction'
:
line_portal_type
=
'Invoice Line'
report_type
=
'sale'
else
:
raise
ValueError
,
"unknown document portal type for report %s"
%
doc_portal_type
else
:
raise
ValueError
,
"unknown type for report"
selection_columns
=
[(
'group_by'
,
"Group by"
)]
if
from_date
is
None
:
# get the minimum start date in catalog
from
Products.ZSQLCatalog.SQLCatalog
import
Query
,
NegatedQuery
kw
=
{
"delivery.start_date"
:
None
,
"key"
:
"DefaultKey"
}
q
=
NegatedQuery
(
Query
(
**
kw
))
select_expression
=
"MIN(delivery.start_date)"
group_by
=
"delivery.start_date"
from_date
=
DateTime
()
result_list
=
context
.
portal_catalog
(
select_expression
=
select_expression
,
group_by_expression
=
group_by
,
simulation_state
=
simulation_state
,
portal_type
=
doc_portal_type
,
query
=
q
,
limit
=
1
)
if
result_list
:
from_date
=
DateTime
(
result_list
[
0
][
2
])
# get period list between given date
interval_list_dict
=
getIntervalListBetweenDates
(
from_date
=
from_date
,
to_date
=
to_date
,
keys
=
{
'year'
:
aggregation_level
==
"year"
,
'month'
:
aggregation_level
==
"month"
,
'week'
:
aggregation_level
==
"week"
,
'day'
:
aggregation_level
==
"day"
})
interval_list
=
interval_list_dict
[
aggregation_level
]
# FIXME: translate column names
# list columns of the listbox
interval_column_list
=
[]
if
group_by
==
"client"
:
interval_column_list
.
extend
([(
"Amount %s"
%
x
,
"Amount %s"
%
x
)
for
x
in
interval_list
])
selection_columns
=
[(
'client'
,
"Client"
)]
stat_columns
=
[(
'client'
,
"client"
)]
total_column_list
=
[(
'total amount'
,
'Total Amount'
),]
total_stat_list
=
[(
'total amount'
,
'total amount'
),]
else
:
if
group_by
==
"product"
:
selection_columns
=
[(
'product_reference'
,
"Product Reference"
,
),
(
'product'
,
"Product"
)]
stat_columns
=
[(
'product'
,
"product"
)]
elif
group_by
==
"function"
:
function_title
=
context
.
AccountingTransactionLine_getFunctionBaseCategoryTitle
()
selection_columns
=
[(
'product'
,
function_title
)]
stat_columns
=
[(
'product'
,
"product"
)]
else
:
selection_columns
=
[(
'client'
,
"Client"
),
(
'product_reference'
,
"Product Reference"
,
),
(
'product'
,
"Product"
)]
stat_columns
=
[(
'client'
,
"client"
),
(
'product'
,
"product"
)]
for
x
in
interval_list
:
interval_column_list
.
extend
([(
"Amount %s"
%
x
,
"Amount %s"
%
x
),
(
"Quantity %s"
%
x
,
"Quantity %s"
%
x
)])
if
not
quantity_unit
:
interval_column_list
.
extend
([(
"Quantity Unit %s"
%
x
,
"Quantity Unit %s"
%
x
)])
total_column_list
=
[(
'total amount'
,
'Total Amount'
),(
'total quantity'
,
'Total Quantity'
)]
total_stat_list
=
[(
'total amount'
,
'total amount'
),(
'total quantity'
,
'total quantity'
)]
selection_columns
.
extend
(
interval_column_list
)
selection_columns
.
extend
(
total_column_list
)
params
=
dict
(
period_list
=
interval_list
,
report_type
=
report_type
,
doc_portal_type
=
doc_portal_type
,
line_portal_type
=
line_portal_type
,
simulation_state
=
simulation_state
)
# stat columns of the listbox
stat_columns
=
stat_columns
+
interval_column_list
+
total_stat_list
context
.
REQUEST
.
set
(
'stat_columns'
,
stat_columns
)
result
.
append
(
ReportSection
(
path
=
context
.
getPhysicalPath
(),
selection_columns
=
selection_columns
,
listbox_display_mode
=
'FlatListMode'
,
selection_params
=
params
,
form_id
=
'OrderModule_viewOrderStatList'
))
return
result
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/OrderModule_getOrderStatList.py
View file @
9ee93048
from
Products.PythonScripts.standard
import
Object
from
json
import
loads
from
Products.ZSQLCatalog.SQLCatalog
import
Query
portal
=
context
.
getPortalObject
()
category_tool
=
portal
.
portal_categories
request
=
container
.
REQUEST
from_date
=
request
.
get
(
'from_date'
,
None
)
to_date
=
request
.
get
(
'at_date'
,
None
)
aggregation_level
=
request
.
get
(
'aggregation_level'
,
None
)
report_group_by
=
request
.
get
(
'group_by'
,
None
)
quantity_unit
=
request
.
get
(
'quantity_unit'
,
None
)
active_process_path
=
request
.
get
(
'active_process'
)
# We have to sum product_dict and client_dict from the results of active process
def
_addDict
(
global_dict
,
local_dict
,
only_amount
=
False
):
if
report_group_by
==
"both"
and
not
only_amount
:
# we have client -> product -> period -> amount
for
local_title
,
local_product_dict
in
local_dict
.
iteritems
():
product_dict
=
global_dict
.
setdefault
(
local_title
,
{})
for
local_product
,
local_period_dict
in
local_product_dict
.
iteritems
():
period_dict
=
product_dict
.
setdefault
(
local_product
,
{})
for
period
,
local_amount_dict
in
local_period_dict
.
iteritems
():
amount_dict
=
period_dict
.
setdefault
(
period
,
{
'amount'
:
0
,
'quantity'
:
0
,
'quantity_unit'
:
''
})
amount_dict
[
'amount'
]
=
amount_dict
[
'amount'
]
+
local_amount_dict
[
'amount'
]
amount_dict
[
'quantity'
]
=
amount_dict
[
'quantity'
]
+
local_amount_dict
[
'quantity'
]
amount_dict
[
'quantity_unit'
]
=
local_amount_dict
[
'quantity_unit'
]
else
:
# We have client or product -> period -> amount
for
local_title
,
local_period_dict
in
local_dict
.
iteritems
():
period_dict
=
global_dict
.
setdefault
(
local_title
,
{})
for
period
,
local_amount_dict
in
local_period_dict
.
iteritems
():
amount_dict
=
period_dict
.
setdefault
(
period
,
{
'amount'
:
0
,
'quantity'
:
0
,
'quantity_unit'
:
''
})
amount_dict
[
'amount'
]
=
amount_dict
[
'amount'
]
+
local_amount_dict
[
'amount'
]
if
not
only_amount
:
amount_dict
[
'quantity'
]
=
amount_dict
[
'quantity'
]
+
local_amount_dict
[
'quantity'
]
amount_dict
[
'quantity_unit'
]
=
local_amount_dict
[
'quantity_unit'
]
product_dict
=
{}
# get all category
incoterm
=
request
.
get
(
'incoterm'
,
None
)
section_category
=
request
.
get
(
'section_category'
,
None
)
order
=
request
.
get
(
'order'
,
None
)
delivery_mode
=
request
.
get
(
'delivery_mode'
,
None
)
catalog_params
=
{}
resource_title_dict
=
{}
# get all organisations for the selected section category
if
section_category
:
group_uid
=
category_tool
.
getCategoryValue
(
section_category
).
getUid
()
organisation_uid_list
=
[
x
.
uid
for
x
in
portal
.
portal_catalog
(
portal_type
=
"Organisation"
,
default_group_uid
=
group_uid
)]
if
report_type
==
"sale"
:
catalog_params
[
'default_source_section_uid'
]
=
organisation_uid_list
or
-
1
elif
report_type
:
catalog_params
[
'default_destination_section_uid'
]
=
organisation_uid_list
or
-
1
# add category params if defined
if
incoterm
not
in
(
''
,
None
):
incoterm_uid
=
category_tool
.
incoterm
.
restrictedTraverse
(
incoterm
).
getUid
()
catalog_params
[
'default_incoterm_uid'
]
=
incoterm_uid
if
order
not
in
(
''
,
None
):
order_uid
=
category_tool
.
order
.
restrictedTraverse
(
order
).
getUid
()
catalog_params
[
'default_order_uid'
]
=
order_uid
if
delivery_mode
not
in
(
''
,
None
):
delivery_mode_uid
=
category_tool
.
delivery_mode
.
restrictedTraverse
(
delivery_mode
).
getUid
()
catalog_params
[
'default_delivery_mode_uid'
]
=
delivery_mode_uid
# compute sql params, we group and order by date and portal type
if
aggregation_level
==
"year"
:
date_format
=
"%Y"
elif
aggregation_level
==
"month"
:
date_format
=
"%Y-%m"
elif
aggregation_level
==
"week"
:
date_format
=
"%Y-%U"
elif
aggregation_level
==
"day"
:
date_format
=
"%Y-%m-%d"
params
=
{
"delivery.start_date"
:(
from_date
,
to_date
)}
query
=
None
if
from_date
is
not
None
and
to_date
is
not
None
:
params
=
{
"delivery.start_date"
:(
from_date
,
to_date
)}
query
=
Query
(
range
=
"minngt"
,
**
params
)
elif
from_date
is
not
None
:
params
=
{
"delivery.start_date"
:
from_date
}
query
=
Query
(
range
=
"min"
,
**
params
)
elif
to_date
is
not
None
:
params
=
{
"delivery.start_date"
:
to_date
}
query
=
Query
(
range
=
"ngt"
,
**
params
)
sort_on_list
=
[
(
'delivery.destination_section_uid'
,
'ASC'
),
(
'delivery.start_date'
,
'ASC'
)]
if
request
.
get
(
'use_selection'
):
selection_name
=
request
[
'selection_name'
]
result_list
=
\
context
.
portal_selections
.
callSelectionFor
(
request
[
'selection_name'
])
else
:
result_list
=
context
.
portal_catalog
.
searchResults
(
limit
=
None
,
query
=
query
,
portal_type
=
doc_portal_type
,
simulation_state
=
simulation_state
,
sort_on
=
sort_on_list
,
**
catalog_params
)
# we build two dict, one that store amount per period per client
# and another that either store amount per period per product and per client
# or only amount per period per product dependings on choosen group by
client_dict
=
{}
if
active_process_path
:
active_process
=
portal
.
restrictedTraverse
(
active_process_path
)
for
result
in
active_process
.
getResultList
():
if
result
.
summary
:
continue
detail
=
loads
(
result
.
detail
)
if
detail
[
'type'
]
==
"result"
:
result_product_dict
=
detail
[
'product_dict'
]
result_client_dict
=
detail
[
"client_dict"
]
product_dict
=
{}
for
result
in
result_list
:
result
=
result
.
getObject
()
period
=
result
.
getStartDate
()
if
period
is
not
None
:
period
=
period
.
strftime
(
date_format
)
if
report_group_by
in
(
"client"
,
"both"
):
# client_title -> period -> amount
if
report_type
==
"sale"
:
client_title
=
result
.
getDestinationSectionTitle
()
else
:
continue
if
not
len
(
client_dict
)
and
len
(
result_client_dict
):
client_dict
=
result_client_dict
.
copy
()
client_title
=
result
.
getSourceSectionTitle
()
# FIXME: if two clients have the same title, do we want to group ?
if
not
client_dict
.
has_key
(
client_title
):
client_dict
[
client_title
]
=
{}
if
client_dict
[
client_title
].
has_key
(
period
):
client_dict
[
client_title
][
period
][
'amount'
]
=
client_dict
[
client_title
][
period
][
'amount'
]
+
result
.
getTotalPrice
()
else
:
client_dict
[
client_title
][
period
]
=
{
'amount'
:
result
.
getTotalPrice
()}
if
not
product_dict
.
has_key
(
client_title
):
line_dict
=
product_dict
[
client_title
]
=
{}
else
:
line_dict
=
product_dict
[
client_title
]
else
:
_addDict
(
client_dict
,
result_client_dict
,
only_amount
=
True
)
line_dict
=
product_dict
if
not
len
(
product_dict
)
and
len
(
result_product_dict
):
product_dict
=
result_product_dict
.
copy
()
if
report_group_by
!=
"client"
:
# client_title -> product_title -> period -> amount/quantity...
# or product_title -> period -> amount/quantity...
for
line
in
result
.
contentValues
(
filter
=
{
'portal_type'
:
line_portal_type
}):
# Filter by quantity_unit
if
quantity_unit
:
if
line
.
getQuantityUnit
()
!=
quantity_unit
:
continue
# FIXME: if two resources have the same title, do we want to group ?
if
report_group_by
==
"function"
:
if
report_type
==
"sale"
:
product_title
=
line
.
getSourceFunctionTitle
()
else
:
_addDict
(
product_dict
,
result_product_dict
)
else
:
raise
ValueError
(
"No active process found to process report"
)
product_title
=
line
.
getDestinationFunctionTitle
()
else
:
product_title
=
line
.
getResourceTitle
()
resource_title_dict
[
product_title
]
=
line
.
getResourceReference
()
if
not
line_dict
.
has_key
(
product_title
):
line_dict
[
product_title
]
=
{
period
:{
"amount"
:
line
.
getTotalPrice
(),
"quantity"
:
line
.
getTotalQuantity
(),
"quantity_unit"
:
line
.
getQuantityUnitTranslatedTitle
()}}
else
:
if
not
line_dict
[
product_title
].
has_key
(
period
):
line_dict
[
product_title
][
period
]
=
{
"amount"
:
line
.
getTotalPrice
(),
"quantity"
:
line
.
getTotalQuantity
(),
"quantity_unit"
:
line
.
getQuantityUnitTranslatedTitle
()}
else
:
line_dict
[
product_title
][
period
][
'amount'
]
=
line_dict
[
product_title
][
period
][
'amount'
]
+
line
.
getTotalPrice
()
line_dict
[
product_title
][
period
][
'quantity'
]
=
line_dict
[
product_title
][
period
][
'quantity'
]
+
line
.
getTotalQuantity
()
def
sortProduct
(
a
,
b
):
return
cmp
(
a
[
'product'
],
b
[
'product'
])
period_counter_dict
=
{}
line_list
=
[]
append
=
line_list
.
append
...
...
@@ -84,6 +173,7 @@ if len(client_dict):
period_counter_dict
[
'total amount'
]
=
period_counter_dict
[
'total amount'
]
+
line_total_amount
else
:
period_counter_dict
[
'total amount'
]
=
line_total_amount
append
(
obj
)
if
report_group_by
==
"both"
:
product_lines_list
=
[]
...
...
@@ -93,6 +183,7 @@ if len(client_dict):
for
product_title
in
line_product_dict
.
keys
():
obj
=
Object
(
uid
=
"new_"
)
obj
[
'product'
]
=
product_title
obj
[
'product_reference'
]
=
resource_title_dict
.
get
(
product_title
)
line_total_amount
=
0
line_total_quantity
=
0
for
period
in
period_list
:
...
...
@@ -109,13 +200,13 @@ if len(client_dict):
line_product_dict
[
product_title
][
period
][
'amount'
]
else
:
period_counter_dict
[
'Amount %s'
%
(
period
)]
=
line_product_dict
[
product_title
][
period
][
'amount'
]
if
quantity_unit
:
if
period_counter_dict
.
has_key
(
'Quantity %s'
%
(
period
)):
period_counter_dict
[
'Quantity %s'
%
(
period
)]
=
period_counter_dict
[
'Quantity %s'
%
(
period
)]
+
\
line_product_dict
[
product_title
][
period
][
'quantity'
]
else
:
period_counter_dict
[
'Quantity %s'
%
(
period
)]
=
line_product_dict
[
product_title
][
period
][
'quantity'
]
else
:
obj
[
'Amount %s'
%
(
period
)]
=
0
obj
[
'Quantity %s'
%
(
period
)]
=
0
...
...
@@ -144,6 +235,8 @@ else:
for
product_title
in
product_dict
.
keys
():
obj
=
Object
(
uid
=
"new_"
)
obj
[
'product'
]
=
product_title
obj
[
'product_reference'
]
=
resource_title_dict
.
get
(
product_title
)
line_total_amount
=
0
line_total_quantity
=
0
for
period
in
period_list
:
...
...
@@ -168,6 +261,7 @@ else:
obj
[
'Amount %s'
%
(
period
)]
=
0
obj
[
'Quantity %s'
%
(
period
)]
=
0
obj
[
'Quantity Unit %s'
%
(
period
)]
=
""
obj
[
'total quantity'
]
=
line_total_quantity
obj
[
'total amount'
]
=
round
(
line_total_amount
,
2
)
# total for stat line
...
...
@@ -181,12 +275,16 @@ else:
else
:
period_counter_dict
[
'total quantity'
]
=
line_total_quantity
append
(
obj
)
line_list
.
sort
(
sortProduct
)
obj
=
Object
(
uid
=
"new_"
)
obj
[
"client"
]
=
'Total'
for
k
,
v
in
period_counter_dict
.
items
():
if
"mount"
in
k
:
v
=
round
(
v
,
2
)
obj
[
k
]
=
v
request
.
set
(
'stat_line'
,
[
obj
,])
return
line_list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment