def rows(self): rows = [] unique_products = self.unique_products( get_supply_points(self.config['domain'], self.config['location_id']), all=(not self.config['export']) ) if self.config['location_id']: for case_id, products in self.config['months_of_stock'].iteritems(): sp = SQLLocation.objects.get(supply_point_id=case_id) url = make_url( StockStatus, self.config['domain'], '?location_id=%s&filter_by_program=%s&startdate=%s&enddate=%s&report_type=%s', (sp.location_id, self.config['program'] or ALL_OPTION, self.config['startdate'].date(), self.config['enddate'].date(), self.config['report_type']) ) row = [ link_format(sp.name, url) if not self.config.get('is_rendered_as_email', False) else sp.name ] for p in unique_products: product_data = products.get(p.product_id) if product_data: value = '%.1f' % product_data else: value = '-' row.append(value) rows.append(row) return rows
def post(self, request, *args, **kwargs): InputStockFormSet = formset_factory(InputStockForm) formset = InputStockFormSet(request.POST) if formset.is_valid(): try: sql_location = SQLLocation.objects.get(site_code=kwargs['site_code'], domain=self.domain) except SQLLocation.DoesNotExist: raise Http404() text = '' for form in formset: product = Product.get(docid=form.cleaned_data['product_id']) if form.cleaned_data['stock_on_hand'] is not None: text += '{} {}.{} '.format( product.code, form.cleaned_data['stock_on_hand'], form.cleaned_data['receipts'] or 0 ) amount = form.cleaned_data['default_consumption'] if amount is not None: set_default_consumption_for_supply_point( self.domain, product.get_id, sql_location.supply_point_id, amount ) if text: WebSubmissionHandler(self.request.couch_user, self.domain, Msg(text), sql_location).handle() url = make_url( StockStatus, self.domain, '?location_id=%s&filter_by_program=%s&startdate=' '&enddate=&report_type=&filter_by_product=%s', (sql_location.location_id, ALL_OPTION, ALL_OPTION) ) return HttpResponseRedirect(url) context = self.get_context_data(**kwargs) context['formset'] = formset return self.render_to_response(context)
def test_web_user_report_submission(self): self.client.login(username=self.username5, password=self.password5) view_url = reverse('input_stock', kwargs={'domain': TEST_DOMAIN, 'site_code': 'tsactive'}) data = { 'form-TOTAL_FORMS': 2, 'form-INITIAL_FORMS': 2, 'form-MAX_NUM_FORMS': 1000 } tsactive = SQLLocation.objects.get(domain=TEST_DOMAIN, site_code='tsactive') data['form-0-product_id'] = self.ad.product_id data['form-0-product'] = 'ad' data['form-0-stock_on_hand'] = 20 data['form-0-receipts'] = 30 data['form-1-product_id'] = self.al.product_id data['form-1-product'] = 'al' data['form-1-stock_on_hand'] = 14 data['form-1-receipts'] = 17 response = self.client.post(view_url, data=data) url = make_url( StockStatus, self.domain, '?location_id=%s&filter_by_program=all&startdate=' '&enddate=&report_type=&filter_by_product=all', (tsactive.location_id, ) ) self.assertRedirects(response, url) messages = SMS.objects.filter(domain=TEST_DOMAIN) self.assertEqual(messages.count(), 1) self.assertEqual( messages[0].text, 'Dear test test2, thank you for reporting the commodities you have. You received ad 30 al 17.' ) stock_states = StockState.objects.filter(case_id=tsactive.supply_point_id) stock_transactions = StockTransaction.objects.filter(case_id=tsactive.supply_point_id) self.assertEqual(stock_states.count(), 2) self.assertEqual(stock_transactions.count(), 6) self.assertEqual(stock_transactions.filter(type='consumption').count(), 2) self.assertEqual(stock_transactions.filter(type='stockonhand').count(), 2) self.assertEqual(stock_transactions.filter(type='receipts').count(), 2) ad_consumption = stock_transactions.filter(type='consumption', product_id=self.ad.product_id)[0].quantity al_consumption = stock_transactions.filter(type='consumption', product_id=self.al.product_id)[0].quantity self.assertEqual(ad_consumption, Decimal(-10)) self.assertEqual(al_consumption, Decimal(-3)) al_stock_state = StockState.objects.get(case_id=tsactive.supply_point_id, product_id=self.al.product_id) ad_stock_state = StockState.objects.get(case_id=tsactive.supply_point_id, product_id=self.ad.product_id) self.assertEqual(int(ad_stock_state.stock_on_hand), 20) self.assertEqual(int(al_stock_state.stock_on_hand), 14) reports = StockReport.objects.filter(domain=TEST_DOMAIN) self.assertEqual(reports.count(), 2)
def rows(self): rows = [] if self.config['location_id']: product_id_to_name = { product_id: product_name for (product_id, product_name) in self.config['unique_products'].values_list('product_id', 'name') } for supply_point in self.config['stockout_table_supply_points']: products_set = self.config['stockouts'].get(supply_point.supply_point_id) url = link_format(supply_point.name, make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (supply_point.location_id, self.config['startdate'], self.config['enddate']) )) if products_set: rows.append( [url if not self.config.get('is_rendered_as_email') else supply_point.name, ', '.join( product_id_to_name[product_id] for product_id in products_set )] ) else: rows.append( [url if not self.config.get('is_rendered_as_email') else supply_point.name, '-'] ) return rows
def rows(self): rows = [] if self.config['location_id']: product_id_to_name = { product_id: product_name for (product_id, product_name) in self.config['unique_products'].values_list('product_id', 'name') } for supply_point in self.config['stockout_table_supply_points']: products_set = self.config['stockouts'].get(supply_point.supply_point_id) url = link_format(supply_point.name, make_url( StockStatus, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (supply_point.location_id, self.config['startdate'], self.config['enddate']) )) if products_set: rows.append( [url if not self.config.get('is_rendered_as_email') else supply_point.name, ', '.join( product_id_to_name[product_id] for product_id in products_set )] ) else: rows.append( [url if not self.config.get('is_rendered_as_email') else supply_point.name, '-'] ) return rows
def post(self, request, *args, **kwargs): InputStockFormSet = formset_factory(InputStockForm) formset = InputStockFormSet(request.POST) if formset.is_valid(): try: location = SQLLocation.objects.get(site_code=kwargs['site_code'], domain=self.domain) except SQLLocation.DoesNotExist: raise Http404() data = [] for form in formset: product = Product.get(docid=form.cleaned_data['product_id']) if form.cleaned_data['receipts']: data.append( StockTransaction( domain=self.domain, location_id=location.location_id, case_id=location.supply_point_id, product=product, action=const.StockActions.RECEIPTS, quantity=form.cleaned_data['receipts'] ), ) if form.cleaned_data['stock_on_hand'] is not None: data.append( StockTransaction( domain=self.domain, location_id=location.location_id, case_id=location.supply_point_id, product=product, action=const.StockActions.STOCKONHAND, quantity=form.cleaned_data['stock_on_hand'] ), ) if data: unpacked_data = { 'timestamp': datetime.utcnow(), 'user': self.request.couch_user, 'phone': 'ewsghana-input-stock', 'location': location.couch_location, 'transactions': data, } process(self.domain, unpacked_data) url = make_url( StockLevelsReport, self.domain, '?location_id=%s&filter_by_program=%s&startdate=' '&enddate=&report_type=&filter_by_product=%s', (location.location_id, ALL_OPTION, ALL_OPTION) ) return HttpResponseRedirect(url) context = self.get_context_data(**kwargs) context['formset'] = formset return self.render_to_response(context)
def post(self, request, *args, **kwargs): InputStockFormSet = formset_factory(InputStockForm) formset = InputStockFormSet(request.POST) if formset.is_valid(): try: location = SQLLocation.objects.get( site_code=kwargs['site_code'], domain=self.domain) except SQLLocation.DoesNotExist: raise Http404() data = [] for form in formset: product = Product.get(docid=form.cleaned_data['product_id']) if form.cleaned_data['receipts']: data.append( StockTransactionHelper( domain=self.domain, location_id=location.location_id, case_id=location.supply_point_id, product_id=product.get_id, action=const.StockActions.RECEIPTS, quantity=form.cleaned_data['receipts']), ) if form.cleaned_data['stock_on_hand'] is not None: data.append( StockTransactionHelper( domain=self.domain, location_id=location.location_id, case_id=location.supply_point_id, product_id=product.get_id, action=const.StockActions.STOCKONHAND, quantity=form.cleaned_data['stock_on_hand']), ) if data: unpacked_data = { 'timestamp': datetime.utcnow(), 'user': self.request.couch_user, 'phone': 'ewsghana-input-stock', 'location': location.couch_location, 'transactions': data, } process(self.domain, unpacked_data) url = make_url( StockLevelsReport, self.domain, '?location_id=%s&filter_by_program=%s&startdate=' '&enddate=&report_type=&filter_by_product=%s', (location.location_id, ALL_OPTION, ALL_OPTION)) return HttpResponseRedirect(url) context = self.get_context_data(**kwargs) context['formset'] = formset return self.render_to_response(context)
def test_incomplete_report_submission(self): self.client.login(username=self.username5, password=self.password5) view_url = reverse('input_stock', kwargs={ 'domain': TEST_DOMAIN, 'site_code': 'tsactive' }) data = { 'form-TOTAL_FORMS': 2, 'form-INITIAL_FORMS': 2, 'form-MAX_NUM_FORMS': 1000 } tsactive = SQLLocation.objects.get(domain=TEST_DOMAIN, site_code='tsactive') data['form-0-product_id'] = self.ad.product_id data['form-0-product'] = 'ad' data['form-0-stock_on_hand'] = '' data['form-0-receipts'] = '' data['form-1-product_id'] = self.al.product_id data['form-1-product'] = 'al' data['form-1-stock_on_hand'] = 14 data['form-1-receipts'] = 17 response = self.client.post(view_url, data=data) url = make_url( StockStatus, self.domain, '?location_id=%s&filter_by_program=all&startdate=' '&enddate=&report_type=&filter_by_product=all', (tsactive.location_id, )) self.assertRedirects(response, url) stock_states = StockState.objects.filter( case_id=tsactive.supply_point_id) stock_transactions = StockTransaction.objects.filter( case_id=tsactive.supply_point_id) self.assertEqual(stock_states.count(), 1) self.assertEqual(stock_transactions.count(), 3) ad_transactions = stock_transactions.filter( product_id=self.ad.product_id) self.assertEqual(ad_transactions.count(), 0) with self.assertRaises(StockState.DoesNotExist): StockState.objects.get(case_id=tsactive.supply_point_id, product_id=self.ad.product_id)
def rows(self): rows = [] if self.config["location_id"]: for sp in self.get_supply_points: location_types = [ loc_type.name for loc_type in filter( lambda loc_type: not loc_type.administrative, Domain.get_by_name(self.config["domain"]).location_types, ) ] if sp.location_type in location_types: cls = StockLevelsReport else: cls = StockStatus url = make_url( cls, self.config["domain"], "?location_id=%s&filter_by_program=%s&startdate=%s" "&enddate=%s&report_type=%s&filter_by_product=%s", ( sp.location_id, self.config["program"] or ALL_OPTION, self.config["startdate"], self.config["enddate"], self.config["report_type"], "&filter_by_product=".join(self.config["products"]), ), ) row = [link_format(sp.name, url)] for p in self.unique_products(self.get_supply_points): stock = StockState.objects.filter(sql_product=p, case_id=sp.supply_point_id).order_by( "-last_modified_date" ) if stock: monthly = stock[0].get_monthly_consumption() if monthly: row.append(int(stock[0].stock_on_hand / monthly)) else: row.append(0) else: row.append("-") rows.append(row) return rows
def get_redirect_url(self, *args, **kwargs): site_code = kwargs['site_code'] domain = kwargs['domain'] sql_location = get_object_or_404(SQLLocation, site_code=site_code, domain=domain) cls = DashboardReport if not sql_location.location_type.administrative: cls = StockStatus url = make_url( cls, domain, '?location_id=%s&filter_by_program=%s&startdate=' '&enddate=&report_type=&filter_by_product=%s', (sql_location.location_id, ALL_OPTION, ALL_OPTION) ) return url
def rows(self): rows = [] if self.config['location_id']: for sp in self.get_supply_points: if sp.location_type.administrative: cls = StockLevelsReport else: cls = StockStatus url = make_url( cls, self.config['domain'], '?location_id=%s&filter_by_program=%s&startdate=%s&enddate=%s&report_type=%s', (sp.location_id, self.config['program'] or ALL_OPTION, self.config['startdate'].date(), self.config['enddate'].date(), self.config['report_type'])) row = [link_format(sp.name, url)] products = self.unique_products(self.get_supply_points, all=(not self.config['export'])) transactions = list(StockTransaction.objects.filter( type='stockonhand', product_id__in=products.values_list('product_id', flat=True), case_id=sp.supply_point_id, report__date__lte=self.config['enddate'] ).order_by('-report__date')) states = list(StockState.objects.filter( case_id=sp.supply_point_id, product_id__in=products.values_list('product_id', flat=True), section_id='stock' )) for p in products: transaction = first_item(transactions, lambda x: x.product_id == p.product_id) state = first_item(states, lambda x: x.product_id == p.product_id) if transaction and state: if state.daily_consumption: row.append("%.1f" % (transaction.stock_on_hand / state.get_monthly_consumption())) else: row.append('-') else: row.append('-') rows.append(row) return rows
def test_incomplete_report_submission(self): self.client.login(username=self.username5, password=self.password5) view_url = reverse('input_stock', kwargs={'domain': TEST_DOMAIN, 'site_code': 'tsactive'}) data = { 'form-TOTAL_FORMS': 2, 'form-INITIAL_FORMS': 2, 'form-MAX_NUM_FORMS': 1000 } tsactive = SQLLocation.objects.get(domain=TEST_DOMAIN, site_code='tsactive') data['form-0-product_id'] = self.ad.product_id data['form-0-product'] = 'ad' data['form-0-stock_on_hand'] = '' data['form-0-receipts'] = '' data['form-1-product_id'] = self.al.product_id data['form-1-product'] = 'al' data['form-1-stock_on_hand'] = 14 data['form-1-receipts'] = 17 response = self.client.post(view_url, data=data) url = make_url( StockStatus, self.domain, '?location_id=%s&filter_by_program=all&startdate=' '&enddate=&report_type=&filter_by_product=all', (tsactive.location_id, ) ) self.assertRedirects(response, url) stock_states = StockState.objects.filter(case_id=tsactive.supply_point_id) stock_transactions = StockTransaction.objects.filter(case_id=tsactive.supply_point_id) self.assertEqual(stock_states.count(), 1) self.assertEqual(stock_transactions.count(), 3) ad_transactions = stock_transactions.filter(product_id=self.ad.product_id) self.assertEqual(ad_transactions.count(), 0) with self.assertRaises(StockState.DoesNotExist): StockState.objects.get(case_id=tsactive.supply_point_id, product_id=self.ad.product_id)
def rows(self): rows = [] if self.config['location_id']: for sp in self.get_supply_points: location_types = [loc_type.name for loc_type in filter( lambda loc_type: not loc_type.administrative, Domain.get_by_name(self.config['domain']).location_types )] if sp.location_type in location_types: cls = StockLevelsReport else: cls = StockStatus url = make_url( cls, self.config['domain'], '?location_id=%s&filter_by_program=%s&startdate=%s' '&enddate=%s&report_type=%s&filter_by_product=%s', (sp.location_id, self.config['program'] or ALL_OPTION, self.config['startdate'], self.config['enddate'], self.config['report_type'], '&filter_by_product='.join(self.config['products']))) row = [link_format(sp.name, url)] for p in self.unique_products(self.get_supply_points, all=True): transaction = StockTransaction.objects.filter( type='stockonhand', product_id=p.product_id, case_id=sp.supply_point_id, report__date__lte=self.config['enddate'], report__date__gte=self.config['startdate'] ).order_by('-report__date') state = StockState.objects.filter(sql_product=p, case_id=sp.supply_point_id)\ .order_by('-last_modified_date') if transaction and state: monthly = state[0].get_monthly_consumption() if monthly: row.append(int(transaction[0].stock_on_hand / monthly)) else: row.append(0) else: row.append('-') rows.append(row) return rows
def rows(self): rows = [] if self.config['location_id']: location = SQLLocation.objects.get( domain=self.config['domain'], location_id=self.config['location_id'] ) if location.location_type.name == 'country': supply_points = SQLLocation.objects.filter( Q(parent__location_id=self.config['location_id']) | Q(location_type__name='Regional Medical Store', domain=self.config['domain']) ).order_by('name').exclude(supply_point_id__isnull=True).exclude(is_archived=True) else: supply_points = SQLLocation.objects.filter( parent__location_id=self.config['location_id'] ).order_by('name').exclude(supply_point_id__isnull=True).exclude(is_archived=True) products = set(self.unique_products(supply_points)) for supply_point in supply_points: product_map = {p.product_id: p.name for p in products.intersection(set(supply_point.products))} stockout = StockTransaction.objects.filter( type='stockonhand', product_id__in=product_map.keys(), case_id=supply_point.supply_point_id, report__date__range=[self.config['startdate'], self.config['enddate']], stock_on_hand=0 ).order_by('product_id', '-report__date').distinct('product_id').values_list('product_id', flat=True) if stockout: url = make_url( StockLevelsReport, self.config['domain'], '?location_id=%s&startdate=%s&enddate=%s', (supply_point.location_id, self.config['startdate'], self.config['enddate']) ) rows.append( [link_format(supply_point.name, url), ', '.join(product_map[id] for id in stockout)] ) return rows