def test_archive(self): original_list = Product.by_domain(self.domain.name, wrap=False) self.products[0].archive() new_list = Product.by_domain(self.domain.name, wrap=False) self.assertTrue( self.products[0]._id not in [p['_id'] for p in new_list], "Archived product still returned by Product.by_domain()" ) self.assertEqual( len(new_list), len(original_list) - 1 ) self.assertEqual( len(Product.by_domain(self.domain.name, wrap=False, include_archived=True)), len(original_list) ) self.assertEqual( len(Product.archived_by_domain(self.domain.name, wrap=False, include_archived=True)), 1 ) self.products[0].unarchive() self.assertEqual( len(original_list), len(Product.by_domain(self.domain.name, wrap=False)) )
def product_data(self): data = [] if self.show_inactive: products = Product.archived_by_domain( domain=self.domain, limit=self.limit, skip=self.skip(), ) else: products = Product.by_domain( domain=self.domain, limit=self.limit, skip=self.skip(), ) for p in products: if p.program_id: program = Program.get(p.program_id) else: program = get_or_create_default_program(self.domain) p.program_id = program.get_id p.save() info = p._doc info['program'] = program.name info['edit_url'] = reverse('commtrack_product_edit', kwargs={'domain': self.domain, 'prod_id': p._id}) info['archive_action_desc'] = self.get_archive_text(self.show_inactive) info['archive_action_text'] = _("Un-Archive") if self.show_inactive else _("Archive") info['archive_url'] = reverse( 'unarchive_product' if self.show_inactive else 'archive_product', kwargs={'domain': self.domain, 'prod_id': p._id} ) data.append(info) return data
def get_default_column_data(domain, location_types): data = { 'headers': {}, 'values': {} } if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults: products = Product.by_domain(domain) for loc_type in location_types: loc = get_loc_config(domain)[loc_type] if not loc.administrative: data['headers'][loc_type] = [ 'default_' + p.code for p in products ] locations = Location.filter_by_type(domain, loc_type) for loc in locations: sp = SupplyPointCase.get_or_create_by_location(loc) data['values'][loc._id] = [ get_default_monthly_consumption( domain, p._id, loc_type, sp._id ) or '' for p in products ] else: data['headers'][loc_type] = [] return data
def setUp(self): # might as well clean house before doing anything delete_all_xforms() delete_all_cases() StockReport.objects.all().delete() StockTransaction.objects.all().delete() self.backend = test.bootstrap(TEST_BACKEND, to_console=True) self.domain = bootstrap_domain() self.ct_settings = CommtrackConfig.for_domain(self.domain.name) if self.requisitions_enabled: self.ct_settings.requisition_config = get_default_requisition_config() self.ct_settings.save() self.loc = make_loc('loc1') self.sp = make_supply_point(self.domain.name, self.loc) self.users = [bootstrap_user(self, **user_def) for user_def in self.user_definitions] if False: # bootstrap additional users for requisitions # needs to get reinserted for requisition stuff later self.approver = bootstrap_user(self, **APPROVER_USER) self.packer = bootstrap_user(self, **PACKER_USER) self.users += [self.approver, self.packer] # everyone should be in a group. self.group = Group(domain=TEST_DOMAIN, name='commtrack-folks', users=[u._id for u in self.users], case_sharing=True) self.group.save() self.sp.owner_id = self.group._id self.sp.save() self.products = sorted(Product.by_domain(self.domain.name), key=lambda p: p._id) self.assertEqual(3, len(self.products))
def setUp(self): # might as well clean house before doing anything delete_all_xforms() delete_all_cases() self.backend = test.bootstrap(TEST_BACKEND, to_console=True) self.domain = bootstrap_domain(requisitions_enabled=self.requisitions_enabled) self.loc = make_loc('loc1') self.reporters = dict((k, bootstrap_user(self, **v)) for k, v in REPORTING_USERS.iteritems()) # backwards compatibility self.user = self.reporters['roaming'] # bootstrap additional users for requisitions self.approver = bootstrap_user(self, **APPROVER_USER) self.packer = bootstrap_user(self, **PACKER_USER) self.users = self.reporters.values() + [self.approver, self.packer] # everyone should be in a group. self.group = Group(domain=TEST_DOMAIN, name='commtrack-folks', users=[u._id for u in self.users], case_sharing=True) self.group.save() self.sp = make_supply_point(self.domain.name, self.loc, owner_id=self.group._id) self.products = Product.by_domain(self.domain.name) self.assertEqual(3, len(self.products)) self.spps = {} for p in self.products: self.spps[p.code] = make_supply_point_product(self.sp, p._id) self.assertEqual(self.spps[p.code].owner_id, self.group._id)
def main_context(self): try: facilities = Location.filter_by_type_count(self.domain, 'FACILITY') except TypeError: facilities = 0 contacts = CommCareUser.by_domain(self.domain, reduce=True) web_users = WebUser.by_domain(self.domain, reduce=True) try: products = len(Product.by_domain(self.domain)) except ResourceNotFound: products = 0 main_context = super(GlobalStats, self).main_context context = { 'supply_points': len(list(Location.by_domain(self.domain))), 'facilities': facilities, 'contacts': contacts[0]['value'] if contacts else 0, 'web_users': web_users[0]['value'] if web_users else 0, 'products': products, #TODO add next after the enlargement ILS migration 'product_stocks': 0, 'stock_transactions': 0, 'inbound_messages': 0, 'outbound_messages': 0 } main_context.update(context) return main_context
def setUp(self): # might as well clean house before doing anything delete_all_xforms() delete_all_cases() self.backend = test.bootstrap(TEST_BACKEND, to_console=True) self.domain = bootstrap_domain(requisitions_enabled=self.requisitions_enabled) self.user = bootstrap_user(**MAIN_USER) self.verified_number = self.user.get_verified_number() # bootstrap additional users for requisitions self.approver = bootstrap_user(**APPROVER_USER) self.packer = bootstrap_user(**PACKER_USER) self.users = [self.user, self.approver, self.packer] # everyone should be in a group. self.group = Group(domain=TEST_DOMAIN, name='commtrack-folks', users=[u._id for u in self.users], case_sharing=True) self.group.save() self.loc = make_loc('loc1') self.sp = make_supply_point(self.domain.name, self.loc, owner_id=self.group._id) self.products = Product.by_domain(self.domain.name) self.assertEqual(3, len(self.products)) self.spps = {} for p in self.products: self.spps[p.code] = make_supply_point_product(self.sp, p._id) self.assertEqual(self.spps[p.code].owner_id, self.group._id)
def get_data(self): sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location ) products = Product.by_domain(self.domain) if self.program_id: products = filter( lambda product: product.program_id == self.program_id, products ) for sp_id in sp_ids: for product in products: loc = SupplyPointCase.get(sp_id).location last_transaction = StockTransaction.latest( sp_id, STOCK_SECTION_TYPE, product._id ) yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( last_transaction, self.start_date, self.end_date ), 'geo': loc._geopoint, }
def setUp(self): self.endpoint = MockEndpoint("http://test-api.com/", "dummy", "dummy") self.api_object = ILSGatewayAPI(TEST_DOMAIN, self.endpoint) self.datapath = os.path.join(os.path.dirname(__file__), "data") initial_bootstrap(TEST_DOMAIN) for product in Prod.by_domain(TEST_DOMAIN): product.delete()
def test_migration(self): bootstrap_domain(ILSGatewayAPI(TEST_DOMAIN, MockEndpoint('http://test-api.com/', 'dummy', 'dummy'))) self.assertEqual(6, len(list(Product.by_domain(TEST_DOMAIN)))) self.assertEqual(5, len(list(Location.by_domain(TEST_DOMAIN)))) self.assertEqual(6, len(list(CommCareUser.by_domain(TEST_DOMAIN)))) self.assertEqual(5, len(list(WebUser.by_domain(TEST_DOMAIN)))) self.assertEqual(ILSMigrationStats.objects.filter(domain=TEST_DOMAIN).count(), 1)
def setUp(self): self.datapath = os.path.join(os.path.dirname(__file__), 'data') self.api = MockOpenLMISEndpoint("uri://mock/lmis/endpoint", username='******', password='******') bootstrap_domain(TEST_DOMAIN) delete_all_cases() for product in Product.by_domain(TEST_DOMAIN): product.delete()
def rows(self): def row_in_names(row, names): if row in names: return True, names.index(row)+1 else: for idx, val in enumerate(names): if unicode(row).lower() in PRODUCT_NAMES.get(val, []): return True, idx+1 return False, 0 commandes = ['Comanndes'] raux = ['Recu'] taux = ['Taux'] products = Product.by_domain(self.config['domain']) for product in products: commandes.append(0) raux.append(0) taux.append(0) names = [] for product in products: names.append(unicode(product.name).lower()) rows = super(DispDesProducts, self).rows for row in rows: exits, index = row_in_names(row[0], names) if exits: commandes[index] = row[1] raux[index] = row[2] taux[index] = "%d%%" % (100*row[2]['html']/(row[1]['html'] or 1)) return [commandes, raux, taux]
def get_default_column_data(domain, location_types): data = { 'headers': {}, 'values': {} } if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults: products = Product.by_domain(domain, wrap=False) for loc_type in location_types: loc = get_loc_config(domain)[loc_type] if not loc.administrative: data['headers'][loc_type] = [ 'default_' + p['code_'] for p in products ] locations = Location.filter_by_type(domain, loc_type) for loc in locations: data['values'][loc._id] = [ get_default_consumption( domain, p['_id'], loc_type, loc._id ) or '' for p in products ] else: data['headers'][loc_type] = [] return data
def product_data(self): data = [] products = Product.by_domain(self.domain) for p in products: info = p._doc info['edit_url'] = reverse('commtrack_product_edit', kwargs={'domain': self.domain, 'prod_id': p._id}) data.append(info) return data
def clean_name(self): name = self.cleaned_data['name'] other_products = [p for p in Product.by_domain(self.product.domain) if p._id != self.product._id] if name in [p.name for p in other_products]: raise forms.ValidationError('name already in use') return name
def test_product_fixture(self): user = bootstrap_user(self, phone_number="1234567890") user_id = user.user_id products = "" product_list = Product.by_domain(user.domain) self._initialize_product_names(len(product_list)) for i, product in enumerate(product_list): product_id = product._id product_name = self.product_names.next() product_unit = self._random_string(20) product_code = self._random_string(20) product_description = self._random_string(20) product_category = self._random_string(20) product_program_id = self._random_string(20) product_cost = 0 if i == 0 else float("%g" % random.uniform(1, 100)) products += """ <product id="{id}"> <name>{name}</name> <unit>{unit}</unit> <code>{code}</code> <description>{description}</description> <category>{category}</category> <program_id>{program_id}</program_id> <cost>{cost}</cost> </product> """.format( id=product_id, name=product_name, unit=product_unit, code=product_code, description=product_description, category=product_category, program_id=product_program_id, cost=product_cost, ) product.name = product_name product.unit = product_unit product.code = product_code product.description = product_description product.category = product_category product.program_id = product_program_id product.cost = product_cost product.save() fixture = product_fixture_generator(user, V1, None) self.assertXmlEqual( """<fixture id="commtrack:products" user_id="{user_id}"> <products> {products} </products> </fixture>""".format( user_id=user_id, products=products ), ElementTree.tostring(fixture[0]), )
def all_sms_codes(domain): config = CommtrackConfig.for_domain(domain) actions = dict((action.keyword, action) for action in config.actions) products = dict((p.code, p) for p in Product.by_domain(domain)) commands = {config.multiaction_keyword: {"type": "stock_report_generic", "caption": "Stock Report"}} sms_codes = zip(("action", "product", "command"), (actions, products, commands)) return dict(itertools.chain(*([(k.lower(), (type, v)) for k, v in codes.iteritems()] for type, codes in sms_codes)))
def test_selective_product_sync(self): user = bootstrap_user(self, phone_number="1234567890") expected_xml = self.generate_product_fixture_xml(user) product_list = Product.by_domain(user.domain) self._initialize_product_names(len(product_list)) fixture_original = product_fixture_generator(user, V1, None, None) generate_restore_payload(user.to_casexml_user()) self.assertXmlEqual( expected_xml, ElementTree.tostring(fixture_original[0]) ) first_sync = sorted(SyncLog.view( "phone/sync_logs_by_user", include_docs=True, reduce=False ).all(), key=lambda x: x.date)[-1] # make sure the time stamp on this first sync is # not on the same second that the products were created first_sync.date += datetime.timedelta(seconds=1) # second sync is before any changes are made, so there should # be no products synced fixture_pre_change = product_fixture_generator(user, V1, None, first_sync) generate_restore_payload(user.to_casexml_user()) self.assertEqual( [], fixture_pre_change, "Fixture was not empty on second sync" ) second_sync = sorted(SyncLog.view( "phone/sync_logs_by_user", include_docs=True, reduce=False ).all(), key=lambda x: x.date)[-1] self.assertTrue(first_sync._id != second_sync._id) # save should make the product more recently updated than the # last sync for product in product_list: product.save() # now that we've updated a product, we should get # product data in sync again fixture_post_change = product_fixture_generator(user, V1, None, second_sync) # regenerate the fixture xml to make sure it is still legit self.assertXmlEqual( expected_xml, ElementTree.tostring(fixture_post_change[0]) )
def test_create_product(self): with open(os.path.join(self.datapath, 'sample_products.json')) as f: product = Product(json.loads(f.read())[0]) self.assertEqual(0, len(Prod.by_domain(TEST_DOMAIN))) ilsgateway_product = sync_ilsgateway_product(TEST_DOMAIN, product) self.assertEqual(product.sms_code, ilsgateway_product.code.lower()) self.assertEqual(product.name, ilsgateway_product.name) self.assertEqual(product.description, ilsgateway_product.description) self.assertEqual(product.units, str(ilsgateway_product.unit))
def test_products_migration(self): checkpoint = MigrationCheckpoint( domain=TEST_DOMAIN, start_date=datetime.utcnow(), date=datetime.utcnow(), api="product", limit=100, offset=0 ) product_api = ApiSyncObject("product", self.endpoint.get_products, self.api_object.product_sync) synchronization(product_api, checkpoint, None, 100, 0) self.assertEqual("product", checkpoint.api) self.assertEqual(100, checkpoint.limit) self.assertEqual(0, checkpoint.offset) self.assertEqual(6, len(list(Prod.by_domain(TEST_DOMAIN))))
def testCreateProgram(self): with open(os.path.join(self.datapath, 'sample_program.json')) as f: lmis_program = Program.from_json(json.loads(f.read())) # program sync self.assertEqual(0, len(Product.by_domain(TEST_DOMAIN))) commtrack_program = sync_openlmis_program(TEST_DOMAIN, lmis_program) self.assertEqual(lmis_program.name, commtrack_program.name) self.assertEqual(lmis_program.code, commtrack_program.code) # product sync self.assertEqual(len(lmis_program.products), len(Product.by_domain(TEST_DOMAIN))) lmis_product = lmis_program.products[0] product = Product.get_by_code(TEST_DOMAIN, lmis_product.code) self.assertEqual(product.code, lmis_product.code) self.assertEqual(product.name, lmis_product.name) self.assertEqual(product.description, lmis_product.description) self.assertEqual(product.unit, str(lmis_product.unit)) self.assertEqual(product.category, str(lmis_product.category))
def __init__(self, domain, *args, **kwargs): self.domain = domain super(ConsumptionForm, self).__init__(*args, **kwargs) products = Product.by_domain(domain) for p in products: field_name = "default_%s" % p._id display = _("Default %(product_name)s") % {"product_name": p.name} self.fields[field_name] = forms.DecimalField( label=display, required=False, initial=get_default_monthly_consumption(self.domain, p._id, None, None) )
def all_sms_codes(domain): config = CommtrackConfig.for_domain(domain) actions = dict((action.keyword, action) for action in config.actions) products = dict((p.code, p) for p in Product.by_domain(domain)) commands = { config.multiaction_keyword: {'type': 'stock_report_generic', 'caption': 'Stock Report'}, } sms_codes = zip(('action', 'product', 'command'), (actions, products, commands)) return dict(itertools.chain(*([(k.lower(), (type, v)) for k, v in codes.iteritems()] for type, codes in sms_codes)))
def setUp(self): self.backend = test.bootstrap(TEST_BACKEND, to_console=True) self.domain = bootstrap_domain() self.user = bootstrap_user() self.verified_number = self.user.get_verified_number() self.loc = make_loc('loc1') self.sp = make_supply_point(self.domain.name, self.loc) self.products = Product.by_domain(self.domain.name) self.assertEqual(3, len(self.products)) self.spps = {} for p in self.products: self.spps[p.code] = make_supply_point_product(self.sp, p._id)
def charts(request, domain, template="commtrack/charts.html"): products = Product.by_domain(domain) prod_codes = [p.code for p in products] prod_codes.extend(range(20)) from random import randint num_facilities = randint(44, 444) ### gen fake data def vals(): tot = 0 l = [] for i in range(4): v = randint(0, num_facilities - tot) l.append(v) tot += v l.append(num_facilities - tot) return l statuses = [ {"key": "stocked out", "color": "#e00707"}, {"key": "under stock", "color": "#ffb100"}, {"key": "adequate stock", "color": "#4ac925"}, {"key": "overstocked", "color": "#b536da"}, {"key": "unknown", "color": "#ABABAB"} ] for s in statuses: s["values"] = [] for i, p in enumerate(prod_codes): vs = vals() for j in range(5): statuses[j]["values"].append({"x": p, "y": vs[j]}) # colors don't actually work correctly for pie charts resp_values = [ {"label": "Submitted on Time", "color": "#4ac925", "value": randint(0, 40)}, {"label": "Didn't respond", "color": "#ABABAB", "value": randint(0, 20)}, {"label": "Submitted Late", "color": "#e00707", "value": randint(0, 8)}, ] response_data = [{ "key": "Current Late Report", "values": resp_values }] ctxt = { "domain": domain, "stock_data": statuses, "response_data": response_data, } return render(request, template, ctxt)
def setUp(self): self.datapath = os.path.join(os.path.dirname(__file__), 'data') initial_bootstrap(TEST_DOMAIN) config = ILSGatewayConfig() config.domain = TEST_DOMAIN config.enabled = True config.password = '******' config.username = '******' config.url = 'http://test-api.com/' config.save() for product in Product.by_domain(TEST_DOMAIN): product.delete()
def consumption(self): consumptions = [] for product in Product.by_domain(self.domain): consumption = get_default_consumption( self.domain, product._id, self.location.location_type, self.supply_point._id if self.supply_point else None, ) if consumption: consumptions.append((product.name, consumption)) return consumptions
def setUpClass(cls): cls.datapath = os.path.join(os.path.dirname(__file__), 'data') cls.sms_backend, cls.sms_backend_mapping = setup_default_sms_test_backend() initial_bootstrap(TEST_DOMAIN) config = ILSGatewayConfig() config.domain = TEST_DOMAIN config.enabled = True config.password = '******' config.username = '******' config.url = 'http://test-api.com/' config.save() for product in Product.by_domain(TEST_DOMAIN): product.delete()
def tearDown(self): for product in Product.by_domain(TEST_DOMAIN): product.delete() for location in Location.by_domain(TEST_DOMAIN): location.delete() for user in CommCareUser.by_domain(TEST_DOMAIN): user.delete() for web_user in WebUser.by_domain(TEST_DOMAIN): web_user.delete() ILSMigrationStats.objects.all().delete() ILSMigrationProblem.objects.all().delete()
def product_data(self): data = [] products = Product.by_domain(domain=self.domain, limit=self.limit, skip=self.skip()) for p in products: if p.program_id: program = Program.get(p.program_id) else: program = get_or_make_def_program(self.domain) p.program_id = program.get_id p.save() info = p._doc info['program'] = program.name info['edit_url'] = reverse('commtrack_product_edit', kwargs={'domain': self.domain, 'prod_id': p._id}) data.append(info) return data
def __init__(self, domain, *args, **kwargs): self.domain = domain super(ConsumptionForm, self).__init__(*args, **kwargs) products = Product.by_domain(domain) for p in products: field_name = 'default_%s' % p.code display = _('Default %(product_name)s') % {'product_name': p.name} self.fields[field_name] = forms.DecimalField( label=display, required=False, initial=get_default_consumption( self.domain, p._id, None, None ) )
def setUp(self): self.datapath = os.path.join(os.path.dirname(__file__), 'data') initial_bootstrap(TEST_DOMAIN) sms_backend = TestSMSBackend(name="MOBILE_BACKEND_TEST", is_global=True) sms_backend._id = sms_backend.name sms_backend.save() config = ILSGatewayConfig() config.domain = TEST_DOMAIN config.enabled = True config.password = '******' config.username = '******' config.url = 'http://test-api.com/' config.save() for product in Product.by_domain(TEST_DOMAIN): product.delete()
def get_default_column_data(domain, location_types): data = { 'headers': {}, 'values': {} } if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults: products = Product.by_domain(domain) supply_point_map = SupplyPointCase.get_location_map_by_domain(domain) consumption_dict = build_consumption_dict(domain) if not consumption_dict: return data for loc_type in location_types: loc = get_loc_config(domain)[loc_type] if not loc.administrative: data['headers'][loc_type] = [ 'default_' + p.code for p in products ] locations = Location.filter_by_type(domain, loc_type) for loc in locations: if loc._id in supply_point_map: sp_id = supply_point_map[loc._id] else: # this only happens if the supply point case did # not already exist sp_id = SupplyPointCase.get_or_create_by_location(loc)._id data['values'][loc._id] = [ get_loaded_default_monthly_consumption( consumption_dict, domain, p._id, loc_type, sp_id ) or '' for p in products ] else: data['headers'][loc_type] = [] return data
def recalculate_domain_consumption(domain): """ Given a domain, recalculate all saved consumption settings in that domain. """ # note: might get slow as this gets huge found_doc_ids = DocDomainMapping.objects.filter( domain_name=domain, doc_type='CommCareCase', ).values_list('doc_id', flat=True) products = Product.by_domain(domain) for supply_point_id in found_doc_ids: for product in products: filtered_transactions = StockTransaction.objects.filter( case_id=supply_point_id, product_id=product._id, section_id=const.SECTION_TYPE_STOCK, ).order_by('-report__date') if filtered_transactions: update_stock_state_for_transaction(filtered_transactions[0])
def test_products_migration(self): checkpoint = MigrationCheckpoint( domain=TEST_DOMAIN, start_date=datetime.utcnow(), date=datetime.utcnow(), api='product', limit=100, offset=0 ) product_api = ApiSyncObject( 'product', self.endpoint.get_products, self.api_object.product_sync ) synchronization(product_api, checkpoint, None, 100, 0) self.assertEqual('product', checkpoint.api) self.assertEqual(100, checkpoint.limit) self.assertEqual(0, checkpoint.offset) self.assertEqual(6, len(list(Prod.by_domain(TEST_DOMAIN))))
def product_fetch(request, domain): page = int(request.GET.get('page', 1)) limit = int(request.GET.get('limit', DEFAULT_PRODUCT_LIST_LIMIT)) skip = (page-1)*limit sort_by = request.GET.get('sortBy', 'abc') show_inactive = json.loads(request.GET.get('show_inactive', 'false')) products = Product.by_domain(domain) #limit=limit, skip=skip) def product_data(p): info = p._doc info['edit_url'] = reverse('commtrack_product_edit', kwargs={'domain': domain, 'prod_id': p._id}) return info return HttpResponse(json.dumps(dict( success=True, current_page=page, product_list=[product_data(p) for p in products], )), 'text/json')
def product_list(request, domain, template="commtrack/manage/products.html"): page = request.GET.get('page', 1) limit = request.GET.get('limit', DEFAULT_PRODUCT_LIST_LIMIT) show_inactive = json.loads(request.GET.get('show_inactive', 'false')) total = len(Product.by_domain(domain)) context = { 'domain': domain, } context.update(product_list=dict( page=page, limit=limit, total=total, ), show_inactive=show_inactive, pagination_limit_options=range(DEFAULT_PRODUCT_LIST_LIMIT, 51, DEFAULT_PRODUCT_LIST_LIMIT)) return render(request, template, context)
def headers(self): header = DataTablesHeader() columns = self.model.columns if self.model.have_groups: header.add_column( DataTablesColumnGroup('', columns[0].data_tables_column)) else: header.add_column(columns[0].data_tables_column) self.groups = [group.name for group in Product.by_domain(self.domain)] for group in self.groups: if self.model.have_groups: header.add_column( DataTablesColumnGroup( group, *[ columns[j].data_tables_column for j in xrange(1, len(columns)) ])) else: header.add_column(DataTablesColumn(group)) return header
def display_config(self): conf = { 'name_column': 'name', 'detail_columns': ['type'], 'table_columns': ['type'], 'column_titles': { 'type': 'Supply Point Type', }, 'enum_captions': {}, 'numeric_format': {}, 'metrics': [ { 'color': { 'column': 'type', }, }, ], } titles = { 'current_stock': 'Stock on Hand', 'consumption': 'Monthly Consumption', 'months_remaining': 'Months of Stock Remaining', 'category': 'Current Stock Status', } products = sorted(Product.by_domain( self.domain, include_archived=self.request.GET.get('archived_products', False)), key=lambda p: p.name) if self.program_id: products = filter(lambda c: c.program_id == self.program_id, products) for p in products: col_id = lambda c: '%s-%s' % (p._id, c) product_cols = [] for c in ('category', 'current_stock', 'months_remaining', 'consumption'): conf['column_titles'][col_id(c)] = titles[c] product_cols.append(col_id(c)) conf['detail_columns'].extend(product_cols) product_metrics = [{ 'icon': { 'column': col_id('category'), 'categories': { 'stockout': '/static/commtrack/img/stockout.png', 'understock': '/static/commtrack/img/warning.png', 'adequate': '/static/commtrack/img/goodstock.png', 'overstock': '/static/commtrack/img/overstock.png', #'nodata': '/static/commtrack/img/no_data.png', '_null': '/static/commtrack/img/no_data.png', }, } }] conf['enum_captions'][col_id('category')] = { 'stockout': 'Stocked out', 'understock': 'Under-stock', 'adequate': 'Adequate Stock', 'overstock': 'Over-stock', '_null': 'No Data', } for c in ('current_stock', 'months_remaining', 'consumption'): metric = { 'title': conf['column_titles'][col_id(c)], 'size': { 'column': col_id(c), }, } if c not in ('consumption', ): metric['color'] = { 'column': col_id('category'), 'categories': { 'stockout': 'rgba(255, 0, 0, .8)', 'understock': 'rgba(255, 120, 0, .8)', 'adequate': 'rgba(50, 200, 50, .8)', 'overstock': 'rgba(120, 0, 255, .8)', '_null': 'rgba(128, 128, 128, .8)', }, } else: metric['color'] = 'rgba(120, 120, 255, .8)' product_metrics.append(metric) conf['numeric_format'][col_id(c)] = { 'current_stock': "return x + ' %s'" % (p.unit or 'unit'), 'months_remaining': "return (Math.round(10 * x) / 10) + (x == 1 ? ' month' : ' months')", 'consumption': "return (Math.round(10 * x) / 10) + ' %s / month'" % (p.unit or 'unit'), }[c] conf['metrics'].append({ 'title': p.name, 'group': True, 'children': product_metrics, }) conf['table_columns'].append({ 'title': p.name, 'subcolumns': product_cols, }) conf['detail_template'] = render_to_string( 'reports/partials/commtrack/stockstatus_mapdetail.html', { 'products': products, 'columns': [{ 'id': c, 'title': titles[c] } for c in ('category', 'current_stock', 'consumption', 'months_remaining')], }) conf['display'] = { 'table': False, } return conf
def test_product_fixture(self): user = bootstrap_user(self, phone_number="1234567890") user_id = user.user_id products = '' product_list = Product.by_domain(user.domain) self._initialize_product_names(len(product_list)) for i, product in enumerate(product_list): product_id = product._id product_name = self.product_names.next() product_unit = self._random_string(20) product_code = self._random_string(20) product_description = self._random_string(20) product_category = self._random_string(20) product_program_id = self._random_string(20) product_cost = 0 if i == 0 else float('%g' % random.uniform(1, 100)) # only set this on one product, so we can also test that # this node doesn't get sent down on every product if i == 0: product_data = {'special_number': '555111'} custom_data_xml = ''' <product_data> <special_number>555111</special_number> </product_data> ''' else: product_data = {} custom_data_xml = '' products += ''' <product id="{id}"> <name>{name}</name> <unit>{unit}</unit> <code>{code}</code> <description>{description}</description> <category>{category}</category> <program_id>{program_id}</program_id> <cost>{cost}</cost> {custom_data} </product> '''.format(id=product_id, name=product_name, unit=product_unit, code=product_code, description=product_description, category=product_category, program_id=product_program_id, cost=product_cost, custom_data=custom_data_xml) product.name = product_name product.unit = product_unit product.code = product_code product.description = product_description product.category = product_category product.program_id = product_program_id product.cost = product_cost product.product_data = product_data product.save() fixture = product_fixture_generator(user, V1, None) self.assertXmlEqual( '''<fixture id="commtrack:products" user_id="{user_id}"> <products> {products} </products> </fixture>'''.format(user_id=user_id, products=products), ElementTree.tostring(fixture[0]))
def obj_get_list(self, request, **kwargs): return Product.by_domain(kwargs['domain'])
def get_data(self): sp_ids = get_relevant_supply_point_ids( self.domain, self.active_location ) products = Product.by_domain(self.domain) if self.program_id: products = filter( lambda product: product.program_id == self.program_id, products ) for sp_id in sp_ids: loc = SupplyPointCase.get(sp_id).location transactions = StockTransaction.objects.filter( case_id=sp_id, ).exclude( report__date__lte=self.start_date ).exclude( report__date__gte=self.end_date ) if transactions: last_transaction = sorted( transactions, key=lambda trans: trans.report.date )[-1] else: last_transaction = None if self.all_relevant_forms: forms_xmlns = [] for form in self.all_relevant_forms.values(): forms_xmlns.append(form['xmlns']) if last_transaction: form = XFormInstance.get(last_transaction.report.form_id) if form.xmlns in forms_xmlns: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( last_transaction, self.start_date, self.end_date ), 'geo': loc._geopoint, } else: yield { 'loc_id': loc._id, 'loc_path': loc.path, 'name': loc.name, 'type': loc.location_type, 'reporting_status': reporting_status( None, self.start_date, self.end_date ), 'geo': loc._geopoint, }
def products(self): prods = Product.by_domain(self.domain, wrap=False) return sorted(prods, key=lambda p: p['name'])
def setUp(self): self.datapath = os.path.join(os.path.dirname(__file__), 'data') initial_bootstrap(TEST_DOMAIN) bootstrap_domain(TEST_DOMAIN) for product in Product.by_domain(TEST_DOMAIN): product.delete()
def headers(self): headers = DataTablesHeader(*[DataTablesColumn('Quantity')]) for product in Product.by_domain(self.config['domain']): headers.add_column(DataTablesColumn(product.name)) return headers
def generate_product_xml(self, user, randomize_data=True): products = '' product_list = Product.by_domain(user.domain) self._initialize_product_names(len(product_list)) for i, product in enumerate(product_list): product_id = product._id product_name = self.product_names.next() product_unit = self._random_string(20) product_code = self._random_string(20) product_description = self._random_string(20) product_category = self._random_string(20) product_program_id = self._random_string(20) product_cost = 0 if i == 0 else float('%g' % random.uniform(1, 100)) # only set this on one product, so we can also test that # this node doesn't get sent down on every product if i == 0: product_data = { 'special_number': '555111' } custom_data_xml = ''' <product_data> <special_number>555111</special_number> </product_data> ''' else: product_data = {} custom_data_xml = '' products += ''' <product id="{id}"> <name>{name}</name> <unit>{unit}</unit> <code>{code}</code> <description>{description}</description> <category>{category}</category> <program_id>{program_id}</program_id> <cost>{cost}</cost> {custom_data} </product> '''.format( id=product_id, name=product_name, unit=product_unit, code=product_code, description=product_description, category=product_category, program_id=product_program_id, cost=product_cost, custom_data=custom_data_xml ) product.name = product_name product.unit = product_unit product.code = product_code product.description = product_description product.category = product_category product.program_id = product_program_id product.cost = product_cost product.product_data = product_data product.save() return products
def charts(request, domain, template="commtrack/charts.html"): products = Product.by_domain(domain) prod_codes = [p.code for p in products] prod_codes.extend(range(20)) from random import randint num_facilities = randint(44, 444) ### gen fake data def vals(): tot = 0 l = [] for i in range(4): v = randint(0, num_facilities - tot) l.append(v) tot += v l.append(num_facilities - tot) return l statuses = [{ "key": "stocked out", "color": "#e00707" }, { "key": "under stock", "color": "#ffb100" }, { "key": "adequate stock", "color": "#4ac925" }, { "key": "overstocked", "color": "#b536da" }, { "key": "unknown", "color": "#ABABAB" }] for s in statuses: s["values"] = [] for i, p in enumerate(prod_codes): vs = vals() for j in range(5): statuses[j]["values"].append({"x": p, "y": vs[j]}) # colors don't actually work correctly for pie charts resp_values = [ { "label": "Submitted on Time", "color": "#4ac925", "value": randint(0, 40) }, { "label": "Didn't respond", "color": "#ABABAB", "value": randint(0, 20) }, { "label": "Submitted Late", "color": "#e00707", "value": randint(0, 8) }, ] response_data = [{"key": "Current Late Report", "values": resp_values}] ctxt = { "domain": domain, "stock_data": statuses, "response_data": response_data, } return render(request, template, ctxt)