added multi-select for customer, project and activity (#1557)
This commit is contained in:
@@ -68,7 +68,8 @@ class ActivityController extends BaseApiController
|
||||
* @SWG\Items(ref="#/definitions/ActivityCollection")
|
||||
* )
|
||||
* )
|
||||
* @Rest\QueryParam(name="project", requirements="\d+", strict=true, nullable=true, description="Project ID to filter activities. If none is provided, all activities will be returned.")
|
||||
* @Rest\QueryParam(name="project", requirements="\d+", strict=true, nullable=true, description="Project ID to filter activities")
|
||||
* @Rest\QueryParam(name="projects", requirements="[\d|,]+", strict=true, nullable=true, description="Comma separated list of project IDs to filter activities")
|
||||
* @Rest\QueryParam(name="visible", requirements="1|2|3", strict=true, nullable=true, description="Visibility status to filter activities. Allowed values: 1=visible, 2=hidden, 3=all (default: 1)")
|
||||
* @Rest\QueryParam(name="globals", requirements="true", strict=true, nullable=true, description="Use if you want to fetch only global activities. Allowed values: true (default: false)")
|
||||
* @Rest\QueryParam(name="globalsFirst", requirements="true|false", strict=true, nullable=true, description="Deprecated parameter, value is not used any more")
|
||||
@@ -99,8 +100,17 @@ class ActivityController extends BaseApiController
|
||||
@trigger_error('API parameter globalsFirst is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!empty($projects = $paramFetcher->get('projects'))) {
|
||||
if (!is_array($projects)) {
|
||||
$projects = explode(',', $projects);
|
||||
}
|
||||
if (!empty($projects)) {
|
||||
$query->setProjects($projects);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($project = $paramFetcher->get('project'))) {
|
||||
$query->setProject($project);
|
||||
$query->addProject($project);
|
||||
}
|
||||
|
||||
if (null !== ($visible = $paramFetcher->get('visible'))) {
|
||||
|
||||
@@ -77,6 +77,7 @@ class ProjectController extends BaseApiController
|
||||
* )
|
||||
* )
|
||||
* @Rest\QueryParam(name="customer", requirements="\d+", strict=true, nullable=true, description="Customer ID to filter projects")
|
||||
* @Rest\QueryParam(name="customers", requirements="[\d|,]+", strict=true, nullable=true, description="Comma separated list of customer IDs to filter projects")
|
||||
* @Rest\QueryParam(name="visible", requirements="\d+", strict=true, nullable=true, description="Visibility status to filter projects. Allowed values: 1=visible, 2=hidden, 3=both (default; 1)")
|
||||
* @Rest\QueryParam(name="start", requirements=@Constraints\DateTime(format="Y-m-d\TH:i:s"), strict=true, nullable=true, description="Only projects that started before this date will be included. Allowed format: HTML5 (default: now, if end is also empty)")
|
||||
* @Rest\QueryParam(name="end", requirements=@Constraints\DateTime(format="Y-m-d\TH:i:s"), strict=true, nullable=true, description="Only projects that ended after this date will be included. Allowed format: HTML5 (default: now, if start is also empty)")
|
||||
@@ -104,8 +105,17 @@ class ProjectController extends BaseApiController
|
||||
$query->setOrderBy($orderBy);
|
||||
}
|
||||
|
||||
if (!empty($customers = $paramFetcher->get('customers'))) {
|
||||
if (!is_array($customers)) {
|
||||
$customers = explode(',', $customers);
|
||||
}
|
||||
if (!empty($customers)) {
|
||||
$query->setCustomers($customers);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($customer = $paramFetcher->get('customer'))) {
|
||||
$query->setCustomer($customer);
|
||||
$query->addCustomer($customer);
|
||||
}
|
||||
|
||||
if (null !== ($visible = $paramFetcher->get('visible'))) {
|
||||
|
||||
@@ -127,9 +127,12 @@ class TimesheetController extends BaseApiController
|
||||
* )
|
||||
*
|
||||
* @Rest\QueryParam(name="user", requirements="\d+|all", strict=true, nullable=true, description="User ID to filter timesheets. Needs permission 'view_other_timesheet', pass 'all' to fetch data for all user (default: current user)")
|
||||
* @Rest\QueryParam(name="customer", requirements="\d+", strict=true, nullable=true, description="Customer ID to filter timesheets")
|
||||
* @Rest\QueryParam(name="project", requirements="\d+", strict=true, nullable=true, description="Project ID to filter timesheets")
|
||||
* @Rest\QueryParam(name="activity", requirements="\d+", strict=true, nullable=true, description="Activity ID to filter timesheets")
|
||||
* @Rest\QueryParam(name="customer", requirements="\d+", strict=true, nullable=true, description="DEPRECATED: Customer ID to filter timesheets (will be removed with 2.0)")
|
||||
* @Rest\QueryParam(name="customers", requirements="[\d|,]+", strict=true, nullable=true, description="Comma separated list of customer IDs to filter timesheets")
|
||||
* @Rest\QueryParam(name="project", requirements="\d+", strict=true, nullable=true, description="DEPRECATED: Project ID to filter timesheets (will be removed with 2.0)")
|
||||
* @Rest\QueryParam(name="projects", requirements="[\d|,]+", strict=true, nullable=true, description="Comma separated list of project IDs to filter timesheets")
|
||||
* @Rest\QueryParam(name="activity", requirements="\d+", strict=true, nullable=true, description="DEPRECATED: Activity ID to filter timesheets (will be removed with 2.0)")
|
||||
* @Rest\QueryParam(name="activities", requirements="[\d|,]+", strict=true, nullable=true, description="Comma separated list of activity IDs to filter timesheets")
|
||||
* @Rest\QueryParam(name="page", requirements="\d+", strict=true, nullable=true, description="The page to display, renders a 404 if not found (default: 1)")
|
||||
* @Rest\QueryParam(name="size", requirements="\d+", strict=true, nullable=true, description="The amount of entries for each page (default: 50)")
|
||||
* @Rest\QueryParam(name="tags", strict=true, nullable=true, description="The name of tags which are in the datasets")
|
||||
@@ -159,16 +162,40 @@ class TimesheetController extends BaseApiController
|
||||
$query->setUser($user);
|
||||
}
|
||||
|
||||
if (!empty($customer = $paramFetcher->get('customer'))) {
|
||||
$query->setCustomer($customer);
|
||||
if (!empty($customers = $paramFetcher->get('customers'))) {
|
||||
if (!is_array($customers)) {
|
||||
$customers = explode(',', $customers);
|
||||
}
|
||||
if (!empty($customers)) {
|
||||
$query->setCustomers($customers);
|
||||
}
|
||||
} elseif (!empty($customer = $paramFetcher->get('customer'))) {
|
||||
@trigger_error('Timesheet API parameter "customer" is deprecated and will be removed with 2.0, use "customers" instead', E_USER_DEPRECATED);
|
||||
$query->addCustomer($customer);
|
||||
}
|
||||
|
||||
if (!empty($project = $paramFetcher->get('project'))) {
|
||||
$query->setProject($project);
|
||||
if (!empty($projects = $paramFetcher->get('projects'))) {
|
||||
if (!is_array($projects)) {
|
||||
$projects = explode(',', $projects);
|
||||
}
|
||||
if (!empty($projects)) {
|
||||
$query->setProjects($projects);
|
||||
}
|
||||
} elseif (!empty($project = $paramFetcher->get('project'))) {
|
||||
@trigger_error('Timesheet API parameter "project" is deprecated and will be removed with 2.0, use "projects" instead', E_USER_DEPRECATED);
|
||||
$query->addProject($project);
|
||||
}
|
||||
|
||||
if (!empty($activity = $paramFetcher->get('activity'))) {
|
||||
$query->setActivity($activity);
|
||||
if (!empty($activities = $paramFetcher->get('activities'))) {
|
||||
if (!is_array($activities)) {
|
||||
$activities = explode(',', $activities);
|
||||
}
|
||||
if (!empty($activities)) {
|
||||
$query->setActivities($activities);
|
||||
}
|
||||
} elseif (!empty($activity = $paramFetcher->get('activity'))) {
|
||||
@trigger_error('Timesheet API parameter "activity" is deprecated and will be removed with 2.0, use "activities" instead', E_USER_DEPRECATED);
|
||||
$query->addActivity($activity);
|
||||
}
|
||||
|
||||
if (null !== ($page = $paramFetcher->get('page'))) {
|
||||
|
||||
@@ -241,7 +241,7 @@ final class ActivityController extends AbstractController
|
||||
'label' => 'label.activity',
|
||||
'query_builder' => function (ActivityRepository $repo) use ($activity) {
|
||||
$query = new ActivityFormTypeQuery();
|
||||
$query->setProject($activity->getProject());
|
||||
$query->addProject($activity->getProject());
|
||||
$query->setActivityToIgnore($activity);
|
||||
|
||||
return $repo->getQueryBuilderForFormType($query);
|
||||
|
||||
@@ -244,7 +244,7 @@ final class CustomerController extends AbstractController
|
||||
$query->setCurrentUser($this->getUser());
|
||||
$query->setPage($page);
|
||||
$query->setPageSize(5);
|
||||
$query->setCustomer($customer);
|
||||
$query->addCustomer($customer);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $projectRepository->getPagerfantaForQuery($query);
|
||||
|
||||
@@ -313,7 +313,7 @@ final class InvoiceController extends AbstractController
|
||||
protected function getEntries(InvoiceQuery $query): array
|
||||
{
|
||||
// customer needs to be defined, as we need the currency for the invoice
|
||||
if (null === $query->getCustomer()) {
|
||||
if (!$query->hasCustomers()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ final class ProjectController extends AbstractController
|
||||
$query->setCurrentUser($this->getUser());
|
||||
$query->setPage($page);
|
||||
$query->setPageSize(5);
|
||||
$query->setProject($project);
|
||||
$query->addProject($project);
|
||||
$query->setExcludeGlobals(true);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
@@ -405,7 +405,7 @@ final class ProjectController extends AbstractController
|
||||
'label' => 'label.project',
|
||||
'query_builder' => function (ProjectRepository $repo) use ($project) {
|
||||
$query = new ProjectFormTypeQuery();
|
||||
$query->setCustomer($project->getCustomer());
|
||||
$query->addCustomer($project->getCustomer());
|
||||
$query->setProjectToIgnore($project);
|
||||
$query->setUser($this->getUser());
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Form\Toolbar;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Form\Type\ActivityType;
|
||||
use App\Form\Type\CustomerType;
|
||||
use App\Form\Type\DateRangeType;
|
||||
@@ -70,25 +71,47 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
]);
|
||||
}
|
||||
|
||||
protected function addCustomerChoice(FormBuilderInterface $builder, array $options = [])
|
||||
protected function addCustomerChoice(FormBuilderInterface $builder, array $options = [], bool $multiProject = false)
|
||||
{
|
||||
$this->addCustomerSelect($builder, $options, false, $multiProject);
|
||||
}
|
||||
|
||||
protected function addCustomerMultiChoice(FormBuilderInterface $builder, array $options = [], bool $multiProject = false)
|
||||
{
|
||||
$this->addCustomerSelect($builder, $options, true, $multiProject);
|
||||
}
|
||||
|
||||
private function addCustomerSelect(FormBuilderInterface $builder, array $options, bool $multiCustomer, bool $multiProject)
|
||||
{
|
||||
$name = 'customer';
|
||||
if ($multiCustomer) {
|
||||
$name = 'customers';
|
||||
}
|
||||
|
||||
// just a fake field for having this field at the right position in the frontend
|
||||
$builder->add('customer', HiddenType::class);
|
||||
$builder->add($name, HiddenType::class);
|
||||
|
||||
$builder->addEventListener(
|
||||
FormEvents::PRE_SUBMIT,
|
||||
function (FormEvent $event) use ($builder, $options) {
|
||||
function (FormEvent $event) use ($builder, $options, $name, $multiCustomer, $multiProject) {
|
||||
$data = $event->getData();
|
||||
$event->getForm()->add('customer', CustomerType::class, array_merge([
|
||||
$event->getForm()->add($name, CustomerType::class, array_merge([
|
||||
'multiple' => $multiCustomer,
|
||||
'required' => false,
|
||||
'project_enabled' => true,
|
||||
'project_enabled' => $multiCustomer ? 'customers' : 'customer',
|
||||
'project_select' => $multiProject ? 'projects' : 'project',
|
||||
'end_date_param' => '%daterange%',
|
||||
'start_date_param' => '%daterange%',
|
||||
'query_builder' => function (CustomerRepository $repo) use ($builder, $data) {
|
||||
'query_builder' => function (CustomerRepository $repo) use ($builder, $data, $name, $multiCustomer) {
|
||||
$query = new CustomerFormTypeQuery();
|
||||
$query->setUser($builder->getOption('user'));
|
||||
if (isset($data['customer']) && !empty($data['customer'])) {
|
||||
$query->setCustomer($data['customer']);
|
||||
|
||||
if (isset($data[$name]) && !empty($data[$name])) {
|
||||
if ($multiCustomer) {
|
||||
$query->setCustomers($data[$name]);
|
||||
} else {
|
||||
$query->addCustomer($data[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
return $repo->getQueryBuilderForFormType($query);
|
||||
@@ -131,28 +154,56 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
]);
|
||||
}
|
||||
|
||||
protected function addProjectChoice(FormBuilderInterface $builder, array $options = [])
|
||||
protected function addProjectChoice(FormBuilderInterface $builder, array $options = [], bool $multiCustomer = false, bool $multiActivity = false)
|
||||
{
|
||||
$this->addProjectSelect($builder, $options, false, $multiCustomer, $multiActivity);
|
||||
}
|
||||
|
||||
protected function addProjectMultiChoice(FormBuilderInterface $builder, array $options = [], bool $multiCustomer = false, bool $multiActivity = false)
|
||||
{
|
||||
$this->addProjectSelect($builder, $options, true, $multiCustomer, $multiActivity);
|
||||
}
|
||||
|
||||
private function addProjectSelect(FormBuilderInterface $builder, array $options, bool $multiProject, bool $multiCustomer, bool $multiActivity)
|
||||
{
|
||||
$name = 'project';
|
||||
if ($multiProject) {
|
||||
$name = 'projects';
|
||||
}
|
||||
// just a fake field for having this field at the right position in the frontend
|
||||
$builder->add('project', HiddenType::class);
|
||||
$builder->add($name, HiddenType::class);
|
||||
|
||||
$builder->addEventListener(
|
||||
FormEvents::PRE_SUBMIT,
|
||||
function (FormEvent $event) use ($builder, $options) {
|
||||
function (FormEvent $event) use ($builder, $options, $name, $multiCustomer, $multiProject, $multiActivity) {
|
||||
$data = $event->getData();
|
||||
$event->getForm()->add('project', ProjectType::class, array_merge([
|
||||
$event->getForm()->add($name, ProjectType::class, array_merge([
|
||||
'multiple' => $multiProject,
|
||||
'required' => false,
|
||||
'activity_enabled' => true,
|
||||
'query_builder' => function (ProjectRepository $repo) use ($builder, $data, $options) {
|
||||
'activity_enabled' => $multiProject ? 'projects' : 'project',
|
||||
'activity_select' => $multiActivity ? 'activities' : 'activity',
|
||||
'query_builder' => function (ProjectRepository $repo) use ($builder, $data, $options, $multiCustomer, $multiProject) {
|
||||
$query = new ProjectFormTypeQuery();
|
||||
$query->setUser($builder->getOption('user'));
|
||||
|
||||
if (isset($data['customer']) && !empty($data['customer'])) {
|
||||
$query->setCustomer($data['customer']);
|
||||
$name = $multiCustomer ? 'customers' : 'customer';
|
||||
if (isset($data[$name]) && !empty($data[$name])) {
|
||||
if (is_array($data[$name])) {
|
||||
$query->setCustomers($data[$name]);
|
||||
} else {
|
||||
$query->addCustomer($data[$name]);
|
||||
}
|
||||
}
|
||||
if (isset($data['project']) && !empty($data['project'])) {
|
||||
$query->setProject($data['project']);
|
||||
|
||||
$name = $multiProject ? 'projects' : 'project';
|
||||
if (isset($data[$name]) && !empty($data[$name])) {
|
||||
if (is_array($data[$name])) {
|
||||
$query->setProjects($data[$name]);
|
||||
} else {
|
||||
$query->addProject($data[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['ignore_date']) && true === $options['ignore_date']) {
|
||||
$query->setIgnoreDate(true);
|
||||
}
|
||||
@@ -164,30 +215,62 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
);
|
||||
}
|
||||
|
||||
protected function addActivityChoice(FormBuilderInterface $builder)
|
||||
protected function addActivityChoice(FormBuilderInterface $builder, array $options = [], bool $multiProject = false)
|
||||
{
|
||||
$this->addActivitySelect($builder, $options, false, $multiProject);
|
||||
}
|
||||
|
||||
protected function addActivityMultiChoice(FormBuilderInterface $builder, array $options = [], bool $multiProject = false)
|
||||
{
|
||||
$this->addActivitySelect($builder, $options, true, $multiProject);
|
||||
}
|
||||
|
||||
private function addActivitySelect(FormBuilderInterface $builder, array $options = [], bool $multiActivity = false, bool $multiProject = false)
|
||||
{
|
||||
$name = 'activity';
|
||||
if ($multiActivity) {
|
||||
$name = 'activities';
|
||||
}
|
||||
|
||||
// just a fake field for having this field at the right position in the frontend
|
||||
$builder->add('activity', HiddenType::class);
|
||||
$builder->add($name, HiddenType::class);
|
||||
|
||||
$builder->addEventListener(
|
||||
FormEvents::PRE_SUBMIT,
|
||||
function (FormEvent $event) {
|
||||
function (FormEvent $event) use ($name, $multiActivity, $multiProject) {
|
||||
$data = $event->getData();
|
||||
$event->getForm()->add('activity', ActivityType::class, [
|
||||
$event->getForm()->add($name, ActivityType::class, [
|
||||
'multiple' => $multiActivity,
|
||||
'required' => false,
|
||||
'query_builder' => function (ActivityRepository $repo) use ($data) {
|
||||
'query_builder' => function (ActivityRepository $repo) use ($data, $multiActivity, $multiProject) {
|
||||
$query = new ActivityFormTypeQuery();
|
||||
|
||||
if (isset($data['activity']) && !empty($data['activity'])) {
|
||||
$activity = $data['activity'];
|
||||
if (is_string($data['activity'])) {
|
||||
$activity = $repo->find($data['activity']);
|
||||
$name = $multiActivity ? 'activities' : 'activity';
|
||||
if (isset($data[$name]) && !empty($data[$name])) {
|
||||
// we need to pre-fetch the activities to see if they are global, see ActivityFormTypeQuery::isGlobalsOnly()
|
||||
$activities = $data[$name];
|
||||
if (!is_array($activities)) {
|
||||
$activities = [$activities];
|
||||
}
|
||||
foreach ($activities as $activity) {
|
||||
if ($activity instanceof Activity) {
|
||||
$query->addActivity($activity);
|
||||
} elseif ($activity !== null) {
|
||||
$tmp = $repo->find($activity);
|
||||
if (null !== $tmp) {
|
||||
$query->addActivity($tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query->setActivity($activity);
|
||||
}
|
||||
if (isset($data['project']) && !empty($data['project'])) {
|
||||
$query->setProject($data['project']);
|
||||
|
||||
$name = $multiProject ? 'projects' : 'project';
|
||||
if (isset($data[$name]) && !empty($data[$name])) {
|
||||
if ($multiProject) {
|
||||
$query->setProjects($data[$name]);
|
||||
} else {
|
||||
$query->addProject($data[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
return $repo->getQueryBuilderForFormType($query);
|
||||
|
||||
@@ -25,8 +25,8 @@ class ActivityToolbarForm extends AbstractToolbarForm
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$this->addSearchTermInputField($builder);
|
||||
$this->addCustomerChoice($builder);
|
||||
$this->addProjectChoice($builder);
|
||||
$this->addCustomerMultiChoice($builder, [], true);
|
||||
$this->addProjectMultiChoice($builder, [], true, false);
|
||||
$builder->add('globalsOnly', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'yes' => 1,
|
||||
|
||||
@@ -31,9 +31,9 @@ class ExportToolbarForm extends AbstractToolbarForm
|
||||
$this->addTimesheetStateChoice($builder);
|
||||
$this->addUsersChoice($builder);
|
||||
$this->addDateRangeChoice($builder);
|
||||
$this->addCustomerChoice($builder, ['start_date_param' => null, 'end_date_param' => null, 'ignore_date' => true]);
|
||||
$this->addProjectChoice($builder, ['ignore_date' => true]);
|
||||
$this->addActivityChoice($builder);
|
||||
$this->addCustomerMultiChoice($builder, ['start_date_param' => null, 'end_date_param' => null, 'ignore_date' => true], true);
|
||||
$this->addProjectMultiChoice($builder, ['ignore_date' => true], true, true);
|
||||
$this->addActivityMultiChoice($builder, [], true);
|
||||
$this->addExportType($builder);
|
||||
$this->addTagInputField($builder);
|
||||
$builder->add('markAsExported', CheckboxType::class, [
|
||||
|
||||
@@ -27,7 +27,7 @@ class InvoiceToolbarForm extends InvoiceToolbarSimpleForm
|
||||
if ($options['include_user']) {
|
||||
$this->addUsersChoice($builder);
|
||||
}
|
||||
$this->addActivityChoice($builder);
|
||||
$this->addActivityMultiChoice($builder, $options, true);
|
||||
$this->addTagInputField($builder);
|
||||
$this->addExportStateChoice($builder);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ class InvoiceToolbarSimpleForm extends AbstractToolbarForm
|
||||
{
|
||||
$this->addTemplateChoice($builder);
|
||||
$this->addDateRangeChoice($builder);
|
||||
$this->addCustomerChoice($builder, ['required' => true, 'start_date_param' => null, 'end_date_param' => null, 'ignore_date' => true, 'placeholder' => '']);
|
||||
$this->addProjectChoice($builder, ['ignore_date' => true]);
|
||||
$this->addCustomerChoice($builder, ['required' => true, 'start_date_param' => null, 'end_date_param' => null, 'ignore_date' => true, 'placeholder' => ''], true);
|
||||
$this->addProjectMultiChoice($builder, ['ignore_date' => true], false, true);
|
||||
$builder->add('markAsExported', CheckboxType::class, [
|
||||
'label' => 'label.mark_as_exported',
|
||||
'required' => false,
|
||||
|
||||
@@ -24,7 +24,7 @@ class ProjectToolbarForm extends AbstractToolbarForm
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$this->addSearchTermInputField($builder);
|
||||
$this->addCustomerChoice($builder);
|
||||
$this->addCustomerMultiChoice($builder, [], false);
|
||||
$this->addVisibilityChoice($builder);
|
||||
$this->addPageSizeChoice($builder);
|
||||
$this->addHiddenPagination($builder);
|
||||
|
||||
@@ -20,6 +20,7 @@ class TeamToolbarForm extends AbstractToolbarForm
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$this->addUsersChoice($builder);
|
||||
$this->addSearchTermInputField($builder);
|
||||
$this->addPageSizeChoice($builder);
|
||||
$this->addHiddenPagination($builder);
|
||||
|
||||
@@ -28,9 +28,9 @@ class TimesheetToolbarForm extends AbstractToolbarForm
|
||||
$this->addUsersChoice($builder);
|
||||
}
|
||||
$this->addDateRangeChoice($builder);
|
||||
$this->addCustomerChoice($builder);
|
||||
$this->addProjectChoice($builder);
|
||||
$this->addActivityChoice($builder);
|
||||
$this->addCustomerMultiChoice($builder, [], true);
|
||||
$this->addProjectMultiChoice($builder, [], true, true);
|
||||
$this->addActivityMultiChoice($builder, [], true);
|
||||
$this->addTagInputField($builder);
|
||||
$this->addTimesheetStateChoice($builder);
|
||||
$this->addExportStateChoice($builder);
|
||||
|
||||
@@ -39,6 +39,7 @@ class CustomerType extends AbstractType
|
||||
'choice_label' => 'name',
|
||||
'query_builder_for_user' => true,
|
||||
'project_enabled' => false,
|
||||
'project_select' => 'project',
|
||||
'start_date_param' => '%begin%',
|
||||
'end_date_param' => '%end%',
|
||||
'ignore_date' => false,
|
||||
@@ -57,8 +58,9 @@ class CustomerType extends AbstractType
|
||||
});
|
||||
|
||||
$resolver->setDefault('api_data', function (Options $options) {
|
||||
if (true === $options['project_enabled']) {
|
||||
$routeParams = ['customer' => '%customer%', 'visible' => $options['project_visibility']];
|
||||
if (false !== $options['project_enabled']) {
|
||||
$name = is_string($options['project_enabled']) ? $options['project_enabled'] : 'customer';
|
||||
$routeParams = [$name => '%' . $name . '%', 'visible' => $options['project_visibility']];
|
||||
$emptyRouteParams = ['visible' => $options['project_visibility']];
|
||||
|
||||
if (!$options['ignore_date']) {
|
||||
@@ -77,7 +79,7 @@ class CustomerType extends AbstractType
|
||||
}
|
||||
|
||||
return [
|
||||
'select' => 'project',
|
||||
'select' => $options['project_select'],
|
||||
'route' => 'get_projects',
|
||||
'route_params' => $routeParams,
|
||||
'empty_route_params' => $emptyRouteParams,
|
||||
|
||||
@@ -64,6 +64,7 @@ class ProjectType extends AbstractType
|
||||
},
|
||||
'query_builder_for_user' => true,
|
||||
'activity_enabled' => false,
|
||||
'activity_select' => 'activity',
|
||||
'activity_visibility' => ActivityQuery::SHOW_VISIBLE,
|
||||
'ignore_date' => false,
|
||||
]);
|
||||
@@ -83,11 +84,13 @@ class ProjectType extends AbstractType
|
||||
});
|
||||
|
||||
$resolver->setDefault('api_data', function (Options $options) {
|
||||
if (true === $options['activity_enabled']) {
|
||||
if (false !== $options['activity_enabled']) {
|
||||
$name = is_string($options['activity_enabled']) ? $options['activity_enabled'] : 'project';
|
||||
|
||||
return [
|
||||
'select' => 'activity',
|
||||
'select' => $options['activity_select'],
|
||||
'route' => 'get_activities',
|
||||
'route_params' => ['project' => '%project%', 'visible' => $options['activity_visibility']],
|
||||
'route_params' => [$name => '%' . $name . '%', 'visible' => $options['activity_visibility']],
|
||||
'empty_route_params' => ['globals' => 'true', 'visible' => $options['activity_visibility']],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Invoice\Hydrator;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\InvoiceModelHydrator;
|
||||
|
||||
@@ -16,24 +17,38 @@ class InvoiceModelActivityHydrator implements InvoiceModelHydrator
|
||||
{
|
||||
public function hydrate(InvoiceModel $model): array
|
||||
{
|
||||
$activity = $model->getQuery()->getActivity();
|
||||
|
||||
if (null === $activity) {
|
||||
if (!$model->getQuery()->hasActivities()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$formatter = $model->getFormatter();
|
||||
$currency = $model->getCurrency();
|
||||
$values = [];
|
||||
$i = 0;
|
||||
|
||||
foreach ($model->getQuery()->getActivities() as $activity) {
|
||||
$prefix = '';
|
||||
if ($i > 0) {
|
||||
$prefix = $i . '.';
|
||||
}
|
||||
$values = array_merge($values, $this->getValuesFromActivity($activity, $prefix));
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
private function getValuesFromActivity(Activity $activity, string $prefix): array
|
||||
{
|
||||
$prefix = 'activity.' . $prefix;
|
||||
|
||||
$values = [
|
||||
'activity.id' => $activity->getId(),
|
||||
'activity.name' => $activity->getName(),
|
||||
'activity.comment' => $activity->getComment(),
|
||||
$prefix . 'id' => $activity->getId(),
|
||||
$prefix . 'name' => $activity->getName(),
|
||||
$prefix . 'comment' => $activity->getComment(),
|
||||
];
|
||||
|
||||
foreach ($activity->getVisibleMetaFields() as $metaField) {
|
||||
$values = array_merge($values, [
|
||||
'activity.meta.' . $metaField->getName() => $metaField->getValue(),
|
||||
$prefix . 'meta.' . $metaField->getName() => $metaField->getValue(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace App\Invoice\Hydrator;
|
||||
|
||||
use App\Entity\Project;
|
||||
use App\Invoice\InvoiceFormatter;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\InvoiceModelHydrator;
|
||||
|
||||
@@ -16,34 +18,51 @@ class InvoiceModelProjectHydrator implements InvoiceModelHydrator
|
||||
{
|
||||
public function hydrate(InvoiceModel $model): array
|
||||
{
|
||||
$project = $model->getQuery()->getProject();
|
||||
|
||||
if (null === $project) {
|
||||
if (!$model->getQuery()->hasProjects()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$formatter = $model->getFormatter();
|
||||
$currency = $model->getCurrency();
|
||||
|
||||
$values = [];
|
||||
$i = 0;
|
||||
|
||||
foreach ($model->getQuery()->getProjects() as $project) {
|
||||
$prefix = '';
|
||||
if ($i > 0) {
|
||||
$prefix = $i . '.';
|
||||
}
|
||||
$values = array_merge($values, $this->getValuesFromProject($project, $formatter, $currency, $prefix));
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
private function getValuesFromProject(Project $project, InvoiceFormatter $formatter, string $currency, string $prefix): array
|
||||
{
|
||||
$prefix = 'project.' . $prefix;
|
||||
|
||||
$values = [
|
||||
'project.id' => $project->getId(),
|
||||
'project.name' => $project->getName(),
|
||||
'project.comment' => $project->getComment(),
|
||||
'project.order_number' => $project->getOrderNumber(),
|
||||
'project.start_date' => null !== $project->getStart() ? $formatter->getFormattedDateTime($project->getStart()) : '',
|
||||
'project.end_date' => null !== $project->getEnd() ? $formatter->getFormattedDateTime($project->getEnd()) : '',
|
||||
'project.order_date' => null !== $project->getOrderDate() ? $formatter->getFormattedDateTime($project->getOrderDate()) : '',
|
||||
'project.budget_money' => $formatter->getFormattedMoney($project->getBudget(), $currency),
|
||||
'project.budget_money_nc' => $formatter->getFormattedMoney($project->getBudget(), null),
|
||||
'project.budget_money_plain' => $project->getBudget(),
|
||||
'project.budget_time' => $project->getTimeBudget(),
|
||||
'project.budget_time_decimal' => $formatter->getFormattedDecimalDuration($project->getTimeBudget()),
|
||||
'project.budget_time_minutes' => number_format($project->getTimeBudget() / 60),
|
||||
$prefix . 'id' => $project->getId(),
|
||||
$prefix . 'name' => $project->getName(),
|
||||
$prefix . 'comment' => $project->getComment(),
|
||||
$prefix . 'order_number' => $project->getOrderNumber(),
|
||||
$prefix . 'start_date' => null !== $project->getStart() ? $formatter->getFormattedDateTime($project->getStart()) : '',
|
||||
$prefix . 'end_date' => null !== $project->getEnd() ? $formatter->getFormattedDateTime($project->getEnd()) : '',
|
||||
$prefix . 'order_date' => null !== $project->getOrderDate() ? $formatter->getFormattedDateTime($project->getOrderDate()) : '',
|
||||
$prefix . 'budget_money' => $formatter->getFormattedMoney($project->getBudget(), $currency),
|
||||
$prefix . 'budget_money_nc' => $formatter->getFormattedMoney($project->getBudget(), null),
|
||||
$prefix . 'budget_money_plain' => $project->getBudget(),
|
||||
$prefix . 'budget_time' => $project->getTimeBudget(),
|
||||
$prefix . 'budget_time_decimal' => $formatter->getFormattedDecimalDuration($project->getTimeBudget()),
|
||||
$prefix . 'budget_time_minutes' => number_format($project->getTimeBudget() / 60),
|
||||
];
|
||||
|
||||
foreach ($project->getVisibleMetaFields() as $metaField) {
|
||||
$values = array_merge($values, [
|
||||
'project.meta.' . $metaField->getName() => $metaField->getValue(),
|
||||
$prefix . 'meta.' . $metaField->getName() => $metaField->getValue(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,13 +154,13 @@ class ActivityRepository extends EntityRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.1
|
||||
* @deprecated since 1.1 - use getQueryBuilderForFormType() instead - will be removed with 2.0
|
||||
*/
|
||||
public function builderForEntityType($activity, $project)
|
||||
{
|
||||
$query = new ActivityFormTypeQuery();
|
||||
$query->setActivity($activity);
|
||||
$query->setProject($project);
|
||||
$query->addActivity($activity);
|
||||
$query->addProject($project);
|
||||
|
||||
return $this->getQueryBuilderForFormType($query);
|
||||
}
|
||||
@@ -212,14 +212,14 @@ class ActivityRepository extends EntityRepository
|
||||
|
||||
if ($query->isGlobalsOnly()) {
|
||||
$where->add($qb->expr()->isNull('a.project'));
|
||||
} elseif (null !== $query->getProject()) {
|
||||
} elseif ($query->hasProjects()) {
|
||||
$where->add(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('a.project', ':project'),
|
||||
$qb->expr()->in('a.project', ':project'),
|
||||
$qb->expr()->isNull('a.project')
|
||||
)
|
||||
);
|
||||
$qb->setParameter('project', $query->getProject());
|
||||
$qb->setParameter('project', $query->getProjects());
|
||||
}
|
||||
|
||||
if (null !== $query->getActivityToIgnore()) {
|
||||
@@ -233,10 +233,9 @@ class ActivityRepository extends EntityRepository
|
||||
$or->add($where);
|
||||
|
||||
// this must always be the last part of the query
|
||||
/* @var Activity $entity */
|
||||
if (null !== $query->getActivity()) {
|
||||
$or->add($qb->expr()->eq('a.id', ':activity'));
|
||||
$qb->setParameter('activity', $query->getActivity());
|
||||
if ($query->hasActivities()) {
|
||||
$or->add($qb->expr()->in('a.id', ':activity'));
|
||||
$qb->setParameter('activity', $query->getActivities());
|
||||
}
|
||||
|
||||
if ($or->count() > 0) {
|
||||
@@ -303,9 +302,9 @@ class ActivityRepository extends EntityRepository
|
||||
|
||||
if ($query->isGlobalsOnly()) {
|
||||
$where->add($qb->expr()->isNull('a.project'));
|
||||
} elseif (null !== $query->getProject()) {
|
||||
} elseif ($query->hasProjects()) {
|
||||
$orX = $qb->expr()->orX(
|
||||
$qb->expr()->eq('a.project', ':project')
|
||||
$qb->expr()->in('a.project', ':project')
|
||||
);
|
||||
|
||||
if (!$query->isExcludeGlobals()) {
|
||||
@@ -313,7 +312,7 @@ class ActivityRepository extends EntityRepository
|
||||
}
|
||||
|
||||
$where->add($orX);
|
||||
$qb->setParameter('project', $query->getProject());
|
||||
$qb->setParameter('project', $query->getProjects());
|
||||
} elseif (null !== $query->getCustomer()) {
|
||||
$where->add('p.customer = :customer');
|
||||
$qb->setParameter('customer', $query->getCustomer());
|
||||
|
||||
@@ -163,12 +163,12 @@ class CustomerRepository extends EntityRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.1 - don't use this method, it ignores team permission checks
|
||||
* @deprecated since 1.1 - use getQueryBuilderForFormType() istead - will be removed with 2.0
|
||||
*/
|
||||
public function builderForEntityType($customer)
|
||||
{
|
||||
$query = new CustomerFormTypeQuery();
|
||||
$query->setCustomer($customer);
|
||||
$query->addCustomer($customer);
|
||||
|
||||
return $this->getQueryBuilderForFormType($query);
|
||||
}
|
||||
@@ -190,9 +190,9 @@ class CustomerRepository extends EntityRepository
|
||||
$qb->andWhere($qb->expr()->eq('c.visible', ':visible'));
|
||||
$qb->setParameter('visible', true, \PDO::PARAM_BOOL);
|
||||
|
||||
$customer = $query->getCustomer();
|
||||
if (null !== $customer) {
|
||||
$qb->orWhere('c.id = :customer')->setParameter('customer', $customer);
|
||||
if ($query->hasCustomers()) {
|
||||
$qb->orWhere($qb->expr()->in('c.id', ':customer'))
|
||||
->setParameter('customer', $query->getCustomers());
|
||||
}
|
||||
|
||||
if (null !== $query->getCustomerToIgnore()) {
|
||||
|
||||
@@ -152,13 +152,13 @@ class ProjectRepository extends EntityRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.1 - don't use this method, it ignores team permission checks
|
||||
* @deprecated since 1.1 - use getQueryBuilderForFormType() istead - will be removed with 2.0
|
||||
*/
|
||||
public function builderForEntityType($project, $customer)
|
||||
{
|
||||
$query = new ProjectFormTypeQuery();
|
||||
$query->setProject($project);
|
||||
$query->setCustomer($customer);
|
||||
$query->addProject($project);
|
||||
$query->addCustomer($customer);
|
||||
|
||||
return $this->getQueryBuilderForFormType($query);
|
||||
}
|
||||
@@ -216,13 +216,14 @@ class ProjectRepository extends EntityRepository
|
||||
$qb->setParameter('visible', true, \PDO::PARAM_BOOL);
|
||||
$qb->setParameter('customer_visible', true, \PDO::PARAM_BOOL);
|
||||
|
||||
if (null !== $query->getProject()) {
|
||||
$qb->orWhere('p.id = :project')->setParameter('project', $query->getProject());
|
||||
if ($query->hasProjects()) {
|
||||
$qb->orWhere($qb->expr()->in('p.id', ':project'))
|
||||
->setParameter('project', $query->getProjects());
|
||||
}
|
||||
|
||||
if (null !== $query->getCustomer()) {
|
||||
$qb->andWhere('p.customer = :customer')
|
||||
->setParameter('customer', $query->getCustomer());
|
||||
if ($query->hasCustomers()) {
|
||||
$qb->andWhere($qb->expr()->in('p.customer', ':customer'))
|
||||
->setParameter('customer', $query->getCustomers());
|
||||
}
|
||||
|
||||
if (null !== $query->getProjectToIgnore()) {
|
||||
@@ -272,9 +273,9 @@ class ProjectRepository extends EntityRepository
|
||||
$qb->setParameter('customer_visible', true, \PDO::PARAM_BOOL);
|
||||
}
|
||||
|
||||
if (null !== $query->getCustomer()) {
|
||||
$qb->andWhere('p.customer = :customer')
|
||||
->setParameter('customer', $query->getCustomer());
|
||||
if ($query->hasCustomers()) {
|
||||
$qb->andWhere($qb->expr()->in('p.customer', ':customer'))
|
||||
->setParameter('customer', $query->getCustomers());
|
||||
}
|
||||
|
||||
// this is far from being perfect, possible enhancements:
|
||||
|
||||
@@ -12,67 +12,32 @@ namespace App\Repository\Query;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Project;
|
||||
|
||||
final class ActivityFormTypeQuery
|
||||
final class ActivityFormTypeQuery extends BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var Activity|int|null
|
||||
*/
|
||||
private $activity;
|
||||
/**
|
||||
* @var Project|int|null
|
||||
*/
|
||||
private $project;
|
||||
/**
|
||||
* @var Activity|null
|
||||
*/
|
||||
private $activityToIgnore;
|
||||
|
||||
/**
|
||||
* @param Activity|int|null $activity
|
||||
* @param Project|int|null $project
|
||||
* @param Activity|int|array|null $activity
|
||||
* @param Project|int|array|null $project
|
||||
*/
|
||||
public function __construct($activity = null, $project = null)
|
||||
{
|
||||
$this->activity = $activity;
|
||||
$this->project = $project;
|
||||
}
|
||||
if (null !== $activity) {
|
||||
if (!is_array($activity)) {
|
||||
$activity = [$activity];
|
||||
}
|
||||
$this->setActivities($activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Activity|int|null
|
||||
*/
|
||||
public function getActivity()
|
||||
{
|
||||
return $this->activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity|int|null $activity
|
||||
* @return ActivityFormTypeQuery
|
||||
*/
|
||||
public function setActivity($activity): ActivityFormTypeQuery
|
||||
{
|
||||
$this->activity = $activity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Project|int|null
|
||||
*/
|
||||
public function getProject()
|
||||
{
|
||||
return $this->project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int|null $project
|
||||
* @return ActivityFormTypeQuery
|
||||
*/
|
||||
public function setProject($project): ActivityFormTypeQuery
|
||||
{
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
if (null !== $project) {
|
||||
if (!is_array($project)) {
|
||||
$project = [$project];
|
||||
}
|
||||
$this->setProjects($project);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,12 +57,21 @@ final class ActivityFormTypeQuery
|
||||
|
||||
public function isGlobalsOnly(): bool
|
||||
{
|
||||
return
|
||||
(
|
||||
null === $this->activity ||
|
||||
($this->activity instanceof Activity && null === $this->activity->getProject())
|
||||
)
|
||||
&&
|
||||
null === $this->project;
|
||||
if ($this->hasProjects()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->hasActivities()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->getActivities() as $activity) {
|
||||
// this is a potential problem, if only IDs were set
|
||||
if ($activity instanceof Activity && !$activity->isGlobal()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ class ActivityQuery extends ProjectQuery
|
||||
public const ACTIVITY_ORDER_ALLOWED = ['id', 'name', 'comment', 'customer', 'project'];
|
||||
|
||||
/**
|
||||
* @var Project|int|null
|
||||
* @var Project[]|int[]
|
||||
*/
|
||||
private $project;
|
||||
private $projects = [];
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -72,20 +72,58 @@ class ActivityQuery extends ProjectQuery
|
||||
|
||||
/**
|
||||
* @return Project|int|null
|
||||
* @deprecated since 1.9 - use getProjects() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getProject()
|
||||
{
|
||||
return $this->project;
|
||||
if (count($this->projects) > 0) {
|
||||
return $this->projects[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int|null $project
|
||||
* @return self
|
||||
* @deprecated since 1.9 - use setProjects() or addProject() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setProject($project = null): self
|
||||
{
|
||||
$this->project = $project;
|
||||
if (null === $project) {
|
||||
$this->projects = [];
|
||||
} else {
|
||||
$this->projects = [$project];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int $project
|
||||
* @return self
|
||||
*/
|
||||
public function addProject($project): self
|
||||
{
|
||||
$this->projects[] = $project;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProjects(array $projects): self
|
||||
{
|
||||
$this->projects = $projects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProjects(): array
|
||||
{
|
||||
return $this->projects;
|
||||
}
|
||||
|
||||
public function hasProjects(): bool
|
||||
{
|
||||
return !empty($this->projects);
|
||||
}
|
||||
}
|
||||
|
||||
257
src/Repository/Query/BaseFormTypeQuery.php
Normal file
257
src/Repository/Query/BaseFormTypeQuery.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Team;
|
||||
use App\Entity\User;
|
||||
|
||||
abstract class BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $activities = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $projects = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $customers = [];
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var array<Team>
|
||||
*/
|
||||
private $teams = [];
|
||||
|
||||
/**
|
||||
* @return Activity|int|null
|
||||
* @deprecated since 1.9 - use getActivities() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getActivity()
|
||||
{
|
||||
if (count($this->activities) > 0) {
|
||||
return $this->activities[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity|int|null $activity
|
||||
* @return self
|
||||
* @deprecated since 1.9 - use setActivities() or addActivity() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setActivity($activity): self
|
||||
{
|
||||
if (null === $activity) {
|
||||
$this->activities = [];
|
||||
} else {
|
||||
$this->activities = [$activity];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity|int $activity
|
||||
* @return self
|
||||
*/
|
||||
public function addActivity($activity): self
|
||||
{
|
||||
if (null !== $activity) {
|
||||
$this->activities[] = $activity;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity[]|int[] $activities
|
||||
* @return self
|
||||
*/
|
||||
public function setActivities(array $activities): self
|
||||
{
|
||||
$this->activities = $activities;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getActivities(): array
|
||||
{
|
||||
return $this->activities;
|
||||
}
|
||||
|
||||
public function hasActivities(): bool
|
||||
{
|
||||
return !empty($this->activities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Project|int|null
|
||||
* @deprecated since 1.9 - use getProjects() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getProject()
|
||||
{
|
||||
if (count($this->projects) > 0) {
|
||||
return $this->projects[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int|null $project
|
||||
* @return self
|
||||
* @deprecated since 1.9 - use addProject() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setProject($project): self
|
||||
{
|
||||
if (null === $project) {
|
||||
$this->projects = [];
|
||||
} else {
|
||||
$this->projects = [$project];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int $project
|
||||
* @return self
|
||||
*/
|
||||
public function addProject($project): self
|
||||
{
|
||||
if (null !== $project) {
|
||||
$this->projects[] = $project;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project[]|int[] $projects
|
||||
* @return self
|
||||
*/
|
||||
public function setProjects(array $projects): self
|
||||
{
|
||||
$this->projects = $projects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProjects(): array
|
||||
{
|
||||
return $this->projects;
|
||||
}
|
||||
|
||||
public function hasProjects(): bool
|
||||
{
|
||||
return !empty($this->projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Customer|int|null
|
||||
* @deprecated since 1.9 - use getCustomers() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
if (count($this->customers) > 0) {
|
||||
return $this->customers[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int|null $customer
|
||||
* @return self
|
||||
* @deprecated since 1.9 - use addCustomer() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setCustomer($customer): self
|
||||
{
|
||||
if (null === $customer) {
|
||||
$this->customers = [];
|
||||
} else {
|
||||
$this->customers = [$customer];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer[]|int[] $customers
|
||||
* @return self
|
||||
*/
|
||||
public function setCustomers(array $customers): self
|
||||
{
|
||||
$this->customers = $customers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int $customer
|
||||
* @return self
|
||||
*/
|
||||
public function addCustomer($customer): self
|
||||
{
|
||||
$this->customers[] = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomers(): array
|
||||
{
|
||||
return $this->customers;
|
||||
}
|
||||
|
||||
public function hasCustomers(): bool
|
||||
{
|
||||
return !empty($this->customers);
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): self
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTeam(Team $team): self
|
||||
{
|
||||
$this->teams[$team->getId()] = $team;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Team[]
|
||||
*/
|
||||
public function getTeams(): array
|
||||
{
|
||||
return array_values($this->teams);
|
||||
}
|
||||
}
|
||||
@@ -10,83 +10,28 @@
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Team;
|
||||
use App\Entity\User;
|
||||
|
||||
/**
|
||||
* Can be used for advanced queries with the: CustomerRepository
|
||||
*/
|
||||
final class CustomerFormTypeQuery
|
||||
final class CustomerFormTypeQuery extends BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var Customer|int|null
|
||||
*/
|
||||
private $customer;
|
||||
/**
|
||||
* @var Customer|null
|
||||
*/
|
||||
private $customerToIgnore;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var array<Team>
|
||||
*/
|
||||
private $teams = [];
|
||||
|
||||
/**
|
||||
* @param Customer|int|null $customer
|
||||
*/
|
||||
public function __construct($customer = null)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
}
|
||||
|
||||
public function addTeam(Team $team): CustomerFormTypeQuery
|
||||
{
|
||||
$this->teams[$team->getId()] = $team;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Team[]
|
||||
*/
|
||||
public function getTeams(): array
|
||||
{
|
||||
return array_values($this->teams);
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): CustomerFormTypeQuery
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Customer|int|null
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int|null $customer
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomer($customer): CustomerFormTypeQuery
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
if (null !== $customer) {
|
||||
if (!is_array($customer)) {
|
||||
$customer = [$customer];
|
||||
}
|
||||
$this->setCustomers($customer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,31 +11,13 @@ namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Team;
|
||||
use App\Entity\User;
|
||||
|
||||
final class ProjectFormTypeQuery
|
||||
final class ProjectFormTypeQuery extends BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var Customer|int|null
|
||||
*/
|
||||
private $customer;
|
||||
/**
|
||||
* @var Project|int|null
|
||||
*/
|
||||
private $project;
|
||||
/**
|
||||
* @var Project|null
|
||||
*/
|
||||
private $projectToIgnore;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var array<Team>
|
||||
*/
|
||||
private $teams = [];
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -47,73 +29,19 @@ final class ProjectFormTypeQuery
|
||||
*/
|
||||
public function __construct($project = null, $customer = null)
|
||||
{
|
||||
$this->project = $project;
|
||||
$this->customer = $customer;
|
||||
}
|
||||
if (null !== $project) {
|
||||
if (!is_array($project)) {
|
||||
$project = [$project];
|
||||
}
|
||||
$this->setProjects($project);
|
||||
}
|
||||
|
||||
public function addTeam(Team $team): ProjectFormTypeQuery
|
||||
{
|
||||
$this->teams[$team->getId()] = $team;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Team[]
|
||||
*/
|
||||
public function getTeams(): array
|
||||
{
|
||||
return array_values($this->teams);
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): ProjectFormTypeQuery
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Customer|int|null
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int|null $customer
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomer($customer): ProjectFormTypeQuery
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Project|int|null
|
||||
*/
|
||||
public function getProject()
|
||||
{
|
||||
return $this->project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project|int|null $project
|
||||
* @return ProjectFormTypeQuery
|
||||
*/
|
||||
public function setProject($project): ProjectFormTypeQuery
|
||||
{
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
if (null !== $customer) {
|
||||
if (!is_array($customer)) {
|
||||
$customer = [$customer];
|
||||
}
|
||||
$this->setCustomers($customer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,9 @@ class ProjectQuery extends BaseQuery implements VisibilityInterface
|
||||
public const PROJECT_ORDER_ALLOWED = ['id', 'name', 'comment', 'customer', 'orderNumber', 'projectStart', 'projectEnd'];
|
||||
|
||||
/**
|
||||
* @var Customer|int|null
|
||||
* @var array
|
||||
*/
|
||||
private $customer;
|
||||
private $customers = [];
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
@@ -42,23 +42,61 @@ class ProjectQuery extends BaseQuery implements VisibilityInterface
|
||||
|
||||
/**
|
||||
* @return Customer|int|null
|
||||
* @deprecated since 1.9 - use getCustomers() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
if (count($this->customers) > 0) {
|
||||
return $this->customers[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int|null $customer
|
||||
* @return $this
|
||||
* @deprecated since 1.9 - use setCustomers() or addCustomer() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setCustomer($customer = null)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
if (null === $customer) {
|
||||
$this->customers = [];
|
||||
} else {
|
||||
$this->customers = [$customer];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer|int $customer
|
||||
* @return $this
|
||||
*/
|
||||
public function addCustomer($customer)
|
||||
{
|
||||
$this->customers[] = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCustomers(array $customers): self
|
||||
{
|
||||
$this->customers = $customers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomers(): array
|
||||
{
|
||||
return $this->customers;
|
||||
}
|
||||
|
||||
public function hasCustomers(): bool
|
||||
{
|
||||
return !empty($this->customers);
|
||||
}
|
||||
|
||||
public function getProjectStart(): ?\DateTime
|
||||
{
|
||||
return $this->projectStart;
|
||||
|
||||
@@ -9,24 +9,6 @@
|
||||
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\User;
|
||||
|
||||
final class TagFormTypeQuery
|
||||
final class TagFormTypeQuery extends BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): TagFormTypeQuery
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,50 @@
|
||||
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\User;
|
||||
|
||||
class TeamQuery extends BaseQuery
|
||||
{
|
||||
public const TEAM_ORDER_ALLOWED = ['id', 'name', 'teamlead'];
|
||||
|
||||
/**
|
||||
* @var User[]
|
||||
*/
|
||||
private $users = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setDefaults([
|
||||
'orderBy' => 'name',
|
||||
]);
|
||||
}
|
||||
|
||||
public function hasUsers(): bool
|
||||
{
|
||||
return !empty($this->users);
|
||||
}
|
||||
|
||||
public function addUser(User $user): self
|
||||
{
|
||||
$this->users[$user->getId()] = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeUser(User $user): self
|
||||
{
|
||||
if (isset($this->users[$user->getId()])) {
|
||||
unset($this->users[$user->getId()]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User[]
|
||||
*/
|
||||
public function getUsers(): array
|
||||
{
|
||||
return array_values($this->users);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ class TimesheetQuery extends ActivityQuery
|
||||
*/
|
||||
protected $timesheetUser;
|
||||
/**
|
||||
* @var Activity|null
|
||||
* @var array
|
||||
*/
|
||||
protected $activity;
|
||||
private $activities = [];
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@@ -114,26 +114,66 @@ class TimesheetQuery extends ActivityQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity overwrites: setProject() and setCustomer()
|
||||
*
|
||||
* @return Activity|null
|
||||
* @return Activity|int|null
|
||||
* @deprecated since 1.9 - use getProjects() instead - will be removed with 2.0
|
||||
*/
|
||||
public function getActivity()
|
||||
{
|
||||
return $this->activity;
|
||||
if (count($this->activities) > 0) {
|
||||
return $this->activities[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getActivities(): array
|
||||
{
|
||||
return $this->activities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity|int|null $activity
|
||||
* @return TimesheetQuery
|
||||
* @return $this
|
||||
* @deprecated since 1.9 - use setActivities() or addActivity() instead - will be removed with 2.0
|
||||
*/
|
||||
public function setActivity($activity = null)
|
||||
public function setActivity($activity)
|
||||
{
|
||||
$this->activity = $activity;
|
||||
if (null === $activity) {
|
||||
$this->activities = [];
|
||||
} else {
|
||||
$this->activities = [$activity];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity|int $activity
|
||||
* @return $this
|
||||
*/
|
||||
public function addActivity($activity)
|
||||
{
|
||||
$this->activities[] = $activity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity[]|int[] $activities
|
||||
* @return $this
|
||||
*/
|
||||
public function setActivities(array $activities)
|
||||
{
|
||||
$this->activities = $activities;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasActivities(): bool
|
||||
{
|
||||
return !empty($this->activities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
||||
@@ -9,47 +9,9 @@
|
||||
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\Team;
|
||||
use App\Entity\User;
|
||||
|
||||
/**
|
||||
* Can be used for pre-filling form types with the: UserRepository
|
||||
*/
|
||||
final class UserFormTypeQuery
|
||||
final class UserFormTypeQuery extends BaseFormTypeQuery
|
||||
{
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
/**
|
||||
* @var array<Team>
|
||||
*/
|
||||
private $teams = [];
|
||||
|
||||
public function addTeam(Team $team): UserFormTypeQuery
|
||||
{
|
||||
$this->teams[$team->getId()] = $team;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Team[]
|
||||
*/
|
||||
public function getTeams(): array
|
||||
{
|
||||
return array_values($this->teams);
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): UserFormTypeQuery
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,14 @@ class TeamRepository extends EntityRepository
|
||||
break;
|
||||
}
|
||||
|
||||
if ($query->hasUsers()) {
|
||||
$qb->orWhere(
|
||||
$qb->expr()->in('t.teamlead', ':user'),
|
||||
$qb->expr()->isMemberOf(':user', 't.users')
|
||||
)
|
||||
->setParameter('user', $query->getUsers());
|
||||
}
|
||||
|
||||
$qb->addOrderBy($orderBy, $query->getOrder());
|
||||
|
||||
if (!empty($query->getSearchTerm())) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\ActivityRate;
|
||||
use App\Entity\CustomerRate;
|
||||
use App\Entity\ProjectRate;
|
||||
@@ -712,19 +711,17 @@ class TimesheetRepository extends EntityRepository
|
||||
$qb->andWhere('t.exported = :exported')->setParameter('exported', false, \PDO::PARAM_BOOL);
|
||||
}
|
||||
|
||||
if (null !== $query->getActivity()) {
|
||||
$qb->andWhere('t.activity = :activity')
|
||||
->setParameter('activity', $query->getActivity());
|
||||
if ($query->hasActivities()) {
|
||||
$qb->andWhere($qb->expr()->in('t.activity', ':activity'))
|
||||
->setParameter('activity', $query->getActivities());
|
||||
}
|
||||
|
||||
if (null === $query->getActivity() || ($query->getActivity() instanceof Activity && null === $query->getActivity()->getProject())) {
|
||||
if (null !== $query->getProject()) {
|
||||
$qb->andWhere('t.project = :project')
|
||||
->setParameter('project', $query->getProject());
|
||||
} elseif (null !== $query->getCustomer()) {
|
||||
$qb->andWhere('p.customer = :customer')
|
||||
->setParameter('customer', $query->getCustomer());
|
||||
}
|
||||
if ($query->hasProjects()) {
|
||||
$qb->andWhere($qb->expr()->in('t.project', ':project'))
|
||||
->setParameter('project', $query->getProjects());
|
||||
} elseif ($query->hasCustomers()) {
|
||||
$qb->andWhere($qb->expr()->in('p.customer', ':customer'))
|
||||
->setParameter('customer', $query->getCustomers());
|
||||
}
|
||||
|
||||
$tags = $query->getTags();
|
||||
|
||||
Reference in New Issue
Block a user