Example #1
0
    def products(self, value):
        # this will set stocks_all_products to true if the user
        # has added all products in the domain to this location
        self.stocks_all_products = (set(value) ==
                                    set(SQLProduct.by_domain(self.domain)))

        self._products = value
Example #2
0
 def products(self):
     """
     If there are no products specified for this location, assume all
     products for the domain are relevant.
     """
     if self.stocks_all_products:
         return SQLProduct.by_domain(self.domain)
     else:
         return self._products.all()
Example #3
0
 def products(self):
     """
     If there are no products specified for this location, assume all
     products for the domain are relevant.
     """
     if self.stocks_all_products:
         return SQLProduct.by_domain(self.domain)
     else:
         return self._products.all()
Example #4
0
    def rows(self):
        def percent(x, y):
            return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x)

        def _stock_status(status, loc):
            daily = status.daily_consumption or 0
            state = status.stock_on_hand / ((daily * 30) or 1)
            if state == 0.0:
                return "stockout"
            elif state < loc.location_type.understock_threshold:
                return "adequate"
            elif state < loc.location_type.overstock_threshold + 7:
                return "low"
            else:
                return "overstock"

        locations = self.get_locations(self.config['location_id'], self.config['domain'])

        row_data = {}

        for product in SQLProduct.by_domain(self.domain).exclude(is_archived=True):
            row_data[product.name] = {'total_fac': 0, 'reported_fac': 0,
                                      'stockout': 0, 'low': 0, 'overstock': 0, 'adequate': 0}

        for location in locations:
            location_products = list(location.products)
            stock_states = StockState.objects.filter(
                case_id=location.supply_point_id,
                section_id=STOCK_SECTION_TYPE,
                sql_product__in=location_products
            )

            for product in location_products:
                row_data[product.name]['total_fac'] += 1

            for state in stock_states:
                p_name = state.sql_product.name
                row_data[p_name]['reported_fac'] += 1
                s = _stock_status(state, location)
                row_data[p_name][s] += 1

        rows = []
        for k, v in row_data.iteritems():
            if v['total_fac'] > 0:
                rows.append([
                    k,
                    v['total_fac'],
                    v['reported_fac'],
                    percent(v['stockout'], v['reported_fac']),
                    percent(v['adequate'], v['reported_fac']),
                    percent(v['low'], v['reported_fac']),
                    percent(v['overstock'], v['reported_fac']),
                ])
        return rows
Example #5
0
 def handle(self):
     topic = self.args[0].lower()
     if topic == 'stock':
         self.respond("Please send your receipts in the format "
                      "' <Commodity code> <stock on hand > . <quantity received>'")
     elif topic == 'stop':
         self.respond("Text 'stop' to stop receiving text message reminders.")
     elif topic == 'start':
         self.respond("Text 'start' to get text message reminders every week to submit your stock reports.")
     elif 'code' in topic:
         codes = SQLProduct.by_domain(self.domain).order_by('code').values_list('code', flat=True)
         self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes))
     else:
         try:
             sql_product = SQLProduct.objects.get(domain=self.domain, code=topic)
             msg = "%s is the commodity code for %s" % (topic, sql_product.name)
             if sql_product.units:
                 msg += " (%s)" % sql_product.units
             if sql_product.description and sql_product.description not in sql_product.name:
                 msg += " %s" % sql_product.description
             self.respond(msg)
         except SQLProduct.DoesNotExist:
             self.help()
Example #6
0
 def handle(self):
     topic = self.args[0].lower()
     if topic == 'stock':
         self.respond("Please send your receipts in the format "
                      "' <Commodity code> <stock on hand > . <quantity received>'")
     elif topic == 'reminder':
         if user_needs_reminders(self.user):
             self.respond(DEACTIVATE_REMINDERS)
         else:
             self.respond(REACTIVATE_REMINDERS)
     elif 'code' in topic:
         codes = SQLProduct.by_domain(self.domain).order_by('code').values_list('code', flat=True)
         self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes))
     else:
         try:
             sql_product = SQLProduct.objects.get(domain=self.domain, code=topic)
             msg = "%s is the commodity code for %s" % (topic, sql_product.name)
             if sql_product.units:
                 msg += " (%s)" % sql_product.units
             if sql_product.description and sql_product.description not in sql_product.name:
                 msg += " %s" % sql_product.description
             self.respond(msg)
         except SQLProduct.DoesNotExist:
             self.help()
Example #7
0
 def handle(self):
     topic = self.args[0].lower()
     if topic == 'stock':
         self.respond("Please send your receipts in the format "
                      "' <Commodity code> <stock on hand > . <quantity received>'")
     elif topic == 'reminder':
         if user_needs_reminders(self.user):
             self.respond(DEACTIVATE_REMINDERS)
         else:
             self.respond(REACTIVATE_REMINDERS)
     elif 'code' in topic:
         codes = SQLProduct.by_domain(self.domain).order_by('code').values_list('code', flat=True)
         self.respond("Available commodity codes: %(codes)s", codes=", ".join(codes))
     else:
         try:
             sql_product = SQLProduct.objects.get(domain=self.domain, code=topic)
             msg = "%s is the commodity code for %s" % (topic, sql_product.name)
             if sql_product.units:
                 msg += " (%s)" % sql_product.units
             if sql_product.description and sql_product.description not in sql_product.name:
                 msg += " %s" % sql_product.description
             self.respond(msg)
         except SQLProduct.DoesNotExist:
             self.help()
Example #8
0
 def all_products(self):
     return [(p.product_id, p.name)
             for p in SQLProduct.by_domain(self.domain)]
Example #9
0
    def rows(self):
        def percent(x, y):
            return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x)

        def _stock_status(transaction, daily_consumption, loc):
            state = transaction.stock_on_hand / ((daily_consumption * 30) or 1)
            if state == 0.0:
                return "stockout"
            elif state < loc.location_type.understock_threshold:
                return "adequate"
            elif state < loc.location_type.overstock_threshold + 7:
                return "low"
            else:
                return "overstock"

        locations = self.get_locations(self.config['location_id'],
                                       self.config['domain'])

        row_data = {}

        for product in SQLProduct.by_domain(
                self.domain).exclude(is_archived=True):
            row_data[product.name] = {
                'total_fac': 0,
                'reported_fac': 0,
                'stockout': 0,
                'low': 0,
                'overstock': 0,
                'adequate': 0
            }

        transactions = self._last_transaction_for_product_in_period()
        stock_states = StockState.objects.filter(
            sql_location__in=locations).values_list('case_id', 'product_id',
                                                    'daily_consumption')

        location_product_to_consumption = {
            (case_id, product_id): daily_consumption or 0
            for case_id, product_id, daily_consumption in stock_states
        }

        for location in locations:
            location_products = list(
                location.products.exclude(is_archived=True))

            for product in location_products:
                row_data[product.name]['total_fac'] += 1

            for transaction in transactions.get(location.supply_point_id, []):
                sql_product = transaction.sql_product
                if sql_product not in location_products:
                    continue
                p_name = sql_product.name
                row_data[p_name]['reported_fac'] += 1
                daily_consumption = location_product_to_consumption.get(
                    (location.supply_point_id, transaction.product_id), 0)
                s = _stock_status(transaction, daily_consumption, location)
                row_data[p_name][s] += 1

        rows = []
        for k, v in six.iteritems(row_data):
            if v['total_fac'] > 0:
                rows.append([
                    k,
                    v['total_fac'],
                    v['reported_fac'],
                    percent(v['stockout'], v['reported_fac']),
                    percent(v['adequate'], v['reported_fac']),
                    percent(v['low'], v['reported_fac']),
                    percent(v['overstock'], v['reported_fac']),
                ])
        return rows
Example #10
0
    def rows(self):
        def percent(x, y):
            return "%d%% <small>(%d)</small>" % (x * 100 / (y or 1), x)

        def _stock_status(transaction, daily_consumption, loc):
            state = transaction.stock_on_hand / ((daily_consumption * 30) or 1)
            if state == 0.0:
                return "stockout"
            elif state < loc.location_type.understock_threshold:
                return "adequate"
            elif state < loc.location_type.overstock_threshold + 7:
                return "low"
            else:
                return "overstock"

        locations = self.get_locations(self.config['location_id'], self.config['domain'])

        row_data = {}

        for product in SQLProduct.by_domain(self.domain).exclude(is_archived=True):
            row_data[product.name] = {'total_fac': 0, 'reported_fac': 0,
                                      'stockout': 0, 'low': 0, 'overstock': 0, 'adequate': 0}

        transactions = self._last_transaction_for_product_in_period()
        stock_states = StockState.objects.filter(
            sql_location__in=locations
        ).values_list('case_id', 'product_id', 'daily_consumption')

        location_product_to_consumption = {
            (case_id, product_id): daily_consumption or 0
            for case_id, product_id, daily_consumption in stock_states
        }

        for location in locations:
            location_products = list(location.products.exclude(is_archived=True))

            for product in location_products:
                row_data[product.name]['total_fac'] += 1

            for transaction in transactions.get(location.supply_point_id, []):
                sql_product = transaction.sql_product
                if sql_product not in location_products:
                    continue
                p_name = sql_product.name
                row_data[p_name]['reported_fac'] += 1
                daily_consumption = location_product_to_consumption.get(
                    (location.supply_point_id, transaction.product_id), 0
                )
                s = _stock_status(transaction, daily_consumption, location)
                row_data[p_name][s] += 1

        rows = []
        for k, v in six.iteritems(row_data):
            if v['total_fac'] > 0:
                rows.append([
                    k,
                    v['total_fac'],
                    v['reported_fac'],
                    percent(v['stockout'], v['reported_fac']),
                    percent(v['adequate'], v['reported_fac']),
                    percent(v['low'], v['reported_fac']),
                    percent(v['overstock'], v['reported_fac']),
                ])
        return rows
Example #11
0
 def all_products(self):
     return [(p.product_id, p.name)
             for p in SQLProduct.by_domain(self.domain)]
Example #12
0
 def get_products(self):
     """
     If there are no products specified for this location, assume all
     products for the domain are relevant.
     """
     return self.products.all() or SQLProduct.by_domain(self.domain)