def setUp(self): p1 = Product.get_by_code(TEST_DOMAIN, 'mc') p2 = Product.get_by_code(TEST_DOMAIN, 'lf') p3 = Product.get_by_code(TEST_DOMAIN, 'mg') self._create_stock_state(p1, 5) self._create_stock_state(p2, 10) self._create_stock_state(p3, 5)
def setUp(self): p1 = Product.get_by_code(TEST_DOMAIN, 'mc') p2 = Product.get_by_code(TEST_DOMAIN, 'lf') p3 = Product.get_by_code(TEST_DOMAIN, 'mg') self._create_stock_state(p1, 5) self._create_stock_state(p2, 10) self._create_stock_state(p3, 5)
def wrap_from_json(cls, obj, domain, location_id): product = Product.get_by_code(domain, obj['product']) obj['product'] = product._id obj['location_id'] = location_id obj['external_id'] = obj['id'] del obj['id'] return cls(**obj)
def sync_requisition_from_openlmis(domain, requisition_id, openlmis_endpoint): cases = [] send_notification = False lmis_requisition_details = openlmis_endpoint.get_requisition_details(requisition_id) if lmis_requisition_details: rec_cases = [c for c in RequisitionCase.get_by_external_id(domain, str(lmis_requisition_details.id)) if c.type == const.REQUISITION_CASE_TYPE] if len(rec_cases) == 0: products = [product for product in lmis_requisition_details.products if product.skipped == False] for product in products: pdt = Product.get_by_code(domain, product.code.lower()) if pdt: case = lmis_requisition_details.to_requisition_case(pdt._id) case.save() if case.requisition_status == 'AUTHORIZED': send_notification = True cases.append(case) else: for case in rec_cases: before_status = case.requisition_status if apply_updates(case, lmis_requisition_details.to_dict(case.product_id)): after_status = case.requisition_status case.save() if before_status in ['INITIATED', 'SUBMITTED'] and after_status == 'AUTHORIZED': send_notification = True cases.append(case) return cases, send_notification else: return None, False
def wrap_from_json(cls, obj, domain, location_id): product = Product.get_by_code(domain, obj['product']) obj['product'] = product._id obj['location_id'] = location_id obj['external_id'] = obj['id'] del obj['id'] return cls(**obj)
def product_from_code(self, prod_code): """return the product doc referenced by prod_code""" prod_code = prod_code.lower() p = Product.get_by_code(self.domain.name, prod_code) if p is None: raise SMSError('invalid product code "%s"' % prod_code) return p
def sync_requisition_from_openlmis(domain, requisition_id, openlmis_endpoint): cases = [] send_notification = False lmis_requisition_details = openlmis_endpoint.get_requisition_details( requisition_id) if lmis_requisition_details: rec_cases = [ c for c in RequisitionCase.get_by_external_id( domain, str(lmis_requisition_details.id)) if c.type == const.REQUISITION_CASE_TYPE ] if len(rec_cases) == 0: products = [ product for product in lmis_requisition_details.products if product.skipped == False ] for product in products: pdt = Product.get_by_code(domain, product.code.lower()) if pdt: case = lmis_requisition_details.to_requisition_case( pdt._id) case.save() if case.requisition_status == 'AUTHORIZED': send_notification = True cases.append(case)
def product_from_code(self, prod_code): """return the product doc referenced by prod_code""" prod_code = prod_code.lower() p = Product.get_by_code(self.domain.name, prod_code) if p is None: raise SMSError('invalid product code "%s"' % prod_code) return p
def sync_stock_transaction(domain, endpoint, facility, xform, checkpoint, date, limit=100, offset=0): has_next = True next_url = "" while has_next: supply_point = facility case = SupplyPointCase.view('hqcase/by_domain_external_id', key=[domain, str(supply_point)], reduce=False, include_docs=True, limit=1).first() if not case: break meta, stocktransactions = endpoint.get_stocktransactions(next_url_params=next_url, limit=limit, offset=offset, filters=(dict(supply_point=supply_point, date__gte=date, order_by='date'))) save_stock_data_checkpoint(checkpoint, 'stock_transaction', meta.get('limit') or limit, meta.get('offset') or offset, date, facility, True) transactions_to_add = [] with transaction.commit_on_success(): for stocktransaction in stocktransactions: if case: product = Product.get_by_code(domain, stocktransaction.product) report = StockReport( form_id=xform._id, date=force_to_datetime(stocktransaction.date), type='balance', domain=domain ) report.save() try: sql_product = SQLProduct.objects.get(product_id=product._id) except SQLProduct.DoesNotExist: continue transactions_to_add.append(StockTransaction( case_id=case._id, product_id=product._id, sql_product=sql_product, section_id='stock', type='stockonhand', stock_on_hand=Decimal(stocktransaction.ending_balance), report=report )) # Doesn't send signal StockTransaction.objects.bulk_create(transactions_to_add) if not meta.get('next', False): has_next = False else: next_url = meta['next'].split('?')[1]
def sync_product_stock(domain, endpoint, facility, checkpoint, date, limit=100, offset=0): has_next = True next_url = "" while has_next: supply_point = facility case = SupplyPointCase.view('hqcase/by_domain_external_id', key=[domain, str(supply_point)], reduce=False, include_docs=True, limit=1).first() meta, product_stocks = endpoint.get_productstocks( next_url_params=next_url, limit=limit, offset=offset, filters=dict(supply_point=supply_point, last_modified__gte=date) ) save_stock_data_checkpoint(checkpoint, 'product_stock', meta.get('limit') or limit, meta.get('offset') or offset, date, facility, True) for product_stock in product_stocks: if case: product = Product.get_by_code(domain, product_stock.product) try: stock_state = StockState.objects.get(section_id='stock', case_id=case._id, product_id=product._id) stock_state.last_modified_date = product_stock.last_modified stock_state.stock_on_hand = product_stock.quantity or 0 except StockState.DoesNotExist: stock_state = StockState(section_id='stock', case_id=case._id, product_id=product._id, stock_on_hand=product_stock.quantity or 0, last_modified_date=product_stock.last_modified, sql_product=SQLProduct.objects.get(product_id=product._id)) if product_stock.auto_monthly_consumption: stock_state.daily_consumption = product_stock.auto_monthly_consumption / DAYS_IN_MONTH else: stock_state.daily_consumption = None stock_state.save() if not meta.get('next', False): has_next = False else: next_url = meta['next'].split('?')[1]
def product_sync(self, ilsgateway_product): product = Product.get_by_code(self.domain, ilsgateway_product.sms_code) product_dict = { "domain": self.domain, "name": ilsgateway_product.name, "code": ilsgateway_product.sms_code, "unit": str(ilsgateway_product.units), "description": ilsgateway_product.description, } if product is None: product = Product(**product_dict) product.save() else: if apply_updates(product, product_dict): product.save() return product
def product_sync(self, ilsgateway_product): product = Product.get_by_code(self.domain, ilsgateway_product.sms_code) product_dict = { 'domain': self.domain, 'name': ilsgateway_product.name, 'code': ilsgateway_product.sms_code, 'unit': str(ilsgateway_product.units), 'description': ilsgateway_product.description, } if product is None: product = Product(**product_dict) product.save() else: if apply_updates(product, product_dict): product.save() return product
def product_sync(self, ilsgateway_product): product = Product.get_by_code(self.domain, ilsgateway_product.sms_code) product_dict = { 'domain': self.domain, 'name': ilsgateway_product.name, 'code': ilsgateway_product.sms_code, 'unit': str(ilsgateway_product.units), 'description': ilsgateway_product.description, } if product is None: product = Product(**product_dict) product.save() else: if apply_updates(product, product_dict): product.save() return product
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.lower(), 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.lower()) 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 no_changes_needed(domain, existing, properties, form_data, consumption, sp=None): if not existing: return False for prop, val in properties.iteritems(): if getattr(existing, prop[1], None) != val: return False for key, val in form_data.iteritems(): if getattr(existing, key, None) != val: return False for product_code, val in consumption: product = Product.get_by_code(domain, product_code) if get_default_consumption( domain, product._id, existing.location_type, existing._id ) != val: return False return True
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.lower(), 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.lower()) 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 test_should_import_consumption(self): existing = make_loc('existingloc', type='state') sp = make_supply_point(self.loc.domain, existing) data = { 'site_code': existing.site_code, 'name': 'existingloc', 'default_pp': 77 } import_location(self.domain.name, 'state', data) self.assertEqual( float(get_default_consumption( self.domain.name, Product.get_by_code(self.domain.name, 'pp')._id, 'state', sp._id, )), 77 / DAYS_IN_MONTH )
def test_should_import_consumption(self): existing = make_loc('existingloc', type='state') sp = make_supply_point(self.loc.domain, existing) data = { 'site_code': existing.site_code, 'name': 'existingloc', 'consumption': { 'pp': 77 }, } import_location(self.domain.name, 'state', data) self.assertEqual( float( get_default_consumption( self.domain.name, Product.get_by_code(self.domain.name, 'pp')._id, 'state', sp._id, )), 77 / DAYS_IN_MONTH)
def test_should_import_consumption(self): parent = make_loc('originalparent', type='village') existing = make_loc('existingloc', type='outlet', parent=parent) sp = existing.linked_supply_point() data = { 'site_code': existing.site_code, 'name': 'existingloc', 'parent_site_code': parent.site_code, 'consumption': {'pp': 77}, } import_location(self.domain.name, 'outlet', data) self.assertEqual( float(get_default_consumption( self.domain.name, Product.get_by_code(self.domain.name, 'pp')._id, 'state', sp.case_id, )), 77 / DAYS_IN_MONTH )
def test_should_import_consumption(self): parent = make_loc('originalparent', type='village') existing = make_loc('existingloc', type='outlet', parent=parent) sp = existing.linked_supply_point() data = { 'site_code': existing.site_code, 'name': 'existingloc', 'parent_site_code': parent.site_code, 'consumption': { 'pp': 77 }, } import_location(self.domain.name, 'outlet', data) self.assertEqual( float( get_default_consumption( self.domain.name, Product.get_by_code(self.domain.name, 'pp')._id, 'state', sp.case_id, )), 77 / DAYS_IN_MONTH)
def get_product(self, code): return Product.get_by_code(self.domain, code)
def get_product(self, code): return Product.get_by_code(self.domain, code)
def get_product(domain, lmis_product): return Product.get_by_code(domain, lmis_product.code)
def setUp(self): super(EWSScriptTest, self).setUp() Product.get_by_code(TEST_DOMAIN, 'mc') Product.get_by_code(TEST_DOMAIN, 'lf')
def setUp(self): super(EWSScriptTest, self).setUp() Product.get_by_code(TEST_DOMAIN, 'mc') Product.get_by_code(TEST_DOMAIN, 'lf')
def setUp(self): Product.get_by_code(TEST_DOMAIN, "mc") Product.get_by_code(TEST_DOMAIN, "lf")
def get_product(domain, lmis_product): return Product.get_by_code(domain, lmis_product.code)
def setUp(self): Product.get_by_code(TEST_DOMAIN, 'mc') Product.get_by_code(TEST_DOMAIN, 'lf')
def submit_form(domain, parent, form_data, properties, existing, location_type, consumption): # don't save if there is nothing to save if no_changes_needed(domain, existing, properties, form_data, consumption): return { 'id': existing._id, 'message': 'no changes for %s %s' % (location_type, existing.name) } form_data.update(properties) form = make_form(domain, parent, form_data, existing) form.strict = False # optimization hack to turn off strict validation if form.is_valid(): loc = form.save() sp = SupplyPointCase.get_by_location(loc) if consumption else None if consumption and sp: for product_code, value in consumption: product = Product.get_by_code(domain, product_code) if not product: # skip any consumption column that doesn't match # to a real product. currently there is no easy # way to alert here, though. continue try: amount = Decimal(value) # only set it if there is a non-negative/non-null value if amount and amount >= 0: set_default_consumption_for_supply_point( domain, product._id, sp._id, amount ) except (TypeError, InvalidOperation): # should inform user, but failing hard due to non numbers # being used on consumption is strange since the # locations would be in a very inconsistent state continue if existing: message = 'updated %s %s' % (location_type, loc.name) else: message = 'created %s %s' % (location_type, loc.name) return { 'id': loc._id, 'message': message } else: message = 'Form errors when submitting: ' # TODO move this to LocationForm somehow forms = filter(None, [form, form.sub_forms.get(location_type)]) for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)): if k != '__all__': message += u'{0} {1}; {2}: {3}. '.format( location_type, form_data.get('name', 'unknown'), k, v[0] ) return { 'id': None, 'message': message }