示例#1
0
def test_deliverable_burned_cost(statistics_api, put_project, post_issue,
                                 post_timesheet, post_deliverable, put_link):
    project = create_project()
    put_project(project)
    bound_deliverable = post_deliverable(project.project_id,
                                         create_deliverable())

    # Issue with default project currency
    bound_issue = post_issue(project.project_id, create_issue())
    put_link(bound_deliverable.object_id, bound_issue.object_id)
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(2)))
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(1)))
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(1)))
    # Issue with overriden currency
    bound_issue = post_issue(
        project.project_id,
        create_issue(hour_rate=Money(Decimal(1000), currency=Currency.czk)))
    put_link(bound_deliverable.object_id, bound_issue.object_id)
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(10)))
    # Issue without timesheet
    bound_issue = post_issue(project.project_id, create_issue())
    put_link(bound_deliverable.object_id, bound_issue.object_id)

    statistics = statistics_api.get_deliverable_statistics(
        bound_deliverable.object_id)
    assert statistics.burned_cost == Money(Decimal(12402), Currency.czk)
示例#2
0
def test_deliverable_estimated_cost(statistics_api, put_project, post_issue,
                                    put_link, post_deliverable):
    project = create_project()
    put_project(project)
    bound_deliverable = post_deliverable(project.project_id,
                                         create_deliverable())

    # Issue with default project currency
    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=Decimal(5)))
    put_link(bound_deliverable.object_id, bound_issue.object_id)
    # Issue with overriden currency
    bound_issue = post_issue(
        project.project_id,
        create_issue(estimated_duration=Decimal(2),
                     hour_rate=Money(amount=Decimal(1000),
                                     currency=Currency.czk)))
    put_link(bound_deliverable.object_id, bound_issue.object_id)
    # Issue without estimated duration
    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=None))
    put_link(bound_deliverable.object_id, bound_issue.object_id)

    statistics = statistics_api.get_deliverable_statistics(
        bound_deliverable.object_id)
    assert statistics.estimated_cost == Money(amount=Decimal("5002.5"),
                                              currency=Currency.czk)
示例#3
0
def test_issue_expenditures_cost(
    statistics_api,
    put_project,
    post_issue,
    post_expenditure,
):
    project = create_project()
    put_project(project)

    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=Decimal(5)))
    post_expenditure(
        bound_issue.object_id,
        create_expenditure(cost=Money(Decimal(10), currency=Currency.czk)))
    post_expenditure(bound_issue.object_id,
                     create_expenditure(status=ExpenditureStatus.submitted))
    post_expenditure(bound_issue.object_id,
                     create_expenditure(status=ExpenditureStatus.refund))
    post_expenditure(
        bound_issue.object_id,
        create_expenditure(cost=Money(Decimal(100), currency=Currency.czk)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.burned_expenditures_cost == Money(
        Decimal(110), Currency.czk)
示例#4
0
def test_issue_burned_cost_overriden_currency(statistics_api, put_project,
                                              post_issue, post_timesheet,
                                              post_deliverable, put_link):
    project = create_project()
    put_project(project)

    # Issue with overriden currency
    bound_issue = post_issue(
        project.project_id,
        create_issue(hour_rate=Money(Decimal(1000), currency=Currency.czk)))
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(10)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.burned_cost == Money(Decimal(10000), Currency.czk)
示例#5
0
 def _compute_expenditures_cost(
         entity_statistics: List[EntityStatistics]) -> Money:
     return Money(
         amount=sum(statistic.expenditure_costs.amount
                    for statistic in entity_statistics),
         currency=Currency.czk,
     )
示例#6
0
    def get_entity_statistics(self, entity_ids: List[EntityId]):
        if not entity_ids:
            return []
        assert len({entity_id.project_id for entity_id in entity_ids}) == 1

        full_ids = [entity_id.full_id for entity_id in entity_ids]
        # All entities are from same project
        default_hour_rate = self._get_project_hour_rate(entity_ids[0].project_id)
        entity_data = self._get_entity_data(full_ids)
        burned_time = self._get_burned_time(full_ids)
        expenditure_costs = self._get_expenditure_costs(full_ids)

        entity_statistics = []
        for entity_id in entity_ids:
            hour_rate = default_hour_rate
            if entity_data[entity_id].hour_rate:
                hour_rate = entity_data[entity_id].hour_rate
            entity_statistics.append(
                EntityStatistics(
                    estimated_duration=entity_data[entity_id].estimated_duration,
                    hour_rate=hour_rate,
                    burned_duration=burned_time.get(entity_id, Decimal(0)),
                    expenditure_costs=expenditure_costs.get(
                        entity_id,
                        Money(
                            amount=Decimal(0),
                            currency=Currency.czk,
                        )
                    ),
                )
            )
        return entity_statistics
示例#7
0
 def _compute_burned_cost(
         entity_statistics: List[EntityStatistics]) -> Money:
     return Money(
         amount=sum(statistic.burned_duration * statistic.hour_rate.amount
                    for statistic in entity_statistics),
         currency=Currency.czk,
     )
示例#8
0
 def _row_to_entity(row) -> BoundIssue:
     hour_rate = None
     if row["hour_rate_amount"] and row["hour_rate_currency"]:
         hour_rate = Money(
             amount=row["hour_rate_amount"],
             currency=Currency(row["hour_rate_currency"]),
         )
     return BoundIssue(object_id=EntityId(row["object_id"]),
                       issue=Issue(
                           name=row["name"],
                           status=IssueStatus(row["status"]),
                           type_=IssueType(row["type"]),
                           priority=IssuePriority(row["priority"]),
                           date_opened=row["date_opened"],
                           date_closed=row["date_closed"],
                           deadline=row["deadline"],
                           description=row["description"],
                           external_type=row["external_type"],
                           estimated_duration=row["estimated_duration"],
                           hour_rate=hour_rate,
                           files=[],
                           links=[],
                           tags=[],
                           tasks=[],
                       ))
示例#9
0
def test_project_expenditures_cost_no_entities(statistics_api, put_project):
    project = create_project()
    put_project(project)

    statistics = statistics_api.get_project_statistics(project.project_id)
    assert statistics.burned_expenditures_cost == Money(
        Decimal(0), Currency.czk)
示例#10
0
 def _get_entity_data(self, entity_ids: List[str]):
     query = select(
         [
             ISSUES_TABLE.c.hour_rate_amount,
             ISSUES_TABLE.c.hour_rate_currency,
             ISSUES_TABLE.c.estimated_duration,
             ISSUES_TABLE.c.object_id,
         ]
     ).where(
         ISSUES_TABLE.c.object_id.in_(entity_ids)
     )
     result = self._session.execute(query)
     entity_data = {}
     for row in result:
         amount = row["hour_rate_amount"]
         currency = row["hour_rate_currency"]
         hour_rate = None
         if amount is not None and currency:
             hour_rate = Money(
                 amount=amount,
                 currency=currency,
             )
         entity_data[EntityId(row["object_id"])] = EntityStatisticsData(
             hour_rate=hour_rate,
             estimated_duration=row["estimated_duration"]
         )
     return entity_data
示例#11
0
def test_project_estimated_cost(statistics_api, put_project, post_issue):
    project = create_project()
    put_project(project)
    # Issue with default project currency
    post_issue(project.project_id, create_issue(estimated_duration=Decimal(5)))
    # Issue with overriden currency
    post_issue(
        project.project_id,
        create_issue(estimated_duration=Decimal(2),
                     hour_rate=Money(amount=Decimal(1000),
                                     currency=Currency.czk)))
    # Issue without estimated duration
    post_issue(project.project_id, create_issue(estimated_duration=None))

    statistics = statistics_api.get_project_statistics(project.project_id)
    assert statistics.estimated_cost == Money(amount=Decimal("5002.5"),
                                              currency=Currency.czk)
示例#12
0
def test_issue_estimated_cost_overriden_currency(
    statistics_api,
    put_project,
    post_issue,
):
    project = create_project()
    put_project(project)

    # Issue with overriden currency
    bound_issue = post_issue(
        project.project_id,
        create_issue(estimated_duration=Decimal(2),
                     hour_rate=Money(amount=Decimal(1000),
                                     currency=Currency.czk)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.estimated_cost == Money(amount=Decimal("2000"),
                                              currency=Currency.czk)
示例#13
0
def test_issue_burned_cost_no_timesheets(
    statistics_api,
    put_project,
    post_issue,
):
    project = create_project()
    put_project(project)

    # Issue without timesheet
    bound_issue = post_issue(project.project_id, create_issue())

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.burned_cost == Money(Decimal(0), Currency.czk)
示例#14
0
 def _get_project_hour_rate(self, project_id: str):
     query = select(
         [
             PROJECTS_TABLE.c.hour_rate_amount,
             PROJECTS_TABLE.c.hour_rate_currency,
         ]
     ).where(
         PROJECTS_TABLE.c.project_id == project_id
     )
     row = self._session.execute(query).fetchone()
     return Money(
         amount=row["hour_rate_amount"],
         currency=Currency(row["hour_rate_currency"]),
     )
示例#15
0
def test_issue_expenditures_cost_no_expenditures(
    statistics_api,
    put_project,
    post_issue,
):
    project = create_project()
    put_project(project)

    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=Decimal(5)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.burned_expenditures_cost == Money(
        Decimal(0), Currency.czk)
示例#16
0
def test_issue_estimated_cost_default_currency(
    statistics_api,
    put_project,
    post_issue,
):
    project = create_project()
    put_project(project)

    # Issue with default project currency
    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=Decimal(5)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.estimated_cost == Money(amount=Decimal("3002.5"),
                                              currency=Currency.czk)
示例#17
0
def test_issue_estimated_cost_no_estimate(
    statistics_api,
    put_project,
    post_issue,
):
    project = create_project()
    put_project(project)

    # Issue without estimated duration
    bound_issue = post_issue(project.project_id,
                             create_issue(estimated_duration=None))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.estimated_cost == Money(amount=Decimal(0),
                                              currency=Currency.czk)
示例#18
0
 def _row_to_cost(row):
     return BoundExpenditure(
         simple_id=SimpleId(SimpleEntityType.expenditure, row["id"]),
         expenditure=Expenditure(name=row["name"],
                                 description=row["description"],
                                 status=ExpenditureStatus(row["status"]),
                                 type_=ExpenditureType(row["type"]),
                                 date_opened=row["date_opened"],
                                 date_closed=row["date_closed"],
                                 deadline=row["deadline"],
                                 files=[],
                                 cost=Money(
                                     amount=row["cost_amount"],
                                     currency=Currency(
                                         row["cost_currency"]),
                                 )))
示例#19
0
 def _row_to_entity(row) -> Project:
     return Project(
         project_id=EntityId(row["project_id"]),
         name=row["name"],
         status=ProjectStatus(row["status"]),
         date_opened=row["date_opened"],
         date_closed=row["date_closed"],
         deadline=row["deadline"],
         hour_rate=Money(
             amount=row["hour_rate_amount"],
             currency=Currency(row["hour_rate_currency"]),
         ),
         description=row["description"],
         limitations_and_restrictions=row["limitations_and_restrictions"],
         goals_and_metrics=row["goals_and_metrics"],
         primary_color=row["primary_color"],
         secondary_color=row["secondary_color"],
         files=[])
示例#20
0
def test_issue_burned_cost_default_currency(
    statistics_api,
    put_project,
    post_issue,
    post_timesheet,
):
    project = create_project()
    put_project(project)

    # Issue with default project currency
    bound_issue = post_issue(project.project_id, create_issue())
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(2)))
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(1)))
    post_timesheet(bound_issue.object_id,
                   create_timesheet(duration=Decimal(1)))

    statistics = statistics_api.get_entity_statistics(bound_issue.object_id)
    assert statistics.burned_cost == Money(Decimal(2402), Currency.czk)
示例#21
0
 def _get_expenditure_costs(self, entity_ids: List[str]):
     query = select(
         [
             EXPENDITURES_TABLE.c.parent_id,
             func.sum(EXPENDITURES_TABLE.c.cost_amount).label("expenditure_costs"),
         ]
     ).group_by(
         EXPENDITURES_TABLE.c.parent_id
     ).where(
         EXPENDITURES_TABLE.c.parent_id.in_(entity_ids)
     ).where(
         EXPENDITURES_TABLE.c.status == ExpenditureStatus.approved.value
     )
     result = self._session.execute(query)
     return {
         EntityId(row["parent_id"]): Money(
             amount=row["expenditure_costs"],
             currency=Currency.czk,
         )
         for row
         in result
     }
示例#22
0
def deserialize_money(money: dict) -> Money:
    return Money(
        amount=Decimal(money["amount"]),
        currency=Currency(money["currency"]),
    )
示例#23
0
def create_money(amount: Decimal = Decimal("600.50"),
                 currency: Currency = Currency.czk):
    return Money(
        amount=amount,
        currency=currency,
    )