Exemple #1
0
def parse_date_range_arguments(options: dict, default_range: str = "last_month", tz: Any = None) -> Tuple[datetime, datetime, List[Tuple[datetime, datetime]]]:
    """
    Parses date range from input and returns timezone-aware date range and
    interval list according to 'step' name argument (optional).
    See add_date_range_arguments()
    :param options: Parsed arguments passed to the command
    :param default_range: Default datetime range to return if no other selected
    :param tz: Optional timezone to use. Default is UTC.
    :return: begin, end, [(begin1,end1), (begin2,end2), ...]
    """
    begin, end = get_date_range_by_name(default_range, tz=tz)
    for range_name in TIME_RANGE_NAMES:
        if options.get(range_name):
            begin, end = get_date_range_by_name(range_name, tz=tz)
    if options.get("begin"):
        begin = parse_datetime(options["begin"], tz)  # type: ignore
        end = now()
    if options.get("end"):
        end = parse_datetime(options["end"], tz)  # type: ignore

    step_type = ""
    for step_name in TIME_STEP_NAMES:
        if options.get(step_name):
            if step_type:
                raise ValueError("Cannot use --{} and --{} simultaneously".format(step_type, step_name))
            step_type = step_name
    if step_type:
        steps = get_time_steps(step_type, begin, end)
    else:
        steps = [(begin, end)]
    return begin, end, steps
Exemple #2
0
def fetch_latest_euribor_rates(commit: bool = False,
                               verbose: bool = False) -> List[EuriborRate]:
    feed_url = (
        "https://www.suomenpankki.fi/WebForms/ReportViewerPage.aspx?report=/tilastot/markkina-_ja_hallinnolliset_korot/euribor_korot_today_xml_en&output=xml"
    )
    res = requests.get(feed_url)
    if verbose:
        logger.info("GET %s HTTP %s\n%s", feed_url, res.status_code,
                    res.content)
    if res.status_code >= 300:
        raise Exception(f"Failed to load Euribor rate feed from {feed_url}")
    results = xml_to_dict(res.content)
    data = results["data"]["period_Collection"]["period"]
    rates: List[EuriborRate] = []

    if isinstance(data, list):  # Sometime get a list or single item
        assert len(data) > 0
        data = data[len(data) - 1]  # Get from newest date

    record_date = parse_datetime(data["@value"]).date()
    for rate_data in data["matrix1_Title_Collection"]["rate"]:
        name = rate_data["@name"]
        rate = dec4(rate_data["intr"]["@value"])
        obj = EuriborRate(name=name, record_date=record_date, rate=rate)
        rates.append(obj)
    if commit:
        out: List[EuriborRate] = []
        for obj in rates:
            out.append(
                EuriborRate.objects.save_unique(obj.record_date, obj.name,
                                                obj.rate))
        return out
    return rates
Exemple #3
0
 def test_account(self):
     print("test_account")
     settlements = create_account_by_type(ACCOUNT_SETTLEMENTS)
     assert isinstance(settlements, Account)
     amounts = [12, "13.12", "-1.23", "20.00"]
     balances = [
         Decimal("12.00"),
         Decimal("25.12"),
         Decimal("23.89"),
         Decimal("43.89")
     ]
     t = parse_datetime("2016-06-13T01:00:00")
     dt = timedelta(minutes=5)
     times = [t + dt * i for i in range(len(amounts))]
     for i in range(len(times)):
         amount = amounts[i]
         t = times[i]
         e = AccountEntry(account=settlements,
                          amount=Decimal(amount),
                          type=EntryType.objects.get(code=E_SETTLEMENT),
                          timestamp=t)
         e.full_clean()
         e.save()
         self.assertEqual(settlements.balance, balances[i])
         self.assertEqual(settlements.balance, e.balance)
     for i in range(len(times)):
         t = times[i]
         self.assertEqual(settlements.get_balance(t + timedelta(seconds=1)),
                          balances[i])
Exemple #4
0
def camt053_get_dt(data: Dict[str, Any], key: str, name: str = "") -> datetime:
    s = camt053_get_val(data, key, None, True, name)
    val = parse_datetime(s)
    if val is None:
        raise ValidationError(
            _("camt.053 field {} type {} missing or invalid").format(
                name, "datetime") + ": {}".format(s))
    return val
Exemple #5
0
 def test_add_month(self):
     t = parse_datetime('2016-06-12T01:00:00')
     self.assertEqual(t.isoformat(), '2016-06-12T01:00:00+00:00')
     t2 = add_month(t)
     self.assertEqual(t2.isoformat(), '2016-07-12T01:00:00+00:00')
     t3 = add_month(t, 7)
     self.assertEqual(t3.isoformat(), '2017-01-12T01:00:00+00:00')
     t4 = add_month(t, -1)
     self.assertEqual(t4.isoformat(), '2016-05-12T01:00:00+00:00')
Exemple #6
0
def parse_start_and_end_date(
        tz: Any, **options) -> Tuple[Optional[date], Optional[date]]:
    start_date = None
    end_date = None
    time_now = now().astimezone(tz if tz else pytz.utc)
    if options["start_date"]:
        if options["start_date"] == "today":
            start_date = time_now.date()
        else:
            start_date = parse_datetime(
                options["start_date"]).date()  # type: ignore
        end_date = start_date
    if options["end_date"]:
        if options["end_date"] == "today":
            end_date = time_now.date()
        else:
            end_date = parse_datetime(
                options["end_date"]).date()  # type: ignore
    return start_date, end_date
Exemple #7
0
    def test_invoice(self):
        print("test_invoice")
        settlements = create_account_by_type(ACCOUNT_SETTLEMENTS)
        receivables_acc = create_account_by_type(ACCOUNT_RECEIVABLES)
        assert isinstance(settlements, Account)

        # create invoices
        t = parse_datetime("2016-05-05")
        amounts = [
            Decimal("120.00"),
            Decimal("100.00"),
            Decimal("50.00"),
            Decimal("40.00"),
        ]
        n = len(amounts)
        times = [add_month(t, i) for i in range(n)]
        invoices = []
        for t, amount in zip(times, amounts):
            invoice = Invoice(due_date=t)
            invoice.full_clean()
            invoice.save()
            AccountEntry.objects.create(
                account=receivables_acc,
                source_invoice=invoice,
                type=EntryType.objects.get(code=E_RENT),
                amount=amount)
            invoice.update_cached_fields()
            self.assertEqual(invoice.unpaid_amount, amount)
            invoices.append(invoice)
            # print(invoice)
        unpaid_invoices = [i for i in invoices]

        # create payments
        payment_ops = [
            (None, [
                Decimal("120.00"),
                Decimal("100.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
            (Decimal("50.00"), [
                Decimal("70.00"),
                Decimal("100.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
            (Decimal("70.50"), [
                Decimal("00.00"),
                Decimal("100.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
            (Decimal("100.00"), [
                Decimal("00.00"),
                Decimal("00.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
            (Decimal("100.00"), [
                Decimal("00.00"),
                Decimal("00.00"),
                Decimal("00.00"),
                Decimal("40.00")
            ]),
        ]
        for j in range(len(payment_ops)):
            print("test_invoice: Payment op test", j)
            for i in range(n):
                inv = invoices[i]
                assert isinstance(inv, Invoice)
            paid_amount, unpaid_amounts = payment_ops[j]
            if paid_amount is not None:
                p = AccountEntry.objects.create(
                    account=settlements,
                    settled_invoice=unpaid_invoices[0],
                    amount=paid_amount,
                    type=EntryType.objects.get(code=E_MANUAL_SETTLEMENT),
                )
                settle_assigned_invoice(receivables_acc, p, AccountEntry)
                if unpaid_invoices[0].is_paid:
                    unpaid_invoices = unpaid_invoices[1:]
            for i in range(n):
                inv = invoices[i]
                assert isinstance(inv, Invoice)
            for i in range(n):
                paid_amount_real = invoices[i]
                unpaid_amount_real = invoices[i].get_unpaid_amount()
                unpaid_amount_ref = unpaid_amounts[i]
                print(
                    "checking invoice {} payment status after payment op {} (real {}, expected {})"
                    .format(i, j, unpaid_amount_real, unpaid_amount_ref))
                self.assertEqual(unpaid_amount_real, unpaid_amount_ref,
                                 "[{}][{}]".format(j, i))

        # create another acc set
        settlements = create_account_by_type(ACCOUNT_SETTLEMENTS)
        assert isinstance(settlements, Account)
        receivables_acc = create_account_by_type(ACCOUNT_RECEIVABLES)
        assert isinstance(receivables_acc, Account)

        # create invoices
        t = parse_datetime("2016-05-05")
        amounts = [
            Decimal("120.00"),
            Decimal("100.00"),
            Decimal("50.00"),
            Decimal("40.00")
        ]
        n = len(amounts)
        times = [add_month(t, i) for i in range(n)]
        invoices = []
        for t, amount in zip(times, amounts):
            invoice = Invoice(due_date=t)
            invoice.full_clean()
            invoice.save()
            AccountEntry.objects.create(
                account=receivables_acc,
                source_invoice=invoice,
                type=EntryType.objects.get(code=E_RENT),
                amount=amount)
            invoice.update_cached_fields()
            self.assertEqual(invoice.unpaid_amount, amount)
            invoices.append(invoice)
            print("invoice created", invoice)
        unpaid_invoices = [i for i in invoices]

        # create payments:
        # paid_amount, unpaid_amounts (after payment)
        payment_ops = [
            (None, [
                Decimal("120.00"),
                Decimal("100.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
            (Decimal("250.00"), [
                Decimal("0.00"),
                Decimal("100.00"),
                Decimal("50.00"),
                Decimal("40.00")
            ]),
        ]
        for j in range(len(payment_ops)):
            paid_amount, unpaid_amounts = payment_ops[j]
            if paid_amount is not None and paid_amount > Decimal("0.00"):
                invoice = unpaid_invoices[0]
                print("Targeting settlement amount", paid_amount, "to invoice",
                      invoice, "invoice.amount", invoice.amount)
                p = AccountEntry.objects.create(
                    account=settlements,
                    amount=paid_amount,
                    settled_invoice=invoice,
                    type=EntryType.objects.get(code=E_MANUAL_SETTLEMENT),
                )
                settle_assigned_invoice(receivables_acc, p, AccountEntry)
                if invoice.is_paid:
                    unpaid_invoices = unpaid_invoices[1:]
                    print("invoice paid, now left", unpaid_invoices)
            for i in range(n):
                unpaid_amount_real = invoices[i].get_unpaid_amount()
                unpaid_amount_ref = unpaid_amounts[i]
                self.assertEqual(unpaid_amount_real, unpaid_amount_ref,
                                 "[{}][{}]".format(j, i))

        # check that the first payment has E_RENT 120
        inv = invoices[0]
        assert isinstance(inv, Invoice)
        es = inv.receivables.order_by("id")
        self.assertEqual(es[0].amount, Decimal("120.00"))
        self.assertEqual(es[1].amount, Decimal("-120.00"))
        self.assertIsNotNone(es[1].parent)
        self.assertTrue(es[1].parent.type.is_settlement)
        self.assertEqual(es[1].parent.amount, Decimal("250.00"))