Example #1
0
    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()
Example #2
0
    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()
Example #3
0
 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
         }
Example #4
0
    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
Example #5
0
 def get_months_remaining(self):
     return months_of_stock_remaining(self.balance,
                                      self.get_daily_consumption())
Example #6
0
 def months_remaining(self):
     return months_of_stock_remaining(
         self.stock_on_hand,
         self.get_daily_consumption()
     )
Example #7
0
    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
Example #8
0
 def get_months_remaining(self):
     return months_of_stock_remaining(
         self.balance,
         self.get_daily_consumption()
     )
Example #9
0
    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
Example #10
0
 def months_remaining(self):
     return months_of_stock_remaining(
         self.stock_on_hand,
         self.get_daily_consumption()
     )
Example #11
0
    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