def get_data(self): sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location ) products = Product.by_domain(self.domain) if self.program_id: products = filter( lambda product: product.program_id == self.program_id, products ) for sp_id in sp_ids: for product in products: loc = SupplyPointCase.get(sp_id).location last_transaction = StockTransaction.latest( sp_id, STOCK_SECTION_TYPE, product._id ) yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( last_transaction, self.start_date, self.end_date ), 'geo': loc._geopoint, }
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.objects.filter(case_id__in=sp_ids).order_by('product_id') product_grouping = {} for state in stock_states: status = state.stock_category() if state.product_id in product_grouping: product_grouping[state.product_id][status] += 1 product_grouping[state.product_id]['facility_count'] += 1 else: product_grouping[state.product_id] = { 'obj': Product.get(state.product_id), 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[state.product_id][status] = 1 for product in product_grouping.values(): yield [ product['obj'].name, product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ]
def chart_data(self): def calculate_weeks_remaining(stock_state, date): if stock_state.last_modified_date < date: if not stock_state.daily_consumption: return 0 consumption = float(stock_state.daily_consumption) * 7.0 quantity = float(stock_state.stock_on_hand) - int((date - state.last_modified_date).days / 7.0) \ * consumption if consumption and consumption > 0 and quantity > 0: return quantity / consumption return 0 stock_states = StockState.include_archived.filter( case_id__in=get_relevant_supply_point_ids(self.config['domain'], self.sublocations[0]), section_id=STOCK_SECTION_TYPE, product_id__in=self.get_products(), last_modified_date__lte=self.config['enddate'], ).order_by('last_modified_date') rows = {} for state in stock_states: product_name = Product.get(state.product_id).name rows[product_name] = [] weeks = ceil((self.config['enddate'] - self.config['startdate']).days / 7.0) for i in range(1, int(weeks + 1)): rows[product_name].append({'x': i, 'y': calculate_weeks_remaining(state, self.config['startdate'] + timedelta(weeks=i))}) return rows
def get_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.objects.filter( section_id=STOCK_SECTION_TYPE, ) if self.program_id: stock_states = stock_states.filter(sql_product__program_id=self.program_id) if len(sp_ids) == 1: stock_states = stock_states.filter( case_id=sp_ids[0], ) return self.leaf_node_data(stock_states) else: stock_states = stock_states.filter( case_id__in=sp_ids, ) if self.config.get('aggregate'): return self.aggregated_data(stock_states) else: return self.raw_product_states(stock_states)
def get_data(self, slugs=None): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) if len(sp_ids) == 1: stock_states = StockState.objects.filter( case_id=sp_ids[0], section_id=STOCK_SECTION_TYPE, last_modified_date__lte=self.end_date, last_modified_date__gte=self.start_date, ) if self.program_id: stock_states = self.filter_by_program(stock_states) return self.leaf_node_data(stock_states) else: stock_states = StockState.objects.filter( case_id__in=sp_ids, section_id=STOCK_SECTION_TYPE, last_modified_date__lte=self.end_date, last_modified_date__gte=self.start_date, ) if self.program_id: stock_states = self.filter_by_program(stock_states) if self.config.get('aggregate'): aggregates = stock_states.values('product_id').annotate( avg_consumption=Avg('daily_consumption'), total_stock=Sum('stock_on_hand') ) return self.aggregated_data(aggregates) else: return self.raw_product_states(stock_states, slugs)
def get_data(self, slugs=None): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) if len(sp_ids) == 1: stock_states = StockState.objects.filter( case_id=sp_ids[0], section_id=STOCK_SECTION_TYPE, last_modified_date__lte=self.end_date, last_modified_date__gte=self.start_date, ) if self.program_id: stock_states = self.filter_by_program(stock_states) return self.leaf_node_data(stock_states) else: stock_states = StockState.objects.filter( case_id__in=sp_ids, section_id=STOCK_SECTION_TYPE, last_modified_date__lte=self.end_date, last_modified_date__gte=self.start_date, ) if self.program_id: stock_states = self.filter_by_program(stock_states) if self.config.get('aggregate'): return self.aggregated_data(stock_states) else: return self.raw_product_states(stock_states, slugs)
def get_data(self, slugs=None): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.objects.filter( section_id=STOCK_SECTION_TYPE, last_modified_date__lte=self.end_date, last_modified_date__gte=self.start_date, ) if len(sp_ids) == 1: stock_states = stock_states.filter( case_id=sp_ids[0], ) if self.program_id: stock_states = self.filter_by_program(stock_states) return self.leaf_node_data(stock_states) else: stock_states = stock_states.filter( case_id__in=sp_ids, ) if self.program_id: stock_states = self.filter_by_program(stock_states) if self.config.get('aggregate'): return self.aggregated_data(stock_states) else: return self.raw_product_states(stock_states, slugs)
def total_records(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) product_ids = get_product_ids_for_program( self.domain, self.program_id) if self.program_id else None return get_total_records(self.domain, sp_ids, STOCK_SECTION_TYPE, product_ids)
def get_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) if len(sp_ids) == 1: return self.leaf_node_data(sp_ids[0]) else: if self.config.get('aggregate'): return self.aggregated_data(sp_ids) else: return self.raw_product_states(sp_ids)
def get_data(self): # todo: this will probably have to paginate eventually if self.all_relevant_forms: sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location, ) form_xmlnses = [form['xmlns'] for form in self.all_relevant_forms.values()] spoint_loc_map = { doc['_id']: doc['location_id'] for doc in iter_docs(SupplyPointCase.get_db(), sp_ids) } locations = { doc['_id']: Location.wrap(doc) for doc in iter_docs(Location.get_db(), spoint_loc_map.values()) } for spoint_id, loc_id in spoint_loc_map.items(): loc = locations[loc_id] form_ids = StockReport.objects.filter( stocktransaction__case_id=spoint_id ).exclude( date__lte=self.start_date ).exclude( date__gte=self.end_date ).values_list( 'form_id', flat=True ).order_by('-date').distinct() # not truly distinct due to ordering matched = False for form_id in form_ids: try: if XFormInstance.get(form_id).xmlns in form_xmlnses: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'reporting', 'geo': loc._geopoint, } matched = True break except ResourceNotFound: logging.error('Stock report for location {} in {} references non-existent form {}'.format( loc._id, loc.domain, form_id )) if not matched: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'nonreporting', 'geo': loc._geopoint, }
def get_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) if len(sp_ids) == 1: return self.leaf_node_data(sp_ids[0]) else: if self.config.get('aggregate'): return self.aggregated_data(sp_ids) else: return self.raw_product_states(sp_ids)
def rows(self): rows = [] if not self.config['products']: prd_id = SQLProduct.objects.filter(domain=self.config['domain'])\ .order_by('code').values_list('product_id') else: prd_id = self.config['products'] if self.config['location_id']: location = Location.get(self.config['location_id']) for loc in location.children: org_summary = OrganizationSummary.objects.filter(date__range=(self.config['startdate'], self.config['enddate']), supply_point=loc._id)[0] soh_data = GroupSummary.objects.get(title=SupplyPointStatusTypes.SOH_FACILITY, org_summary=org_summary) facs = Location.filter_by_type(self.config['domain'], 'FACILITY', loc) facs_count = (float(len(list(facs))) or 1) soh_on_time = soh_data.on_time * 100 / facs_count soh_late = soh_data.late * 100 / facs_count soh_not_responding = soh_data.not_responding * 100 / facs_count fac_ids = get_relevant_supply_point_ids(self.config['domain'], loc) stockouts = (StockTransaction.objects.filter( case_id__in=fac_ids, quantity__lte=0, report__date__month=int(self.config['month']), report__date__year=int(self.config['year'])).count() or 0) / facs_count url = make_url( StockOnHandReport, self.config['domain'], '?location_id=%s&month=%s&year=%s', (loc._id, self.config['month'], self.config['year'])) row_data = [ link_format(loc.name, url), format_percent(soh_on_time), format_percent(soh_late), format_percent(soh_not_responding), format_percent(stockouts) ] for product in prd_id: ps = ProductAvailabilityData.objects.filter( supply_point=loc._id, product=product, date=self.config['startdate']) if ps: row_data.append(format_percent(ps[0].without_stock * 100 / float(ps[0].total))) else: row_data.append("<span class='no_data'>None</span>") rows.append(row_data) return rows
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.include_archived.filter( case_id__in=sp_ids, last_modified_date__lte=self.datespan.enddate_utc, last_modified_date__gte=self.datespan.startdate_utc, section_id=STOCK_SECTION_TYPE ) if not self.archived_products: stock_states = stock_states.exclude( sql_product__is_archived=True ) stock_states = stock_states.order_by('product_id') if self.program_id: stock_states = stock_states.filter( product_id__in=product_ids_filtered_by_program( self.domain, self.program_id ) ) product_grouping = {} for state in stock_states: status = state.stock_category if state.product_id in product_grouping: product_grouping[state.product_id][status] += 1 product_grouping[state.product_id]['facility_count'] += 1 else: product_grouping[state.product_id] = { 'obj': Product.get(state.product_id), 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[state.product_id][status] = 1 for product in product_grouping.values(): yield [ product['obj'].name, product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ]
def get_data(self, slugs=None): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) if len(sp_ids) == 1: stock_states = StockState.objects.filter(case_id=sp_ids[0]) return self.leaf_node_data(stock_states) else: stock_states = StockState.objects.filter(case_id__in=sp_ids) if self.config.get('aggregate'): aggregates = stock_states.values('product_id').annotate( avg_consumption=Avg('daily_consumption'), total_stock=Sum('stock_on_hand') ) return self.aggregated_data(aggregates) else: return self.raw_cases(stock_states, slugs)
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.include_archived.filter( case_id__in=sp_ids, last_modified_date__lte=self.datespan.enddate_utc, last_modified_date__gte=self.datespan.startdate_utc, section_id=STOCK_SECTION_TYPE) if not self.archived_products: stock_states = stock_states.exclude(sql_product__is_archived=True) stock_states = stock_states.order_by('product_id') if self.program_id: stock_states = stock_states.filter( product_id__in=product_ids_filtered_by_program( self.domain, self.program_id)) product_grouping = {} for state in stock_states: status = state.stock_category if state.product_id in product_grouping: product_grouping[state.product_id][status] += 1 product_grouping[state.product_id]['facility_count'] += 1 else: product_grouping[state.product_id] = { 'obj': Product.get(state.product_id), 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[state.product_id][status] = 1 for product in product_grouping.values(): yield [ product['obj'].name, product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ]
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) product_ids = get_product_ids_for_program( self.domain, self.program_id) if self.program_id else None ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=sp_ids, section_id=STOCK_SECTION_TYPE, entry_ids=product_ids, pagination=self.pagination, ) product_grouping = {} for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value( Domain.get_by_name(self.domain), ledger_value) status = consumption_helper.get_stock_category() if ledger_value.entry_id in product_grouping: product_grouping[ledger_value.entry_id][status] += 1 product_grouping[ledger_value.entry_id]['facility_count'] += 1 else: product_grouping[ledger_value.entry_id] = { 'entry_id': ledger_value.entry_id, 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[ledger_value.entry_id][status] = 1 product_name_map = get_product_id_name_mapping(self.domain) rows = [[ product_name_map.get(product['entry_id'], product['entry_id']), product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ] for product in product_grouping.values()] return sorted(rows, key=lambda r: r[0].lower())
def get_data(self): # todo: this will probably have to paginate eventually if self.all_relevant_forms: sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location, ) supply_points = ( SupplyPointCase.wrap(doc) for doc in iter_docs(SupplyPointCase.get_db(), sp_ids)) form_xmlnses = [ form['xmlns'] for form in self.all_relevant_forms.values() ] for supply_point in supply_points: # todo: get locations in bulk loc = supply_point.location transactions = StockTransaction.objects.filter( case_id=supply_point._id, ).exclude(report__date__lte=self.start_date).exclude( report__date__gte=self.end_date).order_by('-report__date') matched = False for trans in transactions: if XFormInstance.get( trans.report.form_id).xmlns in form_xmlnses: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'reporting', 'geo': loc._geopoint, } matched = True break if not matched: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'nonreporting', 'geo': loc._geopoint, }
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) stock_states = StockState.objects.filter( case_id__in=sp_ids, last_modified_date__lte=self.datespan.enddate_utc, last_modified_date__gte=self.datespan.startdate_utc, section_id=STOCK_SECTION_TYPE ) stock_states = stock_states.order_by('product_id') if self.program_id: stock_states = stock_states.filter(sql_product__program_id=self.program_id) product_grouping = {} for state in stock_states: status = state.stock_category if state.product_id in product_grouping: product_grouping[state.product_id][status] += 1 product_grouping[state.product_id]['facility_count'] += 1 else: product_grouping[state.product_id] = { 'obj': Product.get(state.product_id), 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[state.product_id][status] = 1 rows = [[ product['obj'].name, product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ] for product in product_grouping.values()] return sorted(rows, key=lambda r: r[0].lower())
def get_prod_data(self): sp_ids = get_relevant_supply_point_ids(self.domain, self.active_location) product_ids = get_product_ids_for_program(self.domain, self.program_id) if self.program_id else None ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=sp_ids, section_id=STOCK_SECTION_TYPE, entry_ids=product_ids, ) product_grouping = {} for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value( Domain.get_by_name(self.domain), ledger_value ) status = consumption_helper.get_stock_category() if ledger_value.entry_id in product_grouping: product_grouping[ledger_value.entry_id][status] += 1 product_grouping[ledger_value.entry_id]['facility_count'] += 1 else: product_grouping[ledger_value.entry_id] = { 'entry_id': ledger_value.entry_id, 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1 } product_grouping[ledger_value.entry_id][status] = 1 product_name_map = get_product_id_name_mapping(self.domain) rows = [[ product_name_map.get(product['entry_id'], product['entry_id']), product['facility_count'], 100.0 * product['stockout'] / product['facility_count'], 100.0 * product['understock'] / product['facility_count'], 100.0 * product['adequate'] / product['facility_count'], 100.0 * product['overstock'] / product['facility_count'], 100.0 * product['nodata'] / product['facility_count'], ] for product in product_grouping.values()] return sorted(rows, key=lambda r: r[0].lower())
def get_data(self): # todo: this will probably have to paginate eventually if self.all_relevant_forms: sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location, ) supply_points = (SupplyPointCase.wrap(doc) for doc in iter_docs(SupplyPointCase.get_db(), sp_ids)) form_xmlnses = [form['xmlns'] for form in self.all_relevant_forms.values()] for supply_point in supply_points: # todo: get locations in bulk loc = supply_point.location transactions = StockTransaction.objects.filter( case_id=supply_point._id, ).exclude( report__date__lte=self.start_date ).exclude( report__date__gte=self.end_date ).order_by('-report__date') matched = False for trans in transactions: if XFormInstance.get(trans.report.form_id).xmlns in form_xmlnses: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'reporting', 'geo': loc._geopoint, } matched = True break if not matched: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': 'nonreporting', 'geo': loc._geopoint, }
def get_data(self): sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location ) products = Product.by_domain(self.domain) if self.program_id: products = filter( lambda product: product.program_id == self.program_id, products ) for sp_id in sp_ids: loc = SupplyPointCase.get(sp_id).location transactions = StockTransaction.objects.filter( case_id=sp_id, section_id=STOCK_SECTION_TYPE, ) if transactions: last_transaction = sorted( transactions, key=lambda trans: trans.report.date )[-1] else: last_transaction = None yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( last_transaction, self.start_date, self.end_date ), 'geo': loc._geopoint, }
def get_data(self): # todo: this will probably have to paginate eventually if self.all_relevant_forms: sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location, ) form_xmlnses = [ form['xmlns'] for form in self.all_relevant_forms.values() ] form_xmlnses.append(COMMTRACK_REPORT_XMLNS) spoint_loc_map = { doc['_id']: doc['location_id'] for doc in iter_docs(SupplyPointCase.get_db(), sp_ids) } locations = _location_map(list(spoint_loc_map.values())) for spoint_id, loc_id in spoint_loc_map.items(): if loc_id not in locations: continue # it's archived, skip loc = locations[loc_id] results = StockReport.objects.filter( stocktransaction__case_id=spoint_id).filter( date__gte=self.converted_start_datetime, date__lte=self.converted_end_datetime).values_list( 'form_id', 'date').distinct( ) # not truly distinct due to ordering matched = False for form_id, date in results: try: if XFormInstance.get(form_id).xmlns in form_xmlnses: yield { 'parent_name': loc.parent.name if loc.parent else '', 'loc_id': loc.location_id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type.name, 'reporting_status': 'reporting', 'geo': geopoint(loc), 'last_reporting_date': date, } matched = True break except ResourceNotFound: logging.error( 'Stock report for location {} in {} references non-existent form {}' .format(loc.location_id, loc.domain, form_id)) if not matched: result = StockReport.objects.filter( stocktransaction__case_id=spoint_id).values_list( 'date').order_by('-date')[:1] yield { 'parent_name': loc.parent.name if loc.parent else '', 'loc_id': loc.location_id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type.name, 'reporting_status': 'nonreporting', 'geo': geopoint(loc), 'last_reporting_date': result[0][0] if result else '' }
def get_data(self): # todo: this will probably have to paginate eventually if self.all_relevant_forms: sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location, ) form_xmlnses = [form['xmlns'] for form in self.all_relevant_forms.values()] spoint_loc_map = { doc['_id']: doc['location_id'] for doc in iter_docs(SupplyPointCase.get_db(), sp_ids) } locations = _location_map(spoint_loc_map.values()) for spoint_id, loc_id in spoint_loc_map.items(): if loc_id not in locations: continue # it's archived, skip loc = locations[loc_id] results = StockReport.objects.filter( stocktransaction__case_id=spoint_id ).filter( date__gte=self.converted_start_datetime, date__lte=self.converted_end_datetime ).values_list( 'form_id', 'date' ).distinct() # not truly distinct due to ordering matched = False for form_id, date in results: try: if XFormInstance.get(form_id).xmlns in form_xmlnses: yield { 'loc': loc, 'loc_id': loc.location_id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type.name, 'reporting_status': 'reporting', 'geo': geopoint(loc), 'last_reporting_date': date, } matched = True break except ResourceNotFound: logging.error('Stock report for location {} in {} references non-existent form {}'.format( loc.location_id, loc.domain, form_id )) if not matched: result = StockReport.objects.filter( stocktransaction__case_id=spoint_id ).values_list( 'date' ).order_by('-date')[:1] yield { 'loc': loc, 'loc_id': loc.location_id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type.name, 'reporting_status': 'nonreporting', 'geo': geopoint(loc), 'last_reporting_date': result[0][0] if result else '' }
def _sp_ids(self): return get_relevant_supply_point_ids(self.domain, self.active_location)
def _sp_ids(self): return get_relevant_supply_point_ids(self.domain, self.active_location)
def get_prod_data(self): def get_months_until_stockout_icon(value): STOCKOUT = 0.0 LOW = 1 ADEQUATE = 3 if float(value) == STOCKOUT: return '%s <span class="icon-remove" style="color:red"/>' % value elif float(value) < LOW: return '%s <span class="icon-warning-sign" style="color:orange"/>' % value elif float(value) <= ADEQUATE: return '%s <span class="icon-ok" style="color:green"/>' % value elif float(value) > ADEQUATE: return '%s <span class="icon-arrow-up" style="color:purple"/>' % value state_grouping = {} if self.config['program'] and not self.config['product']: product_ids = [product.get_id for product in Product.by_program_id(self.config['domain'], self.config['program'])] elif self.config['program'] and self.config['product']: product_ids = [self.config['product']] else: product_ids = Product.ids_by_domain(self.config['domain']) stock_states = StockState.objects.filter( case_id__in=get_relevant_supply_point_ids(self.config['domain'], self.sublocations[0]), section_id=STOCK_SECTION_TYPE, product_id__in=product_ids ).order_by('-last_modified_date') for state in stock_states: days = (datetime.now() - state.last_modified_date).days monthly_consumption = int(state.get_monthly_consumption()) if state.get_monthly_consumption() else 0 if state.product_id not in state_grouping: state_grouping[state.product_id] = { 'commodity': Product.get(state.product_id).name, 'months_until_stockout': "%.2f" % (days / 30.0) if state.stock_on_hand else '', 'months_until_stockout_helper': state.stock_on_hand != 0, 'stockout_duration': timesince(state.last_modified_date) if state.stock_on_hand == 0 else '', 'stockout_duration_helper': state.stock_on_hand == 0, 'current_stock': state.stock_on_hand, 'monthly_consumption': monthly_consumption, 'reorder_level': int(monthly_consumption * REORDER_LEVEL), 'maximum_level': int(monthly_consumption * MAXIMUM_LEVEL), 'date_of_last_report': state.last_modified_date.strftime("%Y-%m-%d") } else: if not state_grouping[state.product_id]['months_until_stockout_helper']: if state.stock_on_hand: state_grouping[state.product_id]['months_until_stockout'] = "%.2f" % (days / 30.0) else: state_grouping[state.product_id]['stockout_duration_helper'] = False if state_grouping[state.product_id]['stockout_duration_helper']: if not state.stock_on_hand: state_grouping[state.product_id]['stockout_duration'] = timesince(state.last_modified_date) else: state_grouping[state.product_id]['stockout_duration_helper'] = False for values in state_grouping.values(): yield { 'commodity': values['commodity'], 'current_stock': int(values['current_stock']), 'monthly_consumption': values['monthly_consumption'] if values['monthly_consumption'] != 0.00 else 'not enough data', 'months_until_stockout': get_months_until_stockout_icon(values['months_until_stockout'] if values['months_until_stockout'] else 0.0), 'stockout_duration': values['stockout_duration'], 'date_of_last_report': values['date_of_last_report'], 'reorder_level': values['reorder_level'] if values['reorder_level'] != 0.00 else 'unknown', 'maximum_level': values['maximum_level'] if values['maximum_level'] != 0.00 else 'unknown'}
def get_data(self): sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location ) products = Product.by_domain(self.domain) if self.program_id: products = filter( lambda product: product.program_id == self.program_id, products ) for sp_id in sp_ids: loc = SupplyPointCase.get(sp_id).location transactions = StockTransaction.objects.filter( case_id=sp_id, ).exclude( report__date__lte=self.start_date ).exclude( report__date__gte=self.end_date ) if transactions: last_transaction = sorted( transactions, key=lambda trans: trans.report.date )[-1] else: last_transaction = None if self.all_relevant_forms: forms_xmlns = [] for form in self.all_relevant_forms.values(): forms_xmlns.append(form['xmlns']) if last_transaction: form = XFormInstance.get(last_transaction.report.form_id) if form.xmlns in forms_xmlns: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( last_transaction, self.start_date, self.end_date ), 'geo': loc._geopoint, } else: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( None, self.start_date, self.end_date ), 'geo': loc._geopoint, }
def get_prod_data(self): for sublocation in self.sublocations: sp_ids = get_relevant_supply_point_ids(self.config['domain'], sublocation) stock_states = StockState.include_archived.filter( case_id__in=sp_ids, last_modified_date__lte=self.config['enddate'], last_modified_date__gte=self.config['startdate'], section_id=STOCK_SECTION_TYPE ) stock_states = stock_states.order_by('product_id') state_grouping = {} for state in stock_states: status = state.stock_category if state.product_id in state_grouping: state_grouping[state.product_id][status] += 1 else: state_grouping[state.product_id] = { 'id': state.product_id, 'stockout': 0, 'understock': 0, 'overstock': 0, 'adequate': 0, 'nodata': 0, 'facility_count': 1, 'amc': int(state.get_monthly_consumption() or 0) } state_grouping[state.product_id][status] = 1 location_grouping = { 'location': sublocation.name, 'stockout': 0, 'understock': 0, 'adequate': 0, 'overstock': 0, 'total': 0, 'amc': 0 } product_ids = [] if self.config['program'] != '' and self.config['product'] == '': product_ids = [product.get_id for product in Product.by_program_id(self.config['domain'], self.config['program'])] elif self.config['program'] != '' and self.config['product'] != '': product_ids = [self.config['product']] else: product_ids = Product.ids_by_domain(self.config['domain']) for product in state_grouping.values(): if product['id'] in product_ids: location_grouping['stockout'] += product['stockout'] location_grouping['understock'] += product['understock'] location_grouping['adequate'] += product['adequate'] location_grouping['overstock'] += product['overstock'] location_grouping['total'] += sum([product['stockout'], product['understock'], product['adequate'], product['overstock']]) location_grouping['amc'] += product['amc'] location_grouping['stockout'] = self.percent_fn(location_grouping['total'], location_grouping['stockout']) location_grouping['understock'] = self.percent_fn(location_grouping['total'], location_grouping['understock']) location_grouping['adequate'] = self.percent_fn(location_grouping['total'], location_grouping['adequate']) location_grouping['overstock'] = self.percent_fn(location_grouping['total'], location_grouping['overstock']) yield location_grouping