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
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Jérome Perrin
erp5
Commits
92bf8075
Commit
92bf8075
authored
Jun 10, 2016
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
group_by_time_sequence_list
parent
d810b3ef
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
342 additions
and
38 deletions
+342
-38
bt5/tmp_work/TestTemplateItem/portal_components/test.erp5.testInventoryAPI.py
...plateItem/portal_components/test.erp5.testInventoryAPI.py
+210
-0
product/ERP5/Tool/SimulationTool.py
product/ERP5/Tool/SimulationTool.py
+44
-37
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Resource_zGetInventoryList.sql
...tem/portal_skins/erp5_core/Resource_zGetInventoryList.sql
+58
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Resource_zGetInventoryList.xml
...tem/portal_skins/erp5_core/Resource_zGetInventoryList.xml
+1
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/SimulationTool_zGetInterpolationMethod.sql
...kins/erp5_core/SimulationTool_zGetInterpolationMethod.sql
+27
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/SimulationTool_zGetInterpolationMethod.xml
...kins/erp5_core/SimulationTool_zGetInterpolationMethod.xml
+2
-1
No files found.
bt5/tmp_work/TestTemplateItem/portal_components/test.erp5.testInventoryAPI.py
View file @
92bf8075
...
...
@@ -1633,6 +1633,216 @@ class TestInventoryList(InventoryAPITestCase):
self
.
assertEqual
([
r
for
r
in
inventory_list
if
r
.
getObject
().
getUse
()
==
'use2'
][
0
].
inventory
,
11
)
def
test_group_by_time_sequence
(
self
):
getInventoryList
=
self
.
getSimulationTool
().
getInventoryList
# Create 3 groups of movements:
self
.
_makeMovement
(
quantity
=
1
,
start_date
=
DateTime
(
'2016/01/01'
))
self
.
_makeMovement
(
quantity
=
3
,
start_date
=
DateTime
(
'2016/02/01'
))
self
.
_makeMovement
(
quantity
=
5
,
start_date
=
DateTime
(
'2016/02/02'
))
self
.
_makeMovement
(
quantity
=
7
,
start_date
=
DateTime
(
'2016/03/01'
))
# Create "noise" movement that we should not select
self
.
_makeMovement
(
quantity
=
10
,
start_date
=
DateTime
(
'2016/02/01'
),
destination_value
=
self
.
portal
.
organisation_module
.
newContent
())
inventory_list
=
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
{
'at_date'
:
DateTime
(
'2016/01/01'
).
latestTime
()},
{
'from_date'
:
DateTime
(
'2016/02/01'
),
'to_date'
:
DateTime
(
'2016/03/01'
)},
{
'from_date'
:
DateTime
(
'2016/03/01'
)},
)
)
self
.
assertEqual
(
3
,
len
(
inventory_list
))
self
.
assertEqual
(
1
,
inventory_list
[
0
].
total_quantity
)
self
.
assertEqual
(
0
,
inventory_list
[
0
].
slot_index
)
self
.
assertEqual
(
3
+
5
,
inventory_list
[
1
].
total_quantity
)
self
.
assertEqual
(
1
,
inventory_list
[
1
].
slot_index
)
self
.
assertEqual
(
7
,
inventory_list
[
2
].
total_quantity
)
self
.
assertEqual
(
2
,
inventory_list
[
2
].
slot_index
)
# now using all combinasion of from_date, at_date & to_date
inventory_list
=
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
{
'at_date'
:
DateTime
(
'2016/01/01'
).
latestTime
()},
{
'to_date'
:
DateTime
(
'2016/01/02'
)},
# equivalent to above
{
'from_date'
:
DateTime
(
'2016/02/01'
),
'at_date'
:
DateTime
(
'2016/02/29'
).
latestTime
()},
{
'from_date'
:
DateTime
(
'2016/02/01'
),
'to_date'
:
DateTime
(
'2016/03/01'
)},
{
'from_date'
:
DateTime
(
'2016/03/01'
)},
)
)
self
.
assertEqual
([
1
,
1
,
3
+
5
,
3
+
5
,
7
],
[
x
.
inventory
for
x
in
inventory_list
])
def
test_group_by_time_sequence_empty_slots_are_returned
(
self
):
getInventoryList
=
self
.
getSimulationTool
().
getInventoryList
self
.
_makeMovement
(
title
=
"M1"
,
quantity
=
3
,
start_date
=
DateTime
(
'2016/01/01'
))
self
.
_makeMovement
(
title
=
"M2"
,
quantity
=
5
,
start_date
=
DateTime
(
'2016/02/01'
))
inventory_list
=
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
# before M1 -> empty
{
'at_date'
:
DateTime
(
'2001/01/01'
).
latestTime
()},
{
'to_date'
:
DateTime
(
'2001/01/01'
)},
{
'from_date'
:
DateTime
(
'1999/01/01'
),
'to_date'
:
DateTime
(
'2001/01/01'
)},
{
'from_date'
:
DateTime
(
'1999/01/01'
),
'at_date'
:
DateTime
(
'2001/01/01'
)},
# selecting M1
{
'from_date'
:
DateTime
(
'2016/01/01'
),
'to_date'
:
DateTime
(
'2016/01/02'
)},
# between M1 & M2 -> empty
{
'from_date'
:
DateTime
(
'2016/01/02'
),
'at_date'
:
DateTime
(
'2001/01/03'
)},
{
'from_date'
:
DateTime
(
'2016/01/02'
),
'to_date'
:
DateTime
(
'2001/01/03'
)},
# selecting M2
{
'from_date'
:
DateTime
(
'2016/02/01'
),
'to_date'
:
DateTime
(
'2016/02/03'
)},
# after M2 -> empty
{
'from_date'
:
DateTime
(
'2016/02/03'
),
'to_date'
:
DateTime
(
'2016/02/04'
)},
{
'from_date'
:
DateTime
(
'2016/02/03'
),
'at_date'
:
DateTime
(
'2001/02/04'
)},
{
'from_date'
:
DateTime
(
'2016/02/03'
)},
)
)
self
.
assertEqual
(
[
0
,
0
,
0
,
0
,
3
,
0
,
0
,
5
,
0
,
0
,
0
],
[
x
.
inventory
for
x
in
inventory_list
])
def
test_group_by_time_sequence_invalid_inputs
(
self
):
getInventoryList
=
self
.
getSimulationTool
().
getInventoryList
self
.
_makeMovement
(
title
=
"M1"
,
quantity
=
3
,
start_date
=
DateTime
(
'2016/01/02'
))
# no from_date, at_date or to_date on a slot raise a ValueError
with
self
.
assertRaises
(
ValueError
):
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
{},
)
)
# slots where start_date > stop_date are valid, but select nothing
self
.
assertEqual
(
[
0
],
[
x
.
inventory
for
x
in
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
{
'from_date'
:
DateTime
(
'2016/01/03'
),
'at_date'
:
DateTime
(
'2016/01/01'
)
}
)
)
]
)
self
.
assertEqual
(
[
0
],
[
x
.
inventory
for
x
in
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
group_by_time_sequence_list
=
(
{
'from_date'
:
DateTime
(
'2016/01/03'
),
'to_date'
:
DateTime
(
'2016/01/01'
)
}
)
)
]
)
def
test_group_by_time_sequence_with_interpolation_method
(
self
):
getInventoryList
=
self
.
getSimulationTool
().
getInventoryList
self
.
_makeMovement
(
quantity
=
10
,
title
=
"M1"
,
start_date
=
DateTime
(
'2016/01/01 01:00:00'
),
stop_date
=
DateTime
(
'2016/01/01 11:00:00'
),
)
self
.
_makeMovement
(
quantity
=
5
,
title
=
"M2"
,
start_date
=
DateTime
(
'2016/01/01 10:00:00'
),
stop_date
=
DateTime
(
'2016/01/01 15:00:00'
),
)
self
.
_makeMovement
(
title
=
"M3"
,
quantity
=
10
,
start_date
=
DateTime
(
"2016/01/01 05:00:00"
),
stop_date
=
DateTime
(
"2016/01/01 15:00:00"
),
)
self
.
_makeMovement
(
title
=
"M4"
,
quantity
=
5
,
start_date
=
DateTime
(
"2016/01/01 18:00:00"
),
stop_date
=
DateTime
(
"2016/01/01 23:00:00"
),
)
self
.
_makeMovement
(
title
=
"M5"
,
destination_value
=
self
.
portal
.
organisation_module
.
newContent
(),
quantity
=
10
,
start_date
=
DateTime
(
"2016/01/01 08:00:00"
),
stop_date
=
DateTime
(
"2016/01/01 17:00:00"
),
)
# We have created these movements:
# 00:00 10:00 20:00
# | | |
# M1 XXXXXXXXXX
# M2 XXXXX
# M3 XXXXXXXXXX
# M4 XXXXX
# M5 YYYYYYYYYY (will not be counted because on another node)
# | | |
# We will query with this time sequence:
# 00:00 10:00 20:00
# | | | expected quantity:
# ... ] 1 ( M1 )
# [ ] 3 ( M1 )
# [] 5 ( M1 + M2 + M3)
# [ ... 2 ( M4 )
# M1 XXXXXXXXXX
# M2 XXXXX
# M3 XXXXXXXXXX
# M4 XXXXX
# M5 YYYYYYYYYY
# | | |
inventory_list
=
getInventoryList
(
node_uid
=
self
.
node
.
getUid
(),
interpolation_method
=
'linear'
,
group_by_time_sequence_list
=
(
{
'at_date'
:
DateTime
(
'2016/01/01 02:00:00'
)},
{
'from_date'
:
DateTime
(
'2016/01/01 01:00:00'
),
'to_date'
:
DateTime
(
'2016/01/01 04:00:00'
)},
{
'from_date'
:
DateTime
(
'2016/01/01 09:00:00'
),
'to_date'
:
DateTime
(
'2016/01/01 11:00:00'
)},
{
'from_date'
:
DateTime
(
'2016/01/01 21:00:00'
),
},
)
)
self
.
assertEqual
(
[
1
,
3
,
5
,
2
],
[
x
.
inventory
for
x
in
inventory_list
])
def
test_OmitInputOmitOutput
(
self
):
getInventoryList
=
self
.
getSimulationTool
().
getInventoryList
self
.
_makeMovement
(
quantity
=
1
,
price
=
1
)
...
...
product/ERP5/Tool/SimulationTool.py
View file @
92bf8075
...
...
@@ -594,6 +594,7 @@ class SimulationTool(BaseTool):
group_by_function_category
=
0
,
group_by_function_category_strict_membership
=
0
,
group_by_date
=
0
,
group_by_time_sequence_list
=
None
,
# sort_on
sort_on
=
None
,
group_by
=
None
,
...
...
@@ -648,6 +649,7 @@ class SimulationTool(BaseTool):
if
date_dict
:
column_value_dict
[
'date'
]
=
date_dict
if
interpolation_method
!=
'default'
:
if
not
group_by_time_sequence_list
:
if
not
(
from_date
and
(
to_date
or
at_date
)):
raise
ValueError
(
"date_range is required to use interpolation_method"
)
# if we consider flow, we also select movement whose mirror date is
...
...
@@ -965,6 +967,8 @@ class SimulationTool(BaseTool):
new_kw
[
'related_key_select_expression_list'
]
=
\
related_key_select_expression_list
# XXX
sql_kw
[
'group_by_time_sequence_list'
]
=
group_by_time_sequence_list
return
sql_kw
,
new_kw
#######################################################
...
...
@@ -1186,6 +1190,7 @@ class SimulationTool(BaseTool):
group_by_section_category
=
0
,
group_by_section_category_strict_membership
=
0
,
group_by_resource
=
None
,
group_by_time_sequence_list
=
(),
movement_list_mode
=
0
,
group_by
=
None
,
**
ignored
):
...
...
@@ -1211,7 +1216,8 @@ class SimulationTool(BaseTool):
group_by_mirror_section
or
group_by_payment
or
\
group_by_sub_variation
or
group_by_variation
or
\
group_by_movement
or
group_by_date
or
group_by_section_category
or
\
group_by_section_category_strict_membership
:
group_by_section_category_strict_membership
or
\
group_by_time_sequence_list
:
if
group_by_resource
is
None
:
group_by_resource
=
1
new_group_by_dict
[
'group_by_resource'
]
=
group_by_resource
...
...
@@ -1329,7 +1335,8 @@ class SimulationTool(BaseTool):
# Get cached data
if
getattr
(
self
,
"Resource_zGetInventoryCacheResult"
,
None
)
is
not
None
and
\
optimisation__
and
(
not
kw
.
get
(
'from_date'
))
and
\
'transformed_resource'
not
in
kw
:
'transformed_resource'
not
in
kw
\
and
"group_by_time_sequence_list"
not
in
kw
:
# Here is the different kind of date
# from_date : >=
# to_date : <
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Resource_zGetInventoryList.sql
View file @
92bf8075
...
...
@@ -4,6 +4,7 @@
interpolation_method_from_date=interpolation_method_from_date,
interpolation_method_to_date=interpolation_method_to_date,
interpolation_method_at_date=interpolation_method_at_date,
group_by_time_sequence_list=group_by_time_sequence_list,
src__=1)"
>
SELECT
...
...
@@ -75,6 +76,8 @@ SELECT
COUNT
(
DISTINCT
<
dtml
-
var
stock_table_id
>
.
uid
)
AS
stock_uid
,
MAX
(
<
dtml
-
var
stock_table_id
>
.
date
)
AS
date
</
dtml
-
if
>
<
dtml
-
if
group_by_time_sequence_list
>
,
slot_index
</
dtml
-
if
>
<
dtml
-
comment
>
XXX
is
this
really
needed
?
are
empty
slots
returned
?
</
dtml
-
comment
>
<
dtml
-
if
select_expression
>
,
<
dtml
-
var
select_expression
></
dtml
-
if
>
FROM
...
...
@@ -88,6 +91,55 @@ FROM
</
dtml
-
if
>
</
dtml
-
in
>
,
<
dtml
-
var
stock_table_id
>
<
dtml
-
if
group_by_time_sequence_list
>
RIGHT
JOIN
(
<
dtml
-
in
prefix
=
"time_slot"
expr
=
"_.list(_.enumerate(group_by_time_sequence_list))"
>
SELECT
<
dtml
-
sqlvar
expr
=
"time_slot_key"
type
=
"int"
>
slot_index
,
<
dtml
-
sqlvar
expr
=
"time_slot_item.get('from_date')"
type
=
"datetime"
optional
>
slot_from_date
,
<
dtml
-
sqlvar
expr
=
"time_slot_item.get('at_date')"
type
=
"datetime"
optional
>
slot_at_date
,
<
dtml
-
sqlvar
expr
=
"time_slot_item.get('to_date')"
type
=
"datetime"
optional
>
slot_to_date
<
dtml
-
unless
time_slot_end
>
UNION
ALL
</
dtml
-
unless
>
</
dtml
-
in
>
)
slots
ON
<
dtml
-
if
group_by_time_sequence_list
>
(
(
slot_from_date
is
not
null
AND
(
slot_at_date
is
not
null
AND
GREATEST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
>=
slot_from_date
AND
LEAST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
<=
slot_at_date
)
OR
(
(
slot_to_date
is
not
null
AND
GREATEST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
>=
slot_from_date
AND
LEAST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
<
slot_to_date
)
OR
(
GREATEST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
>=
slot_from_date
AND
slot_at_date
is
null
AND
slot_to_date
is
null
)
)
)
OR
(
slot_from_date
is
null
AND
(
(
slot_at_date
is
not
null
AND
(
LEAST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
<=
slot_at_date
)
)
OR
LEAST
(
`stock`
.
`date`
,
`stock`
.
`mirror_date`
)
<
slot_to_date
)
)
)
<
dtml
-
else
>
(
(
slot_from_date
is
null
OR
stock
.
date
>=
slot_from_date
)
AND
(
slot_at_date
is
null
OR
stock
.
date
<=
slot_at_date
)
AND
(
slot_to_date
is
null
OR
stock
.
date
<
slot_to_date
)
)
</
dtml
-
if
>
</
dtml
-
if
>
</
dtml
-
if
>
<
dtml
-
if
quantity_unit_uid
>
<
dtml
-
comment
>
XXX
quantity
unit
conversion
will
not
work
when
using
implict_join
=
False
</
dtml
-
comment
>
LEFT
JOIN
quantity_unit_conversion
ON
...
...
@@ -135,10 +187,16 @@ WHERE
<
dtml
-
if
group_by_expression
>
GROUP
BY
<
dtml
-
if
transformed_uid
>
transformation
.
transformed_uid
,
</
dtml
-
if
>
<
dtml
-
if
group_by_time_sequence_list
>
slot_index
,
</
dtml
-
if
>
<
dtml
-
var
group_by_expression
>
</
dtml
-
if
>
<
dtml
-
if
order_by_expression
>
ORDER
BY
<
dtml
-
var
order_by_expression
>
<
dtml
-
else
>
<
dtml
-
if
group_by_time_sequence_list
>
ORDER
BY
slot_index
</
dtml
-
if
>
</
dtml
-
if
>
</
dtml
-
let
>
\ No newline at end of file
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Resource_zGetInventoryList.xml
View file @
92bf8075
...
...
@@ -46,6 +46,7 @@ quantity_unit_uid\r\n
stock_table_id=stock\r\n
transformed_uid\r\n
transformed_variation_text\r\n
group_by_time_sequence_list:list\r\n
interpolation_method\r\n
interpolation_method_from_date=not_applicable\r\n
interpolation_method_to_date=not_applicable\r\n
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/SimulationTool_zGetInterpolationMethod.sql
View file @
92bf8075
<
dtml
-
if
expr
=
"interpolation_method == 'linear'"
>
<
dtml
-
if
group_by_time_sequence_list
>
CASE
WHEN
<
dtml
-
var
stock_table_id
>
.
mirror_date
=
<
dtml
-
var
stock_table_id
>
.
date
THEN
1
ELSE
(
UNIX_TIMESTAMP
(
IFNULL
(
LEAST
(
IFNULL
(
slot_at_date
,
slot_to_date
),
GREATEST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
)
),
GREATEST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
)
)
)
-
UNIX_TIMESTAMP
(
GREATEST
(
IFNULL
(
slot_from_date
,
TIMESTAMP
(
0
)
),
LEAST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
)
)
)
)
/
(
UNIX_TIMESTAMP
(
GREATEST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
))
-
UNIX_TIMESTAMP
(
LEAST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
))
)
END
<
dtml
-
else
>
CASE
WHEN
<
dtml
-
var
stock_table_id
>
.
mirror_date
=
<
dtml
-
var
stock_table_id
>
.
date
THEN
1
ELSE
(
...
...
@@ -13,6 +39,7 @@
LEAST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
))))
/
(
UNIX_TIMESTAMP
(
GREATEST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
))
-
UNIX_TIMESTAMP
(
LEAST
(
<
dtml
-
var
stock_table_id
>
.
date
,
<
dtml
-
var
stock_table_id
>
.
mirror_date
))
)
END
</
dtml
-
if
>
<
dtml
-
elif
expr
=
"interpolation_method == 'all_or_nothing'"
>
CASE
WHEN
(
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/SimulationTool_zGetInterpolationMethod.xml
View file @
92bf8075
...
...
@@ -12,7 +12,8 @@
interpolation_method\r\n
interpolation_method_from_date\r\n
interpolation_method_to_date\r\n
interpolation_method_at_date
</string>
</value>
interpolation_method_at_date\r\n
group_by_time_sequence_list:list
</string>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
...
...
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