def new_bill_protocol(bill_model: BillModel, entity_slug: str or EntityModel, user_model: UserModel, bill_desc: str = None) -> Tuple[LedgerModel, BillModel]: if isinstance(entity_slug, str): entity_qs = EntityModel.objects.for_user(user_model=user_model) entity_model: EntityModel = get_object_or_404(entity_qs, slug__exact=entity_slug) elif isinstance(entity_slug, EntityModel): entity_model = entity_slug else: raise ValidationError( 'entity_slug must be an instance of str or EntityModel') bill_model.bill_number = generate_bill_number() ledger_name = f'Bill {bill_model.bill_number}' if bill_desc: ledger_name += f' | {bill_desc}' ledger_model: LedgerModel = LedgerModel.objects.create( entity=entity_model, posted=True, name=ledger_name, ) ledger_model.clean() bill_model.ledger = ledger_model return ledger_model, bill_model
def new_bill_protocol(bill_model: BillModel, entity_slug: str or EntityModel, user_model: UserModel, unit_slug: str = None) -> BillModel: if isinstance(entity_slug, str): entity_qs = EntityModel.objects.for_user( user_model=user_model) entity_model: EntityModel = get_object_or_404(entity_qs, slug__exact=entity_slug) elif isinstance(entity_slug, EntityModel): entity_model = entity_slug else: raise ValidationError('entity_slug must be an instance of str or EntityModel') if unit_slug: unit_model_qs = entity_model.entityunitmodel_set.all() unit_model = get_object_or_404(unit_model_qs, slug__exact=unit_slug) else: unit_model = None bill_model.bill_number = generate_bill_number() ledger_model = LedgerModel.objects.create( entity=entity_model, posted=True, name=f'Bill {bill_model.bill_number}', unit=unit_model ) ledger_model.clean() bill_model.ledger = ledger_model return bill_model
def generate_random_bill( entity_model: EntityModel, unit_models: list, user_model, vendor_models: list, expense_models: list, is_accruable: bool, progress: float, accounts_by_role: dict, issue_dt: date, is_paid: bool, paid_dt: date): bill_model: BillModel = BillModel( vendor=choice(vendor_models), accrue=is_accruable, progress=progress, terms=choice(BillModel.TERMS)[0], bill_number=generate_bill_number(), amount_due=0, cash_account=choice(accounts_by_role['asset_ca_cash']), prepaid_account=choice(accounts_by_role['asset_ca_recv']), unearned_account=choice(accounts_by_role['lia_cl_acc_pay']), date=issue_dt, paid=is_paid, paid_date=paid_dt ) ledger_model, bill_model = new_bill_protocol( bill_model=bill_model, entity_slug=entity_model, user_model=user_model) bill_items = [ BillModelItemsThroughModel( bill_model=bill_model, item_model=choice(expense_models), quantity=round(random() * randint(1, 5), 2), unit_cost=round(random() * randint(100, 800), 2), entity_unit=choice(unit_models) if random() > .75 else None ) for _ in range(randint(1, 10)) ] for bi in bill_items: bi.clean() bill_model.update_amount_due(item_list=bill_items) bill_model.amount_paid = Decimal.from_float(round(random() * float(bill_model.amount_due), 2)) bill_model.new_state(commit=True) bill_model.clean() bill_model.save() bill_items = bill_model.billmodelitemsthroughmodel_set.bulk_create(bill_items) bill_model.migrate_state( user_model=user_model, item_models=bill_items, entity_slug=entity_model.slug, je_date=issue_dt) if is_paid: ledger_model.locked = True ledger_model.save(update_fields=['locked'])
def generate_random_bill( entity_model: EntityModel, user_model, vendor_models: list, expense_models: list, is_progressible: bool, progress: float, accounts_by_role: dict, issue_dt: date, is_paid: bool, paid_dt: date): bill_model = BillModel( vendor=choice(vendor_models), progressible=is_progressible, progress=progress, terms=choice(BillModel.TERMS)[0], bill_number=generate_bill_number(), amount_due=0, cash_account=choice(accounts_by_role['asset_ca_cash']), receivable_account=choice(accounts_by_role['asset_ca_recv']), payable_account=choice(accounts_by_role['lia_cl_acc_pay']), earnings_account=choice(accounts_by_role['ex_op']), date=issue_dt, paid=is_paid, paid_date=paid_dt ) bill_model = new_bill_protocol( bill_model=bill_model, entity_slug=entity_model, user_model=user_model) bill_model.clean() bill_model.save() bill_items = [ BillModelItemsThroughModel( bill_model=bill_model, item_model=choice(expense_models), quantity=round(random() * randint(1, 5), 2), unit_cost=round(random() * randint(100, 800), 2) ) for _ in range(randint(1, 10)) ] for ii in bill_items: ii.clean() bill_model.billmodelitemsthroughmodel_set.bulk_create(bill_items) bill_model.update_amount_due() bill_model.amount_paid = Decimal(round(random() * float(bill_model.amount_due), 2)) bill_model.new_state(commit=True) bill_model.clean() bill_model.save() bill_model.migrate_state( user_model=user_model, entity_slug=entity_model.slug, je_date=paid_dt)
def new_bill_protocol(bill_model: BillModel, entity_slug: str or EntityModel, user_model: UserModel) -> BillModel: if isinstance(entity_slug, str): entity_model = EntityModel.objects.for_user( user_model=user_model).get( slug__exact=entity_slug) elif isinstance(entity_slug, EntityModel): entity_model = entity_slug else: raise ValidationError('entity_slug must be an instance of str or EntityModel') bill_model.bill_number = generate_bill_number() ledger_model = LedgerModel.objects.create( entity=entity_model, posted=True, name=f'Bill {bill_model.bill_number}' ) ledger_model.clean() bill_model.ledger = ledger_model return bill_model
def generate_sample_data(entity: str or EntityModel, user_model, start_dt: datetime, days_fw: int, cap_contribution: float or int = 20000, income_tx_avg: float or int = 2000, expense_tx_avg: float or int = 1000, tx_quantity: int = 100, is_progressible_probability: float = 0.2, is_paid_probability: float = 0.97): """ TXS = List[{ 'account_id': Account Database UUID 'tx_type': credit/debit, 'amount': Decimal/Float/Integer, 'description': string, 'staged_tx_model': StagedTransactionModel or None }] :param is_paid_probability: :param is_progressible_probability: :param tx_quantity: :param expense_tx_avg: :param income_tx_avg: :param cap_contribution: :param days_fw: :param start_dt: :param user_model: :param entity: :return: """ try: from faker import Faker from faker.providers import company, address, phone_number global FAKER_IMPORTED FAKER_IMPORTED = True fk = Faker() fk.add_provider(company) fk.add_provider(address) fk.add_provider(phone_number) except ImportError: return False if not isinstance(entity, EntityModel): entity = EntityModel.objects.get(slug__exact=entity) entity.ledgers.all().delete() entity.customers.all().delete() entity.vendors.all().delete() vendor_count = randint(40, 60) vendor_models = [ VendorModel(vendor_name=fk.name() if random() > .7 else fk.company(), entity=entity, address_1=fk.street_address(), address_2=f'{fk.city()}. {fk.postcode()}', phone=fk.phone_number(), email=fk.email(), website=fk.url(), active=True, hidden=False) for _ in range(vendor_count) ] for vendor in vendor_models: vendor.clean() vendor_models = VendorModel.objects.bulk_create(vendor_models) customer_count = randint(40, 60) customer_models = [ CustomerModel( customer_name=fk.name() if random() > .2 else fk.company(), entity=entity, address_1=fk.street_address(), address_2=f'{fk.city()}. {fk.postcode()}', phone=fk.phone_number(), email=fk.email(), website=fk.url(), active=True, hidden=False) for _ in range(customer_count) ] for customer in customer_models: customer.clean() customer_models = CustomerModel.objects.bulk_create(customer_models) # todo: create bank account models... ledger, created = entity.ledgers.get_or_create( name='Business Funding Ledger', posted=True) accounts = AccountModel.on_coa.for_entity_available( entity_slug=entity.slug, user_model=user_model).order_by('role') accounts_gb = { g: list(v) for g, v in groupby(accounts, key=lambda a: a.role) } capital_acc = choice(accounts_gb['eq_capital']) cash_acc = choice(accounts_gb['asset_ca_cash']) txs = list() txs.append({ 'account_id': cash_acc.uuid, 'tx_type': 'debit', 'amount': cap_contribution, 'description': f'Sample data for {entity.name}' }) txs.append({ 'account_id': capital_acc.uuid, 'tx_type': 'credit', 'amount': cap_contribution, 'description': f'Sample data for {entity.name}' }) entity.commit_txs(je_date=start_dt, je_txs=txs, je_activity='op', je_posted=True, je_ledger=ledger) loc_time = localtime() rng = tx_quantity for i in range(rng): issue_dttm = start_dt + timedelta(days=randint(0, days_fw)) if issue_dttm > loc_time: issue_dttm = loc_time is_progressible = random() < is_progressible_probability progress = Decimal(round(random(), 2)) if is_progressible else 0 is_paid = random() < is_paid_probability paid_dttm = issue_dttm + timedelta( days=randint(0, 60)) if is_paid else None if paid_dttm and paid_dttm >= loc_time: paid_dttm = None is_paid = False issue_dt = issue_dttm.date() paid_dt = paid_dttm.date() if paid_dttm else None switch_amt = random() > 0.75 if i % 2 == 0: amt = expense_tx_avg if not switch_amt else income_tx_avg bill_amt = Decimal(round(random() * amt, 2)) bill_amt_paid = Decimal(round(Decimal(random()) * bill_amt, 2)) bill = BillModel( vendor=choice(vendor_models), progressible=is_progressible, progress=progress, terms=choice(BillModel.TERMS)[0], xref=generate_bill_number(length=15, prefix=False), cash_account=choice(accounts_gb['asset_ca_cash']), receivable_account=choice(accounts_gb['asset_ca_recv']), payable_account=choice(accounts_gb['lia_cl_acc_pay']), earnings_account=choice(accounts_gb['ex_op']), amount_due=bill_amt, amount_paid=bill_amt_paid, date=issue_dt, paid=is_paid, paid_date=paid_dt) bill = new_bill_protocol(bill_model=bill, entity_slug=entity.slug, user_model=user_model) bill.clean() bill.migrate_state(user_model=user_model, entity_slug=entity.slug, je_date=paid_dt) bill.save() else: amt = income_tx_avg if not switch_amt else expense_tx_avg inv_amt = Decimal(round(random() * amt, 2)) inv_amt_paid = Decimal(round(Decimal(random()) * inv_amt, 2)) invoice = InvoiceModel( customer=choice(customer_models), progressible=is_progressible, progress=progress, terms=choice(InvoiceModel.TERMS)[0], invoice_number=generate_invoice_number(), cash_account=choice(accounts_gb['asset_ca_cash']), receivable_account=choice(accounts_gb['asset_ca_recv']), payable_account=choice(accounts_gb['lia_cl_acc_pay']), earnings_account=choice(accounts_gb['in_sales']), amount_due=inv_amt, amount_paid=inv_amt_paid, date=issue_dt, paid=is_paid, paid_date=paid_dt) invoice = new_invoice_protocol(invoice_model=invoice, entity_slug=entity.slug, user_model=user_model) invoice.clean() invoice.migrate_state(user_model=user_model, entity_slug=entity.slug, je_date=paid_dt) invoice.save()