def print_ledger_history(ledger_ref, verbose=False): case_id, section_id, entry_id = ledger_ref.split("/") cch_trans = list(summarize_trans( CouchTransaction.to_ledgers( get_couch_transactions(case_id, section_id, entry_id)))) sql_trans = list( summarize_trans(get_sql_transactions(case_id, section_id, entry_id))) print("Ledger", ledger_ref) print("date couch sql form/tx type") print(" +/- = +/- =") for ccht, sqlt in merge_transactions(cch_trans, sql_trans): both = ccht or sqlt ptx = verbose or \ (ccht and sqlt and ccht.updated_balance != sqlt.updated_balance) header = both.report_date.strftime("%Y-%m-%d %H:%M:%S") footer = f"{both.form_id} {both.server_date}" print_tx(header, ccht, sqlt, footer) if ptx: print_transactions(ccht, sqlt) stock = StockState.objects.get( case_id=case_id, section_id=section_id, product_id=entry_id) try: ledger = LedgerAccessorSQL.get_ledger_value( case_id=case_id, section_id=section_id, entry_id=entry_id) except LedgerValueNotFound: class ledger: balance = None print(f"ledger value: {num(stock.balance):>17} {num(ledger.balance):>11}")
def get_models_to_update(self, stock_report_helper, ledger_db=None): latest_values = {} for stock_trans in stock_report_helper.transactions: def _lazy_original_balance(): # needs to be in closures because it's zero-argument. # see compute_ledger_values for more information if stock_trans.ledger_reference in latest_values: return latest_values[stock_trans.ledger_reference] else: return self.get_current_ledger_value(stock_trans.ledger_reference) new_ledger_values = compute_ledger_values( _lazy_original_balance, stock_report_helper.report_type, stock_trans.relative_quantity ) latest_values[stock_trans.ledger_reference] = new_ledger_values.balance to_save = [] for touched_ledger_reference, quantity in latest_values.items(): try: ledger_value = LedgerAccessorSQL.get_ledger_value(**touched_ledger_reference._asdict()) except LedgerValue.DoesNotExist: ledger_value = LedgerValue(**touched_ledger_reference._asdict()) ledger_value.balance = quantity to_save.append(ledger_value) return StockModelUpdateResult(to_save=to_save)
def hard_rebuild_ledgers(case_id, section_id=None, entry_id=None): transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(case_id, section_id, entry_id) if not transactions: LedgerAccessorSQL.delete_ledger_values(case_id, section_id, entry_id) return ledger_value = LedgerAccessorSQL.get_ledger_value(case_id, section_id, entry_id) ledger_value = LedgerProcessorSQL._rebuild_ledger_value_from_transactions(ledger_value, transactions) LedgerAccessorSQL.save_ledger_values([ledger_value]) publish_ledger_v2_saved(ledger_value)
def hard_rebuild_ledgers(domain, case_id, section_id, entry_id): transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(case_id, section_id, entry_id) if not transactions: LedgerAccessorSQL.delete_ledger_values(case_id, section_id, entry_id) publish_ledger_v2_deleted(domain, case_id, section_id, entry_id) return ledger_value = LedgerAccessorSQL.get_ledger_value(case_id, section_id, entry_id) ledger_value = LedgerProcessorSQL._rebuild_ledger_value_from_transactions(ledger_value, transactions) LedgerAccessorSQL.save_ledger_values([ledger_value]) publish_ledger_v2_saved(ledger_value)
def _get_daily_consumption_for_ledger(ledger): from corehq.apps.commtrack.consumption import get_consumption_for_ledger_json daily_consumption = get_consumption_for_ledger_json(ledger) from corehq.form_processor.backends.sql.dbaccessors import LedgerAccessorSQL ledger_value = LedgerAccessorSQL.get_ledger_value(ledger['case_id'], ledger['section_id'], ledger['entry_id']) ledger_value.daily_consumption = daily_consumption LedgerAccessorSQL.save_ledger_values([ledger_value]) return daily_consumption
def _get_daily_consumption_for_ledger(ledger): from corehq.apps.commtrack.consumption import get_consumption_for_ledger_json daily_consumption = get_consumption_for_ledger_json(ledger) if should_use_sql_backend(ledger['domain']): from corehq.form_processor.backends.sql.dbaccessors import LedgerAccessorSQL ledger_value = LedgerAccessorSQL.get_ledger_value( ledger['case_id'], ledger['section_id'], ledger['entry_id']) ledger_value.daily_consumption = daily_consumption LedgerAccessorSQL.save_ledger_values([ledger_value]) else: from corehq.apps.commtrack.models import StockState StockState.objects.filter(pk=ledger['_id']).update( daily_consumption=daily_consumption) return daily_consumption
def _get_daily_consumption_for_ledger(ledger): from corehq.apps.commtrack.consumption import get_consumption_for_ledger_json daily_consumption = get_consumption_for_ledger_json(ledger) if should_use_sql_backend(ledger['domain']): from corehq.form_processor.backends.sql.dbaccessors import LedgerAccessorSQL ledger_value = LedgerAccessorSQL.get_ledger_value( ledger['case_id'], ledger['section_id'], ledger['entry_id'] ) ledger_value.daily_consumption = daily_consumption LedgerAccessorSQL.save_ledger_values([ledger_value]) else: from corehq.apps.commtrack.models import StockState StockState.objects.filter(pk=ledger['_id']).update(daily_consumption=daily_consumption) return daily_consumption
def check_stock(self, code, amount, case_id=None, section_id='stock'): if not case_id: case_id = self.sp.case_id [product] = [p for p in self.products if p.code_ == code] try: state = LedgerAccessorSQL.get_ledger_value(case_id, section_id, product._id) self.assertEqual(amount, state.stock_on_hand) except LedgerValueNotFound: if amount != 0: # only error if we weren't checking for no stock raise Exception( f'Ledger value for "{section_id}" section does not exist')
def patch_ledger_daily_consumption(diff): """Patch missing LedgerValue daily_consumption This is deliberately done as a patch action rather than automatically as part of the main migration to leave an audit trail showing that the difference existed in the initial happy-path migration phase. The migration does not publish ledger changes to Kafka change feeds where daily_consumption is normally calculated. Instead the value is copied from the Couch StockState. """ ref = diff.ref ledger = LedgerAccessorSQL.get_ledger_value(ref.case_id, ref.section_id, ref.entry_id) assert ledger.daily_consumption is None, ref ledger.daily_consumption = diff.old_value ledger.save()
def _get_ledger(self, unique_ledger_reference): try: return LedgerAccessorSQL.get_ledger_value( **unique_ledger_reference._asdict()) except LedgerValueNotFound: return None
def get_current_ledger_value(self, unique_ledger_reference): try: return LedgerAccessorSQL.get_ledger_value(**unique_ledger_reference._asdict()).balance except LedgerValue.DoesNotExist: return 0
def _get_ledger(self, unique_ledger_reference): try: return LedgerAccessorSQL.get_ledger_value(**unique_ledger_reference._asdict()) except LedgerValueNotFound: return None
def get_sql_ledger_value(*args): return LedgerAccessorSQL.get_ledger_value(*args)