def _test_subtype(self, initial, final): case_id = uuid.uuid4().hex CommCareCase( _id=case_id, domain='fakedomain', ).save() product_id = uuid.uuid4().hex SQLProduct(product_id=product_id, domain='fakedomain').save() report = StockReport.objects.create(form_id=uuid.uuid4().hex, date=ago(1), server_date=datetime.utcnow(), type=const.REPORT_TYPE_BALANCE) txn = StockTransaction( report=report, section_id=const.SECTION_TYPE_STOCK, type=const.TRANSACTION_TYPE_STOCKONHAND, subtype=initial, case_id=case_id, product_id=product_id, stock_on_hand=Decimal(10), ) txn.save() saved = StockTransaction.objects.get(id=txn.id) self.assertEqual(final, saved.subtype)
def setUpClass(cls): super(TestGetValuesByProduct, cls).setUpClass() cls.data = [ { "product": "coke", "section": "soh", "balance": 32 }, { "product": "coke", "section": "consumption", "balance": 63 }, { "product": "surge", "section": "soh", "balance": 85 }, { "product": "fanta", "section": "soh", "balance": 11 }, ] product_ids = {p['product'] for p in cls.data} SQLProduct.objects.bulk_create([ SQLProduct(domain=cls.domain_name, product_id=id, code=id) for id in product_ids ])
class StockTestBase(TestCase): @classmethod def setUpClass(cls): super(StockTestBase, cls).setUpClass() cls.domain = create_domain("stock-report-test") @classmethod def tearDownClass(cls): cls.domain.delete() super(StockTestBase, cls).tearDownClass() def setUp(self): # create case case = CaseFactory(domain=self.domain.name).create_case() self.case_id = case.case_id self.product_id = uuid.uuid4().hex SQLProduct(product_id=self.product_id, domain=self.domain.name).save() self._stock_report = functools.partial(_stock_report, self.domain.name, self.case_id, self.product_id) self._receipt_report = functools.partial(_receipt_report, self.domain.name, self.case_id, self.product_id) self._test_config = ConsumptionConfiguration.test_config() self._compute_consumption = functools.partial( compute_daily_consumption, self.domain.name, self.case_id, self.product_id, now, configuration=self._test_config)
def setUp(self): super(TestGetValuesByProduct, self).setUp() self.ledger_processor = FormProcessorInterface( domain=self.domain_name).ledger_processor self.domain_obj = create_domain(self.domain_name) SQLProduct.objects.bulk_create([ SQLProduct(domain=self.domain_name, product_id=data['product_id'], code=data['product']) for data in self.data ]) transactions_flat = [] self.transactions = {} for d in self.data: product = d['product'] product_id = d['product_id'] section = d['section'] balance = d['balance'] transactions_flat.append( StockTransactionHelper(case_id=self.case_id, section_id=section, product_id=product_id, action='soh', quantity=balance, timestamp=datetime.utcnow())) self.transactions.setdefault(self.case_id, {}).setdefault(section, {})[product] = balance self.new_stock_report, self.form = self.create_report( transactions_flat) self._create_models_for_stock_report_helper(self.form, self.new_stock_report)
def handle(self): topic = self.args[0].lower() if topic == 'stock': self.respond( "Please send your receipts in the format " "' <Commodity code> <stock on hand > . <quantity received>'") elif topic == 'reminder': if user_needs_reminders(self.user): self.respond(DEACTIVATE_REMINDERS) else: self.respond(REACTIVATE_REMINDERS) elif 'code' in topic: codes = SQLProduct.by_domain( self.domain).order_by('code').values_list('code', flat=True) self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes)) else: try: sql_product = SQLProduct.objects.get(domain=self.domain, code=topic) msg = "%s is the commodity code for %s" % (topic, sql_product.name) if sql_product.units: msg += " (%s)" % sql_product.units if sql_product.description and sql_product.description not in sql_product.name: msg += " %s" % sql_product.description self.respond(msg) except SQLProduct.DoesNotExist: self.help()
def products(self, value): # this will set stocks_all_products to true if the user # has added all products in the domain to this location self.stocks_all_products = (set(value) == set( SQLProduct.by_domain(self.domain))) self._products.set(value)
def products(self, value): # this will set stocks_all_products to true if the user # has added all products in the domain to this location self.stocks_all_products = (set(value) == set(SQLProduct.by_domain(self.domain))) self._products = value
def products(self): """ If there are no products specified for this location, assume all products for the domain are relevant. """ if self.stocks_all_products: return SQLProduct.by_domain(self.domain) else: return self._products.all()
def rows(self): def percent(x, y): return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x) def _stock_status(status, loc): daily = status.daily_consumption or 0 state = status.stock_on_hand / ((daily * 30) or 1) if state == 0.0: return "stockout" elif state < loc.location_type.understock_threshold: return "adequate" elif state < loc.location_type.overstock_threshold + 7: return "low" else: return "overstock" locations = self.get_locations(self.config['location_id'], self.config['domain']) row_data = {} for product in SQLProduct.by_domain(self.domain).exclude(is_archived=True): row_data[product.name] = {'total_fac': 0, 'reported_fac': 0, 'stockout': 0, 'low': 0, 'overstock': 0, 'adequate': 0} for location in locations: location_products = list(location.products) stock_states = StockState.objects.filter( case_id=location.supply_point_id, section_id=STOCK_SECTION_TYPE, sql_product__in=location_products ) for product in location_products: row_data[product.name]['total_fac'] += 1 for state in stock_states: p_name = state.sql_product.name row_data[p_name]['reported_fac'] += 1 s = _stock_status(state, location) row_data[p_name][s] += 1 rows = [] for k, v in row_data.iteritems(): if v['total_fac'] > 0: rows.append([ k, v['total_fac'], v['reported_fac'], percent(v['stockout'], v['reported_fac']), percent(v['adequate'], v['reported_fac']), percent(v['low'], v['reported_fac']), percent(v['overstock'], v['reported_fac']), ]) return rows
def setUpClass(cls): cls.domain = Domain(name='test') cls.domain.save() cls.case_id = uuid.uuid4().hex CommCareCase( _id=cls.case_id, domain='fakedomain', ).save() cls.product_id = uuid.uuid4().hex SQLProduct(product_id=cls.product_id).save()
def setUpClass(cls): super(LogisticsConsumptionTest, cls).setUpClass() cls.domain = Domain(name='test') cls.domain.save() cls.case_id = uuid.uuid4().hex CommCareCase( _id=cls.case_id, domain='fakedomain', ).save() cls.product_id = uuid.uuid4().hex SQLProduct(product_id=cls.product_id, domain='fakedomain').save()
def setUp(self): # create case self.case_id = uuid.uuid4().hex CommCareCase( _id=self.case_id, domain='fakedomain', ).save() self.product_id = uuid.uuid4().hex SQLProduct(product_id=self.product_id).save() self._stock_report = functools.partial(_stock_report, self.case_id, self.product_id) self._receipt_report = functools.partial(_receipt_report, self.case_id, self.product_id) self._test_config = ConsumptionConfiguration.test_config() self._compute_consumption = functools.partial(compute_daily_consumption, self.case_id, self.product_id, now, configuration=self._test_config)
def handle(self): topic = self.args[0].lower() if topic == 'stock': self.respond("Please send your receipts in the format " "' <Commodity code> <stock on hand > . <quantity received>'") elif topic == 'stop': self.respond("Text 'stop' to stop receiving text message reminders.") elif topic == 'start': self.respond("Text 'start' to get text message reminders every week to submit your stock reports.") elif 'code' in topic: codes = SQLProduct.by_domain(self.domain).order_by('code').values_list('code', flat=True) self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes)) else: try: sql_product = SQLProduct.objects.get(domain=self.domain, code=topic) msg = "%s is the commodity code for %s" % (topic, sql_product.name) if sql_product.units: msg += " (%s)" % sql_product.units if sql_product.description and sql_product.description not in sql_product.name: msg += " %s" % sql_product.description self.respond(msg) except SQLProduct.DoesNotExist: self.help()
def handle(self): topic = self.args[0].lower() if topic == 'stock': self.respond("Please send your receipts in the format " "' <Commodity code> <stock on hand > . <quantity received>'") elif topic == 'reminder': if user_needs_reminders(self.user): self.respond(DEACTIVATE_REMINDERS) else: self.respond(REACTIVATE_REMINDERS) elif 'code' in topic: codes = SQLProduct.by_domain(self.domain).order_by('code').values_list('code', flat=True) self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes)) else: try: sql_product = SQLProduct.objects.get(domain=self.domain, code=topic) msg = "%s is the commodity code for %s" % (topic, sql_product.name) if sql_product.units: msg += " (%s)" % sql_product.units if sql_product.description and sql_product.description not in sql_product.name: msg += " %s" % sql_product.description self.respond(msg) except SQLProduct.DoesNotExist: self.help()
def get_products(self): """ If there are no products specified for this location, assume all products for the domain are relevant. """ return self.products.all() or SQLProduct.by_domain(self.domain)
def all_products(self): return [(p.product_id, p.name) for p in SQLProduct.by_domain(self.domain)]
def rows(self): def percent(x, y): return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x) def _stock_status(transaction, daily_consumption, loc): state = transaction.stock_on_hand / ((daily_consumption * 30) or 1) if state == 0.0: return "stockout" elif state < loc.location_type.understock_threshold: return "adequate" elif state < loc.location_type.overstock_threshold + 7: return "low" else: return "overstock" locations = self.get_locations(self.config['location_id'], self.config['domain']) row_data = {} for product in SQLProduct.by_domain( self.domain).exclude(is_archived=True): row_data[product.name] = { 'total_fac': 0, 'reported_fac': 0, 'stockout': 0, 'low': 0, 'overstock': 0, 'adequate': 0 } transactions = self._last_transaction_for_product_in_period() stock_states = StockState.objects.filter( sql_location__in=locations).values_list('case_id', 'product_id', 'daily_consumption') location_product_to_consumption = { (case_id, product_id): daily_consumption or 0 for case_id, product_id, daily_consumption in stock_states } for location in locations: location_products = list( location.products.exclude(is_archived=True)) for product in location_products: row_data[product.name]['total_fac'] += 1 for transaction in transactions.get(location.supply_point_id, []): sql_product = transaction.sql_product if sql_product not in location_products: continue p_name = sql_product.name row_data[p_name]['reported_fac'] += 1 daily_consumption = location_product_to_consumption.get( (location.supply_point_id, transaction.product_id), 0) s = _stock_status(transaction, daily_consumption, location) row_data[p_name][s] += 1 rows = [] for k, v in six.iteritems(row_data): if v['total_fac'] > 0: rows.append([ k, v['total_fac'], v['reported_fac'], percent(v['stockout'], v['reported_fac']), percent(v['adequate'], v['reported_fac']), percent(v['low'], v['reported_fac']), percent(v['overstock'], v['reported_fac']), ]) return rows
def rows(self): def percent(x, y): return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x) def _stock_status(transaction, daily_consumption, loc): state = transaction.stock_on_hand / ((daily_consumption * 30) or 1) if state == 0.0: return "stockout" elif state < loc.location_type.understock_threshold: return "adequate" elif state < loc.location_type.overstock_threshold + 7: return "low" else: return "overstock" locations = self.get_locations(self.config['location_id'], self.config['domain']) row_data = {} for product in SQLProduct.by_domain(self.domain).exclude(is_archived=True): row_data[product.name] = {'total_fac': 0, 'reported_fac': 0, 'stockout': 0, 'low': 0, 'overstock': 0, 'adequate': 0} transactions = self._last_transaction_for_product_in_period() stock_states = StockState.objects.filter( sql_location__in=locations ).values_list('case_id', 'product_id', 'daily_consumption') location_product_to_consumption = { (case_id, product_id): daily_consumption or 0 for case_id, product_id, daily_consumption in stock_states } for location in locations: location_products = list(location.products.exclude(is_archived=True)) for product in location_products: row_data[product.name]['total_fac'] += 1 for transaction in transactions.get(location.supply_point_id, []): sql_product = transaction.sql_product if sql_product not in location_products: continue p_name = sql_product.name row_data[p_name]['reported_fac'] += 1 daily_consumption = location_product_to_consumption.get( (location.supply_point_id, transaction.product_id), 0 ) s = _stock_status(transaction, daily_consumption, location) row_data[p_name][s] += 1 rows = [] for k, v in six.iteritems(row_data): if v['total_fac'] > 0: rows.append([ k, v['total_fac'], v['reported_fac'], percent(v['stockout'], v['reported_fac']), percent(v['adequate'], v['reported_fac']), percent(v['low'], v['reported_fac']), percent(v['overstock'], v['reported_fac']), ]) return rows