Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Commit

Permalink
fix(redmine): fix NoneType for amount offered/invoiced for projects
Browse files Browse the repository at this point in the history
Write 0.00 in redmine if the project has no amount offered/invoiced
  • Loading branch information
trowik committed Mar 1, 2023
1 parent e444308 commit 6e1f4c8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
14 changes: 11 additions & 3 deletions timed/redmine/management/commands/update_project_expenditure.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ def handle(self, *args, **options):
)
continue
issue.estimated_hours = estimated_hours

amount_offered = (
project.amount_offered and project.amount_offered.amount
) or "0.00"
amount_invoiced = (
project.amount_invoiced and project.amount_invoiced.amount
) or "0.00"

# fields not active in Redmine projects settings won't be saved
issue.custom_fields = [
{
Expand All @@ -67,11 +75,11 @@ def handle(self, *args, **options):
},
{
"id": settings.REDMINE_AMOUNT_OFFERED_FIELD,
"value": project.amount_offered.amount,
"value": amount_offered,
},
{
"id": settings.REDMINE_AMOUNT_INVOICED_FIELD,
"value": project.amount_invoiced.amount,
"value": amount_invoiced,
},
]
if not pretend:
Expand All @@ -87,6 +95,6 @@ def handle(self, *args, **options):

self.stdout.write(
self.style.SUCCESS(
f"Updating Redmine issue {project.redmine_project.issue_id} with total spent hours {total_spent_hours}, amount offered {project.amount_offered.amount}, amount invoiced {project.amount_invoiced.amount}"
f"Updating Redmine issue {project.redmine_project.issue_id} with total spent hours {total_spent_hours}, amount offered {amount_offered}, amount invoiced {amount_invoiced}"
)
)
14 changes: 10 additions & 4 deletions timed/redmine/tests/test_update_project_expenditure.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
from timed.redmine.models import RedmineProject


@pytest.mark.parametrize("pretend", [False, True])
def test_update_project_expenditure(db, mocker, capsys, report_factory, pretend):
@pytest.mark.parametrize("pretend", [True, False])
@pytest.mark.parametrize("amount_offered", [None, 100.00, 0])
def test_update_project_expenditure(
db, mocker, capsys, report_factory, pretend, amount_offered
):
redmine_instance = mocker.MagicMock()
issue = mocker.MagicMock()
redmine_instance.issue.get.return_value = issue
Expand All @@ -18,24 +21,27 @@ def test_update_project_expenditure(db, mocker, capsys, report_factory, pretend)
report = report_factory(duration=datetime.timedelta(hours=4))
project = report.task.project
project.estimated_time = datetime.timedelta(hours=10)
project.amount_offered = amount_offered
project.save()

RedmineProject.objects.create(project=report.task.project, issue_id=1000)

call_command("update_project_expenditure", pretend=pretend)

offered = (project.amount_offered and project.amount_offered.amount) or "0.00"

if not pretend:
redmine_instance.issue.get.assert_called_once_with(1000)
assert issue.estimated_hours == project.estimated_time.total_seconds() / 3600
assert issue.custom_fields[0]["value"] == report.duration.total_seconds() / 3600
assert issue.custom_fields[1]["value"] == project.amount_offered.amount
assert issue.custom_fields[1]["value"] == offered
assert issue.custom_fields[2]["value"] == project.amount_invoiced.amount
issue.save.assert_called_once_with()
else:
out, _ = capsys.readouterr()
assert "Redmine issue 1000" in out
assert f"total spent hours {report.duration.total_seconds() / 3600}" in out
assert f"amount offered {project.amount_offered.amount}" in out
assert f"amount offered {offered}" in out
assert f"amount invoiced {project.amount_invoiced.amount}" in out


Expand Down

0 comments on commit 6e1f4c8

Please sign in to comment.