def aggregated_data(self, stock_states): product_aggregation = {} for state in stock_states: if state.product_id in product_aggregation: product = product_aggregation[state.product_id] product['current_stock'] = self.format_decimal( product['current_stock'] + state.stock_on_hand ) if product['total_consumption'] is None: product['total_consumption'] = state.get_consumption() elif state.get_consumption() is not None: product['total_consumption'] += state.get_consumption() product['count'] += 1 if product['total_consumption'] is not None: product['consumption'] = product['total_consumption'] / product['count'] else: product['consumption'] = None product['category'] = stock_category( product['current_stock'], product['consumption'], Domain.get_by_name(self.domain) ) product['months_remaining'] = months_of_stock_remaining( product['current_stock'], product['consumption'] ) else: product = Product.get(state.product_id) consumption = state.get_consumption() product_aggregation[state.product_id] = { 'product_id': product._id, 'location_id': None, 'product_name': product.name, 'location_lineage': None, 'resupply_quantity_needed': None, 'current_stock': self.format_decimal(state.stock_on_hand), 'total_consumption': consumption, 'count': 1, 'consumption': consumption, 'category': stock_category( state.stock_on_hand, consumption, Domain.get_by_name(self.domain) ), 'months_remaining': months_of_stock_remaining( state.stock_on_hand, consumption ) } return product_aggregation.values()
def aggregated_data(self, stock_states): def _convert_to_daily(consumption): return consumption / 30 if consumption is not None else None product_aggregation = {} for state in stock_states: if state.product_id in product_aggregation: product = product_aggregation[state.product_id] product['current_stock'] = format_decimal( product['current_stock'] + state.stock_on_hand ) consumption = state.get_monthly_consumption() if product['consumption'] is None: product['consumption'] = consumption elif consumption is not None: product['consumption'] += consumption product['count'] += 1 product['category'] = stock_category( product['current_stock'], _convert_to_daily(product['consumption']), Domain.get_by_name(self.domain) ) product['months_remaining'] = months_of_stock_remaining( product['current_stock'], _convert_to_daily(product['consumption']) ) else: product = Product.get(state.product_id) consumption = state.get_monthly_consumption() product_aggregation[state.product_id] = { 'product_id': product._id, 'location_id': None, 'product_name': product.name, 'location_lineage': None, 'resupply_quantity_needed': None, 'current_stock': format_decimal(state.stock_on_hand), 'count': 1, 'consumption': consumption, 'category': stock_category( state.stock_on_hand, _convert_to_daily(consumption), Domain.get_by_name(self.domain) ), 'months_remaining': months_of_stock_remaining( state.stock_on_hand, _convert_to_daily(consumption) ) } return product_aggregation.values()
def get_stock_category(self): if not self.sql_location: return 'nodata' location_type = self.sql_location.location_type return stock_category( self.balance, self.get_daily_consumption(), location_type.understock_threshold, location_type.overstock_threshold, )
def aggregated_data(self, stock_states): for state in stock_states: product = Product.get(state['product_id']) yield { 'category': stock_category(state['total_stock'], state['avg_consumption']), 'product_id': product._id, 'consumption': state['avg_consumption'], 'months_remaining': months_of_stock_remaining(state['total_stock'], state['avg_consumption']), 'location_id': None, 'product_name': product.name, 'current_stock': state['total_stock'], 'location_lineage': None }
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 aggregated_data(self, stock_states): def _convert_to_daily(consumption): return consumption / 30 if consumption is not None else None if self._include_advanced_data(): product_aggregation = {} for state in stock_states: if state.product_id in product_aggregation: product = product_aggregation[state.product_id] product['current_stock'] = format_decimal( product['current_stock'] + state.stock_on_hand ) consumption = state.get_monthly_consumption() if product['consumption'] is None: product['consumption'] = consumption elif consumption is not None: product['consumption'] += consumption product['count'] += 1 if state.sql_location is not None: location_type = state.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 = Product.get(state.product_id) consumption = state.get_monthly_consumption() product_aggregation[state.product_id] = { 'product_id': product._id, 'location_id': None, 'product_name': product.name, 'location_lineage': None, 'resupply_quantity_needed': None, 'current_stock': format_decimal(state.stock_on_hand), 'count': 1, 'consumption': consumption, 'category': state_stock_category(state), 'months_remaining': months_of_stock_remaining( state.stock_on_hand, _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_states = stock_states.values_list( 'sql_product__name', 'sql_product__product_id', ).annotate(stock_on_hand=Sum('stock_on_hand')) result = [] for ag in aggregated_states: result.append({ 'product_name': ag[0], 'product_id': ag[1], 'current_stock': format_decimal(ag[2]) }) return result
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
def aggregated_data(self, stock_states): def _convert_to_daily(consumption): return consumption / 30 if consumption is not None else None if self._include_advanced_data(): product_aggregation = {} for state in stock_states: if state.product_id in product_aggregation: product = product_aggregation[state.product_id] product['current_stock'] = format_decimal( product['current_stock'] + state.stock_on_hand) consumption = state.get_monthly_consumption() if product['consumption'] is None: product['consumption'] = consumption elif consumption is not None: product['consumption'] += consumption product['count'] += 1 if state.sql_location is not None: location_type = state.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 = Product.get(state.product_id) consumption = state.get_monthly_consumption() product_aggregation[state.product_id] = { 'product_id': product._id, 'location_id': None, 'product_name': product.name, 'location_lineage': None, 'resupply_quantity_needed': None, 'current_stock': format_decimal(state.stock_on_hand), 'count': 1, 'consumption': consumption, 'category': state_stock_category(state), 'months_remaining': months_of_stock_remaining( state.stock_on_hand, _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_states = stock_states.values_list( 'sql_product__name', 'sql_product__product_id', ).annotate(stock_on_hand=Sum('stock_on_hand')) result = [] for ag in aggregated_states: result.append({ 'product_name': ag[0], 'product_id': ag[1], 'current_stock': format_decimal(ag[2]) }) return result