Commit 6c510537 authored by Nicolas Wavrant's avatar Nicolas Wavrant

SimulationTool: adds ledger in the Inventory API

A new column ledger in the stock table and some related keys
(stored in erp5_mysql_innodb_catalog) have also been created
Adds tests for inventory queries based on ledger in testInventoryAPI
parent af31f2be
......@@ -523,14 +523,14 @@ class SimulationTool(BaseTool):
resource=None, node=None, payment=None,
section=None, mirror_section=None, item=None,
function=None, project=None, funding=None, payment_request=None,
transformed_resource=None,
transformed_resource=None, ledger=None,
# used for tracking
input=0, output=0,
# categories
resource_category=None, node_category=None, payment_category=None,
section_category=None, mirror_section_category=None,
function_category=None, project_category=None, funding_category=None,
payment_request_category=None,
ledger_category=None, payment_request_category=None,
# categories with strict membership
resource_category_strict_membership=None,
node_category_strict_membership=None,
......@@ -540,6 +540,7 @@ class SimulationTool(BaseTool):
function_category_strict_membership=None,
project_category_strict_membership=None,
funding_category_strict_membership=None,
ledger_category_strict_membership=None,
payment_request_category_strict_membership=None,
# simulation_state
strict_simulation_state=0,
......@@ -553,7 +554,8 @@ class SimulationTool(BaseTool):
# uids
resource_uid=None, node_uid=None, section_uid=None, payment_uid=None,
mirror_node_uid=None, mirror_section_uid=None, function_uid=None,
project_uid=None, funding_uid=None, payment_request_uid=None,
project_uid=None, funding_uid=None, ledger_uid=None,
payment_request_uid=None,
# omit input and output
omit_input=0,
omit_output=0,
......@@ -585,6 +587,9 @@ class SimulationTool(BaseTool):
group_by_funding=0,
group_by_funding_category=0,
group_by_funding_category_strict_membership=0,
group_by_ledger=0,
group_by_ledger_category=0,
group_by_ledger_category_strict_membership=0,
group_by_payment_request=0,
group_by_payment_request_category=0,
group_by_payment_request_category_strict_membership=0,
......@@ -653,6 +658,7 @@ class SimulationTool(BaseTool):
column_value_dict.set('payment_uid', payment_uid)
column_value_dict.set('project_uid', project_uid)
column_value_dict.set('funding_uid', funding_uid)
column_value_dict.set('ledger_uid', ledger_uid)
column_value_dict.set('payment_request_uid', payment_request_uid)
column_value_dict.set('function_uid', function_uid)
column_value_dict.set('section_uid', section_uid)
......@@ -665,6 +671,7 @@ class SimulationTool(BaseTool):
column_value_dict.setUIDList('payment_uid', payment)
column_value_dict.setUIDList('project_uid', project)
column_value_dict.setUIDList('funding_uid', funding)
column_value_dict.setUIDList('ledger_uid', ledger)
column_value_dict.setUIDList('payment_request_uid', payment_request)
column_value_dict.setUIDList('function_uid', function)
......@@ -684,6 +691,7 @@ class SimulationTool(BaseTool):
related_key_dict.setUIDList('node_category_uid', node_category)
related_key_dict.setUIDList('project_category_uid', project_category)
related_key_dict.setUIDList('funding_category_uid', funding_category)
related_key_dict.setUIDList('ledger_category_uid', ledger_category)
related_key_dict.setUIDList('payment_request_category_uid', payment_request_category)
related_key_dict.setUIDList('function_category_uid', function_category)
related_key_dict.setUIDList('payment_category_uid', payment_category)
......@@ -699,6 +707,8 @@ class SimulationTool(BaseTool):
project_category_strict_membership)
related_key_dict.setUIDList('funding_category_strict_membership_uid',
funding_category_strict_membership)
related_key_dict.setUIDList('ledger_category_strict_membership_uid',
ledger_category_strict_membership)
related_key_dict.setUIDList('payment_request_category_strict_membership_uid',
payment_request_category_strict_membership)
related_key_dict.setUIDList('function_category_strict_membership_uid',
......@@ -741,6 +751,8 @@ class SimulationTool(BaseTool):
group_by_project = 1
elif value == 'funding_uid':
group_by_funding = 1
elif value == 'ledger_uid':
group_by_ledger = 1
elif value == 'payment_request_uid':
group_by_payment_request = 1
elif value == "function_uid":
......@@ -839,6 +851,8 @@ class SimulationTool(BaseTool):
column_group_by_expression_list.append('project_uid')
if group_by_funding:
column_group_by_expression_list.append('funding_uid')
if group_by_ledger:
column_group_by_expression_list.append('ledger_uid')
if group_by_payment_request:
column_group_by_expression_list.append('payment_request_uid')
if group_by_function:
......@@ -912,6 +926,14 @@ class SimulationTool(BaseTool):
'funding_category_strict_membership_uid')
related_key_select_expression_list.append(
'funding_category_strict_membership_uid')
if group_by_ledger_category:
related_key_group_by_expression_list.append('ledger_category_uid')
related_key_select_expression_list.append('ledger_category_uid')
if group_by_ledger_category_strict_membership:
related_key_group_by_expression_list.append(
'ledger_category_strict_membership_uid')
related_key_select_expression_list.append(
'ledger_category_strict_membership_uid')
if group_by_payment_category:
related_key_group_by_expression_list.append('payment_request_category_uid')
related_key_select_expression_list.append('payment_request_category_uid')
......@@ -1131,7 +1153,7 @@ class SimulationTool(BaseTool):
group_by_node=0, group_by_mirror_node=0,
group_by_section=0, group_by_mirror_section=0,
group_by_payment=0, group_by_project=0, group_by_funding=0,
group_by_function=0,
group_by_ledger=0, group_by_function=0,
group_by_variation=0, group_by_sub_variation=0,
group_by_movement=0, group_by_date=0,
group_by_section_category=0,
......@@ -1158,8 +1180,8 @@ class SimulationTool(BaseTool):
new_group_by_dict = {}
if not ignore_group_by and group_by is None:
if group_by_node or group_by_mirror_node or group_by_section or \
group_by_project or group_by_funding or group_by_function or \
group_by_mirror_section or group_by_payment or \
group_by_project or group_by_funding or group_by_ledger or \
group_by_function or 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:
......
......@@ -24,6 +24,7 @@ WHERE
getDestinationFunctionUid[loop_item],
getDestinationProjectUid[loop_item],
getDestinationFundingUid[loop_item],
getLedgerUid[loop_item],
getDestinationPaymentRequestUid[loop_item],
getSourceSectionUid[loop_item],
getSourceUid[loop_item],
......@@ -51,6 +52,7 @@ WHERE
getSourceFunctionUid[loop_item],
getSourceProjectUid[loop_item],
getSourceFundingUid[loop_item],
getLedgerUid[loop_item],
getSourcePaymentRequestUid[loop_item],
getDestinationSectionUid[loop_item],
getDestinationUid[loop_item],
......@@ -84,6 +86,7 @@ REPLACE INTO
`function_uid`,
`project_uid`,
`funding_uid`,
`ledger_uid`,
`payment_request_uid`,
`mirror_section_uid`,
`mirror_node_uid`,
......@@ -114,19 +117,20 @@ VALUES
<dtml-sqlvar expr="row_item[9]" type="int" optional>,
<dtml-sqlvar expr="row_item[10]" type="int" optional>,
<dtml-sqlvar expr="row_item[11]" type="int" optional>,
<dtml-sqlvar expr="row_item[12]" type="int">,
<dtml-sqlvar expr="row_item[13]" type="float" optional>,
<dtml-sqlvar expr="row_item[14]" type="int">,
<dtml-sqlvar expr="row_item[12]" type="int" optional>,
<dtml-sqlvar expr="row_item[13]" type="int">,
<dtml-sqlvar expr="row_item[14]" type="float" optional>,
<dtml-sqlvar expr="row_item[15]" type="int">,
<dtml-sqlvar expr="row_item[16]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[16]" type="int">,
<dtml-sqlvar expr="row_item[17]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[18]" type="float" optional>,
<dtml-sqlvar expr="row_item[19]" type="string" optional>,
<dtml-sqlvar expr="row_item[18]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[19]" type="float" optional>,
<dtml-sqlvar expr="row_item[20]" type="string" optional>,
<dtml-sqlvar expr="row_item[21]" type="string" optional>,
<dtml-sqlvar expr="row_item[22]" type="string" optional>
<dtml-sqlvar expr="row_item[22]" type="string" optional>,
<dtml-sqlvar expr="row_item[23]" type="string" optional>
)
<dtml-if sequence-end><dtml-else>,</dtml-if>
</dtml-in>
</dtml-if>
</dtml-let>
\ No newline at end of file
</dtml-let>
......@@ -33,6 +33,7 @@ getSourceProjectUid\r\n
getDestinationProjectUid\r\n
getSourceFundingUid\r\n
getDestinationFundingUid\r\n
getLedgerUid\r\n
getSourcePaymentRequestUid\r\n
getDestinationPaymentRequestUid\r\n
getSimulationState\r\n
......
......@@ -12,6 +12,7 @@
getDestinationFunctionUid[loop_item],
getDestinationProjectUid[loop_item],
getDestinationFundingUid[loop_item],
getLedgerUid[loop_item],
getDestinationPaymentRequestUid[loop_item],
getSourceSectionUid[loop_item],
getSourceUid[loop_item],
......@@ -38,6 +39,7 @@
getSourceFunctionUid[loop_item],
getSourceProjectUid[loop_item],
getSourceFundingUid[loop_item],
getLedgerUid[loop_item],
getSourcePaymentRequestUid[loop_item],
getDestinationSectionUid[loop_item],
getDestinationUid[loop_item],
......@@ -73,17 +75,18 @@ VALUES
<dtml-sqlvar expr="row_item[9]" type="int" optional>,
<dtml-sqlvar expr="row_item[10]" type="int" optional>,
<dtml-sqlvar expr="row_item[11]" type="int" optional>,
<dtml-sqlvar expr="row_item[12]" type="int">,
<dtml-sqlvar expr="row_item[13]" type="float" optional>,
<dtml-sqlvar expr="row_item[14]" type="int">,
<dtml-sqlvar expr="row_item[15]" type="int">,
<dtml-sqlvar expr="row_item[16]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[12]" type="int" optional>,
<dtml-sqlvar expr="row_item[13]" type="int">,
<dtml-sqlvar expr="row_item[14]" type="float" optional>,
<dtml-sqlvar expr="row_item[15]" type="int">,
<dtml-sqlvar expr="row_item[16]" type="int">,
<dtml-sqlvar expr="row_item[17]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[18]" type="float" optional>,
<dtml-sqlvar expr="row_item[19]" type="string" optional>,
<dtml-sqlvar expr="row_item[18]" type="datetime" optional>,
<dtml-sqlvar expr="row_item[19]" type="float" optional>,
<dtml-sqlvar expr="row_item[20]" type="string" optional>,
<dtml-sqlvar expr="row_item[21]" type="string" optional>,
<dtml-sqlvar expr="row_item[22]" type="string" optional>
<dtml-sqlvar expr="row_item[22]" type="string" optional>,
<dtml-sqlvar expr="row_item[23]" type="string" optional>
)
<dtml-if sequence-end><dtml-else>,</dtml-if>
</dtml-in>
......
......@@ -29,6 +29,7 @@ getSourceProjectUid\r\n
getDestinationProjectUid\r\n
getSourceFundingUid\r\n
getDestinationFundingUid\r\n
getLedgerUid\r\n
getSourcePaymentRequestUid\r\n
getDestinationPaymentRequestUid\r\n
getSimulationState\r\n
......
......@@ -12,6 +12,7 @@ CREATE TABLE `stock` (
`function_uid` BIGINT UNSIGNED,
`project_uid` BIGINT UNSIGNED,
`funding_uid` BIGINT UNSIGNED,
`ledger_uid` BIGINT UNSIGNED,
`payment_request_uid` BIGINT UNSIGNED,
`mirror_section_uid` BIGINT UNSIGNED,
`mirror_node_uid` BIGINT UNSIGNED,
......@@ -34,6 +35,7 @@ CREATE TABLE `stock` (
KEY `node_uid` (`node_uid`),
KEY `payment_uid` (`payment_uid`),
KEY `function_uid` (`function_uid`),
KEY `ledger_uid` (`ledger_uid`),
  • For now I would suggest we do not add index and wait to see which index is needed when we have some example of slow queries.

    /cc @vpelletier

  • This index is incorrect (as are many indexes in ERP5 catalog anyway): alone, this column will not be enough to narrow a row set down enough to get decent performance. So an index involving ledger_uid will have to involve more columns too.

    I wonder if ledger functionality will have a large enough impact on performance that it should be benchmarked and indexes adjusted before entering master: once ledger is really used (and by that I mean the code is installed and more than one ledger exist and there is an order of magnitude at least in number of documents per ledger), it becomes the dominant condition when queries run on the more synthetic ledger. So just pushing the change like this poses the risk of more than one project starting to really use ledger.

    I think that, due to its nature, all indexes will have to be prefixed with ledger_uid column - but maybe the old indexes will have to coexist as well, if MySQL is not smart enough to do a scan on the first index level when the condition does not get passed (for whetever reason).

    @Nicolas : Do you have an instance you can test on with ledger actually enabled & used before pushing this to master ? To be representative, it will need to have at least hundreds of thousands of rows candidates for a query with one ledger, an tens of thousands for the other ledger, and in both cases only a small fraction of rows (less than one thousand) needed for a real report. Then you'll have to intercept queries (either as they execute, or in slow query log), check the number of rows they scanned. It must be within less than an order of magnitude of the number of rows needed for the report, after discounting row counts comming from joins, and checking that joins are only here to retrieve additional columns, and not restrict result set.

  • I can make benchmarks on a clone instance of a project to see if it worths it. For the moment, I will patch this commit to remove the index. If the generation of accounting reports in the instance gets far more slower, then I'll study what I can improve to fix it.

Please register or sign in to reply
KEY `payment_request_uid` (`payment_request_uid`),
KEY `project_uid` (`project_uid`),
KEY `funding_uid` (`funding_uid`),
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>table_0</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_related_ledger_uid_from_stock</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>table_0</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_related_strict_membership_ledger_uid_from_stock</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -41,6 +41,8 @@
<key>stock_function_category_uid | category/category_uid/z_related_function_uid_from_stock</key>
<key>stock_funding_category_strict_membership_uid | category/category_uid/z_related_strict_membership_funding_uid_from_stock</key>
<key>stock_funding_category_uid | category/category_uid/z_related_funding_uid_from_stock</key>
<key>stock_ledger_category_strict_membership_uid | category/category_uid/z_related_strict_membership_ledger_uid_from_stock</key>
<key>stock_ledger_category_uid | category/category_uid/z_related_ledger_uid_from_stock</key>
<key>stock_mirror_section_category_strict_membership_uid | category/category_uid/z_related_strict_membership_mirror_section_uid_from_stock</key>
<key>stock_mirror_section_category_uid | category/category_uid/z_related_mirror_section_uid_from_stock</key>
<key>stock_mirror_section_title | catalog/title/z_related_mirror_section_uid_from_stock</key>
......
......@@ -86,6 +86,7 @@ erp5_mysql_innodb/z_related_explanation_translated_portal_type_from_stock
erp5_mysql_innodb/z_related_function_uid_from_stock
erp5_mysql_innodb/z_related_funding_uid_from_stock
erp5_mysql_innodb/z_related_grand_parent
erp5_mysql_innodb/z_related_ledger_uid_from_stock
erp5_mysql_innodb/z_related_metric_type
erp5_mysql_innodb/z_related_mirror_section_uid_from_stock
erp5_mysql_innodb/z_related_node_uid_from_item
......@@ -106,6 +107,7 @@ erp5_mysql_innodb/z_related_section_uid_from_item
erp5_mysql_innodb/z_related_section_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_function_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_funding_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_ledger_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_mirror_section_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_node_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_payment_request_uid_from_stock
......
......@@ -66,6 +66,8 @@ children_reference | catalog/reference/z_related_children
related_resource_from_use_category_uid | category,category/category_uid/z_related_resource_from_use
stock_funding_category_strict_membership_uid | category/category_uid/z_related_strict_membership_funding_uid_from_stock
stock_funding_category_uid | category/category_uid/z_related_funding_uid_from_stock
stock_ledger_category_strict_membership_uid | category/category_uid/z_related_strict_membership_ledger_uid_from_stock
stock_ledger_category_uid | category/category_uid/z_related_ledger_uid_from_stock
stock_payment_request_category_strict_membership_uid | category/category_uid/z_related_strict_membership_payment_request_uid_from_stock
stock_payment_request_category_uid | category/category_uid/z_related_payment_request_uid_from_stock
stock_explanation_portal_type | catalog/portal_type/z_related_explanation_from_stock
......
......@@ -174,6 +174,9 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'use/use2',
'function/function1',
'function/function1/function2',
'ledger/accounting',
'ledger/accounting/detailled',
Please register or sign in to reply
'ledger/accounting/general',
# we create a huge group category for consolidation tests
) + self.GROUP_CATEGORIES + self.VARIATION_CATEGORIES
......@@ -463,6 +466,47 @@ class TestInventory(InventoryAPITestCase):
self.assertInventoryEquals(100,
funding_category_strict_membership='function/function1/function2')
def test_Ledger(self):
"""Tests inventory on ledger"""
self._makeMovement(quantity=100, source_value=None,
ledger='accounting/general')
self._makeMovement(quantity=50, source_value=None,
ledger='accounting/detailled')
self.assertInventoryEquals(100, ledger='ledger/accounting/general')
self.assertInventoryEquals(50, ledger='ledger/accounting/detailled')
self.assertInventoryEquals(150, ledger=['ledger/accounting/general',
'ledger/accounting/detailled'])
def test_LedgerUid(self):
"""Tests inventory on ledger uid"""
ledger = self.portal.portal_categories.ledger
self._makeMovement(quantity=100, source_value=None,
ledger='accounting/general')
self.assertInventoryEquals(100,
ledger_uid=ledger.accounting.general.getUid())
self.assertInventoryEquals(0,
ledger_uid=ledger.accounting.detailled.getUid())
def test_LedgerCategory(self):
"""Tests inventory on ledger category"""
self._makeMovement(quantity=100, source_value=None,
ledger='accounting/general')
self.assertInventoryEquals(100, ledger_category='ledger/accounting')
self.assertInventoryEquals(100, ledger='ledger/accounting/general')
def test_LedgerCategoryStrictMembership(self):
"""Tests inventory on ledger category strict membership"""
self._makeMovement(quantity=100, source_value=None,
ledger='accounting/general')
self.assertInventoryEquals(0,
ledger_category_strict_membership='ledger/accounting')
self.assertInventoryEquals(100,
ledger_category_strict_membership='ledger/accounting/general')
def test_PaymentRequest(self):
"""Tests inventory on payment_request"""
self._makeMovement(quantity=30, destination_payment_request='function/function1')
......@@ -1034,6 +1078,23 @@ class TestInventoryList(InventoryAPITestCase):
self.assertEqual([r for r in inventory_list if r.funding_uid ==
funding2.getUid()][0].inventory, 3)
def test_GroupByLedger(self):
getInventoryList = self.getSimulationTool().getInventoryList
ledger = self.portal.portal_categories.ledger
self._makeMovement(ledger='accounting/general', quantity=100)
self._makeMovement(ledger='accounting/general', quantity=30)
self._makeMovement(ledger='accounting/detailled', quantity=70)
inventory_list = getInventoryList(node_uid=self.node.getUid(),
group_by_ledger=1)
self.assertEqual(2, len(inventory_list))
self.assertEqual([r for r in inventory_list if r.ledger_uid ==
ledger.accounting.general.getUid()][0].inventory, 130)
self.assertEqual([r for r in inventory_list if r.ledger_uid ==
ledger.accounting.detailled.getUid()][0].inventory, 70)
def test_GroupByPaymentRequest(self):
getInventoryList = self.getSimulationTool().getInventoryList
payment_request1 = self.portal.portal_categories.restrictedTraverse(
......@@ -1558,6 +1619,7 @@ class TestMovementHistoryList(InventoryAPITestCase):
self.assertTrue(hasattr(brain, 'payment_uid'))
self.assertTrue(hasattr(brain, 'project_uid'))
self.assertTrue(hasattr(brain, 'funding_uid'))
self.assertTrue(hasattr(brain, 'ledger_uid'))
self.assertTrue(hasattr(brain, 'mirror_node_uid'))
self.assertTrue(hasattr(brain, 'mirror_section_uid'))
......@@ -1765,6 +1827,31 @@ class TestMovementHistoryList(InventoryAPITestCase):
section_category=section_category)
self.assertEqual(len(movement_history_list), 0)
def testLedger(self):
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
ledger = self.portal.portal_categories.ledger
mvt = self._makeMovement(quantity=100, ledger="accounting/general")
another_mvt = self._makeMovement(quantity=50, ledger="accounting/detailled")
# first ledger
mvt_history_list = getMovementHistoryList(
node_uid=self.node.getUid(),
ledger_uid=ledger.accounting.general.getUid())
self.assertEqual(1, len(mvt_history_list))
self.assertEqual(100, mvt_history_list[0].total_quantity)
# second ledger
mvt_history_list = getMovementHistoryList(
node_uid=self.node.getUid(),
ledger_uid=ledger.accounting.detailled.getUid())
self.assertEqual(1, len(mvt_history_list))
self.assertEqual(50, mvt_history_list[0].total_quantity)
# non existing ledger
self.assertEqual(0, len(getMovementHistoryList(
ledger_uid = self.node.getUid())))
# Date tests:
# ===========
......
  • mentioned in commit 473f74af

    Toggle commit list
  • Another thing, now that we have proper support for ledger_uid in inventory API, we should remove parent_ledger_relative_url related key and change Research Item Report to use ledger_uid.

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