Release 2.0.17 (#3992)
* prevent empty title for select options * removed css for unused sweetalert * fix isWeekend() check with DateTimeInterface * reset timesheet rates on "create copy" * wrap long names in multi-selects - fix #4001 * rename profile menus * show all possible links in user profile dropdown * check if plugin is compatible before displaying the buy link
This commit is contained in:
@@ -17,11 +17,11 @@ class Constants
|
||||
/**
|
||||
* The current release version
|
||||
*/
|
||||
public const VERSION = '2.0.16';
|
||||
public const VERSION = '2.0.17';
|
||||
/**
|
||||
* The current release: major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
public const VERSION_ID = 20016;
|
||||
public const VERSION_ID = 20017;
|
||||
/**
|
||||
* The software name
|
||||
*/
|
||||
|
||||
@@ -202,6 +202,7 @@ abstract class TimesheetAbstractController extends AbstractController
|
||||
protected function duplicate(Timesheet $timesheet, Request $request): Response
|
||||
{
|
||||
$copyTimesheet = clone $timesheet;
|
||||
$copyTimesheet->resetRates();
|
||||
|
||||
$event = new TimesheetMetaDefinitionEvent($copyTimesheet);
|
||||
$this->dispatcher->dispatch($event);
|
||||
|
||||
@@ -615,6 +615,15 @@ class Timesheet implements EntityWithMetaFields, ExportableItem
|
||||
return $all;
|
||||
}
|
||||
|
||||
public function resetRates(): void
|
||||
{
|
||||
$this->setRate(0.00);
|
||||
$this->setInternalRate(null);
|
||||
$this->setHourlyRate(null);
|
||||
$this->setFixedRate(null);
|
||||
$this->setBillableMode(Timesheet::BILLABLE_AUTOMATIC);
|
||||
}
|
||||
|
||||
public function getMetaField(string $name): ?MetaTableTypeInterface
|
||||
{
|
||||
foreach ($this->meta as $field) {
|
||||
|
||||
@@ -997,7 +997,7 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
$this->password = $data['password'];
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->getDisplayName();
|
||||
}
|
||||
|
||||
@@ -43,21 +43,22 @@ class UserDetailsSubscriber implements EventSubscriberInterface
|
||||
$event->setUser($user);
|
||||
|
||||
if ($this->auth->isGranted('view', $user)) {
|
||||
$event->addLink(
|
||||
new MenuItemModel('user_profile', 'my.profile', 'user_profile', ['username' => $user->getUserIdentifier()], 'fas fa-tachometer-alt')
|
||||
);
|
||||
$event->addLink(new MenuItemModel('user_profile', 'my.profile', 'user_profile', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
|
||||
if ($this->auth->isGranted('edit', $user)) {
|
||||
$event->addLink(
|
||||
new MenuItemModel('user_profile_edit', 'action.edit', 'user_profile_edit', ['username' => $user->getUserIdentifier()], 'fas fa-tachometer-alt')
|
||||
);
|
||||
$event->addLink(new MenuItemModel('user_profile_edit', 'action.edit', 'user_profile_edit', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
if ($this->auth->isGranted('password', $user)) {
|
||||
$event->addLink(new MenuItemModel('password', 'profile.password', 'user_profile_password', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
if ($this->auth->isGranted('2fa', $user)) {
|
||||
$event->addLink(new MenuItemModel('2fa', 'profile.2fa', 'user_profile_2fa', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
if ($this->auth->isGranted('api-token', $user)) {
|
||||
$event->addLink(new MenuItemModel('api-token', 'profile.api-token', 'user_profile_api_token', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
|
||||
if ($this->auth->isGranted('preferences', $user)) {
|
||||
$event->addLink(
|
||||
new MenuItemModel('user_profile_preferences', 'profile.preferences', 'user_profile_preferences', ['username' => $user->getUserIdentifier()], 'fas fa-tachometer-alt')
|
||||
);
|
||||
$event->addLink(new MenuItemModel('user_profile_preferences', 'profile.preferences', 'user_profile_preferences', ['username' => $user->getUserIdentifier()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ final class ExportFilename
|
||||
return FileHelper::convertToAsciiFilename($filename);
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
public function getFilename(): string
|
||||
{
|
||||
if ($this->filename === null) {
|
||||
$filename = date('Ymd');
|
||||
@@ -91,7 +91,7 @@ final class ExportFilename
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->getFilename();
|
||||
}
|
||||
|
||||
@@ -17,29 +17,20 @@ final class RateResetCalculator implements CalculatorInterface
|
||||
public function calculate(Timesheet $record, array $changeset): void
|
||||
{
|
||||
// check if the rate was changed manually
|
||||
$changedRate = false;
|
||||
foreach (['hourlyRate', 'fixedRate', 'internalRate', 'rate'] as $field) {
|
||||
if (\array_key_exists($field, $changeset)) {
|
||||
$changedRate = true;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if no manual rate changed was applied:
|
||||
// check if a field changed, that is relevant for the rate calculation: if one was changed =>
|
||||
// check if a field changed, that is relevant for the rate calculation
|
||||
// reset all rates, because most users do not even see their rates and would not be able
|
||||
// to fix or empty the rate, even if they knew that the changed project has another base rate
|
||||
if (!$changedRate) {
|
||||
foreach (['project', 'activity', 'user'] as $field) {
|
||||
if (\array_key_exists($field, $changeset)) {
|
||||
// this has room for minor improvements: entries with a manual rate might be changed
|
||||
$record->setRate(0.00);
|
||||
$record->setInternalRate(null);
|
||||
$record->setHourlyRate(null);
|
||||
$record->setFixedRate(null);
|
||||
$record->setBillableMode(Timesheet::BILLABLE_AUTOMATIC);
|
||||
break;
|
||||
}
|
||||
// to change the rate, even if they knew that the changed project has another base rate
|
||||
foreach (['project', 'activity', 'user'] as $field) {
|
||||
if (\array_key_exists($field, $changeset)) {
|
||||
$record->resetRates();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
|
||||
|
||||
public function isWeekend(\DateTimeInterface|string|null $dateTime): bool
|
||||
{
|
||||
if (!$dateTime instanceof \DateTime) {
|
||||
if (!$dateTime instanceof \DateTimeInterface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ final class SearchTerm
|
||||
return $this->originalTerm;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->originalTerm;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user