def _report_info(self): program_id = self.request.GET.get('filter_by_program') return [['Title of report', 'Location', 'Date range', 'Program'], [ self.title, self.location.name if self.location else 'NATIONAL', '{} - {}'.format(ews_date_format(self.datespan.startdate), ews_date_format(self.datespan.enddate)), 'all' if not program_id or program_id == 'all' else Program.get(docid=program_id).name ], []]
def select_options(self): start_year = getattr(settings, 'START_YEAR', 2008) years = [ dict(val=six.text_type(y), text=y) for y in range(start_year, datetime.utcnow().year + 1) ] years.reverse() months = [ dict(val="%02d" % m, text=calendar.month_name[m]) for m in range(1, 13) ] now = datetime.now() three_month_earlier = now - relativedelta(months=3) first_friday = rrule(DAILY, dtstart=datetime(three_month_earlier.year, three_month_earlier.month, 1), until=now, byweekday=FR)[0] if first_friday.day != 1: first_friday = first_friday - relativedelta(days=7) fridays = rrule(WEEKLY, dtstart=first_friday, until=now, byweekday=FR) weeks = [] value = None text = None for idx, val in enumerate(fridays): try: value = '{0}|{1}'.format(val.strftime("%Y-%m-%d"), fridays[idx + 1].strftime("%Y-%m-%d")) text = '{0} - {1}'.format( ews_date_format(val), ews_date_format(fridays[idx + 1] - relativedelta(days=1))) except IndexError: next_thursday = val + relativedelta(days=6) value = '{0}|{1}'.format(val.strftime("%Y-%m-%d"), next_thursday.strftime("%Y-%m-%d")) text = '{0} - {1}'.format(ews_date_format(val), ews_date_format(next_thursday)) finally: weeks.append(dict(val=value, text=text)) return [{ 'text': 'Week (Friday - Thursday)', 'val': 2, 'firstOptions': weeks, 'secondOptions': [] }, { 'text': 'Month', 'val': 1, 'firstOptions': months, 'secondOptions': years }]
def _report_info(self): program_id = self.request.GET.get('filter_by_program') return [ ['Title of report', 'Location', 'Date range', 'Program'], [ self.title, self.location.name if self.location else 'NATIONAL', '{} - {}'.format( ews_date_format(self.datespan.startdate), ews_date_format(self.datespan.enddate) ), 'all' if not program_id or program_id == 'all' else Program.get(docid=program_id).name ], [] ]
def rows(self): supply_points = self.location.get_descendants().filter( location_type__administrative=False, is_archived=False).exclude(supply_point_id__isnull=True).values_list('supply_point_id', flat=True) transactions = StockTransaction.objects.filter( case_id__in=supply_points, sql_product__in=self.products, report__date__range=[self.datespan.startdate, self.datespan.end_of_end_day]).order_by('case_id', '-report__date') product_dict = {p.code: idx for idx, p in enumerate(self.products)} rows = OrderedDict() for tr in transactions: key = (tr.case_id, tr.report.date.date(), tr.type) if key not in rows: rows[key] = ['No Data'] * self.products.count() * 2 product_idx = product_dict[tr.sql_product.code] * 2 rows[key][product_idx] = tr.stock_on_hand rows[key][product_idx + 1] = tr.quantity if tr.quantity else 'No Data' for key, val in rows.iteritems(): loc = SQLLocation.objects.get(supply_point_id=key[0]) date = key[1] yield [ loc.name, ews_date_format(date), key[2] ] + val
def rows(self): if self.location.location_type.administrative: supply_points = self.location.get_descendants().filter( location_type__administrative=False, is_archived=False).exclude( supply_point_id__isnull=True).values_list( 'supply_point_id', flat=True) else: supply_points = [self.location.supply_point_id] transactions = StockTransaction.objects.filter( case_id__in=supply_points, sql_product__in=self.products, report__date__range=[ self.datespan.startdate, self.datespan.end_of_end_day ]).order_by('case_id', '-report__date') product_dict = {p.code: idx for idx, p in enumerate(self.products)} rows = OrderedDict() for tr in transactions: key = (tr.case_id, tr.report.date.date(), tr.type) if key not in rows: rows[key] = ['No Data'] * self.products.count() * 2 product_idx = product_dict[tr.sql_product.code] * 2 rows[key][product_idx] = tr.stock_on_hand rows[key][product_idx + 1] = tr.quantity if tr.quantity else 'No Data' for key, val in rows.iteritems(): loc = SQLLocation.objects.get(supply_point_id=key[0]) date = key[1] yield [loc.name, ews_date_format(date), key[2]] + val
def select_options(self): start_year = getattr(settings, 'START_YEAR', 2008) years = [dict(val=unicode(y), text=y) for y in range(start_year, datetime.utcnow().year + 1)] years.reverse() months = [dict(val="%02d" % m, text=calendar.month_name[m]) for m in range(1, 13)] now = datetime.now() three_month_earlier = now - relativedelta(months=3) first_friday = rrule(DAILY, dtstart=datetime(three_month_earlier.year, three_month_earlier.month, 1), until=now, byweekday=FR)[0] if first_friday.day != 1: first_friday = first_friday - relativedelta(days=7) fridays = rrule(WEEKLY, dtstart=first_friday, until=now, byweekday=FR) weeks = [] value = None text = None for idx, val in enumerate(fridays): try: value = '{0}|{1}'.format(val.strftime("%Y-%m-%d"), fridays[idx + 1].strftime("%Y-%m-%d")) text = '{0} - {1}'.format( ews_date_format(val), ews_date_format(fridays[idx + 1] - relativedelta(days=1)) ) except IndexError: next_thursday = val + relativedelta(days=6) value = '{0}|{1}'.format(val.strftime("%Y-%m-%d"), next_thursday.strftime("%Y-%m-%d")) text = '{0} - {1}'.format(ews_date_format(val), ews_date_format(next_thursday)) finally: weeks.append(dict(val=value, text=text)) return [ { 'text': 'Week (Friday - Thursday)', 'val': 2, 'firstOptions': weeks, 'secondOptions': [] }, { 'text': 'Month', 'val': 1, 'firstOptions': months, 'secondOptions': years } ]
def report_subtitles(self): if self.is_rendered_as_email: program = self.request.GET.get('filter_by_program') products = self.request.GET.getlist('filter_by_product') return mark_safe(""" <br>For Filters:<br> Location: {0}<br> Program: {1}<br> Product: {2}<br> Date range: {3} - {4} """.format( self.location.name, Program.get(program).name if program and program != ALL_OPTION else ALL_OPTION.title(), ", ".join( [p.name for p in SQLProduct.objects.filter(product_id__in=products)] ) if products != ALL_OPTION and products else ALL_OPTION.title(), ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc) )) return None
def rows(self): rows = [] if self.location_id: for name, location_id, date in self.config['incomplete_table']: url = make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location_id, self.config['startdate'], self.config['enddate']) ) rows.append([link_format(name, url), ews_date_format(date)]) return rows
def report_subtitles(self): if self.is_rendered_as_email: program = self.request.GET.get('filter_by_program') products = self.request.GET.getlist('filter_by_product') return mark_safe(""" <br>For Filters:<br> Location: {0}<br> Program: {1}<br> Product: {2}<br> Date range: {3} - {4} """.format( self.location.name, Program.get(program).name if program and program != ALL_OPTION else ALL_OPTION.title(), ", ".join([ p.name for p in SQLProduct.objects.filter(product_id__in=products) ]) if products != ALL_OPTION and products else ALL_OPTION.title(), ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc))) return None
def rows(self): rows = [] if self.location_id: for name, location_id, date in self.config['incomplete_table']: url = make_url(ReportingRatesReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location_id, self.config['startdate'], self.config['enddate'])) rows.append([ link_format(name, url) if not self.config['is_rendered_as_email'] else name, ews_date_format(date) ]) return rows
def rows(self): rows = [] if self.location_id: for name, location_id, date in self.config['incomplete_table']: url = make_url( ReportingRatesReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location_id, self.config['startdate'], self.config['enddate']) ) rows.append( [ link_format(name, url) if not self.config['is_rendered_as_email'] else name, ews_date_format(date) ] ) return rows
def rows(self): rows = [] if self.location_id: for name, location_id, date, supply_point_id in self.config['non_reporting_table']: url = make_url( ReportingRatesReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location_id, self.config['startdate'], self.config['enddate']) ) st = StockTransaction.objects.filter( case_id=supply_point_id, report__date__lte=self.config['startdate'] ).select_related('report').order_by('-report__date') if st: date = ews_date_format(st[0].report.date) else: date = '---' rows.append([link_format(name, url) if not self.config['is_rendered_as_email'] else name, date]) return rows
def rows(self): rows = [] if self.location_id: for name, location_id, date, supply_point_id in self.config['non_reporting_table']: url = make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location_id, self.config['startdate'], self.config['enddate']) ) st = StockTransaction.objects.filter( case_id=supply_point_id, report__date__lte=self.config['startdate'] ).select_related('report__date').order_by('-report__date') if st: date = ews_date_format(st[0].report.date) else: date = '---' rows.append([link_format(name, url), date]) return rows
def rows(self): rows = [] if self.location_id: for name, location_id, date, supply_point_id in self.config["non_reporting_table"]: url = make_url( ReportingRatesReport, self.config["domain"], "?location_id=%s&startdate=%s&enddate=%s", (location_id, self.config["startdate"], self.config["enddate"]), ) st = ( StockTransaction.objects.filter(case_id=supply_point_id, report__date__lte=self.config["startdate"]) .select_related("report__date") .order_by("-report__date") ) if st: date = ews_date_format(st[0].report.date) else: date = "---" rows.append([link_format(name, url) if not self.config["is_rendered_as_email"] else name, date]) return rows
def rows(self): rows = [] if self.location_id: supply_points = self.reporting_supply_points() for location in SQLLocation.objects.filter(supply_point_id__in=supply_points): st = StockTransaction.objects.filter( case_id=location.supply_point_id, report__date__range=[self.config['startdate'], self.config['enddate']] ).order_by('-report__date') products_per_location = {product.product_id for product in location.products} if products_per_location - set(st.values_list('product_id', flat=True)): if st: date = ews_date_format(st[0].report.date) else: date = '---' url = make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location.location_id, self.config['startdate'], self.config['enddate'])) rows.append([link_format(location.name, url), date]) return rows
def rows(self): rows = [] if self.location_id: supply_points = self.get_supply_points() not_reported = supply_points.exclude(supply_point_id__in=self.reporting_supply_points()) for location in not_reported: url = make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (location.location_id, self.config['startdate'], self.config['enddate']) ) st = StockTransaction.objects.filter( case_id=location.supply_point_id, report__date__lte=self.config['startdate'] ).order_by('-report__date') if st: date = ews_date_format(st[0].report.date) else: date = '---' rows.append([link_format(location.name, url), date]) return rows
def get_prod_data(self): def get_months_until_stockout_icon(value, loc): if float(value) == 0.0: return '%s <span class="fa fa-remove" style="color:red"/>' % value elif float(value) <= loc.location_type.understock_threshold: return '%s <span class="fa fa-exclamation-triangle" style="color:orange"/>' % value elif loc.location_type.understock_threshold < float( value) < loc.location_type.overstock_threshold: return '%s <span class="fa fa-check" style="color:green"/>' % value elif float(value) >= loc.location_type.overstock_threshold: return '%s <span class="fa fa-arrow-up" style="color:purple"/>' % value state_grouping = {} loc = SQLLocation.objects.get(location_id=self.config['location_id']) stock_states = StockState.objects.filter( case_id=loc.supply_point_id, section_id=STOCK_SECTION_TYPE, sql_product__in=self.unique_products( SQLLocation.objects.filter( pk=loc.pk))).order_by('-last_modified_date') for state in stock_states: monthly_consumption = state.get_monthly_consumption() max_level = 0 if monthly_consumption: monthly_consumption = round(monthly_consumption) max_level = round(monthly_consumption * float(loc.location_type.overstock_threshold)) state_grouping[state.product_id] = { 'commodity': state.sql_product.name, 'months_until_stockout': "%.1f" % (float(state.stock_on_hand) / monthly_consumption) if state.stock_on_hand and monthly_consumption else 0, 'stockout_duration': '', 'stockout_duration_helper': True, 'current_stock': state.stock_on_hand, 'monthly_consumption': monthly_consumption, 'reorder_level': round(max_level / 2.0), 'maximum_level': max_level, 'last_report': ews_date_format(state.last_modified_date) } if state.stock_on_hand == 0: try: st = StockTransaction.objects.filter( case_id=loc.supply_point_id, product_id=state.product_id, stock_on_hand__gt=0).latest('report__date') state_grouping[ state.product_id]['stockout_duration'] = timesince( st.report.date, now=datetime.datetime.now()) except StockTransaction.DoesNotExist: state_grouping[ state.product_id]['stockout_duration'] = 'Always' else: state_grouping[ state.product_id]['stockout_duration_helper'] = False for values in state_grouping.values(): if values['monthly_consumption'] is not None or values[ 'current_stock'] == 0: months_until_stockout = get_months_until_stockout_icon( values['months_until_stockout'] if values['months_until_stockout'] else 0.0, loc) else: months_until_stockout = '-' if values['monthly_consumption'] and values[ 'monthly_consumption'] != 0.00: monthly_consumption = int(values['monthly_consumption']) else: monthly_consumption = 'not enough data' if values['maximum_level'] and values['maximum_level'] != 0.00: maximum_level = int(values['maximum_level']) else: maximum_level = 'unknown' if values['reorder_level'] and values['reorder_level'] != 0.00: reorder_level = int(values['reorder_level']) else: reorder_level = 'unknown' yield { 'commodity': values['commodity'], 'current_stock': int(values['current_stock']) if values['current_stock'] is not None else '--', 'monthly_consumption': monthly_consumption, 'months_until_stockout': months_until_stockout, 'stockout_duration': values['stockout_duration'], 'last_report': values['last_report'], 'reorder_level': reorder_level, 'maximum_level': maximum_level }
def title(self): return 'Weekly Stock Summary Report - CMS and RMS - {0} {1}'.format( ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc))
def title(self): return 'Weekly Stock Summary Report - {0} - {1} {2}'.format( self.location.name, ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc))
def title(self): return 'Weekly Stock Summary Report - {0} - {1} {2}'.format( SQLLocation.objects.get( location_id=self.report_config['location_id']).name, ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc))
def title(self): return 'Weekly Stock Summary Report - CMS and RMS - {0} {1}'.format( ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc) )
def title(self): return 'Weekly Stock Summary Report - {0} - {1} {2}'.format( self.location.name, ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc) )
def title(self): return 'Weekly Stock Summary Report - {0} - {1} {2}'.format( SQLLocation.objects.get(location_id=self.report_config['location_id']).name, ews_date_format(self.datespan.startdate_utc), ews_date_format(self.datespan.enddate_utc) )
def get_prod_data(self): def get_months_until_stockout_icon(value, loc): if float(value) == 0.0: return '%s <span class="icon-remove" style="color:red"/>' % value elif float(value) < loc.location_type.understock_threshold: return '%s <span class="icon-warning-sign" style="color:orange"/>' % value elif loc.location_type.understock_threshold < float(value) < loc.location_type.overstock_threshold: return '%s <span class="icon-ok" style="color:green"/>' % value elif float(value) >= loc.location_type.overstock_threshold: return '%s <span class="icon-arrow-up" style="color:purple"/>' % value state_grouping = {} loc = SQLLocation.objects.get(location_id=self.config['location_id']) stock_states = StockState.objects.filter( case_id=loc.supply_point_id, section_id=STOCK_SECTION_TYPE, sql_product__in=self.unique_products(SQLLocation.objects.filter(pk=loc.pk)) ).order_by('-last_modified_date') for state in stock_states: if state.daily_consumption: monthly_consumption = round(state.get_monthly_consumption()) max_level = round(monthly_consumption * float(loc.location_type.overstock_threshold)) else: monthly_consumption = None max_level = 0 state_grouping[state.product_id] = { 'commodity': state.sql_product.name, 'months_until_stockout': "%.1f" % (float(state.stock_on_hand) / monthly_consumption) if state.stock_on_hand and monthly_consumption else 0, 'stockout_duration': '', 'stockout_duration_helper': True, 'current_stock': state.stock_on_hand, 'monthly_consumption': monthly_consumption, 'reorder_level': round(max_level / 2.0), 'maximum_level': max_level, 'last_report': ews_date_format(state.last_modified_date) } if state.stock_on_hand == 0: try: st = StockTransaction.objects.filter( case_id=loc.supply_point_id, product_id=state.product_id, stock_on_hand__gt=0 ).latest('report__date') state_grouping[state.product_id]['stockout_duration'] = timesince( st.report.date, now=datetime.datetime.now() ) except StockTransaction.DoesNotExist: state_grouping[state.product_id]['stockout_duration'] = 'Always' else: state_grouping[state.product_id]['stockout_duration_helper'] = False for values in state_grouping.values(): if values['monthly_consumption'] is not None or values['current_stock'] == 0: months_until_stockout = get_months_until_stockout_icon( values['months_until_stockout'] if values['months_until_stockout'] else 0.0, loc ) else: months_until_stockout = '-' if values['monthly_consumption'] and values['monthly_consumption'] != 0.00: monthly_consumption = int(values['monthly_consumption']) else: monthly_consumption = 'not enough data' if values['maximum_level'] and values['maximum_level'] != 0.00: maximum_level = int(values['maximum_level']) else: maximum_level = 'unknown' if values['reorder_level'] and values['reorder_level'] != 0.00: reorder_level = int(values['reorder_level']) else: reorder_level = 'unknown' yield { 'commodity': values['commodity'], 'current_stock': int(values['current_stock']) if values['current_stock'] is not None else '--', 'monthly_consumption': monthly_consumption, 'months_until_stockout': months_until_stockout, 'stockout_duration': values['stockout_duration'], 'last_report': values['last_report'], 'reorder_level': reorder_level, 'maximum_level': maximum_level}
def rows(self): rows = [] if self.location_id: for name, location_id, date in self.config["incomplete_table"]: url = make_url( ReportingRatesReport, self.config["domain"], "?location_id=%s&startdate=%s&enddate=%s", (location_id, self.config["startdate"], self.config["enddate"]), ) rows.append( [link_format(name, url) if not self.config["is_rendered_as_email"] else name, ews_date_format(date)] ) return rows