def test_edit_submissions_simple(self): initial_quantity = 100 form = submit_case_blocks( case_blocks=get_single_balance_block(quantity=initial_quantity, **self._stock_state_key), domain=self.domain, )[0] self._assert_stats(1, initial_quantity, initial_quantity) case_accessors = CaseAccessors(self.domain) case = case_accessors.get_case(self.case.case_id) try: self.assertTrue(any([action.is_ledger_transaction for action in case.actions])) except AttributeError: self.assertTrue('commtrack' in [action.action_type for action in case.actions]) self.assertEqual([form.form_id], case.xform_ids[1:]) # change the value to 50 edit_quantity = 50 submit_case_blocks( case_blocks=get_single_balance_block(quantity=edit_quantity, **self._stock_state_key), domain=self.domain, form_id=form.form_id, ) case = case_accessors.get_case(self.case.case_id) try: # CaseTransaction self.assertTrue(any([action.is_ledger_transaction for action in case.actions])) except AttributeError: # CaseAction self.assertTrue('commtrack' in [action.action_type for action in case.actions]) self._assert_stats(1, edit_quantity, edit_quantity) self.assertEqual([form.form_id], case.xform_ids[1:])
def test_edit_submissions_simple(self): initial_quantity = 100 form_id = submit_case_blocks( case_blocks=get_single_balance_block(quantity=initial_quantity, **self._stock_state_key), domain=self.domain, ) stock_state, latest_txn, all_txns = self._get_stats() self.assertEqual(stock_state.stock_on_hand, initial_quantity) self.assertEqual(latest_txn.stock_on_hand, initial_quantity) self.assertEqual(all_txns.count(), 1) case = CommCareCase.get(id=self.case.case_id) self.assertEqual(1, len(case.actions)) self.assertEqual([form_id], case.xform_ids) # change the value to 50 edit_quantity = 50 submit_case_blocks( case_blocks=get_single_balance_block(quantity=edit_quantity, **self._stock_state_key), domain=self.domain, form_id=form_id, ) case = CommCareCase.get(id=self.case.case_id) self.assertEqual(1, len(case.actions)) stock_state, latest_txn, all_txns = self._get_stats() self.assertEqual(stock_state.stock_on_hand, edit_quantity) self.assertEqual(latest_txn.stock_on_hand, edit_quantity) self.assertEqual(all_txns.count(), 1) self.assertEqual([form_id], case.xform_ids)
def test_edit_submissions_simple(self): initial_quantity = 100 form = submit_case_blocks( case_blocks=get_single_balance_block(quantity=initial_quantity, **self._stock_state_key), domain=self.domain, )[0] self._assert_stats(1, initial_quantity, initial_quantity) case_accessors = CaseAccessors(self.domain) case = case_accessors.get_case(self.case.case_id) try: self.assertTrue(any([action.is_ledger_transaction for action in case.actions])) except AttributeError: self.assertTrue('commtrack' in [action.action_type for action in case.actions]) self.assertEqual([form.form_id], case.xform_ids[1:]) # change the value to 50 edit_quantity = 50 submit_case_blocks( case_blocks=get_single_balance_block(quantity=edit_quantity, **self._stock_state_key), domain=self.domain, form_id=form.form_id, ) case = case_accessors.get_case(self.case.case_id) try: # CaseTransaction self.assertTrue(any([action.is_ledger_transaction for action in case.actions])) except AttributeError: # CaseAction self.assertTrue('commtrack' in [action.action_type for action in case.actions]) self._assert_stats(1, edit_quantity, edit_quantity) self.assertEqual([form.form_id], case.xform_ids[1:])
def test_error_reprocessing_ledgers_after_borked_save(self): from corehq.apps.commtrack.tests.util import get_single_balance_block form_id, case_id, product_id = uuid.uuid4().hex, uuid.uuid4( ).hex, uuid.uuid4().hex # setup by creating the case submit_case_blocks([CaseBlock(case_id=case_id, create=True).as_text()], self.domain) # submit a form that updates the case and ledger submit_case_blocks([ CaseBlock(case_id=case_id, update={ 'a': "1" }).as_text(), get_single_balance_block(case_id, product_id, 100), ], self.domain, form_id=form_id) # simulate an error by deleting the form XML form = XFormInstance.objects.get_form(form_id) form.get_attachment_meta('form.xml').delete() # re-submit the form again submit_case_blocks([ CaseBlock(case_id=case_id, update={ 'a': "1" }).as_text(), get_single_balance_block(case_id, product_id, 100), ], self.domain, form_id=form_id) form = XFormInstance.objects.get_form(form_id) self.assertTrue(form.is_normal)
def test_two_ledger(self): from corehq.apps.commtrack.tests.util import get_single_balance_block self._submit_ledgers([ get_single_balance_block(self.case_one.case_id, self.product_a._id, 1), get_single_balance_block(self.case_two.case_id, self.product_a._id, 3), ]) self._check_result([{'entry_id': self.product_a._id, 'balance': 4}])
def test_reprocess_unfinished_submission_ledger_rebuild(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex form_ids = [] form_ids.append( submit_case_blocks([ CaseBlock(case_id=case_id, create=True, case_type='shop').as_text(), get_single_balance_block(case_id, 'product1', 100), ], self.domain)[0].form_id) with _patch_save_to_raise_error(self): submit_case_blocks( get_single_balance_block(case_id, 'product1', 50), self.domain) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) form_ids.append(stubs[0].xform_id) # submit another form afterwards form_ids.append( submit_case_blocks( get_single_balance_block(case_id, 'product1', 25), self.domain)[0].form_id) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) self.assertEqual(25, ledgers[0].balance) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case( case_id) self.assertEqual(2, len(ledger_transactions)) # should rebuild ledger transactions result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(1, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) # still only 1 self.assertEqual(25, ledgers[0].balance) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case( case_id) self.assertEqual(3, len(ledger_transactions)) # make sure transactions are in correct order self.assertEqual(form_ids, [trans.form_id for trans in ledger_transactions]) self.assertEqual(100, ledger_transactions[0].updated_balance) self.assertEqual(100, ledger_transactions[0].delta) self.assertEqual(50, ledger_transactions[1].updated_balance) self.assertEqual(-50, ledger_transactions[1].delta) self.assertEqual(25, ledger_transactions[2].updated_balance) self.assertEqual(-25, ledger_transactions[2].delta)
def test_ledger_pillow(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() consumer = get_test_kafka_consumer(topics.LEDGER) # have to get the seq id before the change is processed kafka_seq = get_topic_offset(topics.LEDGER) from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks([ get_single_balance_block(case.case_id, self.product_id, 100)], self.domain ) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) # confirm change made it to kafka message = consumer.next() change_meta = change_meta_from_kafka_message(message.value) if should_use_sql_backend(self.domain): self.assertEqual(ref.as_id(), change_meta.document_id) else: from corehq.apps.commtrack.models import StockState state = StockState.objects.all() self.assertEqual(1, len(state)) self.assertEqual(state[0].pk, change_meta.document_id) # self.assertEqual(self.domain, change_meta.domain) # send to elasticsearch self.pillow.process_changes(since=kafka_seq, forever=False) self.elasticsearch.indices.refresh(LEDGER_INDEX_INFO.index) # confirm change made it to elasticserach self._assert_ledger_in_es(ref)
def test_get_ledger_values_for_case_as_of_same_date(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # submit two transfers at the same time transfer_date = json_format_datetime(datetime.utcnow()) transfers = [ (self.product_a._id, 1, transfer_date), (self.product_a._id, 2, transfer_date), ] for prod_id, transfer, date in transfers: submit_case_blocks(get_single_transfer_block(case_id, None, prod_id, transfer, date), self.domain) # check results results = get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(1, len(results)) self.assertEqual(97, results[self.product_a._id])
def test_get_ledger_values_for_case_as_of(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), (self.product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # check results results = get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(2, len(results)) self.assertEqual(100, results[self.product_a._id]) self.assertEqual(50, results[self.product_b._id]) # check the date filter works before_data = datetime.utcnow() - timedelta(days=2) self.assertEqual({}, get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=before_data))
def test_get_document_archived(self): from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.commtrack.models import StockState from corehq.apps.products.models import SQLProduct block = get_single_balance_block(self.case.case_id, self.product_a._id, 100) submit_case_blocks(block, DOMAIN) stock_states = StockState.include_archived.all() self.assertEquals(1, len(stock_states)) def toggle_product_archive(): sql_product = SQLProduct.objects.get(code=self.product_a.code) sql_product.is_archived = not sql_product.is_archived sql_product.save() toggle_product_archive() self.addCleanup(toggle_product_archive) self.assertTrue(SQLProduct.objects.get(code=self.product_a.code).is_archived) state = stock_states[0] store = LedgerV1DocumentStore(DOMAIN) doc = store.get_document(state.id) self.assertEquals(int(doc['_id']), state.id) self.assertEquals(doc['case_id'], state.case_id)
def test_edit_form_that_removes_ledgers(self): from corehq.apps.commtrack.tests.util import get_single_balance_block form_id = uuid.uuid4().hex submit_case_blocks([ get_single_balance_block(self.case.case_id, self.product_a._id, 100)], DOMAIN, form_id=form_id ) self._assert_ledger_state(100) transactions = CaseAccessorSQL.get_transactions(self.case.case_id) self.assertEqual(2, len(transactions)) self.assertTrue(transactions[0].is_form_transaction) self.assertTrue(transactions[1].is_form_transaction) self.assertTrue(transactions[1].is_ledger_transaction) submit_case_blocks([ CaseBlock(case_id=self.case.case_id).as_string().decode('utf-8')], DOMAIN, form_id=form_id ) self._assert_ledger_state(0) transactions = CaseAccessorSQL.get_transactions(self.case.case_id) self.assertEqual(3, len(transactions)) self.assertTrue(transactions[0].is_form_transaction) # ordering not guaranteed since they have the same date self.assertTrue(transactions[1].is_form_transaction) self.assertFalse(transactions[1].is_ledger_transaction) # no longer a ledger transaction self.assertTrue(transactions[2].is_case_rebuild) self._assert_transactions([])
def test_balance_submission_multiple(self): from corehq.apps.commtrack.tests.util import get_single_balance_block balances = { self.product_a._id: 100, self.product_b._id: 50, self.product_c._id: 25, } self._submit_ledgers([ get_single_balance_block(self.case.case_id, prod_id, balance) for prod_id, balance in balances.items() ]) expected_transactions = [] for prod_id, expected_balance in balances.items(): expected_transactions.append(self._expected_val( expected_balance, expected_balance, product_id=prod_id )) balance = self.interface.ledger_db.get_current_ledger_value( UniqueLedgerReference( case_id=self.case.case_id, section_id='stock', entry_id=prod_id )) self.assertEqual(expected_balance, balance) self._assert_transactions(expected_transactions, ignore_ordering=True)
def test_get_ledger_values_for_case_as_of(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), (self.product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # check results results = get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(2, len(results)) self.assertEqual(100, results[self.product_a._id]) self.assertEqual(50, results[self.product_b._id]) # check the date filter works before_data = datetime.utcnow() - timedelta(days=2) self.assertEqual({}, get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=before_data))
def test_get_ledger_values_for_case_as_of_same_date(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ((self.product_a._id, 100), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # submit two transfers at the same time transfer_date = json_format_datetime(datetime.utcnow()) transfers = [ (self.product_a._id, 1, transfer_date), (self.product_a._id, 2, transfer_date), ] for prod_id, transfer, date in transfers: submit_case_blocks( get_single_transfer_block(case_id, None, prod_id, transfer, date), self.domain) # check results results = get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(1, len(results)) self.assertEqual(97, results[self.product_a._id])
def test_blank_case_id_in_balance(self): instance_id = submit_case_blocks( case_blocks=get_single_balance_block(case_id="", product_id=self.products[0]._id, quantity=100), domain=self.domain.name, ) instance = XFormInstance.get(instance_id) self.assertEqual("XFormError", instance.doc_type) self.assertTrue("IllegalCaseId" in instance.problem)
def test_blank_case_id_in_balance(self): form = submit_case_blocks( case_blocks=get_single_balance_block(case_id='', product_id=self.products[0]._id, quantity=100), domain=self.domain.name, ) instance = FormAccessors(self.domain.name).get_form(form.form_id) self.assertTrue(instance.is_error) self.assertTrue('IllegalCaseId' in instance.problem)
def setUpClass(cls): super(ImmunizationUtilTestCase, cls).setUpClass() cls.ccs_record = cls.create_case('ccs_record', update={'edd': '2017-08-01'}) cls.tasks_pregnancy = cls.create_case( 'tasks', parent_case_id=cls.ccs_record.case_id, parent_case_type='ccs_record', parent_identifier='parent', parent_relationship='extension', update={ 'tasks_type': 'pregnancy', 'schedule_flag': 'tt_norm' }) cls.person_child = cls.create_case('person', update={'dob': '2017-08-10'}) cls.child_health = cls.create_case( 'child_health', parent_case_id=cls.person_child.case_id, parent_case_type='person', parent_identifier='parent', parent_relationship='extension') cls.tasks_child = cls.create_case( 'tasks', parent_case_id=cls.child_health.case_id, parent_case_type='child_health', parent_identifier='parent', parent_relationship='extension', update={'tasks_type': 'child'}) cls.lone_tasks_case = cls.create_case('tasks', update={'tasks_type': 'child'}) cls.dpt2 = cls.create_product('2g_dpt_2', 'child', '70', '730', '1g_dpt_1', '28') cls.dpt3 = cls.create_product('3g_dpt_3', 'child', '98', '730', '2g_dpt_2', '28') cls.tt1 = cls.create_product('tt_1', 'pregnancy', '-274', '180', schedule_flag='tt_norm') cls.ttbooster = cls.create_product('tt_booster', 'pregnancy', '-1096', '180', schedule_flag='tt_boost') cls.anc1 = cls.create_product('anc_1', 'pregnancy', '-274', '180') cls.anc2 = cls.create_product('anc_2', 'pregnancy', '-274', '180', 'anc_1', '30') submit_case_blocks( get_single_balance_block(cls.lone_tasks_case.case_id, cls.dpt2.get_id, 17400, section_id='immuns'), cls.domain)
def test_blank_case_id_in_balance(self): form = submit_case_blocks( case_blocks=get_single_balance_block( case_id='', product_id=self.products[0]._id, quantity=100), domain=self.domain.name, ) instance = FormAccessors(self.domain.name).get_form(form.form_id) self.assertTrue(instance.is_error) self.assertTrue('IllegalCaseId' in instance.problem)
def _stock_report(domain, case_id, product_id, amount, days_ago): from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks from dimagi.utils.parsing import json_format_date date_string = json_format_date(ago(days_ago)) stock_block = get_single_balance_block( case_id=case_id, product_id=product_id, quantity=amount, date_string=date_string ) submit_case_blocks(stock_block, domain=domain)
def _stock_report(domain, case_id, product_id, amount, days_ago): from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks from dimagi.utils.parsing import json_format_date date_string = json_format_date(ago(days_ago)) stock_block = get_single_balance_block( case_id=case_id, product_id=product_id, quantity=amount, date_string=date_string ) submit_case_blocks(stock_block, domain=domain)
def test_blank_case_id_in_balance(self): form = submit_case_blocks( case_blocks=util.get_single_balance_block( case_id='', product_id=self.products[0]._id, quantity=100), domain=self.domain.name, )[0] self.addCleanup(self.delete_ledger_transactions, form.form_id) instance = XFormInstance.objects.get_form(form.form_id, self.domain.name) self.assertTrue(instance.is_error) self.assertTrue('IllegalCaseId' in instance.problem)
def test_reprocess_unfinished_submission_ledger_create(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex self.factory.create_or_update_cases([ CaseStructure(case_id=case_id, attrs={ 'case_type': 'parent', 'create': True }) ]) transaction_patch = patch( 'corehq.form_processor.backends.sql.processor.transaction') ledger_save_patch = patch( 'corehq.form_processor.backends.sql.dbaccessors.LedgerAccessorSQL.save_ledger_values', side_effect=InternalError) with transaction_patch, ledger_save_patch, self.assertRaises( InternalError): submit_case_blocks( get_single_balance_block(case_id, 'product1', 100), self.domain) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id) self.assertEqual(0, len(ledgers)) # case transaction got saved case = CaseAccessorSQL.get_case(case_id) self.assertEqual(2, len(case.transactions)) self.assertTrue(case.transactions[0].is_case_create) self.assertTrue(case.transactions[1].is_ledger_transaction) ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case( case_id) self.assertEqual(0, len(ledger_transactions)) result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(0, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case( case_id) self.assertEqual(1, len(ledger_transactions)) # case still only has 2 transactions case = CaseAccessorSQL.get_case(case_id) self.assertEqual(2, len(case.transactions))
def test_get_document(self): from corehq.apps.commtrack.tests.util import get_single_balance_block block = get_single_balance_block(self.case.case_id, self.product_a._id, 100) submit_case_blocks(block, DOMAIN) from corehq.apps.commtrack.models import StockState stock_states = StockState.include_archived.all() self.assertEquals(1, len(stock_states)) state = stock_states[0] store = LedgerV1DocumentStore(DOMAIN) doc = store.get_document(state.id) self.assertEquals(int(doc['_id']), state.id) self.assertEquals(doc['case_id'], state.case_id)
def _report_soh(soh_reports, case_id, domain): report_date = json_format_datetime(datetime.utcnow()) balance_blocks = [ get_single_balance_block(case_id, report.product_id, report.amount, report_date, section_id=report.section_id) for report in soh_reports ] form = submit_case_blocks(balance_blocks, domain) return json_format_datetime( FormAccessors(domain).get_form(form.form_id).received_on)
def setUp(self): super(LedgerAccessorErrorTests, self).setUp() # can't do this in setUpClass until Django 1.9 since @override_settings # doesn't apply to classmethods from corehq.apps.commtrack.tests.util import get_single_balance_block factory = CaseFactory(domain=self.domain) self.case = factory.create_case() submit_case_blocks([ get_single_balance_block(self.case.case_id, self.product._id, 10) ], self.domain) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(self.case.case_id) self.assertEqual(1, len(ledger_values))
def _report_soh(soh_reports, case_id, domain): report_date = json_format_datetime(datetime.utcnow()) balance_blocks = [ util.get_single_balance_block(case_id, report.product_id, report.amount, report_date, section_id=report.section_id) for report in soh_reports ] form = submit_case_blocks(balance_blocks, domain)[0] received_on = json_format_datetime( XFormInstance.objects.get_form(form.form_id, domain).received_on) return form.form_id, received_on
def _report_soh(soh_reports, case_id, domain): report_date = json_format_datetime(datetime.utcnow()) balance_blocks = [ get_single_balance_block( case_id, report.product_id, report.amount, report_date, section_id=report.section_id ) for report in soh_reports ] form = submit_case_blocks(balance_blocks, domain) return json_format_datetime(FormAccessors(domain).get_form(form.form_id).received_on)
def test_ledgers(self): expected_object_counts = Counter({ XFormInstanceSQL: 3, BlobMeta: 3, CommCareCaseSQL: 1, CaseTransaction: 3, LedgerValue: 1, LedgerTransaction: 2 }) case = self.factory.create_case() submit_case_blocks([ get_single_balance_block(case.case_id, self.product._id, 10) ], self.domain_name) submit_case_blocks([ get_single_balance_block(case.case_id, self.product._id, 5) ], self.domain_name) pre_ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(case.case_id) pre_ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(case.case_id) self.assertEqual(1, len(pre_ledger_values)) self.assertEqual(2, len(pre_ledger_transactions)) self._dump_and_load(expected_object_counts) post_ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(case.case_id) post_ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(case.case_id) self.assertEqual(1, len(post_ledger_values)) self.assertEqual(2, len(post_ledger_transactions)) self.assertEqual(pre_ledger_values[0].ledger_reference, post_ledger_values[0].ledger_reference) self.assertDictEqual(pre_ledger_values[0].to_json(), post_ledger_values[0].to_json()) pre_ledger_transactions = sorted(pre_ledger_transactions, key=lambda t: t.pk) post_ledger_transactions = sorted(post_ledger_transactions, key=lambda t: t.pk) for pre, post in zip(pre_ledger_transactions, post_ledger_transactions): self.assertEqual(str(pre), str(post))
def setUpClass(cls): super(StockStatusDataSourceTests, cls).setUpClass() cls.domain = uuid.uuid4().hex cls.project = bootstrap_domain(cls.domain) cls.interface = SupplyInterface(cls.domain) cls.product = make_product(cls.domain, 'A Product', 'prodcode_a') cls.location = make_loc('1234', name='ben', domain=cls.domain) cls.location2 = make_loc('1235', name='ken', domain=cls.domain) cls.supply_point = cls.location.linked_supply_point() submit_case_blocks( [get_single_balance_block(cls.supply_point.case_id, cls.product._id, 50)], cls.domain )
def test_delete_ledger_values_case_section(self): from corehq.apps.commtrack.tests.util import get_single_balance_block form_id = self._submit_ledgers([ get_single_balance_block(self.case_one.case_id, product_id, 10) for product_id in [self.product_a._id, self.product_b._id] ]) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(self.case_one.case_id) self.assertEqual(2, len(ledger_values)) LedgerAccessorSQL.delete_ledger_transactions_for_form([self.case_one.case_id], form_id) deleted = LedgerAccessorSQL.delete_ledger_values(self.case_one.case_id, 'stock') self.assertEqual(2, deleted) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(self.case_one.case_id) self.assertEqual(0, len(ledger_values))
def test_reprocess_unfinished_submission_ledger_create(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex self.factory.create_or_update_cases([ CaseStructure(case_id=case_id, attrs={ 'case_type': 'parent', 'create': True }) ]) with _patch_save_to_raise_error(self): submit_case_blocks( get_single_balance_block(case_id, 'product1', 100), self.domain) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(0, len(ledgers)) case = self.casedb.get_case(case_id) self.assertEqual(1, len(case.xform_ids)) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case( case_id) self.assertEqual(0, len(ledger_transactions)) result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(1, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case( case_id) self.assertEqual(1, len(ledger_transactions)) # case still only has 2 transactions case = self.casedb.get_case(case_id) self.assertEqual(2, len(case.xform_ids)) if should_use_sql_backend(self.domain): self.assertTrue(case.actions[1].is_ledger_transaction)
def test_ledger_reindexer(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks([ get_single_balance_block(case.case_id, self.product_id, 100)], self.domain ) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) index_id = 'ledger-v2' if settings.TESTS_SHOULD_USE_SQL_BACKEND else 'ledger-v1' call_command('ptop_reindexer_v2', index_id, cleanup=True, noinput=True, reset=True) self._assert_ledger_in_es(ref)
def test_delete_ledger_values_case_section(self): from corehq.apps.commtrack.tests.util import get_single_balance_block form_id = self._submit_ledgers([ get_single_balance_block(self.case_one.case_id, product_id, 10) for product_id in [self.product_a._id, self.product_b._id] ]) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case( self.case_one.case_id) self.assertEqual(2, len(ledger_values)) LedgerAccessorSQL.delete_ledger_transactions_for_form( [self.case_one.case_id], form_id) deleted = LedgerAccessorSQL.delete_ledger_values( self.case_one.case_id, 'stock') self.assertEqual(2, deleted) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case( self.case_one.case_id) self.assertEqual(0, len(ledger_values))
def create_docs(cls, domain, count): from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks from corehq.apps.commtrack.helpers import make_product from corehq.form_processor.parsers.ledgers.helpers import UniqueLedgerReference cls.product = make_product(cls.domain, 'A Product', 'prodcode_a') factory = CaseFactory(cls.domain) case_ids = [factory.create_case().case_id for i in range(count)] for case_id in case_ids: submit_case_blocks([ get_single_balance_block(case_id, cls.product._id, 10) ], domain) return [ UniqueLedgerReference(case_id, 'stock', cls.product._id).as_id() for case_id in case_ids ]
def test_duplicate_ledger_published(self): # this test also only runs on the sql backend for reasons described in test_duplicate_case_published # setup products and case product_a = make_product(self.domain, 'A Product', 'prodcode_a') product_b = make_product(self.domain, 'B Product', 'prodcode_b') case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain) # submit ledger data balances = ( (product_a._id, 100), (product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] form = submit_case_blocks(ledger_blocks, self.domain)[0] # submit duplicate with process_pillow_changes(self.ledger_pillow): with process_pillow_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form.get_xml(), domain=self.domain).xform self.assertTrue(dupe_form.is_duplicate) # confirm republished ledger_meta_a = self.processor.changes_seen[0].metadata ledger_meta_b = self.processor.changes_seen[1].metadata format_id = lambda product_id: '{}/{}/{}'.format( case_id, 'stock', product_id) expected_ids = {format_id(product_a._id), format_id(product_b._id)} for meta in [ledger_meta_a, ledger_meta_b]: self.assertTrue(meta.document_id in expected_ids) expected_ids.remove(meta.document_id) self.assertEqual(self.domain, meta.domain) # cleanup product_a.delete() product_b.delete()
def test_delete_ledger_transactions_for_form(self): from corehq.apps.commtrack.tests.util import get_single_balance_block self._set_balance(100, self.case_one.case_id, self.product_a._id) case_ids = [self.case_one.case_id, self.case_two.case_id] form_id = self._submit_ledgers([ get_single_balance_block(case_id, product_id, 10) for case_id in case_ids for product_id in [self.product_a._id, self.product_b._id] ]) deleted = LedgerAccessorSQL.delete_ledger_transactions_for_form(case_ids, form_id) self.assertEqual(4, deleted) self.assertEqual( 1, len(LedgerAccessorSQL.get_ledger_transactions_for_case(self.case_one.case_id)) ) self.assertEqual( 0, len(LedgerAccessorSQL.get_ledger_transactions_for_case(self.case_two.case_id)) )
def test_reprocess_unfinished_submission_ledger_create(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex self.factory.create_or_update_cases([ CaseStructure(case_id=case_id, attrs={'case_type': 'parent', 'create': True}) ]) with _patch_save_to_raise_error(self): submit_case_blocks( get_single_balance_block(case_id, 'product1', 100), self.domain ) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(0, len(ledgers)) case = self.casedb.get_case(case_id) self.assertEqual(1, len(case.xform_ids)) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case(case_id) self.assertEqual(0, len(ledger_transactions)) result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(1, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case(case_id) self.assertEqual(1, len(ledger_transactions)) # case still only has 2 transactions case = self.casedb.get_case(case_id) self.assertEqual(2, len(case.xform_ids)) if should_use_sql_backend(self.domain): self.assertTrue(case.actions[1].is_ledger_transaction)
def test_duplicate_ledger_published(self): # this test also only runs on the sql backend for reasons described in test_duplicate_case_published # setup products and case product_a = make_product(self.domain, 'A Product', 'prodcode_a') product_b = make_product(self.domain, 'B Product', 'prodcode_b') case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (product_a._id, 100), (product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] form = submit_case_blocks(ledger_blocks, self.domain)[0] # submit duplicate with process_kafka_changes(self.ledger_pillow): with process_couch_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form.get_xml(), domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) # confirm republished ledger_meta_a = self.processor.changes_seen[0].metadata ledger_meta_b = self.processor.changes_seen[1].metadata format_id = lambda product_id: '{}/{}/{}'.format(case_id, 'stock', product_id) expected_ids = {format_id(product_a._id), format_id(product_b._id)} for meta in [ledger_meta_a, ledger_meta_b]: self.assertTrue(meta.document_id in expected_ids) expected_ids.remove(meta.document_id) self.assertEqual(self.domain, meta.domain) # cleanup product_a.delete() product_b.delete()
def test_ledger_update_with_case_update(self): from corehq.apps.commtrack.tests.util import get_single_balance_block submit_case_blocks([ CaseBlock(case_id=self.case.case_id, update={'a': "1"}).as_string(), get_single_balance_block(self.case.case_id, self.product_a._id, 100)], DOMAIN ) self._assert_ledger_state(100) case = CaseAccessors(DOMAIN).get_case(self.case.case_id) self.assertEqual("1", case.dynamic_case_properties()['a']) if settings.TESTS_SHOULD_USE_SQL_BACKEND: transactions = CaseAccessorSQL.get_transactions(self.case.case_id) self.assertEqual(2, len(transactions)) self.assertTrue(transactions[0].is_form_transaction) # ordering not guaranteed since they have the same date self.assertTrue(transactions[1].is_form_transaction) self.assertTrue(transactions[1].is_ledger_transaction) self._assert_transactions([ self._expected_val(100, 100), ])
def test_delete_ledger_transactions_for_form(self): from corehq.apps.commtrack.tests.util import get_single_balance_block self._set_balance(100, self.case_one.case_id, self.product_a._id) case_ids = [self.case_one.case_id, self.case_two.case_id] form_id = self._submit_ledgers([ get_single_balance_block(case_id, product_id, 10) for case_id in case_ids for product_id in [self.product_a._id, self.product_b._id] ]) deleted = LedgerAccessorSQL.delete_ledger_transactions_for_form( case_ids, form_id) self.assertEqual(4, deleted) self.assertEqual( 1, len( LedgerAccessorSQL.get_ledger_transactions_for_case( self.case_one.case_id))) self.assertEqual( 0, len( LedgerAccessorSQL.get_ledger_transactions_for_case( self.case_two.case_id)))
def test_reprocess_unfinished_submission_ledger_rebuild(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex form_ids = [] form_ids.append(submit_case_blocks( [ CaseBlock(case_id=case_id, create=True, case_type='shop').as_string().decode('utf-8'), get_single_balance_block(case_id, 'product1', 100), ], self.domain )[0].form_id) with _patch_save_to_raise_error(self): submit_case_blocks( get_single_balance_block(case_id, 'product1', 50), self.domain ) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) form_ids.append(stubs[0].xform_id) # submit another form afterwards form_ids.append(submit_case_blocks( get_single_balance_block(case_id, 'product1', 25), self.domain )[0].form_id) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) self.assertEqual(25, ledgers[0].balance) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case(case_id) if should_use_sql_backend(self.domain): self.assertEqual(2, len(ledger_transactions)) else: # includes extra consumption transaction self.assertEqual(3, len(ledger_transactions)) # should rebuild ledger transactions result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(1, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = self.ledgerdb.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) # still only 1 self.assertEqual(25, ledgers[0].balance) ledger_transactions = self.ledgerdb.get_ledger_transactions_for_case(case_id) if should_use_sql_backend(self.domain): self.assertEqual(3, len(ledger_transactions)) # make sure transactions are in correct order self.assertEqual(form_ids, [trans.form_id for trans in ledger_transactions]) self.assertEqual(100, ledger_transactions[0].updated_balance) self.assertEqual(100, ledger_transactions[0].delta) self.assertEqual(50, ledger_transactions[1].updated_balance) self.assertEqual(-50, ledger_transactions[1].delta) self.assertEqual(25, ledger_transactions[2].updated_balance) self.assertEqual(-25, ledger_transactions[2].delta) else: self.assertEqual(3, len(ledger_transactions)) self.assertEqual(form_ids, [trans.report.form_id for trans in ledger_transactions]) self.assertEqual(100, ledger_transactions[0].stock_on_hand) self.assertEqual(50, ledger_transactions[1].stock_on_hand) self.assertEqual(25, ledger_transactions[2].stock_on_hand)
def _set_balance(self, balance): from corehq.apps.commtrack.tests.util import get_single_balance_block self._submit_ledgers([ get_single_balance_block(self.case.case_id, self.product_a._id, balance) ])
def _set_balance(self, balance, case_id, product_id): from corehq.apps.commtrack.tests.util import get_single_balance_block return self._submit_ledgers( [get_single_balance_block(case_id, product_id, balance)])
def _set_balance(self, balance, case_id, product_id): from corehq.apps.commtrack.tests.util import get_single_balance_block return self._submit_ledgers([ get_single_balance_block(case_id, product_id, balance) ])