Skip to content

Commit

Permalink
JE-403: Changed how project billing is put on record, to allow for fi…
Browse files Browse the repository at this point in the history
…nishing a partially complete process. Added exported date to invoices overview.
  • Loading branch information
tuj committed Dec 19, 2023
1 parent 21c3fc4 commit 21c3649
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 25 deletions.
18 changes: 7 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.1.1] - 2023-12-18
* Changed how project billing is put on record, to allow for finishing a partially
complete process.
* Added exported date to invoices overview.

## [1.1.1]

* Added choices.js to dropdowns with many options.
* Added epic filter to worklog selection page.
* Removed time from period selections on worklog selection page.
* Optimized sync memory usage.

## [1.1.0] - 2023-12-14
## [1.1.0]

* Updated api source to use Leantime
* Modified getPlanningData to work with Leantime data
Expand All @@ -39,21 +43,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.0.2]

### Changed

* Updated package-lock.json.

## [1.0.1]

### Changed

* Updated openid-connect to newest version.
* Updated docker-compose files to newest version.

## [1.0.0]

### Added

* Added Billing.
* Added migration path from JiraEconomics.
* Added Sprint Report.
Expand All @@ -66,9 +64,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added help text to invoice entry (worklog) type.
* Added publiccode.yml
* Added OpenID Connect Controller

### Changed

* Updated docker files to the newest version.
* Fixed path bugs.
* Added filtering to lists.
Expand All @@ -92,6 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed worklog save button styling to be sticky.

[Unreleased]: https://github.com/itk-dev/economics/compare/1.1.0...HEAD
[1.1.1]: https://github.com/itk-dev/economics/compare/1.1.0...1.1.1
[1.1.0]: https://github.com/itk-dev/economics/compare/1.0.4...1.1.0
[1.0.4]: https://github.com/itk-dev/economics/compare/1.0.3...1.0.4
[1.0.3]: https://github.com/itk-dev/economics/compare/1.0.2...1.0.3
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class Invoice
#[ORM\ManyToOne(inversedBy: 'invoices')]
private ?Project $project = null;

#[ORM\ManyToOne(inversedBy: 'invoices')]
#[ORM\ManyToOne(fetch: 'EAGER', inversedBy: 'invoices')]
private ?Client $client = null;

#[ORM\Column(nullable: true)]
Expand Down
8 changes: 8 additions & 0 deletions src/Exception/InvoiceAlreadyOnRecordException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Exception;

class InvoiceAlreadyOnRecordException extends \Exception
{

}
5 changes: 3 additions & 2 deletions src/Form/ProjectBillingType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
Expand Down Expand Up @@ -36,7 +37,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->orderBy('p.name', 'ASC');
},
])
->add('periodStart', DateTimeType::class, [
->add('periodStart', DateType::class, [
'required' => true,
'label' => 'project_billing.field_period_start',
'label_attr' => ['class' => 'label'],
Expand All @@ -46,7 +47,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'html5' => true,
'attr' => ['class' => 'form-element'],
])
->add('periodEnd', DateTimeType::class, [
->add('periodEnd', DateType::class, [
'required' => true,
'label' => 'project_billing.field_period_end',
'label_attr' => ['class' => 'label'],
Expand Down
15 changes: 8 additions & 7 deletions src/Service/BillingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Entity\Worklog;
use App\Enum\ClientTypeEnum;
use App\Enum\InvoiceEntryTypeEnum;
use App\Exception\InvoiceAlreadyOnRecordException;
use App\Repository\AccountRepository;
use App\Repository\ClientRepository;
use App\Repository\InvoiceEntryRepository;
Expand Down Expand Up @@ -369,17 +370,17 @@ public function syncProjects(callable $progressCallback): void
/**
* @throws \Exception
*/
public function recordInvoice(Invoice $invoice): void
public function recordInvoice(Invoice $invoice, bool $flush = true): void
{
// Make sure client is set.
$errors = $this->getInvoiceRecordableErrors($invoice);

if ($invoice->isRecorded()) {
throw new \Exception('Already recorded.');
throw new InvoiceAlreadyOnRecordException('Invoice is already on record.');
}

// Make sure client is set.
$errors = $this->getInvoiceRecordableErrors($invoice);

if (!empty($errors)) {
throw new \Exception('Cannot record invoices. Errors not handled.');
throw new \Exception('Cannot record invoice ' . $invoice->getName() .'('. $invoice->getId().'). Errors not handled: ' . json_encode($errors));
}

$client = $invoice->getClient();
Expand Down Expand Up @@ -408,7 +409,7 @@ public function recordInvoice(Invoice $invoice): void
}
}

$this->invoiceRepository->save($invoice, true);
$this->invoiceRepository->save($invoice, $flush);
}

// TODO: Replace with exceptions.
Expand Down
10 changes: 9 additions & 1 deletion src/Service/ProjectBillingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Enum\ClientTypeEnum;
use App\Enum\InvoiceEntryTypeEnum;
use App\Enum\MaterialNumberEnum;
use App\Exception\InvoiceAlreadyOnRecordException;
use App\Repository\AccountRepository;
use App\Repository\ClientRepository;
use App\Repository\IssueRepository;
Expand Down Expand Up @@ -208,9 +209,16 @@ public function createProjectBilling(int $projectBillingId): void
public function recordProjectBilling(ProjectBilling $projectBilling): void
{
foreach ($projectBilling->getInvoices() as $invoice) {
$this->billingService->recordInvoice($invoice);
try {
$this->billingService->recordInvoice($invoice, false);
} catch (InvoiceAlreadyOnRecordException) {
// Ignore if invoice is already on record.
}
}

// Persist the changes to invoices.
$this->entityManager->flush();

$projectBilling->setRecorded(true);
$this->projectBillingRepository->save($projectBilling, true);
}
Expand Down
17 changes: 14 additions & 3 deletions templates/invoices/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{{ form_end(form) }}

{% set recordedInvoices = invoiceFilterData.recorded %}
{% set numberOfColumns = recordedInvoices ? 8 : 7 %}
{% set numberOfColumns = recordedInvoices ? 9 : 7 %}

<div {{ stimulus_controller('entry-select') }} data-submit-endpoint="{{ submitEndpoint }}">
<form id="entry-form">
Expand All @@ -37,6 +37,9 @@
<th class="table-th{% if invoices.isSorted('invoice.createdBy') %} sorted{% endif %}">{{ knp_pagination_sortable(invoices, 'invoices.list_created_by'|trans, 'invoice.createdBy') }}</th>
<th class="table-th{% if invoices.isSorted('invoice.updatedAt') %} sorted{% endif %}">{{ knp_pagination_sortable(invoices, 'invoices.list_updated_at'|trans, 'invoice.updatedAt') }}</th>
<th class="table-th">{{ 'invoices.list_total_price'|trans }}</th>
{% if recordedInvoices %}
<th class="table-th{% if invoices.isSorted('invoice.exportedDate') %} sorted{% endif %}">{{ knp_pagination_sortable(invoices, 'invoices.list_exported_date'|trans, 'invoice.exportedDate') }}</th>
{% endif %}
<th class="table-th">{{ 'invoices.list_actions'|trans }}</th>
</tr>
</thead>
Expand Down Expand Up @@ -64,9 +67,17 @@
<td class="table-td">{{ invoice.createdBy }}</td>
<td class="table-td">{{ invoice.updatedAt ? invoice.updatedAt|date('Y-m-d') : '' }}</td>
<td class="table-td">{{ invoice.totalPrice }}</td>
{% if recordedInvoices %}
<td class="table-td">{{ invoice.exportedDate ? invoice.exportedDate|date('Y-m-d') : '' }}</td>
{% endif %}
<td class="table-td">
<a class="link"
href="{{ path('app_invoices_edit', {'id': invoice.id}) }}">{{ 'invoices.action_edit'|trans }}</a>
<a class="link" href="{{ path('app_invoices_edit', {'id': invoice.id}) }}">
{% if recordedInvoices %}
{{ 'invoices.action_view'|trans }}
{% else %}
{{ 'invoices.action_edit'|trans }}
{% endif %}
</a>
</td>
</tr>
{% endfor %}
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.da.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ invoices:
list_recorded: 'Bogført'
export_only_available_when_mandatory_fields_are_set: 'Eksport kun muligt når der er sat en kundekonto'
action_export_selected: 'Eksporter valg'
action_view: 'Se'
list_exported_date: 'Eksportdato'

material_number_enum:
internal: "Interne: 103361"
Expand Down

0 comments on commit 21c3649

Please sign in to comment.