prevent duplicate if overlapping records are disabled (#2311)
This commit is contained in:
@@ -11,8 +11,10 @@ APP_SECRET=change_this_to_something_unique
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# For a MySQL database, use: "mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=10.2.12&charset=utf8"
|
||||
# For a MariaDB database, use: "mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=mariadb-10.2.12"
|
||||
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data/kimai.sqlite"
|
||||
# Configure your db driver and server_version in config/packages/doctrine.yaml
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
# DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/kimai.sqlite
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,6 +19,7 @@ php.ini
|
||||
public/avatars/*.png
|
||||
|
||||
templates/invoice/renderer/.~lock*
|
||||
translations/branding.en.xlf
|
||||
|
||||
/var/data/*
|
||||
!/var/data/.gitkeep
|
||||
|
||||
3188
composer.lock
generated
3188
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ doctrine:
|
||||
default:
|
||||
# existing migrations will fail if the schema filter is activated
|
||||
#schema_filter: ~^(?!(bundle_migration_|kimai2_sessions))~
|
||||
# Removing "resolve:" would fail eg. SQLite URLs
|
||||
url: '%env(resolve:DATABASE_URL)%'
|
||||
driver: 'pdo_mysql'
|
||||
# this setting prevents automatic database detection and finds a lot of false-negatives on doctrine:migrations:diff
|
||||
|
||||
@@ -495,7 +495,7 @@ class TimesheetRepository extends EntityRepository
|
||||
|
||||
// yes, we only want to compare the day, not the time
|
||||
if ((int) $end->format('Ymd') < (int) $newDateBegin->format('Ymd')) {
|
||||
break 1;
|
||||
break;
|
||||
}
|
||||
} while ($dateKey !== $dateKeyEnd);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Voter;
|
||||
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Security\RolePermissionManager;
|
||||
@@ -47,6 +48,9 @@ final class TimesheetVoter extends Voter
|
||||
'duplicate'
|
||||
];
|
||||
|
||||
private $configuration;
|
||||
private $cacheAllowCopy;
|
||||
|
||||
private $permissionManager;
|
||||
private $lockdownService;
|
||||
|
||||
@@ -55,10 +59,11 @@ final class TimesheetVoter extends Voter
|
||||
private $editExported;
|
||||
private $now;
|
||||
|
||||
public function __construct(RolePermissionManager $permissionManager, LockdownService $lockdownService)
|
||||
public function __construct(RolePermissionManager $permissionManager, LockdownService $lockdownService, SystemConfiguration $configuration)
|
||||
{
|
||||
$this->permissionManager = $permissionManager;
|
||||
$this->lockdownService = $lockdownService;
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,6 +209,17 @@ final class TimesheetVoter extends Voter
|
||||
|
||||
protected function canDuplicate(User $user, Timesheet $timesheet): bool
|
||||
{
|
||||
if ($this->cacheAllowCopy === null) {
|
||||
$this->cacheAllowCopy = $this->configuration->isTimesheetAllowOverlappingRecords();
|
||||
}
|
||||
|
||||
// This is a quickfix, because the API cannot open dialogs. if the method is copied to the timesheet controller,
|
||||
// we could open the edit dialog instead of directly saving the copied entry.
|
||||
// Probably add a new permission is required to differentiate between API and UI.
|
||||
if (!$this->cacheAllowCopy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->isAllowedInLockdown($user, $timesheet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
15
symfony.lock
15
symfony.lock
@@ -120,6 +120,9 @@
|
||||
"ref": "bb31a3bbec00a8fc8aa1c9fbf9b0ef9fc492f93d"
|
||||
}
|
||||
},
|
||||
"friendsofphp/proxy-manager-lts": {
|
||||
"version": "v1.0.3"
|
||||
},
|
||||
"friendsofsymfony/rest-bundle": {
|
||||
"version": "2.2",
|
||||
"recipe": {
|
||||
@@ -177,6 +180,15 @@
|
||||
"kimai/user-bundle": {
|
||||
"version": "dev-master"
|
||||
},
|
||||
"laminas/laminas-code": {
|
||||
"version": "3.4.1"
|
||||
},
|
||||
"laminas/laminas-eventmanager": {
|
||||
"version": "3.2.1"
|
||||
},
|
||||
"laminas/laminas-zendframework-bridge": {
|
||||
"version": "1.1.1"
|
||||
},
|
||||
"laravolt/avatar": {
|
||||
"version": "3.0.0"
|
||||
},
|
||||
@@ -285,6 +297,9 @@
|
||||
"phpspec/prophecy": {
|
||||
"version": "1.7.3"
|
||||
},
|
||||
"phpstan/phpdoc-parser": {
|
||||
"version": "0.4.10"
|
||||
},
|
||||
"phpstan/phpstan": {
|
||||
"version": "0.11.7"
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
{% macro customers(view) %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
|
||||
{% set actions = {'search': {'class': 'search-toggle visible-xs-inline'}, 'visibility': '#modal_customer_admin'} %}
|
||||
|
||||
{% set actions = actions|merge({'download': {'url': path('customer_export'), 'class': 'toolbar-action'}}) %}
|
||||
{% set actions = {
|
||||
'search': {'class': 'search-toggle visible-xs-inline'},
|
||||
'visibility': {'modal': '#modal_customer_admin'},
|
||||
'download': {'url': path('customer_export'), 'class': 'toolbar-action'}
|
||||
} %}
|
||||
|
||||
{% if is_granted('create_customer') %}
|
||||
{% set actions = actions|merge({'create': {'url': path('admin_customer_create'), 'class': 'modal-ajax-form'}}) %}
|
||||
|
||||
@@ -210,11 +210,12 @@ class TimesheetVoterTest extends AbstractVoterTest
|
||||
'lockdown_period_start' => $lockdownBegin,
|
||||
'lockdown_period_end' => $lockdownEnd,
|
||||
'lockdown_grace_period' => $lockdownGrace,
|
||||
'allow_overlapping_records' => true,
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
$voter = new TimesheetVoter($this->getRolePermissionManager(), new LockdownService($config));
|
||||
$voter = new TimesheetVoter($this->getRolePermissionManager(), new LockdownService($config), $config);
|
||||
self::assertInstanceOf(Voter::class, $voter);
|
||||
|
||||
return $voter;
|
||||
|
||||
Reference in New Issue
Block a user