diff --git a/src/Reporting/ProjectView/ProjectViewModel.php b/src/Reporting/ProjectView/ProjectViewModel.php index 08598c78..e2095211 100644 --- a/src/Reporting/ProjectView/ProjectViewModel.php +++ b/src/Reporting/ProjectView/ProjectViewModel.php @@ -45,17 +45,25 @@ final class ProjectViewModel * @var float */ private $notExportedRate = 0.00; + /** + * @var int + */ + private $notBilledDuration = 0; + /** + * @var float + */ + private $notBilledRate = 0.00; - public function getProject(): ?Project - { - return $this->project; - } - - public function setProject(Project $project): void + public function __construct(Project $project) { $this->project = $project; } + public function getProject(): Project + { + return $this->project; + } + public function getDurationDay(): int { return $this->durationDay; @@ -116,6 +124,26 @@ final class ProjectViewModel $this->notExportedRate = $notExportedRate; } + public function getNotBilledDuration(): int + { + return $this->notBilledDuration; + } + + public function setNotBilledDuration(int $notBilledDuration): void + { + $this->notBilledDuration = $notBilledDuration; + } + + public function getNotBilledRate(): float + { + return $this->notBilledRate; + } + + public function setNotBilledRate(float $notBilledRate): void + { + $this->notBilledRate = $notBilledRate; + } + public function getRateTotal(): float { return $this->rateTotal; diff --git a/src/Reporting/ProjectView/ProjectViewService.php b/src/Reporting/ProjectView/ProjectViewService.php index c11d66ea..09d7fdf1 100644 --- a/src/Reporting/ProjectView/ProjectViewService.php +++ b/src/Reporting/ProjectView/ProjectViewService.php @@ -87,8 +87,7 @@ final class ProjectViewService $projectViews = []; foreach ($result as $res) { - $entity = new ProjectViewModel(); - $entity->setProject($res['project']); + $entity = new ProjectViewModel($res['project']); $entity->setDurationTotal($res['totalDuration'] ?? 0); $entity->setRateTotal($res['totalRate'] ?? 0.00); @@ -164,6 +163,25 @@ final class ProjectViewService $projectViews[$row['id']]->setNotExportedRate($row['rate']); } + // values for the all time (not exported and billable) + $qb = $this->timesheetRepository->createQueryBuilder('t'); + $qb + ->select('IDENTITY(t.project) AS id, SUM(t.duration) AS duration, SUM(t.rate) AS rate') + ->andWhere($qb->expr()->in('t.project', ':project')) + ->andWhere('t.exported = :exported') + ->andWhere('t.billable = :billable') + ->groupBy('t.project') + ->setParameter('exported', false, Types::BOOLEAN) + ->setParameter('billable', true, Types::BOOLEAN) + ->setParameter('project', array_values($projectIds)) + ; + + $result = $qb->getQuery()->getScalarResult(); + foreach ($result as $row) { + $projectViews[$row['id']]->setNotBilledDuration($row['duration']); + $projectViews[$row['id']]->setNotBilledRate($row['rate']); + } + return array_values($projectViews); } } diff --git a/templates/reporting/project_view.html.twig b/templates/reporting/project_view.html.twig index 09250594..687ee4fd 100644 --- a/templates/reporting/project_view.html.twig +++ b/templates/reporting/project_view.html.twig @@ -32,7 +32,7 @@ {% import "macros/widgets.html.twig" as widgets %} {% import "macros/datatables.html.twig" as tables %} {% import "project/actions.html.twig" as projectActions %} - {% block box_body_class %}project-view-reporting-box {% if hasData %}no-padding{% endif %} table-responsive{% endblock %} + {% block box_body_class %}project-view-reporting-box {% if hasData %}no-padding{% endif %}{% endblock %} {% block box_before %} {{ form_start(form, {'attr': {'class': 'form-inline form-reporting', 'id': 'project-view-form'}}) }} {% endblock %} @@ -52,7 +52,6 @@ {{ tables.datatable_header(tableName, columns, null, {'bordered': true, 'striped': false, 'boxClass': ''}) }} {% for id, mapping in entries|sort((a, b) => a.customer.name <=> b.customer.name) %} - {% if is_granted('budget', mapping.customer) %} {{ widgets.label_customer(mapping.customer) }} @@ -60,7 +59,7 @@ {% set project = entry.project %} {% set currency = project.customer.currency %} {% if is_granted('budget', project) %} - + {{ widgets.label_project(project) }} {{ entry.durationDay|duration }} {{ entry.durationWeek|duration }} @@ -87,11 +86,11 @@ {% if is_granted('view_invoice') %} - - {{ entry.notExportedRate|money(currency) }} + + {{ entry.notBilledRate|money(currency) }} {% else %} - {{ entry.notExportedRate|money(currency) }} + {{ entry.notBilledRate|money(currency) }} {% endif %} {% if project.end is not null %}{{ project.end|date_short }}{% endif %} @@ -102,7 +101,6 @@ {% endif %} {% endfor %} - {% endif %} {% endfor %} {{ tables.data_table_footer(entries) }} {% endif %} diff --git a/tests/Reporting/ProjectView/ProjectViewModelTest.php b/tests/Reporting/ProjectView/ProjectViewModelTest.php index 99484dc3..32d8e784 100644 --- a/tests/Reporting/ProjectView/ProjectViewModelTest.php +++ b/tests/Reporting/ProjectView/ProjectViewModelTest.php @@ -20,9 +20,10 @@ class ProjectViewModelTest extends TestCase { public function testDefaults() { - $sut = new ProjectViewModel(); + $project = new Project(); + $sut = new ProjectViewModel($project); - self::assertNull($sut->getProject()); + self::assertSame($project, $sut->getProject()); self::assertEquals(0, $sut->getDurationDay()); self::assertEquals(0, $sut->getDurationMonth()); self::assertEquals(0, $sut->getDurationTotal()); @@ -34,11 +35,7 @@ class ProjectViewModelTest extends TestCase public function testSetterGetter() { - $sut = new ProjectViewModel(); - - $project = new Project(); - $sut->setProject($project); - self::assertSame($project, $sut->getProject()); + $sut = new ProjectViewModel(new Project()); $sut->setDurationDay(123456789); $sut->setDurationMonth(23456789);