| @@ -1000,7 +1000,7 @@ paths: | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: createdBy | |||
| name: name | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| @@ -1012,7 +1012,19 @@ paths: | |||
| explode: 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 | |||
| description: '' | |||
| required: false | |||
| @@ -1026,7 +1038,7 @@ paths: | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: partner | |||
| name: product | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| @@ -1038,7 +1050,7 @@ paths: | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: 'partner[]' | |||
| name: 'product[]' | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| @@ -1052,7 +1064,7 @@ paths: | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: product | |||
| name: 'order[name]' | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| @@ -1060,22 +1072,41 @@ paths: | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| enum: | |||
| - asc | |||
| - desc | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: 'product[]' | |||
| name: 'order[partner.name]' | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: array | |||
| items: | |||
| type: string | |||
| type: string | |||
| enum: | |||
| - asc | |||
| - desc | |||
| 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 | |||
| deprecated: false | |||
| post: | |||
| @@ -1553,6 +1584,51 @@ paths: | |||
| style: form | |||
| explode: true | |||
| 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 | |||
| post: | |||
| operationId: api_partner_follows_post | |||
| @@ -1838,6 +1914,18 @@ paths: | |||
| style: form | |||
| explode: true | |||
| 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]' | |||
| in: query | |||
| @@ -1854,7 +1942,37 @@ paths: | |||
| explode: 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 | |||
| description: '' | |||
| required: false | |||
| @@ -1862,6 +1980,9 @@ paths: | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| enum: | |||
| - asc | |||
| - desc | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| @@ -2086,6 +2207,18 @@ paths: | |||
| style: form | |||
| explode: 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]' | |||
| in: query | |||
| @@ -3113,6 +3246,96 @@ paths: | |||
| style: form | |||
| explode: true | |||
| 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 | |||
| post: | |||
| operationId: api_sales_post | |||
| @@ -4127,6 +4350,36 @@ paths: | |||
| style: form | |||
| explode: 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 | |||
| post: | |||
| operationId: api_users_post | |||
| @@ -7,6 +7,7 @@ | |||
| namespace App\ApiResource; | |||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||
| use ApiPlatform\Doctrine\Orm\State\Options; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| @@ -53,7 +54,16 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| processor: EntityClassDtoStateProcessor::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 | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -17,6 +17,7 @@ use ApiPlatform\Metadata\ApiResource; | |||
| use App\Entity\MediaObject; | |||
| use App\Entity\Partner; | |||
| use App\Enum\PartnerType; | |||
| use App\Filter\PartnerUnassignedFilter; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use ApiPlatform\Metadata\Delete; | |||
| @@ -51,6 +52,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| stateOptions: new Options(entityClass: Partner::class) | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['type' => 'exact', 'name' => 'ipartial'])] | |||
| #[ApiFilter(PartnerUnassignedFilter::class)] | |||
| #[ApiFilter(OrderFilter::class, properties: ['name', 'city', 'website'], arguments: ['orderParameterName' => 'order'])] | |||
| class PartnerApi | |||
| { | |||
| @@ -7,6 +7,7 @@ | |||
| namespace App\ApiResource; | |||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||
| use ApiPlatform\Doctrine\Orm\State\Options; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| @@ -50,6 +51,12 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| 'user' => 'exact', | |||
| 'partner.type' => 'exact' | |||
| ])] | |||
| #[ApiFilter(OrderFilter::class, properties: [ | |||
| 'product.name', | |||
| 'partner.name', | |||
| 'partner.city', | |||
| 'partner.website' | |||
| ], arguments: ['orderParameterName' => 'order'])] | |||
| class PartnerFollowApi implements OwnerInterface | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -53,8 +53,13 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| 'product.name' => 'ipartial', | |||
| 'partner.type' => 'exact' | |||
| ])] | |||
| #[ApiFilter(OrderFilter::class, properties: ['product.name'], arguments: ['orderParameterName' => 'order'])] | |||
| #[ApiFilter(PartnerProductUnassignedFilter::class)] | |||
| #[ApiFilter(OrderFilter::class, properties: [ | |||
| 'product.name', | |||
| 'partner.name', | |||
| 'partner.city', | |||
| 'partner.website' | |||
| ], arguments: ['orderParameterName' => 'order'])] | |||
| class PartnerProductApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -7,6 +7,7 @@ | |||
| namespace App\ApiResource; | |||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||
| use ApiPlatform\Doctrine\Orm\State\Options; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| @@ -48,7 +49,19 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| processor: EntityClassDtoStateProcessor::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 | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -7,6 +7,7 @@ | |||
| namespace App\ApiResource; | |||
| use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; | |||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||
| use ApiPlatform\Doctrine\Orm\State\Options; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| @@ -49,6 +50,11 @@ use Symfony\Component\Validator\Constraints as Assert; | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | |||
| #[ApiFilter(UserNameFilter::class)] | |||
| #[ApiFilter(OrderFilter::class, properties: [ | |||
| 'firstName', | |||
| 'lastName', | |||
| ], arguments: ['orderParameterName' => 'order'])] | |||
| class UserApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -49,7 +49,12 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| 'user' => '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 | |||
| { | |||
| #[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', | |||
| ], | |||
| ], | |||
| ]; | |||
| } | |||
| } | |||