示例#1
0
def migrate_invoices(apps, schema_editor):
    from systori.apps.company.models import Company
    from systori.apps.document.models import Invoice
    from systori.apps.task.models import Job
    from systori.apps.accounting.report import create_invoice_report
    from systori.apps.accounting.constants import TAX_RATE
    from systori.lib.accounting.tools import Amount

    for company in Company.objects.all():
        company.activate()

        for invoice in Invoice.objects.all():

            invoice.json["debit"] = Amount(invoice.json["debit_net"],
                                           invoice.json["debit_tax"])

            if "debits" not in invoice.json:
                invoice.json["jobs"] = []
                invoice.save()
                continue

            invoice.json["jobs"] = invoice.json["debits"]
            del invoice.json["debits"]

            jobs = Job.objects.filter(
                id__in=[job["job.id"] for job in invoice.json["jobs"]])
            tdate = date(
                *map(int, invoice.json["transactions"][-1]["date"].split("-")))
            new_json = create_invoice_report(invoice.transaction, jobs, tdate)
            if (company.schema == "mehr_handwerk"
                    and invoice.id not in [86, 111]) or (
                        company.schema == "montageservice_grad"
                        and invoice.id not in [1]):
                assert new_json["debit"].gross == invoice.json["debit"].gross
                assert new_json["invoiced"].gross == invoice.json[
                    "debited_gross"]
            invoice.json.update(new_json)

            for job in invoice.json["jobs"]:

                taskgroup_total = Decimal("0.00")
                for taskgroup in job["taskgroups"]:
                    taskgroup_total += taskgroup["total"]
                job["progress"] = Amount.from_net(taskgroup_total, TAX_RATE)

                invoiced_total = Amount.zero()
                for debit in invoice.json["job_debits"].get(job["job.id"], []):
                    invoiced_total += debit["amount"]
                job["invoiced"] = invoiced_total

                job["debit"] = Amount(job["amount_net"], job["amount_tax"])

                job["balance"] = Amount(job["balance_net"], job["balance_tax"])
                job["estimate"] = Amount.from_net(job["estimate_net"],
                                                  TAX_RATE)

                job["is_itemized"] = job["invoiced"].gross == job[
                    "progress"].gross

            invoice.save()
示例#2
0
    def calculate_accounting_state(self, state):

        state.paid_amount = self.job.account.paid.negate

        state.invoiced_amount = self.job.account.invoiced
        state.invoiced_diff_amount = state.invoiced_amount - state.paid_amount

        state.progress_amount = Amount.from_net(self.job.progress, TAX_RATE)
        state.progress_diff_amount = state.progress_amount - state.invoiced_amount
示例#3
0
    def calculate_accounting_state(self, state):

        state.estimate_amount = Amount.from_net(self.job.estimate, TAX_RATE)

        state.progress_amount = Amount.from_net(self.job.progress, TAX_RATE)
        state.progress_percent = self.job.progress_percent

        state.invoiced_amount = self.job.account.invoiced
        state.invoiced_percent = 0
        if state.progress_amount.net > 0:
            state.invoiced_percent = (
                state.invoiced_amount.net / state.progress_amount.net * 100
            )

        state.balance_amount = self.job.account.balance

        state.itemized_amount = state.progress_amount - state.invoiced_amount
        if state.itemized_amount.gross < 0:
            state.itemized_amount = Amount.zero()
示例#4
0
    def calculate_accounting_state(self, state):
        # Paid Column
        state.paid_amount = self.job.account.paid.negate

        # Invoiced Column
        state.invoiced_amount = self.job.account.invoiced
        state.invoiced_diff_amount = state.invoiced_amount - state.paid_amount

        # Billable Column
        state.progress_amount = Amount.from_net(self.job.progress, TAX_RATE)
        state.progress_diff_amount = state.progress_amount - state.invoiced_amount
示例#5
0
    def test_project_143_having_open_claim_2016_04_06(self):

        txn = debit_jobs(
            [
                (self.job, Amount.from_net(D("22721.38"),
                                           TAX_RATE), Entry.WORK_DEBIT),
                (self.job2, Amount.from_net(D("3400.05"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(8),
        )
        self.assertEqual(
            self.tbl(txn, [self.job, self.job2]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "26121.43", "4963.07", "31084.50"),
                ("debit", "26121.43", "4963.07", "31084.50"),
            ],
        )

        credit_jobs(
            [
                (self.job, A("26227.29"), A("811.15"), A()),
                (self.job2, A("1572.71"), A("48.64"), A("2424.71")),
            ],
            D("27800.00"),
            transacted_on=days_ago(7),
        )

        txn = debit_jobs(
            [
                (self.job, Amount.from_net(D("8500"),
                                           TAX_RATE), Entry.WORK_DEBIT),
                (self.job2, Amount.from_net(D("4000"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("1000"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(6),
        )
        self.assertEqual(
            self.tbl(txn, [self.job, self.job2, self.job3]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "37583.86", "7140.93", "44724.79"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("debit", "13500.00", "2565.00", "16065.00"),
            ],
        )

        credit_jobs(
            [
                (self.job, A("9811.55"), A("303.45"), A()),
                (self.job2, A("3188.45"), A("98.61"), A("1472.94")),
            ],
            D("13000.00"),
            transacted_on=days_ago(5),
        )

        txn = debit_jobs(
            [
                (self.job2, Amount.from_net(D("11895.04"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("1628.86"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job4, Amount.from_net(D("358.31"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(4),
        )
        self.assertEqual(
            self.tbl(txn, [self.job, self.job2, self.job3, self.job4]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "50228.31", "9543.37", "59771.68"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("payment", "-10924.37", "-2075.63", "-13000.00"),
                ("discount", "-337.87", "-64.19", "-402.06"),
                ("unpaid", "-1000.00", "-190.00", "-1190.00"),
                ("debit", "13882.21", "2637.62", "16519.83"),
            ],
        )

        credit_jobs(
            [
                (self.job2, A("6585.27"), A("203.67"), A("7366.16")),
                (self.job3, A("1938.34"), A("59.95"), A()),
                (self.job4, A("426.39"), A("13.19"), A()),
            ],
            D("8950.00"),
            transacted_on=days_ago(3),
        )

        # Initial Case: Due to an underpaid job, invoice shows 'open claim'.

        dtxn = debit_jobs(
            [
                (self.job2, Amount.from_net(D("17790.25"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job5, Amount.from_net(D("6377.68"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("2034.90"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job4, Amount.from_net(D("716.62"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(1),
        )
        self.assertEqual(
            self.tbl(dtxn,
                     [self.job, self.job2, self.job3, self.job4, self.job5]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "70957.71", "13481.96", "84439.67"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("payment", "-10924.37", "-2075.63", "-13000.00"),
                ("discount", "-337.87", "-64.19", "-402.06"),
                ("payment", "-7521.01", "-1428.99", "-8950.00"),
                ("discount", "-232.61", "-44.20", "-276.81"),
                ("unpaid", "-938.54", "-178.32", "-1116.86"),  # <-- open claim
                ("debit", "26919.45", "5114.70", "32034.15"),
            ],
        )
        dtxn.delete()

        # Adjusted Case: We adjust two jobs, no open claim, but progress is high due to over invoiced job.

        atxn = adjust_jobs(
            [
                (self.job3, A(n="-949.62", t="-180.43")),
                (self.job4, A(n="11.08", t="2.11")),
            ],
            transacted_on=days_ago(1),
        )

        dtxn = debit_jobs(
            [
                (self.job2, Amount.from_net(D("17790.25"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job5, Amount.from_net(D("6377.68"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("2984.52"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job4, Amount.from_net(D("705.54"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(3),
        )
        self.assertEqual(
            self.tbl(dtxn,
                     [self.job, self.job2, self.job3, self.job4, self.job5]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "70957.71", "13481.96", "84439.67"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("payment", "-10924.37", "-2075.63", "-13000.00"),
                ("discount", "-337.87", "-64.19", "-402.06"),
                ("payment", "-7521.01", "-1428.99", "-8950.00"),
                ("discount", "-232.61", "-44.20", "-276.81"),
                # ('unpaid',    '-938.54',  '-178.32',  '-1116.86'), <-- consumed into debit below
                ("debit", "27857.99", "5293.02", "33151.01"),
            ],
        )
        atxn.delete()
        dtxn.delete()

        # Adjusted Case II: We adjust three jobs, now invoice progress is correct and there is no open claim.

        atxn = adjust_jobs(
            [
                (self.job, A(n="-4678.55", t="-888.92")),
                (self.job3, A(n="-949.62", t="-180.43")),
                (self.job4, A(n="11.08", t="2.11")),
            ],
            transacted_on=days_ago(1),
        )

        dtxn = debit_jobs(
            [
                (self.job2, Amount.from_net(D("17790.25"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job5, Amount.from_net(D("6377.68"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("2984.52"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job4, Amount.from_net(D("705.54"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(3),
        )
        self.assertEqual(
            self.tbl(dtxn,
                     [self.job, self.job2, self.job3, self.job4, self.job5]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "66279.16", "12593.04", "78872.20"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("payment", "-10924.37", "-2075.63", "-13000.00"),
                ("discount", "-337.87", "-64.19", "-402.06"),
                ("payment", "-7521.01", "-1428.99", "-8950.00"),
                ("discount", "-232.61", "-44.20", "-276.81"),
                ("debit", "27857.99", "5293.02", "33151.01"),
            ],
        )
        atxn.delete()
        dtxn.delete()

        # Adjusted & Refund Case: We adjust three jobs as before but also issue a refund.
        #                         Just making sure refund does not change the invoice in anyway.

        atxn = adjust_jobs(
            [
                (self.job, A(n="-4678.55", t="-888.92")),
                (self.job3, A(n="-949.62", t="-180.43")),
                (self.job4, A(n="11.08", t="2.11")),
            ],
            transacted_on=days_ago(1),
        )

        rtxn = refund_jobs(
            [
                (self.job, A(n="4678.55", t="888.92"), A()),
                (self.job2, A(), A(n="4678.55", t="888.92")),
            ],
            transacted_on=days_ago(1),
        )

        dtxn = debit_jobs(
            [
                (self.job2, Amount.from_net(D("17790.25"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job5, Amount.from_net(D("6377.68"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job3, Amount.from_net(D("2984.52"),
                                            TAX_RATE), Entry.WORK_DEBIT),
                (self.job4, Amount.from_net(D("705.54"),
                                            TAX_RATE), Entry.WORK_DEBIT),
            ],
            transacted_on=days_ago(3),
        )
        self.assertEqual(
            self.tbl(dtxn,
                     [self.job, self.job2, self.job3, self.job4, self.job5]),
            [
                ("", "net", "tax", "gross"),
                ("progress", "66279.16", "12593.04", "78872.20"),
                ("payment", "-23361.35", "-4438.65", "-27800.00"),
                ("discount", "-722.51", "-137.28", "-859.79"),
                ("payment", "-10924.37", "-2075.63", "-13000.00"),
                ("discount", "-337.87", "-64.19", "-402.06"),
                ("payment", "-7521.01", "-1428.99", "-8950.00"),
                ("discount", "-232.61", "-44.20", "-276.81"),
                ("debit", "27857.99", "5293.02", "33151.01"),
            ],
        )
        atxn.delete()
        rtxn.delete()
        dtxn.delete()
示例#6
0
def migrate_proposals(apps, schema_editor):
    from systori.apps.company.models import Company
    from systori.apps.task.models import Job
    from systori.apps.document.models import Proposal
    from systori.apps.accounting.constants import TAX_RATE
    from systori.lib.accounting.tools import Amount

    for company in Company.objects.all():
        company.activate()

        for proposal in Proposal.objects.all():

            try:
                if "total_base" not in proposal.json and "jobs" not in proposal.json:
                    proposal.json["date"] = proposal.document_date
                    proposal.json["estimate_total"] = Amount(
                        proposal.json["total_net"],
                        proposal.json["total_gross"] -
                        proposal.json["total_net"],
                    )
                    proposal.json["jobs"] = []

                else:
                    proposal.json["estimate_total"] = Amount(
                        proposal.json["total_base"],
                        proposal.json["total_tax"])
                    del proposal.json["total_base"], proposal.json[
                        "total_tax"], proposal.json["total_gross"]

                proposal.json["id"] = proposal.id
                proposal.json["title"] = _("Proposal")

                for job in proposal.json["jobs"]:

                    if "id" in job:
                        job["job.id"] = job["id"]
                        del job["id"]

                    else:
                        job_obj = Job.objects.filter(project=proposal.project,
                                                     name=job["name"]).get()
                        job["job.id"] = job_obj.id

                    job_estimate_net = Decimal("0.00")
                    for group in job["taskgroups"]:
                        group["estimate_net"] = group["total"]
                        del group["total"]
                        job_estimate_net += Decimal(group["estimate_net"])
                        for task in group["tasks"]:
                            task["estimate_net"] = task["total"]
                            del task["total"]
                    job["estimate"] = Amount.from_net(job_estimate_net,
                                                      TAX_RATE)

                proposal.save()

            except:

                if proposal.status == proposal.DECLINED:
                    proposal.delete()
                else:
                    raise
示例#7
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.estimate_amount = Amount.from_net(self.job.estimate, TAX_RATE)