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 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 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
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)