default value for billable flag and support in batch update (#2851)

This commit is contained in:
Kevin Papst
2021-10-13 15:49:20 +02:00
committed by GitHub
parent 9226daa891
commit 6b066046c6
12 changed files with 92 additions and 51 deletions

View File

@@ -232,6 +232,11 @@ class SystemConfiguration implements SystemBundleConfiguration
return (string) $this->find('timesheet.default_begin');
}
public function getTimesheetDefaultBillable(): bool
{
return (bool) $this->find('defaults.timesheet.billable');
}
public function isTimesheetAllowFutureTimes(): bool
{
return (bool) $this->find('timesheet.rules.allow_future_times');

View File

@@ -382,6 +382,10 @@ final class SystemConfigurationController extends AbstractController
->setConstraints([
new GreaterThanOrEqual(['value' => 0])
]),
(new Configuration())
->setName('defaults.timesheet.billable')
->setType(YesNoType::class)
->setOptions(['help' => 'default_value_new', 'label' => 'label.billable']),
]),
(new SystemConfigurationModel())
->setSection(SystemConfigurationModel::SECTION_LOCKDOWN)

View File

@@ -364,6 +364,10 @@ abstract class TimesheetAbstractController extends AbstractController
$timesheet->setExported($dto->isExported());
$execute = true;
}
if (null !== $dto->isBillable()) {
$timesheet->setBillable($dto->isBillable());
$execute = true;
}
if ($dto->isRecalculateRates()) {
$timesheet->setFixedRate(null);

View File

@@ -635,6 +635,12 @@ class Configuration implements ConfigurationInterface
->scalarNode('currency')->defaultValue(Customer::DEFAULT_CURRENCY)->end()
->end()
->end()
->arrayNode('timesheet')
->addDefaultsIfNotSet()
->children()
->booleanNode('billable')->defaultTrue()->end()
->end()
->end()
->arrayNode('user')
->addDefaultsIfNotSet()
->children()

View File

@@ -207,6 +207,17 @@ class TimesheetMultiUpdate extends AbstractType
]);
}
if ($options['include_billable']) {
$builder->add('billable', ChoiceType::class, [
'label' => 'label.billable',
'choices' => [
'' => null,
'yes' => true,
'no' => false,
],
]);
}
if ($options['include_rate']) {
$builder
->add('recalculateRates', YesNoType::class, [
@@ -279,6 +290,7 @@ class TimesheetMultiUpdate extends AbstractType
'include_user' => false,
'include_rate' => false,
'include_exported' => false,
'include_billable' => true,
]);
}
}

View File

@@ -22,6 +22,7 @@ use Doctrine\Common\Collections\Collection;
/**
* @App\Validator\Constraints\TimesheetMultiUpdate
* @internal
*/
class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithMetaFields
{
@@ -57,6 +58,10 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
* @var bool|null
*/
private $exported = null;
/**
* @var bool|null
*/
private $billable = null;
/**
* @var float|null
*/
@@ -84,11 +89,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->customer;
}
public function setCustomer(Customer $customer): TimesheetMultiUpdateDTO
public function setCustomer(Customer $customer): void
{
$this->customer = $customer;
return $this;
}
public function getProject(): ?Project
@@ -96,11 +99,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->project;
}
public function setProject(Project $project): TimesheetMultiUpdateDTO
public function setProject(Project $project): void
{
$this->project = $project;
return $this;
}
public function getActivity(): ?Activity
@@ -108,11 +109,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->activity;
}
public function setActivity(Activity $activity): TimesheetMultiUpdateDTO
public function setActivity(Activity $activity): void
{
$this->activity = $activity;
return $this;
}
/**
@@ -123,11 +122,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->tags;
}
public function setTags(iterable $tags): TimesheetMultiUpdateDTO
public function setTags(iterable $tags): void
{
$this->tags = $tags;
return $this;
}
public function getUser(): ?User
@@ -135,11 +132,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->user;
}
public function setUser(User $user): TimesheetMultiUpdateDTO
public function setUser(User $user): void
{
$this->user = $user;
return $this;
}
public function isExported(): ?bool
@@ -147,11 +142,19 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->exported;
}
public function setExported(bool $exported): TimesheetMultiUpdateDTO
public function setExported(?bool $exported): void
{
$this->exported = $exported;
}
return $this;
public function isBillable(): ?bool
{
return $this->billable;
}
public function setBillable(?bool $billable): void
{
$this->billable = $billable;
}
public function isRecalculateRates(): bool
@@ -159,11 +162,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->recalculateRates;
}
public function setRecalculateRates(bool $recalculateRates): TimesheetMultiUpdateDTO
public function setRecalculateRates(bool $recalculateRates): void
{
$this->recalculateRates = $recalculateRates;
return $this;
}
public function isReplaceTags(): bool
@@ -171,11 +172,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->replaceTags;
}
public function setReplaceTags(bool $replaceTags): TimesheetMultiUpdateDTO
public function setReplaceTags(bool $replaceTags): void
{
$this->replaceTags = $replaceTags;
return $this;
}
public function getFixedRate(): ?float
@@ -183,11 +182,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->fixedRate;
}
public function setFixedRate(?float $fixedRate): TimesheetMultiUpdateDTO
public function setFixedRate(?float $fixedRate): void
{
$this->fixedRate = $fixedRate;
return $this;
}
public function getHourlyRate(): ?float
@@ -195,11 +192,9 @@ class TimesheetMultiUpdateDTO extends MultiUpdateTableDTO implements EntityWithM
return $this->hourlyRate;
}
public function setHourlyRate(?float $hourlyRate): TimesheetMultiUpdateDTO
public function setHourlyRate(?float $hourlyRate): void
{
$this->hourlyRate = $hourlyRate;
return $this;
}
/**

View File

@@ -110,6 +110,8 @@ final class TimesheetService
$mode = $this->trackingModeService->getActiveMode();
$mode->create($timesheet, $request);
$timesheet->setBillable($this->configuration->getTimesheetDefaultBillable());
return $timesheet;
}

View File

@@ -36,6 +36,11 @@
{{ form_row(form.exported) }}
</fieldset>
{% endif %}
{% if form.billable is defined %}
<fieldset>
{{ form_row(form.billable) }}
</fieldset>
{% endif %}
{% if form.recalculateRates is defined %}
<fieldset>
{{ form_row(form.recalculateRates) }}

View File

@@ -140,6 +140,9 @@ class AppExtensionTest extends TestCase
'templates/invoice/renderer/',
],
'kimai.defaults' => [
'timesheet' => [
'billable' => true,
],
'customer' => [
'timezone' => null,
'country' => 'DE',

View File

@@ -395,6 +395,9 @@ class ConfigurationTest extends TestCase
'dashboard' => [],
'widgets' => [],
'defaults' => [
'timesheet' => [
'billable' => true,
],
'customer' => [
'timezone' => null,
'country' => 'DE',

View File

@@ -32,6 +32,7 @@ class TimesheetMultiUpdateDTOTest extends TestCase
self::assertNull($sut->getAction());
self::assertNull($sut->isExported());
self::assertNull($sut->isBillable());
self::assertNull($sut->getProject());
self::assertNull($sut->getAction());
self::assertNull($sut->getCustomer());
@@ -70,37 +71,44 @@ class TimesheetMultiUpdateDTOTest extends TestCase
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setEntities($entities));
self::assertEquals($entities, $sut->getEntities());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setExported(true));
self::assertNull($sut->isExported());
$sut->setExported(true);
self::assertTrue($sut->isExported());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setExported(false));
$sut->setExported(false);
self::assertFalse($sut->isExported());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setTags(['foo', '0815']));
self::assertNull($sut->isBillable());
$sut->setBillable(true);
self::assertTrue($sut->isBillable());
$sut->setExported(false);
self::assertFalse($sut->isExported());
$sut->setTags(['foo', '0815']);
self::assertEquals(['foo', '0815'], $sut->getTags());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setReplaceTags(true));
$sut->setReplaceTags(true);
self::assertTrue($sut->isReplaceTags());
$user = (new User())->setUsername('sdfsdfsd');
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setUser($user));
$sut->setUser($user);
self::assertSame($user, $sut->getUser());
$activity = (new Activity())->setName('sdfsdfsd');
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setActivity($activity));
$sut->setActivity($activity);
self::assertSame($activity, $sut->getActivity());
$project = (new Project())->setName('sdfsdfsd');
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setProject($project));
$sut->setProject($project);
self::assertSame($project, $sut->getProject());
$customer = (new Customer())->setName('sdfsdfsd');
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setCustomer($customer));
$sut->setCustomer($customer);
self::assertSame($customer, $sut->getCustomer());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setFixedRate(12.78));
$sut->setFixedRate(12.78);
self::assertEquals(12.78, $sut->getFixedRate());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setHourlyRate(123.45));
$sut->setHourlyRate(123.45);
self::assertEquals(123.45, $sut->getHourlyRate());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setUpdateMeta(['foo', 'bar']));

View File

@@ -44,10 +44,8 @@ class TimesheetMultiUpdateValidatorTest extends ConstraintValidatorTestCase
$activity->setProject($project1);
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setActivity($activity)
->setProject($project2)
;
$timesheet->setActivity($activity);
$timesheet->setProject($project2);
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
@@ -90,10 +88,8 @@ class TimesheetMultiUpdateValidatorTest extends ConstraintValidatorTestCase
public function testHourlyRateAndFixedRateInParallelAreNotAllowed()
{
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setHourlyRate(10.12)
->setFixedRate(123.45)
;
$timesheet->setHourlyRate(10.12);
$timesheet->setFixedRate(123.45);
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
@@ -118,10 +114,8 @@ class TimesheetMultiUpdateValidatorTest extends ConstraintValidatorTestCase
$activity->setProject($project);
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setActivity($activity)
->setProject($project)
;
$timesheet->setActivity($activity);
$timesheet->setProject($project);
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));