Ejemplo n.º 1
0
 def commtrack_settings(self):
     # this import causes some dependency issues so lives in here
     from corehq.apps.commtrack.models import SQLCommtrackConfig
     if self.commtrack_enabled:
         return SQLCommtrackConfig.for_domain(self.name)
     else:
         return None
Ejemplo n.º 2
0
    def setUp(self):
        super(XMLTest, self).setUp()
        self.domain = util.bootstrap_domain(util.TEST_DOMAIN)
        util.bootstrap_location_types(self.domain.name)
        util.bootstrap_products(self.domain.name)
        self.products = sorted(Product.by_domain(self.domain.name),
                               key=lambda p: p._id)
        self.ct_settings = SQLCommtrackConfig.for_domain(self.domain.name)
        self.ct_settings.sqlconsumptionconfig = SQLConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
        )
        self.ct_settings.save()
        self.ct_settings.sqlconsumptionconfig.commtrack_settings = self.ct_settings
        self.ct_settings.sqlconsumptionconfig.save()
        self.domain = Domain.get(self.domain._id)

        self.loc = make_loc('loc1')
        self.sp = self.loc.linked_supply_point()
        self.users = [
            util.bootstrap_user(self, **user_def)
            for user_def in self.user_definitions
        ]
        self.user = self.users[0]
Ejemplo n.º 3
0
def stock_level_config_for_domain(domain, commtrack_enabled):
    if not commtrack_enabled:
        return None
    from corehq.apps.commtrack.models import SQLCommtrackConfig
    ct_config = SQLCommtrackConfig.for_domain(domain)
    if ct_config is None or not hasattr(ct_config, 'sqlstocklevelsconfig'):
        return None
    else:
        return ct_config.sqlstocklevelsconfig
Ejemplo n.º 4
0
def should_exclude_invalid_periods(domain):
    """
    Whether the domain's consumption calculation should exclude invalid periods
    i.e. periods where the stock went up without a receipt being reported
    """
    from corehq.apps.commtrack.models import SQLCommtrackConfig
    if domain:
        config = SQLCommtrackConfig.for_domain(domain)
        if config and hasattr(config, 'sqlconsumptionconfig'):
            return config.sqlconsumptionconfig.exclude_invalid_periods
    return False
Ejemplo n.º 5
0
    def process_change(self, change):
        ledger = change.get_document()
        from corehq.apps.commtrack.models import SQLCommtrackConfig
        commtrack_config = SQLCommtrackConfig.for_domain(ledger['domain'])

        if commtrack_config and commtrack_config.use_auto_consumption:
            daily_consumption = _get_daily_consumption_for_ledger(ledger)
            ledger['daily_consumption'] = daily_consumption

        if not ledger.get('location_id') and ledger.get('case_id'):
            ledger['location_id'] = _location_id_for_case(ledger['case_id'])

        _update_ledger_section_entry_combinations(ledger)
 def test_report_with_exclude_disabled(self):
     commtrack_config = SQLCommtrackConfig(domain=self.domain.name)
     commtrack_config.sqlconsumptionconfig = SQLConsumptionConfig()
     commtrack_config.save(
         sync_to_couch=False)  # don't bother syncing in tests
     commtrack_config.sqlconsumptionconfig.commtrack_config = commtrack_config
     commtrack_config.sqlconsumptionconfig.save()
     self.create_transactions(self.domain.name)
     self.assertEqual(StockTransaction.objects.all().count(), 3)
     self.assertEqual(
         StockTransaction.objects.filter(type='receipts').count(), 1)
     commtrack_config.delete()
Ejemplo n.º 7
0
def _create_commtrack_config_if_needed(domain):
    if SQLCommtrackConfig.for_domain(domain):
        return

    config = SQLCommtrackConfig(domain=domain)
    config.save(
        sync_to_couch=False)  # must be saved before submodels can be saved

    SQLAlertConfig(commtrack_config=config).save()
    SQLConsumptionConfig(commtrack_config=config).save()
    SQLStockLevelsConfig(commtrack_config=config).save()
    SQLStockRestoreConfig(commtrack_config=config).save()
    config.set_actions([
        SQLActionConfig(
            action='receipts',
            keyword='r',
            caption='Received',
        ),
        SQLActionConfig(
            action='consumption',
            keyword='c',
            caption='Consumed',
        ),
        SQLActionConfig(
            action='consumption',
            subaction='loss',
            keyword='l',
            caption='Losses',
        ),
        SQLActionConfig(
            action='stockonhand',
            keyword='soh',
            caption='Stock on hand',
        ),
        SQLActionConfig(
            action='stockout',
            keyword='so',
            caption='Stock-out',
        ),
    ])
    config.save()  # save actions, and sync couch
Ejemplo n.º 8
0
def all_sms_codes(domain):
    config = SQLCommtrackConfig.for_domain(domain)

    actions = {action.keyword: action for action in config.all_actions}
    products = {
        p.code: p
        for p in SQLProduct.active_objects.filter(domain=domain)
    }

    ret = {}
    for action_key, action in actions.items():
        ret[action_key] = ('action', action)
    for product_key, product in products.items():
        ret[product_key] = ('product', product)

    return ret
Ejemplo n.º 9
0
def send_confirmation(v, data):
    C = SQLCommtrackConfig.for_domain(v.domain)

    static_loc = data['location']
    location_name = static_loc.name
    metadata = MessageMetadata(location_id=static_loc.get_id)
    tx_by_action = map_reduce(lambda tx: [(tx.action_config(C).name,)], data=data['transactions'], include_docs=True)

    def summarize_action(action, txs):
        return '%s %s' % (txs[0].action_config(C).keyword.upper(), ' '.join(sorted(tx.fragment() for tx in txs)))

    msg = 'received stock report for %s(%s) %s' % (
        static_loc.site_code,
        truncate(location_name, 20),
        ' '.join(sorted(summarize_action(a, txs) for a, txs in tx_by_action.items()))
    )

    send_sms_to_verified_number(v, msg, metadata=metadata)
Ejemplo n.º 10
0
    def setUpClass(cls):
        super(StockStateTest, cls).setUpClass()
        cls.domain_obj = util.bootstrap_domain(cls.domain)
        util.bootstrap_location_types(cls.domain)
        util.bootstrap_products(cls.domain)
        cls.ct_settings = SQLCommtrackConfig.for_domain(cls.domain)
        cls.ct_settings.use_auto_consumption = True
        cls.ct_settings.sqlconsumptionconfig = SQLConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
        )
        cls.ct_settings.save()
        cls.ct_settings.sqlconsumptionconfig.commtrack_settings = cls.ct_settings
        cls.ct_settings.sqlconsumptionconfig.save()

        cls.loc = util.make_loc('loc1', domain=cls.domain)
        cls.sp = cls.loc.linked_supply_point()
        cls.products = sorted(Product.by_domain(cls.domain),
                              key=lambda p: p._id)

        cls.process_ledger_changes = process_pillow_changes(
            'LedgerToElasticsearchPillow')
Ejemplo n.º 11
0
    def testOTASettings(self):
        ct_settings = SQLCommtrackConfig.for_domain(self.domain)
        ct_settings.sqlconsumptionconfig = SQLConsumptionConfig(
            min_transactions=10,
            min_window=20,
            optimal_window=60,
        )
        ct_settings.sqlstockrestoreconfig = SQLStockRestoreConfig(
            section_to_consumption_types={'stock': 'consumption'}, )
        set_default_monthly_consumption_for_domain(self.domain,
                                                   5 * DAYS_IN_MONTH)
        restore_settings = ct_settings.get_ota_restore_settings()
        self.assertEqual(1, len(restore_settings.section_to_consumption_types))
        self.assertEqual(
            'consumption',
            restore_settings.section_to_consumption_types['stock'])
        self.assertEqual(10, restore_settings.consumption_config.min_periods)
        self.assertEqual(20, restore_settings.consumption_config.min_window)
        self.assertEqual(60, restore_settings.consumption_config.max_window)
        self.assertEqual(
            150,
            restore_settings.consumption_config.
            default_monthly_consumption_function('foo', 'bar'))
        self.assertFalse(
            restore_settings.force_consumption_case_filter(
                CommCareCase(type='force-type')))
        self.assertEqual(0, len(restore_settings.default_product_list))

        ct_settings.sqlstockrestoreconfig.force_consumption_case_types = [
            'force-type'
        ]
        ct_settings.sqlstockrestoreconfig.use_dynamic_product_list = True
        restore_settings = ct_settings.get_ota_restore_settings()
        self.assertTrue(
            restore_settings.force_consumption_case_filter(
                CommCareCase(type='force-type')))
        self.assertEqual(3, len(restore_settings.default_product_list))
Ejemplo n.º 12
0
    def _create_unsynced_sql(self):
        """
            Create a SQLCommtrackConfig matching the one created by _create_unsynced_couch
        """
        sqlalertconfig = SQLAlertConfig(
            stock_out_facilities=True,
            stock_out_commodities=True,
            stock_out_rates=True,
            non_report=True,
        )
        sqlstockrestoreconfig = SQLStockRestoreConfig(
            section_to_consumption_types={'s1': 'c1'},
            force_consumption_case_types=['type1'],
            use_dynamic_product_list=True,
        )
        sqlconsumptionconfig = SQLConsumptionConfig(
            min_transactions=1,
            min_window=2,
            optimal_window=3,
            use_supply_point_type_default_consumption=True,
            exclude_invalid_periods=False,
        )
        sqlstocklevelsconfig = SQLStockLevelsConfig(
            emergency_level=0.5,
            understock_threshold=1.5,
            overstock_threshold=3,
        )
        sql = SQLCommtrackConfig(
            domain='my_project',
            use_auto_emergency_levels=False,
            sync_consumption_fixtures=False,
            use_auto_consumption=False,
            individual_consumption_defaults=True,
            sqlalertconfig=sqlalertconfig,
            sqlstockrestoreconfig=sqlstockrestoreconfig,
            sqlconsumptionconfig=sqlconsumptionconfig,
            sqlstocklevelsconfig=sqlstocklevelsconfig,
        )
        sql.save(sync_to_couch=False)  # save so that set_actions works

        sql.set_actions([
            SQLActionConfig(
                action='receipts',
                subaction='sub-receipts',
                _keyword='one',
                caption='first action',
            ),
            SQLActionConfig(
                action='receipts',
                subaction='sub-receipts',
                _keyword='two',
                caption='second action',
            ),
        ])
        sql.save(sync_to_couch=False)  # save actions

        # Save submodels
        sqlstockrestoreconfig.commtrack_config = sql
        sqlstockrestoreconfig.save()
        sqlalertconfig.commtrack_config = sql
        sqlalertconfig.save()
        sqlconsumptionconfig.commtrack_config = sql
        sqlconsumptionconfig.save()
        sqlstocklevelsconfig.commtrack_config = sql
        sqlstocklevelsconfig.save()

        return sql
Ejemplo n.º 13
0
 def test_delete_commtrack_config(self):
     SQLCommtrackConfig.for_domain(self.domain.name) or SQLCommtrackConfig(
         domain=self.domain.name).save()
     self.assertIsNotNone(SQLCommtrackConfig.for_domain(self.domain.name))
     self.domain.delete()
     self.assertIsNone(SQLCommtrackConfig.for_domain(self.domain.name))
Ejemplo n.º 14
0
 def test_make_domain_commtrack(self):
     domain_obj = create_domain("test-make-domain-commtrack")
     make_domain_commtrack(domain_obj)
     self.assertTrue(domain_obj.commtrack_enabled)
     self.assertTrue(domain_obj.locations_enabled)
     config = SQLCommtrackConfig.for_domain(domain_obj.name)
     self.assertEqual(
         config.to_json(), {
             'domain':
             'test-make-domain-commtrack',
             'actions': [{
                 'action': 'receipts',
                 'subaction': None,
                 '_keyword': 'r',
                 'caption': 'Received',
             }, {
                 'action': 'consumption',
                 'subaction': None,
                 '_keyword': 'c',
                 'caption': 'Consumed',
             }, {
                 'action': 'consumption',
                 'subaction': 'loss',
                 '_keyword': 'l',
                 'caption': 'Losses',
             }, {
                 'action': 'stockonhand',
                 'subaction': None,
                 '_keyword': 'soh',
                 'caption': 'Stock on hand',
             }, {
                 'action': 'stockout',
                 'subaction': None,
                 '_keyword': 'so',
                 'caption': 'Stock-out',
             }],
             'use_auto_emergency_levels':
             False,
             'sync_consumption_fixtures':
             False,
             'use_auto_consumption':
             False,
             'individual_consumption_defaults':
             False,
             'alert_config': {
                 'stock_out_facilities': False,
                 'stock_out_commodities': False,
                 'stock_out_rates': False,
                 'non_report': False,
             },
             'consumption_config': {
                 'min_transactions': 2,
                 'min_window': 10,
                 'optimal_window': None,
                 'use_supply_point_type_default_consumption': False,
                 'exclude_invalid_periods': False,
             },
             'ota_restore_config': {
                 'section_to_consumption_types': {},
                 'force_consumption_case_types': [],
                 'use_dynamic_product_list': False,
             },
             'stock_levels_config': {
                 'emergency_level': 0.5,
                 'understock_threshold': 1.5,
                 'overstock_threshold': 3,
             }
         })
     doc = CommtrackConfig.get_db().get(config.couch_id)
     self.assertIsNone(Command.get_diff_as_string(doc, config))
     config.delete()
     domain_obj.delete()
Ejemplo n.º 15
0
 def test_delete_commtrack_config(self):
     # Config will have been created by convert_to_commtrack in setUp
     self.assertIsNotNone(SQLCommtrackConfig.for_domain(self.domain.name))
     self.domain.delete()
     self.assertIsNone(SQLCommtrackConfig.for_domain(self.domain.name))
Ejemplo n.º 16
0
 def config(self):
     return SQLCommtrackConfig.for_domain(self.domain)