| @@ -1000,7 +1000,7 @@ paths: | |||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: createdBy | |||||
| name: name | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1012,7 +1012,19 @@ paths: | |||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: 'createdBy[]' | |||||
| name: partner | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'partner[]' | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1026,7 +1038,7 @@ paths: | |||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: partner | |||||
| name: product | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1038,7 +1050,7 @@ paths: | |||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: 'partner[]' | |||||
| name: 'product[]' | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1052,7 +1064,7 @@ paths: | |||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: product | |||||
| name: 'order[name]' | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1060,22 +1072,41 @@ paths: | |||||
| allowEmptyValue: true | allowEmptyValue: true | ||||
| schema: | schema: | ||||
| type: string | type: string | ||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: 'product[]' | |||||
| name: 'order[partner.name]' | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| deprecated: false | deprecated: false | ||||
| allowEmptyValue: true | allowEmptyValue: true | ||||
| schema: | schema: | ||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | style: form | ||||
| explode: true | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[product.name]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | allowReserved: false | ||||
| deprecated: false | deprecated: false | ||||
| post: | post: | ||||
| @@ -1553,6 +1584,51 @@ paths: | |||||
| style: form | style: form | ||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: 'order[partner.name]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[partner.city]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[partner.website]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | deprecated: false | ||||
| post: | post: | ||||
| operationId: api_partner_follows_post | operationId: api_partner_follows_post | ||||
| @@ -1838,6 +1914,18 @@ paths: | |||||
| style: form | style: form | ||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: excludeContactId | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | - | ||||
| name: 'order[product.name]' | name: 'order[product.name]' | ||||
| in: query | in: query | ||||
| @@ -1854,7 +1942,37 @@ paths: | |||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | - | ||||
| name: excludeContactId | |||||
| name: 'order[partner.name]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[partner.city]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[partner.website]' | |||||
| in: query | in: query | ||||
| description: '' | description: '' | ||||
| required: false | required: false | ||||
| @@ -1862,6 +1980,9 @@ paths: | |||||
| allowEmptyValue: true | allowEmptyValue: true | ||||
| schema: | schema: | ||||
| type: string | type: string | ||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| @@ -2086,6 +2207,18 @@ paths: | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: excludeProductId | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | - | ||||
| name: 'order[name]' | name: 'order[name]' | ||||
| in: query | in: query | ||||
| @@ -3113,6 +3246,96 @@ paths: | |||||
| style: form | style: form | ||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: 'order[owner.lastName]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[partner.name]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[product.name]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[turnover]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[profit]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[createdAt]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | deprecated: false | ||||
| post: | post: | ||||
| operationId: api_sales_post | operationId: api_sales_post | ||||
| @@ -4127,6 +4350,36 @@ paths: | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: 'order[firstName]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'order[lastName]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| enum: | |||||
| - asc | |||||
| - desc | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | deprecated: false | ||||
| post: | post: | ||||
| operationId: api_users_post | operationId: api_users_post | ||||
| @@ -7,6 +7,7 @@ | |||||
| namespace App\ApiResource; | namespace App\ApiResource; | ||||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | ||||
| use ApiPlatform\Doctrine\Orm\State\Options; | use ApiPlatform\Doctrine\Orm\State\Options; | ||||
| use ApiPlatform\Metadata\ApiFilter; | use ApiPlatform\Metadata\ApiFilter; | ||||
| @@ -53,7 +54,16 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| processor: EntityClassDtoStateProcessor::class, | processor: EntityClassDtoStateProcessor::class, | ||||
| stateOptions: new Options(entityClass: Document::class), | stateOptions: new Options(entityClass: Document::class), | ||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['createdBy' => 'exact', 'partner' => 'exact', 'product' => 'exact'])] | |||||
| #[ApiFilter(SearchFilter::class, properties: [ | |||||
| 'name' => 'ipartial', | |||||
| 'partner' => 'exact', | |||||
| 'product' => 'exact', | |||||
| ])] | |||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'name', | |||||
| 'partner.name', | |||||
| 'product.name', | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class DocumentApi | class DocumentApi | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -17,6 +17,7 @@ use ApiPlatform\Metadata\ApiResource; | |||||
| use App\Entity\MediaObject; | use App\Entity\MediaObject; | ||||
| use App\Entity\Partner; | use App\Entity\Partner; | ||||
| use App\Enum\PartnerType; | use App\Enum\PartnerType; | ||||
| use App\Filter\PartnerUnassignedFilter; | |||||
| use App\State\EntityClassDtoStateProcessor; | use App\State\EntityClassDtoStateProcessor; | ||||
| use App\State\EntityToDtoStateProvider; | use App\State\EntityToDtoStateProvider; | ||||
| use ApiPlatform\Metadata\Delete; | use ApiPlatform\Metadata\Delete; | ||||
| @@ -51,6 +52,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| stateOptions: new Options(entityClass: Partner::class) | stateOptions: new Options(entityClass: Partner::class) | ||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['type' => 'exact', 'name' => 'ipartial'])] | #[ApiFilter(SearchFilter::class, properties: ['type' => 'exact', 'name' => 'ipartial'])] | ||||
| #[ApiFilter(PartnerUnassignedFilter::class)] | |||||
| #[ApiFilter(OrderFilter::class, properties: ['name', 'city', 'website'], arguments: ['orderParameterName' => 'order'])] | #[ApiFilter(OrderFilter::class, properties: ['name', 'city', 'website'], arguments: ['orderParameterName' => 'order'])] | ||||
| class PartnerApi | class PartnerApi | ||||
| { | { | ||||
| @@ -7,6 +7,7 @@ | |||||
| namespace App\ApiResource; | namespace App\ApiResource; | ||||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | ||||
| use ApiPlatform\Doctrine\Orm\State\Options; | use ApiPlatform\Doctrine\Orm\State\Options; | ||||
| use ApiPlatform\Metadata\ApiFilter; | use ApiPlatform\Metadata\ApiFilter; | ||||
| @@ -50,6 +51,12 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| 'user' => 'exact', | 'user' => 'exact', | ||||
| 'partner.type' => 'exact' | 'partner.type' => 'exact' | ||||
| ])] | ])] | ||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'product.name', | |||||
| 'partner.name', | |||||
| 'partner.city', | |||||
| 'partner.website' | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class PartnerFollowApi implements OwnerInterface | class PartnerFollowApi implements OwnerInterface | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -53,8 +53,13 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| 'product.name' => 'ipartial', | 'product.name' => 'ipartial', | ||||
| 'partner.type' => 'exact' | 'partner.type' => 'exact' | ||||
| ])] | ])] | ||||
| #[ApiFilter(OrderFilter::class, properties: ['product.name'], arguments: ['orderParameterName' => 'order'])] | |||||
| #[ApiFilter(PartnerProductUnassignedFilter::class)] | #[ApiFilter(PartnerProductUnassignedFilter::class)] | ||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'product.name', | |||||
| 'partner.name', | |||||
| 'partner.city', | |||||
| 'partner.website' | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class PartnerProductApi | class PartnerProductApi | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -7,6 +7,7 @@ | |||||
| namespace App\ApiResource; | namespace App\ApiResource; | ||||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | ||||
| use ApiPlatform\Doctrine\Orm\State\Options; | use ApiPlatform\Doctrine\Orm\State\Options; | ||||
| use ApiPlatform\Metadata\ApiFilter; | use ApiPlatform\Metadata\ApiFilter; | ||||
| @@ -48,7 +49,19 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| processor: EntityClassDtoStateProcessor::class, | processor: EntityClassDtoStateProcessor::class, | ||||
| stateOptions: new Options(entityClass: Sale::class), | stateOptions: new Options(entityClass: Sale::class), | ||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['owner' => 'exact', 'partner' => 'exact', 'product' => 'exact'])] | |||||
| #[ApiFilter(SearchFilter::class, properties: [ | |||||
| 'owner' => 'exact', | |||||
| 'partner' => 'exact', | |||||
| 'product' => 'exact' | |||||
| ])] | |||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'owner.lastName', | |||||
| 'partner.name', | |||||
| 'product.name', | |||||
| 'turnover', | |||||
| 'profit', | |||||
| 'createdAt' | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class SaleApi implements OwnerInterface | class SaleApi implements OwnerInterface | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -7,6 +7,7 @@ | |||||
| namespace App\ApiResource; | namespace App\ApiResource; | ||||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | ||||
| use ApiPlatform\Doctrine\Orm\State\Options; | use ApiPlatform\Doctrine\Orm\State\Options; | ||||
| use ApiPlatform\Metadata\ApiFilter; | use ApiPlatform\Metadata\ApiFilter; | ||||
| @@ -49,6 +50,11 @@ use Symfony\Component\Validator\Constraints as Assert; | |||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | ||||
| #[ApiFilter(UserNameFilter::class)] | #[ApiFilter(UserNameFilter::class)] | ||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'firstName', | |||||
| 'lastName', | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class UserApi | class UserApi | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -49,7 +49,12 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| 'user' => 'exact', | 'user' => 'exact', | ||||
| 'product' => 'exact' | 'product' => 'exact' | ||||
| ])] | ])] | ||||
| #[ApiFilter(OrderFilter::class, properties: ['product.name'], arguments: ['orderParameterName' => 'order'])] | |||||
| #[ApiFilter(OrderFilter::class, properties: [ | |||||
| 'product.name', | |||||
| 'partner.name', | |||||
| 'partner.city', | |||||
| 'partner.website' | |||||
| ], arguments: ['orderParameterName' => 'order'])] | |||||
| class UserProductApi implements OwnerInterface | class UserProductApi implements OwnerInterface | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| @@ -0,0 +1,61 @@ | |||||
| <?php | |||||
| /** | |||||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||||
| * @date 10.06.24 | |||||
| */ | |||||
| namespace App\Filter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; | |||||
| use Doctrine\ORM\Query\Expr\Join; | |||||
| use Doctrine\ORM\QueryBuilder; | |||||
| use ApiPlatform\Metadata\ApiFilter; | |||||
| use Doctrine\Persistence\ManagerRegistry; | |||||
| use Psr\Log\LoggerInterface; | |||||
| #[ApiFilter(PartnerUnassignedFilter::class)] | |||||
| class PartnerUnassignedFilter extends AbstractFilter | |||||
| { | |||||
| public const FILTER_NAME = "excludeProductId"; | |||||
| public function __construct(ManagerRegistry $managerRegistry, ?LoggerInterface $logger = null, ?array $properties = null) | |||||
| { | |||||
| parent::__construct($managerRegistry, $logger, $properties); | |||||
| } | |||||
| protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?\ApiPlatform\Metadata\Operation $operation = null, array $context = []): void | |||||
| { | |||||
| if ($property !== self::FILTER_NAME) { | |||||
| return; | |||||
| } | |||||
| if ($value) { | |||||
| // Alias für das Produkt | |||||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||||
| // Join mit PartnerProduct | |||||
| $queryBuilder->leftJoin("$rootAlias.partnerProducts", 'pp', Join::WITH, 'pp.product = :product_id') | |||||
| ->andWhere('pp.product IS NULL') | |||||
| ->setParameter('product_id', $value); | |||||
| } | |||||
| } | |||||
| public function getDescription(string $resourceClass): array | |||||
| { | |||||
| return [ | |||||
| self::FILTER_NAME => [ | |||||
| 'property' => self::FILTER_NAME, | |||||
| 'type' => 'boolean', | |||||
| 'required' => false, | |||||
| 'swagger' => [ | |||||
| 'description' => 'Filter partners that are not assigned to a given product id', | |||||
| 'type' => 'integer', | |||||
| 'format' => 'partner_id', | |||||
| ], | |||||
| ], | |||||
| ]; | |||||
| } | |||||
| } | |||||