Esempio n. 1
0
    def test_archive_only_form(self):
        # check no data in stock states
        ledger_accessors = LedgerAccessors(self.domain.name)
        ledger_values = ledger_accessors.get_ledger_values_for_case(
            self.sp.case_id)
        self.assertEqual(0, len(ledger_values))

        initial_amounts = [(p._id, float(100)) for p in self.products]
        form_id = self.submit_xml_form(balance_submission(initial_amounts))

        # check that we made stuff
        def _assert_initial_state():
            self.assertEqual(
                3, len(self._get_all_ledger_transactions(Q(form_id=form_id))))

            ledger_values = ledger_accessors.get_ledger_values_for_case(
                self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for state in ledger_values:
                self.assertEqual(100, int(state.stock_on_hand))

        _assert_initial_state()

        # archive and confirm commtrack data is cleared
        form = XFormInstance.objects.get_form(form_id, self.domain.name)
        form.archive()
        self.assertEqual(
            0,
            len(ledger_accessors.get_ledger_values_for_case(self.sp.case_id)))
        self.assertEqual(
            0, len(self._get_all_ledger_transactions(Q(form_id=form_id))))

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
Esempio n. 2
0
 def _assert_stats(self, epxected_tx_count, expected_stock_state_balance, expected_tx_balance):
     ledger_value = LedgerAccessors(self.domain).get_ledger_value(**self.unique_reference._asdict())
     latest_txn = LedgerAccessors(self.domain).get_latest_transaction(**self.unique_reference._asdict())
     all_txns = LedgerAccessors(self.domain).get_ledger_transactions_for_case(**self.unique_reference._asdict())
     self.assertEqual(epxected_tx_count, len(all_txns))
     self.assertEqual(expected_stock_state_balance, ledger_value.stock_on_hand)
     self.assertEqual(expected_tx_balance, latest_txn.stock_on_hand)
Esempio n. 3
0
 def test_get_case_ledger_state(self):
     for case_id in self.case_ids:
         state = LedgerAccessors(self.domain).get_case_ledger_state(case_id)
         for section, products in state.items():
             for product, state in products.items():
                 self.assertEqual(
                     state.stock_on_hand,
                     self.transactions[case_id][section][product])
Esempio n. 4
0
    def test_archive_last_form(self):
        initial_amounts = [(p._id, float(100)) for p in self.products]
        self.submit_xml_form(
            balance_submission(initial_amounts),
            timestamp=datetime.utcnow() + timedelta(-30)
        )

        final_amounts = [(p._id, float(50)) for i, p in enumerate(self.products)]
        second_form_id = self.submit_xml_form(balance_submission(final_amounts))

        ledger_accessors = LedgerAccessors(self.domain.name)

        def _assert_initial_state():
            if should_use_sql_backend(self.domain):
                self.assertEqual(3, len(self._get_all_ledger_transactions(Q(form_id=second_form_id))))
            else:
                self.assertEqual(1, StockReport.objects.filter(form_id=second_form_id).count())
                # 6 = 3 stockonhand and 3 inferred consumption txns
                self.assertEqual(6, StockTransaction.objects.filter(report__form_id=second_form_id).count())

            ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for lv in ledger_values:
                self.assertEqual(50, lv.stock_on_hand)
                self.assertEqual(
                    round(float(lv.daily_consumption), 2),
                    1.67
                )

        # check initial setup
        _assert_initial_state()

        # archive and confirm commtrack data is deleted
        form = FormAccessors(self.domain.name).get_form(second_form_id)
        with process_pillow_changes('LedgerToElasticsearchPillow'):
            form.archive()

        if should_use_sql_backend(self.domain):
            self.assertEqual(0, len(self._get_all_ledger_transactions(Q(form_id=second_form_id))))
        else:
            self.assertEqual(0, StockReport.objects.filter(form_id=second_form_id).count())
            self.assertEqual(0, StockTransaction.objects.filter(report__form_id=second_form_id).count())

        ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
        self.assertEqual(3, len(ledger_values))
        for state in ledger_values:
            # balance should be reverted to 100 in the StockState
            self.assertEqual(100, int(state.stock_on_hand))
            # consumption should be none since there will only be 1 data point
            self.assertIsNone(state.daily_consumption)

        # unarchive and confirm commtrack data is restored
        with process_pillow_changes('LedgerToElasticsearchPillow'):
            form.unarchive()
        _assert_initial_state()
Esempio n. 5
0
    def test_archive_only_form(self):
        # check no data in stock states
        ledger_accessors = LedgerAccessors(self.domain.name)
        ledger_values = ledger_accessors.get_ledger_values_for_case(
            self.sp.case_id)
        self.assertEqual(0, len(ledger_values))

        initial_amounts = [(p._id, float(100)) for p in self.products]
        form_id = self.submit_xml_form(balance_submission(initial_amounts))

        # check that we made stuff
        def _assert_initial_state():
            if should_use_sql_backend(self.domain):
                self.assertEqual(
                    3,
                    LedgerTransaction.objects.filter(form_id=form_id).count())
            else:
                self.assertEqual(
                    1,
                    StockReport.objects.filter(form_id=form_id).count())
                self.assertEqual(
                    3,
                    StockTransaction.objects.filter(
                        report__form_id=form_id).count())

            ledger_values = ledger_accessors.get_ledger_values_for_case(
                self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for state in ledger_values:
                self.assertEqual(100, int(state.stock_on_hand))

        _assert_initial_state()

        # archive and confirm commtrack data is cleared
        form = FormAccessors(self.domain.name).get_form(form_id)
        form.archive()
        self.assertEqual(
            0,
            len(ledger_accessors.get_ledger_values_for_case(self.sp.case_id)))
        if should_use_sql_backend(self.domain):
            self.assertEqual(
                0,
                LedgerTransaction.objects.filter(form_id=form_id).count())
        else:
            self.assertEqual(
                0,
                StockReport.objects.filter(form_id=form_id).count())
            self.assertEqual(
                0,
                StockTransaction.objects.filter(
                    report__form_id=form_id).count())

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
Esempio n. 6
0
    def test_archive_last_form(self):
        initial_amounts = [(p._id, float(100)) for p in self.products]
        self.submit_xml_form(
            balance_submission(initial_amounts),
            timestamp=datetime.utcnow() + timedelta(-30)
        )

        final_amounts = [(p._id, float(50)) for i, p in enumerate(self.products)]
        second_form_id = self.submit_xml_form(balance_submission(final_amounts))

        ledger_accessors = LedgerAccessors(self.domain.name)

        def _assert_initial_state():
            if should_use_sql_backend(self.domain):
                self.assertEqual(3, len(self._get_all_ledger_transactions(Q(form_id=second_form_id))))
            else:
                self.assertEqual(1, StockReport.objects.filter(form_id=second_form_id).count())
                # 6 = 3 stockonhand and 3 inferred consumption txns
                self.assertEqual(6, StockTransaction.objects.filter(report__form_id=second_form_id).count())

            ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for lv in ledger_values:
                self.assertEqual(50, lv.stock_on_hand)
                self.assertEqual(
                    round(float(lv.daily_consumption), 2),
                    1.67
                )

        # check initial setup
        _assert_initial_state()

        # archive and confirm commtrack data is deleted
        form = FormAccessors(self.domain.name).get_form(second_form_id)
        with process_pillow_changes('LedgerToElasticsearchPillow'):
            form.archive()

        if should_use_sql_backend(self.domain):
            self.assertEqual(0, len(self._get_all_ledger_transactions(Q(form_id=second_form_id))))
        else:
            self.assertEqual(0, StockReport.objects.filter(form_id=second_form_id).count())
            self.assertEqual(0, StockTransaction.objects.filter(report__form_id=second_form_id).count())

        ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
        self.assertEqual(3, len(ledger_values))
        for state in ledger_values:
            # balance should be reverted to 100 in the StockState
            self.assertEqual(100, int(state.stock_on_hand))
            # consumption should be none since there will only be 1 data point
            self.assertIsNone(state.daily_consumption)

        # unarchive and confirm commtrack data is restored
        with process_pillow_changes('LedgerToElasticsearchPillow'):
            form.unarchive()
        _assert_initial_state()
Esempio n. 7
0
def get_episode_adherence_ledger(domain, episode_case_id, entry_id):
    """
    :param domain: domain name
    :param episode_case_id: episode case id for adherence
    :param entry_id: example date_2017-12-09
    """
    ledger_accessor = LedgerAccessors(domain)
    try:
        return ledger_accessor.get_ledger_value(episode_case_id,
                                                EPISODE_LEDGER_SECTION_ID,
                                                entry_id)
    except LedgerValueNotFound:
        return None
Esempio n. 8
0
    def test_archive_last_form(self):
        initial_amounts = [(p._id, float(100)) for p in self.products]
        self.submit_xml_form(balance_submission(initial_amounts),
                             timestamp=datetime.utcnow() + timedelta(-30))

        final_amounts = [(p._id, float(50))
                         for i, p in enumerate(self.products)]
        second_form_id = self.submit_xml_form(
            balance_submission(final_amounts))

        ledger_accessors = LedgerAccessors(self.domain.name)

        def _assert_initial_state():
            self.assertEqual(
                3,
                len(
                    self._get_all_ledger_transactions(
                        Q(form_id=second_form_id))))

            ledger_values = ledger_accessors.get_ledger_values_for_case(
                self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for lv in ledger_values:
                self.assertEqual(50, lv.stock_on_hand)
                self.assertEqual(round(float(lv.daily_consumption), 2), 1.67)

        # check initial setup
        _assert_initial_state()

        # archive and confirm commtrack data is deleted
        form = XFormInstance.objects.get_form(second_form_id, self.domain.name)
        with self.process_legder_changes:
            form.archive()

        self.assertEqual(
            0,
            len(self._get_all_ledger_transactions(Q(form_id=second_form_id))))

        ledger_values = ledger_accessors.get_ledger_values_for_case(
            self.sp.case_id)
        self.assertEqual(3, len(ledger_values))
        for state in ledger_values:
            # balance should be reverted to 100 in the ledger value
            self.assertEqual(100, int(state.stock_on_hand))
            # consumption should be none since there will only be 1 data point
            self.assertIsNone(state.daily_consumption)

        # unarchive and confirm commtrack data is restored
        with self.process_legder_changes:
            form.unarchive()
        _assert_initial_state()
Esempio n. 9
0
    def test_balance_consumption(self):
        initial = float(100)
        initial_amounts = [(p._id, initial) for p in self.products]
        self.submit_xml_form(balance_submission(initial_amounts))

        final_amounts = [(p._id, float(50 - 10 * i))
                         for i, p in enumerate(self.products)]
        self.submit_xml_form(balance_submission(final_amounts))
        for product, amt in final_amounts:
            self.check_product_stock(self.sp, product, amt, 0)
            inferred = amt - initial
            if should_use_sql_backend(self.domain):
                sql_txn = LedgerAccessors(
                    self.domain.name).get_latest_transaction(
                        self.sp.case_id, 'stock', product)
                self.assertEqual(inferred, sql_txn.delta)
            else:
                inferred_txn = StockTransaction.objects.get(
                    case_id=self.sp.case_id,
                    product_id=product,
                    subtype=stockconst.TRANSACTION_SUBTYPE_INFERRED)
                self.assertEqual(Decimal(str(inferred)), inferred_txn.quantity)
                self.assertEqual(Decimal(str(amt)), inferred_txn.stock_on_hand)
                self.assertEqual(stockconst.TRANSACTION_TYPE_CONSUMPTION,
                                 inferred_txn.type)
Esempio n. 10
0
def get_wrapped_ledger_values(domain, case_ids, section_id, entry_ids=None):
    if isinstance(case_ids, (list, tuple, set)):
        case_ids_list = list(case_ids)
    else:
        case_ids_list = [case_ids]
    return LedgerAccessors(domain).get_ledger_values_for_cases(
        case_ids_list, [section_id], entry_ids)
    def test_get_case_ledger_state_1(self):
        def test_transactions(expected):
            for case_id in self.case_ids:
                state = LedgerAccessors(self.domain).get_case_ledger_state(case_id)
                self._validate_case_data(state, expected[case_id])

        self._test_get_current_ledger_transactions(test_transactions)

        self.assertEqual({}, LedgerAccessors(self.domain).get_case_ledger_state('non-existent'))
    def test_get_current_ledger_state(self):
        def test_transactions(expected):
            state = LedgerAccessors(self.domain).get_current_ledger_state(self.case_ids.keys())
            for case_id, sections in state.items():
                self._validate_case_data(sections, expected[case_id])

        self._test_get_current_ledger_transactions(test_transactions)

        self.assertEqual({}, LedgerAccessors(self.domain).get_current_ledger_state([]))
Esempio n. 13
0
    def _get_values_by_product(ledger_section, case_id, product_codes, domain):
        """returns a defaultdict mapping product codes to their values"""
        ret = defaultdict(lambda: 0)
        ledgers = LedgerAccessors(domain).get_ledger_values_for_case(case_id)
        for ledger in ledgers:
            if ledger.section_id == ledger_section and ledger.entry_id in product_codes:
                ret[ledger.entry_id] = ledger.stock_on_hand

        return ret
Esempio n. 14
0
class ExplodeLedgersTest(BaseSyncTest):
    def setUp(self):
        super(ExplodeLedgersTest, self).setUp()
        self.case_accessor = CaseAccessors(self.project.name)
        self.ledger_accessor = LedgerAccessors(self.project.name)
        self._create_ledgers()

    def tearDown(self):
        delete_all_ledgers()
        delete_all_cases()
        delete_all_xforms()
        super(ExplodeLedgersTest, self).tearDown()

    def _create_ledgers(self):
        case_type = 'case'

        case1 = CaseStructure(
            case_id='case1',
            attrs={'create': True, 'case_type': case_type},
        )
        case2 = CaseStructure(
            case_id='case2',
            attrs={'create': True, 'case_type': case_type},
        )  # case2 will have no ledgers
        self.ledgers = {
            'icecream': Balance(
                entity_id=case1.case_id,
                date=datetime(2017, 11, 21, 0, 0, 0, 0),
                section_id='test',
                entry=Entry(id='icecream', quantity=4),
            ),
            'blondie': Balance(
                entity_id=case1.case_id,
                date=datetime(2017, 11, 21, 0, 0, 0, 0),
                section_id='test',
                entry=Entry(id='blondie', quantity=5),
            )
        }
        self.device.post_changes([case1, case2])
        self.device.post_changes(list(self.ledgers.values()))

    def test_explode_ledgers(self):
        explode_cases(self.project.name, self.user_id, 5)
        cases = self.case_accessor.iter_cases(self.case_accessor.get_case_ids_in_domain())
        for case in cases:
            ledger_values = {l.entry_id: l for l in self.ledger_accessor.get_ledger_values_for_case(case.case_id)}

            if case.case_id == 'case2' or case.get_case_property('cc_exploded_from') == 'case2':
                self.assertEqual(len(ledger_values), 0)
            else:
                self.assertEqual(len(ledger_values), len(self.ledgers))
                for id, balance in six.iteritems(self.ledgers):
                    self.assertEqual(ledger_values[id].balance, balance.entry.quantity)
                    self.assertEqual(ledger_values[id].entry_id, balance.entry.id)
Esempio n. 15
0
    def test_balance_consumption(self):
        initial = float(100)
        initial_amounts = [(p._id, initial) for p in self.products]
        self.submit_xml_form(balance_submission(initial_amounts))

        final_amounts = [(p._id, float(50 - 10 * i))
                         for i, p in enumerate(self.products)]
        self.submit_xml_form(balance_submission(final_amounts))
        for product, amt in final_amounts:
            self.check_product_stock(self.sp, product, amt, 0)
            inferred = amt - initial
            sql_txn = LedgerAccessors(self.domain.name).get_latest_transaction(
                self.sp.case_id, 'stock', product)
            self.assertEqual(inferred, sql_txn.delta)
Esempio n. 16
0
    def test_archive_only_form(self):
        # check no data in stock states
        ledger_accessors = LedgerAccessors(self.domain.name)
        ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
        self.assertEqual(0, len(ledger_values))

        initial_amounts = [(p._id, float(100)) for p in self.products]
        form_id = self.submit_xml_form(balance_submission(initial_amounts))

        # check that we made stuff
        def _assert_initial_state():
            if should_use_sql_backend(self.domain.name):
                self.assertEqual(3, LedgerTransaction.objects.filter(form_id=form_id).count())
            else:
                self.assertEqual(1, StockReport.objects.filter(form_id=form_id).count())
                self.assertEqual(3, StockTransaction.objects.filter(report__form_id=form_id).count())

            ledger_values = ledger_accessors.get_ledger_values_for_case(self.sp.case_id)
            self.assertEqual(3, len(ledger_values))
            for state in ledger_values:
                self.assertEqual(100, int(state.stock_on_hand))

        _assert_initial_state()

        # archive and confirm commtrack data is cleared
        form = FormAccessors(self.domain.name).get_form(form_id)
        form.archive()
        self.assertEqual(0, len(ledger_accessors.get_ledger_values_for_case(self.sp.case_id)))
        if should_use_sql_backend(self.domain.name):
            self.assertEqual(0, LedgerTransaction.objects.filter(form_id=form_id).count())
        else:
            self.assertEqual(0, StockReport.objects.filter(form_id=form_id).count())
            self.assertEqual(0, StockTransaction.objects.filter(report__form_id=form_id).count())

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
def rebuild_case_changes(form, rebuild_reason=None):
    """
    Publishes changes for the form and rebuilds any touched cases.

    """
    domain = form.domain
    case_ids = get_case_ids_from_form(form)
    for case_id in case_ids:
        detail = FormReprocessRebuild(form_id=form.form_id)
        FormProcessorInterface(domain).hard_rebuild_case(case_id, detail)
        if LedgerAccessors(domain).get_ledger_values_for_case(case_id):
            with open('case_ids_with_ledgers.csv', 'a+') as f:
                print("{}, {}".format(domain, case_id), file=f)

    return len(case_ids)
Esempio n. 18
0
def get_values_by_product(domain, case_id, ledger_section, product_codes):
    ledgers = LedgerAccessors(domain).get_ledger_values_for_case(case_id)

    products = SQLProduct.objects.filter(domain=domain,
                                         code__in=product_codes).values(
                                             'product_id', 'code')

    entry_id_to_code = {
        product['product_id']: product['code']
        for product in products
    }

    return {
        entry_id_to_code[ledger.entry_id]: ledger.stock_on_hand
        for ledger in ledgers if (ledger.section_id == ledger_section
                                  and ledger.entry_id in entry_id_to_code)
    }
Esempio n. 19
0
    def _consumption_sections(self, case_stub, case_ledgers,
                              section_timestamp_map):
        case_id = case_stub.case_id
        for section_id, consumption_section_id in self.stock_settings.section_to_consumption_types.items(
        ):
            if section_id in case_ledgers or self.stock_settings.force_consumption_case_filter(
                    case_stub):

                consumption_entries = []
                current_section_sate = case_ledgers.get(section_id, {})
                if self.stock_settings.default_product_list:
                    for product_id in self.stock_settings.default_product_list:
                        state = current_section_sate.get(product_id, None)
                        if not state:
                            try:
                                state = LedgerAccessors(
                                    self.domain_name).get_ledger_value(
                                        case_id, section_id, product_id)
                            except LedgerValueNotFound:
                                pass

                        consumption_entries.append(
                            self._consumption_entry(case_id, product_id,
                                                    state))
                else:
                    for product_id in sorted(current_section_sate.keys()):
                        state = current_section_sate[product_id]
                        consumption_entries.append(
                            self._consumption_entry(case_id, product_id,
                                                    state))

                consumption_entries = [
                    e for e in consumption_entries if e is not None
                ]
                if consumption_entries:
                    yield self.elem_maker.balance(
                        *consumption_entries, **{
                            'entity-id': case_id,
                            'date': section_timestamp_map[section_id],
                            'section-id': consumption_section_id,
                        })
Esempio n. 20
0
    def test_stock_status_data_source_raw(self):
        ledger_value = LedgerAccessors(self.domain).get_ledger_value(
            self.supply_point.case_id, "stock", self.product._id
        )

        config = {
            'domain': self.domain,
            'aggregate': False,
            'advanced_columns': True,
        }
        self.assertEqual(
            list(StockStatusDataSource(config).get_data()),
            [{
                'category': 'nodata',
                'consumption': None,
                'current_stock': 50,
                'last_reported': ledger_value.last_modified,
                'location_id': self.location.location_id,
                'months_remaining': None,
                'product_id': self.product._id,
                'product_name': self.product.name,
                'resupply_quantity_needed': None}]
        )
Esempio n. 21
0
def compute_daily_consumption(domain,
                              case_id,
                              product_id,
                              window_end,
                              section_id=const.SECTION_TYPE_STOCK,
                              configuration=None):
    """
    Computes the consumption for a product at a supply point.

    Can optionally pass a section_id, but by default the 'stock'
    value is used for computation.

    Returns None if there is insufficient history.
    """
    from corehq.form_processor.interfaces.dbaccessors import LedgerAccessors

    configuration = configuration or ConsumptionConfiguration()
    window_start = window_end - timedelta(days=configuration.max_window)
    transactions = LedgerAccessors(domain).get_transactions_for_consumption(
        case_id, product_id, section_id, window_start, window_end)
    return compute_daily_consumption_from_transactions(transactions,
                                                       window_start,
                                                       configuration)
 def setUp(self):
     super(ExplodeLedgersTest, self).setUp()
     self.case_accessor = CaseAccessors(self.project.name)
     self.ledger_accessor = LedgerAccessors(self.project.name)
     self._create_ledgers()
Esempio n. 23
0
class ReprocessSubmissionStubTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super(ReprocessSubmissionStubTests, cls).setUpClass()
        cls.domain = uuid.uuid4().hex
        cls.product = SQLProduct.objects.create(domain=cls.domain,
                                                product_id='product1',
                                                name='product1')

    @classmethod
    def tearDownClass(cls):
        cls.product.delete()
        super(ReprocessSubmissionStubTests, cls).tearDownClass()

    def setUp(self):
        super(ReprocessSubmissionStubTests, self).setUp()
        self.factory = CaseFactory(domain=self.domain)
        self.formdb = XFormInstance.objects
        self.ledgerdb = LedgerAccessors(self.domain)

    def tearDown(self):
        FormProcessorTestUtils.delete_all_cases_forms_ledgers(self.domain)
        super(ReprocessSubmissionStubTests, self).tearDown()

    def test_reprocess_unfinished_submission_case_create(self):
        case_id = uuid.uuid4().hex
        with _patch_save_to_raise_error(self):
            self.factory.create_or_update_cases([
                CaseStructure(case_id=case_id,
                              attrs={
                                  'case_type': 'parent',
                                  'create': True
                              })
            ])

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain,
                                                        saved=False).all()
        self.assertEqual(1, len(stubs))

        # form that was saved before case error raised
        normal_form_ids = XFormInstance.objects.get_form_ids_in_domain(
            self.domain, 'XFormInstance')
        self.assertEqual(0, len(normal_form_ids))

        # shows error form (duplicate of form that was saved before case error)
        # this is saved becuase the saving was assumed to be atomic so if there was any error it's assumed
        # the form didn't get saved
        # we don't really care about this form in this test
        error_forms = XFormInstance.objects.get_forms_by_type(
            self.domain, 'XFormError', 10)
        self.assertEqual(1, len(error_forms))
        self.assertIsNone(error_forms[0].orig_id)
        self.assertEqual(error_forms[0].form_id, stubs[0].xform_id)

        self.assertEqual(
            0, len(CommCareCase.objects.get_case_ids_in_domain(self.domain)))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))

        case_ids = CommCareCase.objects.get_case_ids_in_domain(self.domain)
        self.assertEqual(1, len(case_ids))
        self.assertEqual(case_id, case_ids[0])

        with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist):
            UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)

    def test_reprocess_unfinished_submission_case_update(self):
        case_id = uuid.uuid4().hex
        form_ids = []
        form_ids.append(
            submit_case_blocks(
                CaseBlock(case_id=case_id, create=True,
                          case_type='box').as_text(), self.domain)[0].form_id)

        with _patch_save_to_raise_error(self):
            submit_case_blocks(
                CaseBlock(case_id=case_id, update={
                    'prop': 'a'
                }).as_text(), 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 second form with case update
        form_ids.append(
            submit_case_blocks(
                CaseBlock(case_id=case_id, update={
                    'prop': 'b'
                }).as_text(), self.domain)[0].form_id)

        case = CommCareCase.objects.get_case(case_id, self.domain)
        self.assertEqual(2, len(case.xform_ids))
        self.assertEqual('b', case.get_case_property('prop'))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))
        self.assertEqual(0, len(result.ledgers))

        case = CommCareCase.objects.get_case(case_id, self.domain)
        self.assertEqual('b', case.get_case_property(
            'prop'))  # should be property value from most recent form
        self.assertEqual(3, len(case.xform_ids))
        self.assertEqual(form_ids, case.xform_ids)

        with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist):
            UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)

    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 = CommCareCase.objects.get_case(case_id, self.domain)
        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 = CommCareCase.objects.get_case(case_id, self.domain)
        self.assertEqual(2, len(case.xform_ids))
        self.assertTrue(case.actions[1].is_ledger_transaction)

    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_fire_signals(self):
        from corehq.apps.receiverwrapper.tests.test_submit_errors import failing_signal_handler
        case_id = uuid.uuid4().hex
        form_id = uuid.uuid4().hex
        with failing_signal_handler('signal death'):
            submit_case_blocks(CaseBlock(case_id=case_id,
                                         create=True,
                                         case_type='box').as_text(),
                               self.domain,
                               form_id=form_id)

        form = self.formdb.get_form(form_id)

        with catch_signal(successful_form_received) as form_handler, \
             catch_signal(sql_case_post_save) as case_handler:
            submit_form_locally(
                instance=form.get_xml(),
                domain=self.domain,
            )

        case = CommCareCase.objects.get_case(case_id, self.domain)

        self.assertEqual(form, form_handler.call_args[1]['xform'])
        self.assertEqual(case, case_handler.call_args[1]['case'])

    def test_reprocess_normal_form(self):
        case_id = uuid.uuid4().hex
        form, cases = submit_case_blocks(
            CaseBlock(case_id=case_id, create=True, case_type='box').as_text(),
            self.domain)
        self.assertTrue(form.is_normal)

        result = reprocess_form(form, save=True, lock_form=False)
        self.assertIsNone(result.error)

        case = CommCareCase.objects.get_case(case_id, self.domain)
        transactions = case.actions
        self.assertEqual([trans.form_id for trans in transactions],
                         [form.form_id])

    def test_processing_skipped_when_migrations_are_in_progress(self):
        case_id = uuid.uuid4().hex
        with _patch_save_to_raise_error(self):
            self.factory.create_or_update_cases([
                CaseStructure(case_id=case_id,
                              attrs={
                                  'case_type': 'parent',
                                  'create': True
                              })
            ])

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain,
                                                        saved=False).all()
        self.assertEqual(1, len(stubs))

        with patch(
                'corehq.form_processor.reprocess.any_migrations_in_progress',
                return_value=True):
            result = reprocess_unfinished_stub(stubs[0])
            self.assertIsNone(result)

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))

    def test_processing_retuns_error_for_missing_form(self):
        case_id = uuid.uuid4().hex
        with _patch_save_to_raise_error(self):
            self.factory.create_or_update_cases([
                CaseStructure(case_id=case_id,
                              attrs={
                                  'case_type': 'parent',
                                  'create': True
                              })
            ])

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain,
                                                        saved=False).all()
        self.assertEqual(1, len(stubs))

        FormProcessorTestUtils.delete_all_cases_forms_ledgers(self.domain)
        with self.assertRaises(XFormNotFound):
            self.formdb.get_form(stubs[0].xform_id)

        result = reprocess_unfinished_stub(stubs[0])
        self.assertIsNotNone(result.error)
Esempio n. 24
0
 def setUp(self):
     super(TestReprocessDuringSubmission, self).setUp()
     self.factory = CaseFactory(domain=self.domain)
     self.formdb = XFormInstance.objects
     self.ledgerdb = LedgerAccessors(self.domain)
Esempio n. 25
0
class ReprocessSubmissionStubTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super(ReprocessSubmissionStubTests, cls).setUpClass()
        cls.domain = uuid.uuid4().hex
        cls.product = SQLProduct.objects.create(domain=cls.domain, product_id='product1', name='product1')

    @classmethod
    def tearDownClass(cls):
        cls.product.delete()
        super(ReprocessSubmissionStubTests, cls).tearDownClass()

    def setUp(self):
        super(ReprocessSubmissionStubTests, self).setUp()
        self.factory = CaseFactory(domain=self.domain)
        self.formdb = FormAccessors(self.domain)
        self.casedb = CaseAccessors(self.domain)
        self.ledgerdb = LedgerAccessors(self.domain)

    def tearDown(self):
        FormProcessorTestUtils.delete_all_cases_forms_ledgers(self.domain)
        super(ReprocessSubmissionStubTests, self).tearDown()

    def test_reprocess_unfinished_submission_case_create(self):
        case_id = uuid.uuid4().hex
        with _patch_save_to_raise_error(self):
            self.factory.create_or_update_cases([
                CaseStructure(case_id=case_id, attrs={'case_type': 'parent', 'create': True})
            ])

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all()
        self.assertEqual(1, len(stubs))

        # form that was saved before case error raised
        normal_form_ids = self.formdb.get_all_form_ids_in_domain('XFormInstance')
        self.assertEqual(0, len(normal_form_ids))

        # shows error form (duplicate of form that was saved before case error)
        # this is saved becuase the saving was assumed to be atomic so if there was any error it's assumed
        # the form didn't get saved
        # we don't really care about this form in this test
        error_forms = self.formdb.get_forms_by_type('XFormError', 10)
        self.assertEqual(1, len(error_forms))
        self.assertIsNone(error_forms[0].orig_id)
        self.assertEqual(error_forms[0].form_id, stubs[0].xform_id)

        self.assertEqual(0, len(self.casedb.get_case_ids_in_domain(self.domain)))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))

        case_ids = self.casedb.get_case_ids_in_domain()
        self.assertEqual(1, len(case_ids))
        self.assertEqual(case_id, case_ids[0])

        with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist):
            UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)

    def test_reprocess_unfinished_submission_case_update(self):
        case_id = uuid.uuid4().hex
        form_ids = []
        form_ids.append(submit_case_blocks(
            CaseBlock(case_id=case_id, create=True, case_type='box').as_string().decode('utf-8'),
            self.domain
        )[0].form_id)

        with _patch_save_to_raise_error(self):
            submit_case_blocks(
                CaseBlock(case_id=case_id, update={'prop': 'a'}).as_string().decode('utf-8'),
                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 second form with case update
        form_ids.append(submit_case_blocks(
            CaseBlock(case_id=case_id, update={'prop': 'b'}).as_string().decode('utf-8'),
            self.domain
        )[0].form_id)

        case = self.casedb.get_case(case_id)
        self.assertEqual(2, len(case.xform_ids))
        self.assertEqual('b', case.get_case_property('prop'))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))
        self.assertEqual(0, len(result.ledgers))

        case = self.casedb.get_case(case_id)
        self.assertEqual('b', case.get_case_property('prop'))  # should be property value from most recent form
        self.assertEqual(3, len(case.xform_ids))
        self.assertEqual(form_ids, case.xform_ids)

        with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist):
            UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)

    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_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 test_fire_signals(self):
        from corehq.apps.receiverwrapper.tests.test_submit_errors import failing_signal_handler
        case_id = uuid.uuid4().hex
        form_id = uuid.uuid4().hex
        with failing_signal_handler('signal death'):
            submit_case_blocks(
                CaseBlock(case_id=case_id, create=True, case_type='box').as_string().decode('utf-8'),
                self.domain,
                form_id=form_id
            )

        form = self.formdb.get_form(form_id)

        with catch_signal(successful_form_received) as form_handler, catch_signal(case_post_save) as case_handler:
            submit_form_locally(
                instance=form.get_xml(),
                domain=self.domain,
            )

        case = self.casedb.get_case(case_id)

        if should_use_sql_backend(self.domain):
            self.assertEqual(form, form_handler.call_args[1]['xform'])
            self.assertEqual(case, case_handler.call_args[1]['case'])
        else:
            signal_form = form_handler.call_args[1]['xform']
            self.assertEqual(form.form_id, signal_form.form_id)
            self.assertEqual(form.get_rev, signal_form.get_rev)

            signal_case = case_handler.call_args[1]['case']
            self.assertEqual(case.case_id, signal_case.case_id)
            self.assertEqual(case.get_rev, signal_case.get_rev)
Esempio n. 26
0
 def setUp(self):
     super(ReprocessSubmissionStubTests, self).setUp()
     self.factory = CaseFactory(domain=self.domain)
     self.formdb = FormAccessors(self.domain)
     self.casedb = CaseAccessors(self.domain)
     self.ledgerdb = LedgerAccessors(self.domain)
Esempio n. 27
0
                            domain=self.domain.name,
                            **submit_extras)
        return instance_id

    def check_product_stock(self,
                            case,
                            product_id,
                            expected_soh,
                            expected_qty,
                            section_id='stock'):
        if not isinstance(expected_qty, Decimal):
            expected_qty = Decimal(str(expected_qty))
        if not isinstance(expected_soh, Decimal):
            expected_soh = Decimal(str(expected_soh))

        latest_trans = LedgerAccessors(
            self.domain.name).get_latest_transaction(case.case_id, section_id,
                                                     product_id)
        self.assertIsNotNone(latest_trans)
        self.assertEqual(section_id, latest_trans.section_id)
        self.assertEqual(expected_soh, latest_trans.stock_on_hand)

        if should_use_sql_backend(self.domain):
            if latest_trans.type == LedgerTransaction.TYPE_TRANSFER:
                self.assertEqual(int(expected_qty), latest_trans.delta)
        else:
            self.assertEqual(expected_qty, latest_trans.quantity)


class CommTrackBalanceTransferTest(CommTrackSubmissionTest):
    @run_with_all_backends
    def test_balance_submit(self):
Esempio n. 28
0
    for section in generator.yield_sections():
        yield section


class StockPayloadGenerator(object):
    def __init__(self, domain_name, stock_settings, case_stub_list):
        self.domain_name = domain_name
        self.stock_settings = stock_settings
        self.case_stub_list = case_stub_list

        from lxml.builder import ElementMaker
        self.elem_maker = ElementMaker(namespace=COMMTRACK_REPORT_XMLNS)

    def yield_sections(self):
        case_ids = [case.case_id for case in self.case_stub_list]
        all_current_ledgers = LedgerAccessors(self.domain_name).get_current_ledger_state(case_ids)
        for case_stub in self.case_stub_list:
            case_id = case_stub.case_id
            case_ledgers = all_current_ledgers[case_id]

            section_timestamp_map = defaultdict(lambda: json_format_datetime(datetime.utcnow()))
            for section_id in sorted(case_ledgers.keys()):
                state_map = case_ledgers[section_id]
                stock_states = sorted(list(state_map.values()), key=lambda s: s.product_id)
                as_of = json_format_datetime(max(txn.last_modified_date for txn in stock_states))
                section_timestamp_map[section_id] = as_of
                yield self.elem_maker.balance(
                    *(self._state_to_xml(e) for e in stock_states),
                    **{'entity-id': case_id, 'date': as_of, 'section-id': section_id}
                )
Esempio n. 29
0
 def test_transactions(expected):
     state = LedgerAccessors(self.domain).get_current_ledger_state(
         list(self.case_ids))
     for case_id, sections in state.items():
         self._validate_case_data(sections, expected[case_id])
Esempio n. 30
0
 def test_transactions(expected):
     for case_id in self.case_ids:
         state = LedgerAccessors(
             self.domain).get_case_ledger_state(case_id)
         self._validate_case_data(state, expected[case_id])
Esempio n. 31
0
 def setUp(self):
     super(ExplodeLedgersTest, self).setUp()
     self.case_accessor = CaseAccessors(self.project.name)
     self.ledger_accessor = LedgerAccessors(self.project.name)
     self._create_ledgers()
Esempio n. 32
0
def render_case(case, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.
    """
    from corehq.apps.hqwebapp.templatetags.proptable_tags import get_tables_as_rows, get_default_definition
    wrapped_case = get_wrapped_case(case)
    timezone = options.get('timezone', pytz.utc)
    timezone = timezone.localize(datetime.datetime.utcnow()).tzinfo
    _get_tables_as_rows = partial(get_tables_as_rows, timezone=timezone)
    display = options.get('display') or wrapped_case.get_display_config()
    show_transaction_export = options.get('show_transaction_export') or False
    get_case_url = options['get_case_url']

    data = copy.deepcopy(wrapped_case.to_full_dict())

    default_properties = _get_tables_as_rows(data, display)

    dynamic_data = wrapped_case.dynamic_properties()

    for section in display:
        for row in section['layout']:
            for item in row:
                dynamic_data.pop(item.get("expr"), None)

    if dynamic_data:
        dynamic_keys = sorted(dynamic_data.keys())
        definition = get_default_definition(
            dynamic_keys, num_columns=DYNAMIC_CASE_PROPERTIES_COLUMNS)

        dynamic_properties = _get_tables_as_rows(dynamic_data, definition)
    else:
        dynamic_properties = None

    the_time_is_now = datetime.datetime.utcnow()
    tz_offset_ms = int(timezone.utcoffset(the_time_is_now).total_seconds()) * 1000
    tz_abbrev = timezone.localize(the_time_is_now).tzname()

    # ledgers
    def _product_name(product_id):
        try:
            return SQLProduct.objects.get(product_id=product_id).name
        except SQLProduct.DoesNotExist:
            return (_('Unknown Product ("{}")').format(product_id))

    ledger_map = LedgerAccessors(case.domain).get_case_ledger_state(case.case_id, ensure_form_id=True)
    for section, product_map in ledger_map.items():
        product_tuples = sorted(
            (_product_name(product_id), product_map[product_id]) for product_id in product_map
        )
        ledger_map[section] = product_tuples

    return render_to_string("case/partials/single_case.html", {
        "default_properties": default_properties,
        "default_properties_options": {
            "style": "table"
        },
        "dynamic_properties": dynamic_properties,
        "dynamic_properties_options": {
            "style": "table"
        },
        "case": wrapped_case.case,
        "case_actions": mark_safe(json.dumps(wrapped_case.actions())),
        "timezone": timezone,
        "tz_abbrev": tz_abbrev,
        "case_hierarchy_options": {
            "show_view_buttons": True,
            "get_case_url": get_case_url,
            "timezone": timezone
        },
        "ledgers": ledger_map,
        "timezone_offset": tz_offset_ms,
        "show_transaction_export": show_transaction_export,
        "xform_api_url": reverse('single_case_forms', args=[case.domain, case.case_id]),
    })
Esempio n. 33
0
 def test_get_case_ledger_state(self):
     for case_id in self.case_ids:
         state = LedgerAccessors(self.domain).get_case_ledger_state(case_id)
         for section, products in state.items():
             for product, state in products.items():
                 self.assertEqual(state.stock_on_hand, self.transactions[case_id][section][product])
Esempio n. 34
0
 def test_transactions(expected):
     state = LedgerAccessors(self.domain).get_current_ledger_state(self.case_ids.keys())
     for case_id, sections in state.items():
         self._validate_case_data(sections, expected[case_id])
Esempio n. 35
0
 def _get_ledger_state(self, case_id):
     return LedgerAccessors(self.domain_name).get_case_ledger_state(case_id)
Esempio n. 36
0
            date_formatter=date_formatter,
        )
        submit_form_locally(
            instance=instance,
            domain=self.domain.name,
            **submit_extras
        )
        return instance_id

    def check_product_stock(self, case, product_id, expected_soh, expected_qty, section_id='stock'):
        if not isinstance(expected_qty, Decimal):
            expected_qty = Decimal(str(expected_qty))
        if not isinstance(expected_soh, Decimal):
            expected_soh = Decimal(str(expected_soh))

        latest_trans = LedgerAccessors(self.domain.name).get_latest_transaction(
            case.case_id, section_id, product_id
        )
        self.assertIsNotNone(latest_trans)
        self.assertEqual(section_id, latest_trans.section_id)
        self.assertEqual(expected_soh, latest_trans.stock_on_hand)

        if should_use_sql_backend(self.domain):
            if latest_trans.type == LedgerTransaction.TYPE_TRANSFER:
                self.assertEqual(int(expected_qty), latest_trans.delta)
        else:
            self.assertEqual(expected_qty, latest_trans.quantity)


class CommTrackBalanceTransferTest(CommTrackSubmissionTest):
Esempio n. 37
0
        ...
    }

    Note: this only works for the Couch backend
    """
    request_params = request.GET
    case_id = request_params.get('case_id')
    if not case_id:
        return json_response(
            {'message': 'You must specify a case id to make this query.'},
            status_code=400)
    try:
        case = CaseAccessors(domain).get_case(case_id)
    except CaseNotFound:
        raise Http404()
    ledger_map = LedgerAccessors(domain).get_case_ledger_state(case.case_id)

    def custom_json_handler(obj):
        if hasattr(obj, 'stock_on_hand'):
            return obj.stock_on_hand
        return json_handler(obj)

    return json_response(
        {
            'entity_id': case_id,
            'ledger': ledger_map,
        },
        default=custom_json_handler,
    )

Esempio n. 38
0
 def setUp(self):
     super(TestReprocessDuringSubmission, self).setUp()
     self.factory = CaseFactory(domain=self.domain)
     self.formdb = FormAccessors(self.domain)
     self.casedb = CaseAccessors(self.domain)
     self.ledgerdb = LedgerAccessors(self.domain)