Commit 6665840e authored by Jérome Perrin's avatar Jérome Perrin

support running total for price and total quantity, computed by RDBMS.

This is SQL code will likely run only on MySQL.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@9790 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 2e3a8087
......@@ -865,10 +865,14 @@ class SimulationTool (BaseTool):
standardise=0, omit_simulation=0,
omit_input=0, omit_output=0,
selection_domain=None, selection_report=None,
initial_running_total_quantity=0,
initial_running_total_price=0,
**kw):
"""
Returns a list of movements which modify the inventory
"""Returns a list of movements which modify the inventory
for a single or a group of resource, node, section, etc.
A running total quantity and a running total price are available on
brains. The initial values can be passed, in case you want to have an
"initial summary line".
"""
sql_kw = self._generateSQLKeywordDict(**kw)
return self.Resource_zGetMovementHistoryList(
......@@ -877,7 +881,12 @@ class SimulationTool (BaseTool):
omit_simulation=omit_simulation,
omit_input=omit_input, omit_output=omit_output,
selection_domain=selection_domain,
selection_report=selection_report, **sql_kw)
selection_report=selection_report,
initial_running_total_quantity=
initial_running_total_quantity,
initial_running_total_price=
initial_running_total_price,
**sql_kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getMovementHistoryStat')
......
......@@ -55,6 +55,18 @@
<dictionary/>
</value>
</item>
<item>
<key> <string>initial_running_total_price</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>initial_running_total_quantity</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>input_simulation_state</string> </key>
<value>
......@@ -143,6 +155,8 @@
<string>omit_simulation</string>
<string>omit_input</string>
<string>omit_output</string>
<string>initial_running_total_quantity</string>
<string>initial_running_total_price</string>
<string>input_simulation_state</string>
<string>output_simulation_state</string>
</list>
......@@ -587,6 +601,8 @@ standardize\r\n
omit_simulation\r\n
omit_input\r\n
omit_output\r\n
initial_running_total_quantity\r\n
initial_running_total_price\r\n
input_simulation_state:list\r\n
output_simulation_state:list</string> </value>
</item>
......@@ -628,14 +644,29 @@ output_simulation_state:list</string> </value>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
SET @running_total_quantity := <dtml-var initial_running_total_quantity>,\n
@running_total_price := <dtml-var initial_running_total_price>;\n
\n
<dtml-var sql_delimiter>\n
\n
SELECT \n
q1.*,\n
@running_total_quantity := q1.total_quantity + \n
@running_total_quantity AS running_total_quantity,\n
@running_total_price := q1.total_price + \n
@running_total_price AS running_total_price\n
FROM (\n
SELECT\n
catalog.path as path,\n
catalog.uid as uid,\n
catalog.relative_url as relative_url,\n
stock.date AS date,\n
stock.quantity AS total_quantity,\n
stock.total_price AS total_price,\n
stock.variation_text AS variation_text,\n
stock.simulation_state AS simulation_state,\n
stock.mirror_section_uid AS mirror_section_uid,\n
stock.mirror_node_uid AS mirror_node_uid,\n
node.uid AS node_uid,\n
node.title AS node_title,\n
node.relative_url AS node_relative_url,\n
......@@ -714,16 +745,19 @@ WHERE\n
<dtml-if selection_report>\n
AND <dtml-var "selection_report.asSqlExpression(strict_membership=1)">\n
</dtml-if>\n
\n
GROUP BY\n
<dtml-if group_by_expression>\n
<dtml-var group_by_expression>\n
<dtml-else>\n
stock.uid, stock.node_uid, stock.resource_uid\n
</dtml-if>\n
\n
<dtml-if order_by_expression>\n
ORDER BY\n
<dtml-var order_by_expression>\n
</dtml-if>\n
) AS q1\n
]]></string> </value>
......@@ -762,14 +796,29 @@ ORDER BY\n
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
SET @running_total_quantity := <dtml-var initial_running_total_quantity>,\n
@running_total_price := <dtml-var initial_running_total_price>;\n
\n
<dtml-var sql_delimiter>\n
\n
SELECT \n
q1.*,\n
@running_total_quantity := q1.total_quantity + \n
@running_total_quantity AS running_total_quantity,\n
@running_total_price := q1.total_price + \n
@running_total_price AS running_total_price\n
FROM (\n
SELECT\n
catalog.path as path,\n
catalog.uid as uid,\n
catalog.relative_url as relative_url,\n
stock.date AS date,\n
stock.quantity AS total_quantity,\n
stock.total_price AS total_price,\n
stock.variation_text AS variation_text,\n
stock.simulation_state AS simulation_state,\n
stock.mirror_section_uid AS mirror_section_uid,\n
stock.mirror_node_uid AS mirror_node_uid,\n
node.uid AS node_uid,\n
node.title AS node_title,\n
node.relative_url AS node_relative_url,\n
......@@ -848,16 +897,19 @@ WHERE\n
<dtml-if selection_report>\n
AND <dtml-var "selection_report.asSqlExpression(strict_membership=1)">\n
</dtml-if>\n
\n
GROUP BY\n
<dtml-if group_by_expression>\n
<dtml-var group_by_expression>\n
<dtml-else>\n
stock.uid, stock.node_uid, stock.resource_uid\n
</dtml-if>\n
\n
<dtml-if order_by_expression>\n
ORDER BY\n
<dtml-var order_by_expression>\n
</dtml-if>\n
) AS q1\n
]]></string> </value>
......
56
\ No newline at end of file
61
\ No newline at end of file
......@@ -850,6 +850,72 @@ class TestMovementHistoryList(InventoryAPITestCase):
self.assertEquals(1, len(movement_history_list))
self.assertEquals(100, movement_history_list[0].quantity)
def test_RunningTotalQuantity(self):
"""Test that a running_total_quantity attribute is set on brains
"""
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
date_and_qty_list = [(DateTime(2006, 01, day), day) for day in range(1, 10)]
for date, quantity in date_and_qty_list:
self._makeMovement(stop_date=date, quantity=quantity)
movement_history_list = getMovementHistoryList(
section_uid=self.section.getUid(),
sort_on=[('stock.date', 'asc'),
('stock.uid', 'asc')])
running_total_quantity=0
for idx, (date, quantity) in enumerate(date_and_qty_list):
brain = movement_history_list[idx]
running_total_quantity += quantity
self.assertEquals(running_total_quantity, brain.running_total_quantity)
self.assertEquals(date, brain.date)
self.assertEquals(quantity, brain.quantity)
def test_RunningTotalPrice(self):
"""Test that a running_total_price attribute is set on brains
"""
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
date_and_price_list = [(DateTime(2006, 01, day), day) for day in range(1, 10)]
for date, price in date_and_price_list:
self._makeMovement(stop_date=date, quantity=1, price=price)
movement_history_list = getMovementHistoryList(
section_uid=self.section.getUid(),
sort_on=[('stock.date', 'asc'),
('stock.uid', 'asc')])
running_total_price=0
for idx, (date, price) in enumerate(date_and_price_list):
brain = movement_history_list[idx]
running_total_price += price
self.assertEquals(running_total_price, brain.running_total_price)
self.assertEquals(date, brain.date)
self.assertEquals(price, brain.total_price)
def test_RunningTotalWithInitialValue(self):
"""Test running_total_price and running_total_quantity with an initial
value.
"""
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
date_and_qty_list = [(DateTime(2006, 01, day), day) for day in range(1, 10)]
for date, quantity in date_and_qty_list:
self._makeMovement(stop_date=date, price=quantity, quantity=quantity)
initial_running_total_price=100
initial_running_total_quantity=-10
movement_history_list = getMovementHistoryList(
initial_running_total_quantity=
initial_running_total_quantity,
initial_running_total_price=
initial_running_total_price,
section_uid=self.section.getUid(),
sort_on=[('stock.date', 'asc'),
('stock.uid', 'asc')])
running_total_price=initial_running_total_price
running_total_quantity=initial_running_total_quantity
for idx, (date, quantity) in enumerate(date_and_qty_list):
brain = movement_history_list[idx]
self.assertEquals(date, brain.date)
running_total_quantity += quantity
self.assertEquals(running_total_quantity, brain.running_total_quantity)
running_total_price += quantity * quantity # we've set price=quantity
self.assertEquals(running_total_price, brain.running_total_price)
class TestInventoryStat(InventoryAPITestCase):
"""Tests Inventory Stat methods.
"""
......
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