def _test_get_current_ledger_transactions(self, tester_fn): tester_fn(self.transactions) date = datetime.utcnow() report, _ = self.create_report([ StockTransactionHelper(case_id='c1', section_id='s1', product_id='p1', action='soh', quantity=864, timestamp=datetime.utcnow()) ], date=date) self._create_models_for_stock_report_helper(self.form, report) # create second report with the same date # results should have this transaction and not the previous one report, _ = self.create_report([ StockTransactionHelper(case_id='c1', section_id='s1', product_id='p1', action='soh', quantity=1, timestamp=datetime.utcnow()) ], date=date) self._create_models_for_stock_report_helper(self.form, report) new_trans = self.transactions.copy() new_trans['c1']['s1']['p1'] = 1 tester_fn(new_trans)
def single_action_transactions(self, action, args): # special case to handle immediate stock-out reports if action.action == const.StockActions.STOCKOUT: if all(self.looks_like_prod_code(arg) for arg in args): for prod_code in args: yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=self.product_from_code( prod_code).product_id, action=action.action, subaction=action.subaction, quantity=0, ) return else: raise SMSError("can't include a quantity for stock-out action") products = [] for arg in args: if self.looks_like_prod_code(arg): products.append(self.product_from_code(arg)) else: if not products: raise SMSError('quantity "%s" doesn\'t have a product' % arg) if len(products) > 1: raise SMSError('missing quantity for product "%s"' % products[-1].code) try: value = int(arg) except: raise SMSError( 'could not understand product quantity "%s"' % arg) for product in products: yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=product.product_id, action=action.action, subaction=action.subaction, quantity=value, ) products = [] if products: raise SMSError('missing quantity for product "%s"' % products[-1].code)
def submit_stock_update(user, site_code, product_code, balance): """For local testing only.""" case, location = get_supply_point_and_location(user.domain, site_code) product = SQLProduct.objects.get(domain=user.domain, code=product_code) tx = StockTransactionHelper( product_id=product.product_id, action=StockActions.STOCKONHAND, domain=user.domain, quantity=balance, location_id=location.location_id, timestamp=datetime.utcnow(), case_id=case.case_id, section_id=SECTION_TYPE_STOCK, ) xml = to_instance({ 'timestamp': datetime.utcnow(), 'user': user, 'phone': user.phone_number or '8675309', 'location': location, 'transactions': [tx], }) submit_form_locally( instance=xml, domain=user.domain, )
def setUp(self): super(StockReportDomainTest, self).setUp() self.domain = _get_name_for_domain() self.ledger_processor = FormProcessorInterface( domain=self.domain).ledger_processor create_domain(self.domain) transactions_flat = [] self.transactions = {} for case, c_bal in self.case_ids.items(): for section, s_bal in self.section_ids.items(): for product, p_bal in self.product_ids.items(): bal = c_bal + s_bal + p_bal transactions_flat.append( StockTransactionHelper(case_id=case, section_id=section, product_id=product, action='soh', quantity=bal, timestamp=datetime.utcnow())) self.transactions.setdefault(case, {}).setdefault( section, {})[product] = bal self.new_stock_report, self.form = self.create_report( transactions_flat) self._create_models_for_stock_report_helper(self.form, self.new_stock_report)
def setUp(self): super(TestGetValuesByProduct, self).setUp() self.ledger_processor = FormProcessorInterface( domain=self.domain_name).ledger_processor self.domain_obj = create_domain(self.domain_name) transactions_flat = [] self.transactions = {} for d in self.data: product = d['product'] section = d['section'] balance = d['balance'] transactions_flat.append( StockTransactionHelper(case_id=self.case_id, section_id=section, product_id=product, action='soh', quantity=balance, timestamp=datetime.utcnow())) self.transactions.setdefault(self.case_id, {}).setdefault(section, {})[product] = balance self.new_stock_report, self.form = self.create_report( transactions_flat) self._create_models_for_stock_report_helper(self.form, self.new_stock_report)
def single_action_transactions(self, action, args): products = [] for arg in args: if self.looks_like_prod_code(arg): product = self.product_from_code(arg) if product: products.append(product) else: self.errors.append(InvalidProductCodeException(arg.lower())) else: if not products: continue if len(products) > 1: raise SMSError('missing quantity for product "%s"' % products[-1].code) try: value = int(arg) except: raise SMSError('could not understand product quantity "%s"' % arg) for p in products: yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=p.get_id, action=action.action, subaction=action.subaction, quantity=value, ) products = [] if products: raise SMSError('missing quantity for product "%s"' % products[-1].code)
def multiple_action_transactions(self, args): action = None # TODO: catch that we don't mix in requisiton and stock report keywords in the same multi-action message? _args = iter(args) def next(): return _args.next() found_product_for_action = True while True: try: keyword = next() except StopIteration: if not found_product_for_action: raise SMSError('product expected for action "%s"' % action) break old_action = action _next_action = self.commtrack_settings.action_by_keyword(keyword) if _next_action: action = _next_action if not found_product_for_action: raise SMSError('product expected for action "%s"' % old_action.keyword) found_product_for_action = False continue try: product = self.product_from_code(keyword) found_product_for_action = True except: product = None if product: if not action: raise SMSError('need to specify an action before product') elif action.action == const.StockActions.STOCKOUT: value = 0 else: try: value = int(next()) except (ValueError, StopIteration): raise SMSError('quantity expected for product "%s"' % product.code) yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=product.get_id, action=action.action, subaction=action.subaction, quantity=value, ) continue raise SMSError('do not recognize keyword "%s"' % keyword)
def single_action_transactions(self, action, args): products = [] for arg in args: if self.looks_like_prod_code(arg): products.append(self.product_from_code(arg)) else: if not products: raise SMSError('quantity "%s" doesn\'t have a product' % arg) if len(products) > 1: raise SMSError('missing quantity for product "%s"' % products[-1].code) # NOTE also custom code here, must be formatted like 11.22 if re.compile("^\d+\.\d+$").match(arg): value = arg else: raise SMSError( 'could not understand product quantity "%s"' % arg) for p in products: # for EWS we have to do two transactions, one being a receipt # and second being a transaction (that's reverse of the order # the user provides them) yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=p.get_id, action=const.StockActions.RECEIPTS, quantity=Decimal(value.split('.')[1])) yield StockTransactionHelper( domain=self.domain.name, location_id=self.location.location_id, case_id=self.case_id, product_id=p.get_id, action=const.StockActions.STOCKONHAND, quantity=Decimal(value.split('.')[0])) products = [] if products: raise SMSError('missing quantity for product "%s"' % products[-1].code)
def _make_transaction_helper(ledger_instruction, action, case_id): subaction = ledger_instruction.type return StockTransactionHelper( domain=ledger_instruction.domain, timestamp=ledger_instruction.date, product_id=ledger_instruction.entry_id, quantity=ledger_instruction.quantity, action=action, case_id=case_id, section_id=ledger_instruction.section_id, subaction=subaction if subaction and subaction != action else None, location_id=None, )