예제 #1
0
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
예제 #2
0
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'])
예제 #3
0
    def create_bill(self, is_accruable: bool, progress: float, issue_dt: date,
                    is_paid: bool, paid_dt: date):

        bill_model: BillModel = BillModel(
            vendor=choice(self.vendor_models),
            accrue=is_accruable,
            progress=progress,
            terms=choice(BillModel.TERMS)[0],
            bill_number=generate_bill_number(),
            amount_due=0,
            cash_account=choice(self.accounts_by_role[ASSET_CA_CASH]),
            prepaid_account=choice(self.accounts_by_role[ASSET_CA_PREPAID]),
            unearned_account=choice(
                self.accounts_by_role[LIABILITY_CL_DEFERRED_REVENUE]),
            date=issue_dt,
            paid=is_paid,
            paid_date=paid_dt)

        ledger_model, bill_model = bill_model.configure(
            entity_slug=self.entity_model,
            user_model=self.user_model,
            ledger_posted=True)

        if random() > 0.3:
            bill_model.bill_status = BillModel.BILL_STATUS_APPROVED

        bill_items = [
            ItemThroughModel(bill_model=bill_model,
                             item_model=choice(self.expense_models),
                             quantity=round(random() * randint(5, 15), 2),
                             unit_cost=round(random() * randint(50, 100), 2),
                             entity_unit=choice(self.entity_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()

        # pylint: disable=no-member
        bill_model.itemthroughmodel_set.bulk_create(bill_items)
        bill_model.migrate_state(user_model=self.user_model,
                                 entity_slug=self.entity_model.slug,
                                 je_date=issue_dt)

        if is_paid:
            ledger_model.locked = True
            ledger_model.save(update_fields=['locked'])
예제 #4
0
    def create_po(self, po_date: date):

        po_model: PurchaseOrderModel = PurchaseOrderModel()
        po_model = po_model.configure(entity_slug=self.entity_model,
                                      user_model=self.user_model,
                                      po_date=po_date)
        po_model.po_title = f'PO Title for {po_model.po_number}'

        po_items = [
            ItemThroughModel(po_model=po_model,
                             item_model=choice(self.inventory_models),
                             po_quantity=round(random() * randint(3, 10), 2),
                             po_unit_cost=round(random() * randint(100, 800),
                                                2),
                             entity_unit=choice(self.entity_unit_models)
                             if random() > .75 else None)
            for _ in range(randint(1, 10))
        ]

        for poi in po_items:
            poi.clean()

        po_model.update_po_state(item_list=po_items)

        po_model.clean()
        po_model.save()

        # pylint: disable=no-member
        po_items = po_model.itemthroughmodel_set.bulk_create(po_items)

        # mark as approved...
        if random() > 0.3:
            po_model.mark_as_approved(commit=True)

            # mark as fulfilled...
            if random() > 0.5:
                ldt = self.localtime.date()
                fulfilled_dt = po_date + timedelta(days=randint(4, 10))
                bill_dt = po_date + timedelta(days=randint(1, 3))

                if bill_dt > ldt:
                    bill_dt = ldt

                bill_model: BillModel = BillModel(
                    bill_number=f'Bill for {po_model.po_number}',
                    date=bill_dt,
                    vendor=choice(self.vendor_models))
                ledger_model, bill_model = bill_model.configure(
                    ledger_posted=True,
                    entity_slug=self.entity_model.slug,
                    user_model=self.user_model)
                bill_model.bill_status = BillModel.BILL_STATUS_APPROVED
                bill_model.amount_due = po_model.po_amount
                bill_model.paid = True

                paid_date = bill_dt + timedelta(days=1)
                if paid_date > ldt:
                    paid_date = ldt
                bill_model.paid_date = paid_date

                bill_model.cash_account = choice(
                    self.accounts_by_role[ASSET_CA_CASH])
                bill_model.prepaid_account = choice(
                    self.accounts_by_role[ASSET_CA_PREPAID])
                bill_model.unearned_account = choice(
                    self.accounts_by_role[LIABILITY_CL_DEFERRED_REVENUE])

                bill_model.terms = choice([
                    BillModel.TERMS_ON_RECEIPT,
                    BillModel.TERMS_NET_30,
                    BillModel.TERMS_NET_60,
                    BillModel.TERMS_NET_60,
                    # BillModel.TERMS_NET_90_PLUS,
                ])
                bill_model.clean()
                bill_model.update_state()
                bill_model.save()

                for po_i in po_items:
                    po_i.total_amount = po_i.po_total_amount
                    po_i.quantity = po_i.po_quantity
                    po_i.unit_cost = po_i.po_unit_cost
                    po_i.bill_model = bill_model
                    po_i.po_item_status = ItemThroughModel.STATUS_RECEIVED
                    po_i.clean()
                ItemThroughModel.objects.bulk_update(
                    po_items,
                    fields=[
                        'po_total_amount', 'total_amount', 'po_quantity',
                        'quantity', 'po_unit_cost', 'unit_cost', 'bill_model',
                        'po_item_status'
                    ])
                bill_model.migrate_state(
                    user_model=self.user_model,
                    entity_slug=self.entity_model.slug,
                    # itemthrough_queryset=po_items
                )

                po_model.mark_as_fulfilled(date=fulfilled_dt,
                                           commit=True,
                                           po_items=po_items)
예제 #5
0
    def create_bill(self,
                    amount: Decimal,
                    date: date = None,
                    is_accrued: bool = False) -> tuple[EntityModel, BillModel]:
        entity_model: EntityModel = choice(self.ENTITY_MODEL_QUERYSET)
        vendor_model: VendorModel = entity_model.vendors.first()
        account_qs = entity_model.get_accounts(user_model=self.user_model)

        len(account_qs)  # force evaluation

        cash_account = account_qs.filter(role__in=[ASSET_CA_CASH]).first()
        prepaid_account = account_qs.filter(
            role__in=[ASSET_CA_PREPAID]).first()
        unearned_account = account_qs.filter(
            role__in=[LIABILITY_CL_DEFERRED_REVENUE]).first()
        dt = self.get_random_date() if not date else date

        bill_model = BillModel()
        ledger_model, bill_model = bill_model.configure(
            entity_slug=entity_model, user_model=self.user_model)

        bill_model.amount_due = amount
        bill_model.date = dt
        bill_model.vendor = vendor_model
        bill_model.accrue = is_accrued
        bill_model.xref = 'ABC123xref'
        bill_model.cash_account = cash_account
        bill_model.prepaid_account = prepaid_account
        bill_model.unearned_account = unearned_account
        bill_model.clean()
        bill_model.save()

        return entity_model, bill_model