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_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 aggregated_data(self, supply_point_ids): def _convert_to_daily(consumption): return consumption / 30 if consumption is not None else None if self._include_advanced_data(): product_aggregation = {} ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=supply_point_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids) for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value( self.domain, ledger_value) if ledger_value.entry_id in product_aggregation: product = product_aggregation[ledger_value.entry_id] product['current_stock'] = format_decimal( product['current_stock'] + ledger_value.balance) consumption = consumption_helper.get_monthly_consumption() if product['consumption'] is None: product['consumption'] = consumption elif consumption is not None: product['consumption'] += consumption product['count'] += 1 if ledger_value.sql_location is not None: location_type = ledger_value.sql_location.location_type product['category'] = stock_category( product['current_stock'], _convert_to_daily(product['consumption']), location_type.understock_threshold, location_type.overstock_threshold, ) else: product['category'] = 'nodata' product['months_remaining'] = months_of_stock_remaining( product['current_stock'], _convert_to_daily(product['consumption'])) else: product = ledger_value.sql_product consumption = consumption_helper.get_monthly_consumption() product_aggregation[ledger_value.entry_id] = { 'product_id': ledger_value.entry_id, 'location_id': None, 'product_name': product.name, 'resupply_quantity_needed': None, 'current_stock': format_decimal(Decimal(ledger_value.balance)), 'count': 1, 'consumption': consumption, 'category': consumption_helper.get_stock_category(), 'months_remaining': months_of_stock_remaining( ledger_value.balance, _convert_to_daily(consumption)) } return list(product_aggregation.values()) else: # If we don't need advanced data, we can # just do some orm magic. # # Note: this leaves out some harder to get quickly # values like location_id, but shouldn't be needed # unless we expand what uses this. aggregated_ledger_values = get_aggregated_ledger_values( domain=self.domain, case_ids=supply_point_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids) product_name_map = get_product_id_name_mapping(self.domain) result = [] for ag in aggregated_ledger_values: result.append({ 'product_name': product_name_map.get(ag.entry_id), 'product_id': ag.entry_id, 'current_stock': format_decimal(Decimal(ag.balance)) }) return result
def _product_name_mapping(self): return get_product_id_name_mapping(self.domain, self.program_id)
def aggregated_data(self, supply_point_ids): def _convert_to_daily(consumption): return consumption / 30 if consumption is not None else None if self._include_advanced_data(): product_aggregation = {} ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=supply_point_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids ) for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value(self.project, ledger_value) if ledger_value.entry_id in product_aggregation: product = product_aggregation[ledger_value.entry_id] product['current_stock'] = format_decimal( product['current_stock'] + ledger_value.balance ) consumption = consumption_helper.get_monthly_consumption() if product['consumption'] is None: product['consumption'] = consumption elif consumption is not None: product['consumption'] += consumption product['count'] += 1 if ledger_value.sql_location is not None: location_type = ledger_value.sql_location.location_type product['category'] = stock_category( product['current_stock'], _convert_to_daily(product['consumption']), location_type.understock_threshold, location_type.overstock_threshold, ) else: product['category'] = 'nodata' product['months_remaining'] = months_of_stock_remaining( product['current_stock'], _convert_to_daily(product['consumption']) ) else: product = ledger_value.sql_product consumption = consumption_helper.get_monthly_consumption() product_aggregation[ledger_value.entry_id] = { 'product_id': ledger_value.entry_id, 'location_id': None, 'product_name': product.name, 'resupply_quantity_needed': None, 'current_stock': format_decimal(ledger_value.balance), 'count': 1, 'consumption': consumption, 'category': consumption_helper.get_stock_category(), 'months_remaining': months_of_stock_remaining( ledger_value.balance, _convert_to_daily(consumption) ) } return product_aggregation.values() else: # If we don't need advanced data, we can # just do some orm magic. # # Note: this leaves out some harder to get quickly # values like location_id, but shouldn't be needed # unless we expand what uses this. aggregated_ledger_values = get_aggregated_ledger_values( domain=self.domain, case_ids=supply_point_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids ) product_name_map = get_product_id_name_mapping(self.domain) result = [] for ag in aggregated_ledger_values: result.append({ 'product_name': product_name_map.get(ag.entry_id), 'product_id': ag.entry_id, 'current_stock': format_decimal(Decimal(ag.balance)) }) return result