def leaf_node_data(self, supply_point_id): ledger_values = get_wrapped_ledger_values( self.domain, [supply_point_id], section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids) for ledger_value in ledger_values: result = { 'product_id': ledger_value.sql_product.product_id, 'product_name': ledger_value.sql_product.name, 'current_stock': format_decimal(ledger_value.balance), } if self._include_advanced_data(): consumption_helper = get_consumption_helper_from_ledger_value( self.project, ledger_value) result.update({ 'location_id': ledger_value.location_id, 'category': consumption_helper.get_stock_category(), 'consumption': consumption_helper.get_monthly_consumption(), 'months_remaining': consumption_helper.get_months_remaining(), 'resupply_quantity_needed': consumption_helper.get_resupply_quantity_needed() }) yield result
def _get_dict_for_ledger_value(self, ledger_value): values = { self.SLUG_PRODUCT_NAME: ledger_value.sql_product.name, self.SLUG_PRODUCT_ID: ledger_value.entry_id, self.SLUG_CURRENT_STOCK: ledger_value.balance, } if self._include_advanced_data(): consumption_helper = get_consumption_helper_from_ledger_value( self.project, ledger_value) values.update({ self.SLUG_LOCATION_ID: ledger_value.location_id, self.SLUG_CONSUMPTION: consumption_helper.get_monthly_consumption(), self.SLUG_MONTHS_REMAINING: consumption_helper.get_months_remaining(), self.SLUG_CATEGORY: consumption_helper.get_stock_category(), self.SLUG_LAST_REPORTED: ledger_value.last_modified, self.SLUG_RESUPPLY_QUANTITY_NEEDED: consumption_helper.get_resupply_quantity_needed() }) return values
def leaf_node_data(self, supply_point_id): ledger_values = get_wrapped_ledger_values( self.domain, [supply_point_id], section_id=STOCK_SECTION_TYPE, entry_ids=self.product_ids ) for ledger_value in ledger_values: result = { 'product_id': ledger_value.sql_product.product_id, 'product_name': ledger_value.sql_product.name, 'current_stock': format_decimal(ledger_value.balance), } if self._include_advanced_data(): consumption_helper = get_consumption_helper_from_ledger_value(self.project, ledger_value) result.update({ 'location_id': ledger_value.location_id, 'category': consumption_helper.get_stock_category(), 'consumption': consumption_helper.get_monthly_consumption(), 'months_remaining': consumption_helper.get_months_remaining(), 'resupply_quantity_needed': consumption_helper.get_resupply_quantity_needed() }) yield result
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 _get_dict_for_ledger_value(self, ledger_value): values = { self.SLUG_PRODUCT_NAME: ledger_value.sql_product.name, self.SLUG_PRODUCT_ID: ledger_value.entry_id, self.SLUG_CURRENT_STOCK: ledger_value.balance, } if self._include_advanced_data(): consumption_helper = get_consumption_helper_from_ledger_value(self.project, ledger_value) values.update({ self.SLUG_LOCATION_ID: ledger_value.location_id, self.SLUG_CONSUMPTION: consumption_helper.get_monthly_consumption(), self.SLUG_MONTHS_REMAINING: consumption_helper.get_months_remaining(), self.SLUG_CATEGORY: consumption_helper.get_stock_category(), self.SLUG_LAST_REPORTED: ledger_value.last_modified, self.SLUG_RESUPPLY_QUANTITY_NEEDED: consumption_helper.get_resupply_quantity_needed() }) return values
def get_prod_data(self): ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=self._sp_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.filter_by_product_ids(), ) product_grouping = {} domain_obj = Domain.get_by_name(self.domain) for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value( domain_obj, 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 = self._product_name_mapping 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(), reverse=self._desc_product_order)
def get_prod_data(self): ledger_values = get_wrapped_ledger_values( domain=self.domain, case_ids=self._sp_ids, section_id=STOCK_SECTION_TYPE, entry_ids=self.filter_by_product_ids(), ) product_grouping = {} domain_obj = Domain.get_by_name(self.domain) for ledger_value in ledger_values: consumption_helper = get_consumption_helper_from_ledger_value(domain_obj, 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 = self._product_name_mapping 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(), reverse=self._desc_product_order)
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 consumption_helper(self): from corehq.apps.reports.commtrack.util import get_consumption_helper_from_ledger_value return get_consumption_helper_from_ledger_value(self.domain, self)
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