Commit 5196c6c7 authored by Jérome Perrin's avatar Jérome Perrin

inventory_api: POC of group by time sequence in getInventory

parent ac95cf57
......@@ -662,6 +662,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=(),
group_by=None,
# sort_on
sort_on=None,
......@@ -1018,6 +1019,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
#######################################################
......
......@@ -48,7 +48,8 @@ transformed_uid\r\n
transformed_variation_text\r\n
flow_valuation_method\r\n
flow_valuation_method_from_date\r\n
flow_valuation_method_to_date</string> </value>
flow_valuation_method_to_date\r\n
group_by_time_sequence_list:list</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
......@@ -182,6 +183,30 @@ FROM\n
</dtml-if>\n
</dtml-in>\n
, <dtml-var stock_table_id>\n
<dtml-if group_by_time_sequence_list>\n
RIGHT JOIN\n
( <dtml-in prefix="time_slot" expr="_.list(_.enumerate(group_by_time_sequence_list))">\n
SELECT\n
<dtml-sqlvar expr="time_slot_key" type="int"> slot_id,\n
<dtml-sqlvar expr="time_slot_item.get(\'from_date\')" type="datetime"> slot_from_date,\n
<dtml-sqlvar expr="time_slot_item.get(\'at_date\')" type="datetime"> slot_at_date,\n
<dtml-sqlvar expr="time_slot_item.get(\'to_date\')" type="datetime"> slot_to_date\n
\n
<dtml-unless time_slot_end>UNION ALL</dtml-unless>\n
</dtml-in> ) slots\n
ON ( slot_from_date is null OR stock.date >= slot_from_date )\n
AND ( slot_at_date is null OR stock.date <= slot_at_date )\n
AND ( slot_to_date is null OR stock.date < slot_to_date )\n
-- TODO if flow method we need to select something like:\n
-- start before slot\n
-- ( stock.date <= start_date and stock.mirror_date >= start_date and stock.mirror_date < stop_date ) or\n
-- fits in the slot\n
-- ( stock.date >= start_date and stock.mirror_date < stop_date ) or\n
-- finishes after slot end\n
-- ( stock.date < stop_date and stock.mirror_date >= stop_date )\n
\n
</dtml-if>\n
\n
</dtml-if>\n
<dtml-if quantity_unit_uid> <dtml-comment>XXX quantity unit conversion will not work when using implict_join=False</dtml-comment>\n
LEFT JOIN quantity_unit_conversion ON \n
......@@ -228,6 +253,7 @@ WHERE\n
\n
<dtml-if group_by_expression>\n
GROUP BY\n
slot_id, -- XXX \n
<dtml-if transformed_uid>transformation.transformed_uid,</dtml-if>\n
<dtml-var group_by_expression>\n
</dtml-if>\n
......
......@@ -1158,6 +1158,66 @@ class TestInventoryList(InventoryAPITestCase):
self.assertEqual([r for r in inventory_list
if r.date.year() == 2001][0].inventory, 1)
def test_GroupByDateSequence(self):
# group by date
getInventoryList = self.getSimulationTool().getInventoryList
self._makeMovement(quantity=1, start_date=DateTime('2000/01/01 12:00 UTC'))
self._makeMovement(quantity=1, start_date=DateTime('2000/01/02 12:00 UTC'))
self._makeMovement(quantity=1, start_date=DateTime('2001/01/01 12:00 UTC'))
if 0:
# first API proposal: similar to getAvailableTimeSequence
# XXX problem with this API is how to deal with DST switch ?
# we could say hour:24 and day:1, but how to pass this to mysql, since
# mysql does not know about zope default timezone.
# also in the generated query we should generate the slots in sql, with techniques such as
# https://www.experts-exchange.com/questions/28642464/How-to-find-open-appointment-slots-with-MySQL-query-based-on-current-table-structure.html
# or http://stackoverflow.com/questions/33402899/better-way-to-repeat-queries-instead-of-union-all
inventory_list = getInventoryList(
node_uid=self.node.getUid(),
group_by_time_sequence={"month": 1, "day": 3}
)
if 0:
# another API proposal: list of from_date, to_date tuples
# this way we generate a query that union all for all tuples.
inventory_list = getInventoryList(
node_uid=self.node.getUid(),
group_by_time_sequence_list=(
(None, DateTime('2000/01/01 00:00 UTC'),)
(DateTime('2000/01/01 00:00 UTC'), DateTime('2001/01/01 00:00 UTC'))
(DateTime('2001/01/01 00:00 UTC'), None)
)
)
# similar, but more flexible
inventory_list = getInventoryList(
node_uid=self.node.getUid(),
group_by_time_sequence_list=(
{
# from_date, to_date, at_date are supported.
'to_date': DateTime('2000/01/01 00:00 UTC'),
},
{
'from_date': DateTime('2000/01/01 00:00 UTC'),
'at_date': DateTime('2000/12/31 23:59 UTC'),
},
{
'from_date': DateTime('2001/01/01 00:00 UTC'),
},
)
)
# results are returned in same order
self.assertEqual(3, len(inventory_list))
self.assertEqual([0, 2, 1], [brain.inventory for brain in inventory_list])
# but the brain must expose slot_from_date & slot_at_date (in the same timezone as input ?)
self.assertEqual(
[None, DateTime('2000/01/01 00:00 UTC'), DateTime('2001/01/01 00:00 UTC')],
[brain.slot_from_date for brain in inventory_list])
def test_GroupByRelatedKey(self):
getInventoryList = self.getSimulationTool().getInventoryList
self._makeMovement(quantity=2, use='use1')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment