| @@ -586,6 +586,18 @@ paths: | |||
| style: form | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: nameSearch | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| post: | |||
| operationId: api_contacts_post | |||
| @@ -1811,6 +1823,18 @@ paths: | |||
| style: form | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: productPartnerUnassigned | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| post: | |||
| operationId: api_partner_products_post | |||
| @@ -2633,6 +2657,18 @@ paths: | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: partnerIdUnassigned | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: 'order[name]' | |||
| in: query | |||
| @@ -4023,6 +4059,18 @@ paths: | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: nameSearch | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| post: | |||
| operationId: api_users_post | |||
| @@ -6657,6 +6705,16 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contact: | |||
| readOnly: true | |||
| description: '?ContactApi' | |||
| $ref: '#/components/schemas/Contact' | |||
| contactIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactType: | |||
| type: string | |||
| enum: | |||
| @@ -6701,6 +6759,16 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contact: | |||
| readOnly: true | |||
| description: '?ContactApi' | |||
| $ref: '#/components/schemas/Contact.jsonhal' | |||
| contactIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactType: | |||
| type: string | |||
| enum: | |||
| @@ -6759,6 +6827,16 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contact: | |||
| readOnly: true | |||
| description: '?ContactApi' | |||
| $ref: '#/components/schemas/Contact.jsonld' | |||
| contactIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactType: | |||
| type: string | |||
| enum: | |||
| @@ -0,0 +1,35 @@ | |||
| <?php | |||
| declare(strict_types=1); | |||
| namespace DoctrineMigrations; | |||
| use Doctrine\DBAL\Schema\Schema; | |||
| use Doctrine\Migrations\AbstractMigration; | |||
| /** | |||
| * Auto-generated Migration: Please modify to your needs! | |||
| */ | |||
| final class Version20240607125011 extends AbstractMigration | |||
| { | |||
| public function getDescription(): string | |||
| { | |||
| return ''; | |||
| } | |||
| public function up(Schema $schema): void | |||
| { | |||
| // this up() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('ALTER TABLE task_note ADD contact_id INT DEFAULT NULL'); | |||
| $this->addSql('ALTER TABLE task_note ADD CONSTRAINT FK_BC0E6E6FE7A1254A FOREIGN KEY (contact_id) REFERENCES contact (id)'); | |||
| $this->addSql('CREATE INDEX IDX_BC0E6E6FE7A1254A ON task_note (contact_id)'); | |||
| } | |||
| public function down(Schema $schema): void | |||
| { | |||
| // this down() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('ALTER TABLE task_note DROP FOREIGN KEY FK_BC0E6E6FE7A1254A'); | |||
| $this->addSql('DROP INDEX IDX_BC0E6E6FE7A1254A ON task_note'); | |||
| $this->addSql('ALTER TABLE task_note DROP contact_id'); | |||
| } | |||
| } | |||
| @@ -14,9 +14,9 @@ use ApiPlatform\Metadata\ApiProperty; | |||
| use ApiPlatform\Metadata\ApiResource; | |||
| use App\Entity\Contact; | |||
| use App\Entity\MediaObject; | |||
| use App\Filter\ContactNameFilter; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use ApiPlatform\Metadata\Delete; | |||
| use ApiPlatform\Metadata\Get; | |||
| use ApiPlatform\Metadata\GetCollection; | |||
| use ApiPlatform\Metadata\Patch; | |||
| @@ -51,6 +51,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| stateOptions: new Options(entityClass: Contact::class), | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['partner' => 'exact'])] | |||
| #[ApiFilter(ContactNameFilter::class)] | |||
| class ContactApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -13,6 +13,7 @@ use ApiPlatform\Metadata\ApiFilter; | |||
| use ApiPlatform\Metadata\ApiProperty; | |||
| use ApiPlatform\Metadata\ApiResource; | |||
| use App\Entity\PartnerProduct; | |||
| use App\Filter\PartnerProductUnassignedFilter; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use ApiPlatform\Metadata\Delete; | |||
| @@ -38,6 +39,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| security: 'is_granted("ROLE_USER")', | |||
| ) | |||
| ], | |||
| order: ['product.name' => 'ASC'], | |||
| security: 'is_granted("ROLE_USER")', | |||
| provider: EntityToDtoStateProvider::class, | |||
| processor: EntityClassDtoStateProcessor::class, | |||
| @@ -50,6 +52,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| 'product.name' => 'ipartial', | |||
| 'partner.type' => 'exact' | |||
| ])] | |||
| #[ApiFilter(PartnerProductUnassignedFilter::class)] | |||
| class PartnerProductApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -16,6 +16,7 @@ use ApiPlatform\Metadata\ApiProperty; | |||
| use ApiPlatform\Metadata\ApiResource; | |||
| use App\Entity\MediaObject; | |||
| use App\Entity\Product; | |||
| use App\Filter\ProductUnassignedFilter; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use ApiPlatform\Metadata\Delete; | |||
| @@ -51,6 +52,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['name' => 'ipartial'])] | |||
| #[ApiFilter(ProductUnassignedFilter::class)] | |||
| #[ApiFilter(OrderFilter::class, properties: ['name'], arguments: ['orderParameterName' => 'order'])] | |||
| class ProductApi | |||
| { | |||
| @@ -76,6 +76,24 @@ class TaskNoteApi implements OwnerInterface | |||
| #[NotBlank] | |||
| public ?TaskApi $taskIri = null; | |||
| /** | |||
| * @var $owner ?ContactApi | |||
| */ | |||
| #[ApiProperty( | |||
| writable: false, | |||
| readableLink: true, | |||
| writableLink: false, | |||
| builtinTypes: [ | |||
| new Type( | |||
| 'object', | |||
| class: ContactApi::class, | |||
| ) | |||
| ] | |||
| )] | |||
| public ?ContactApi $contact = null; | |||
| public ?ContactApi $contactIri = null; | |||
| #[NotBlank] | |||
| public TaskNoteContactType $contactType; | |||
| @@ -18,6 +18,7 @@ use ApiPlatform\Metadata\Patch; | |||
| use ApiPlatform\Metadata\Post; | |||
| use App\Entity\MediaObject; | |||
| use App\Entity\User; | |||
| use App\Filter\UserNameFilter; | |||
| use App\Interface\AdminOrOwnerInterface; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| @@ -47,6 +48,7 @@ use Symfony\Component\Validator\Constraints as Assert; | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | |||
| #[ApiFilter(UserNameFilter::class)] | |||
| class UserApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -54,6 +54,9 @@ class Contact | |||
| #[ORM\OneToMany(mappedBy: 'contact', targetEntity: ContactPartnerProduct::class)] | |||
| private Collection $contactPartnerProducts; | |||
| #[ORM\OneToMany(mappedBy: 'contact', targetEntity: TaskNote::class)] | |||
| private Collection $taskNotes; | |||
| public function __construct(Partner $partner, User $createdBy) | |||
| { | |||
| $this->partner = $partner; | |||
| @@ -61,6 +64,7 @@ class Contact | |||
| $this->createdAt = new \DateTimeImmutable(); | |||
| $this->posts = new ArrayCollection(); | |||
| $this->contactPartnerProducts = new ArrayCollection(); | |||
| $this->taskNotes = new ArrayCollection(); | |||
| } | |||
| public function getId(): ?int | |||
| @@ -241,4 +245,34 @@ class Contact | |||
| return $this; | |||
| } | |||
| /** | |||
| * @return Collection<int, TaskNote> | |||
| */ | |||
| public function getTaskNotes(): Collection | |||
| { | |||
| return $this->taskNotes; | |||
| } | |||
| public function addTaskNote(TaskNote $taskNote): static | |||
| { | |||
| if (!$this->taskNotes->contains($taskNote)) { | |||
| $this->taskNotes->add($taskNote); | |||
| $taskNote->setContact($this); | |||
| } | |||
| return $this; | |||
| } | |||
| public function removeTaskNote(TaskNote $taskNote): static | |||
| { | |||
| if ($this->taskNotes->removeElement($taskNote)) { | |||
| // set the owning side to null (unless already changed) | |||
| if ($taskNote->getContact() === $this) { | |||
| $taskNote->setContact(null); | |||
| } | |||
| } | |||
| return $this; | |||
| } | |||
| } | |||
| @@ -26,12 +26,17 @@ class TaskNote | |||
| #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')] | |||
| private ?Task $task = null; | |||
| #[ORM\ManyToOne(inversedBy: 'taskNotes')] | |||
| private ?Contact $contact = null; | |||
| #[ORM\Column(type: 'string', enumType: TaskNoteContactType::class)] | |||
| private TaskNoteContactType $type; | |||
| #[ORM\Column] | |||
| private ?\DateTimeImmutable $createdAt = null; | |||
| public function __construct(User $owner, Task $task) | |||
| { | |||
| $this->owner = $owner; | |||
| @@ -101,4 +106,16 @@ class TaskNote | |||
| return $this; | |||
| } | |||
| public function getContact(): ?Contact | |||
| { | |||
| return $this->contact; | |||
| } | |||
| public function setContact(?Contact $contact): static | |||
| { | |||
| $this->contact = $contact; | |||
| return $this; | |||
| } | |||
| } | |||
| @@ -53,6 +53,7 @@ final class TaskNoteFactory extends ModelFactory | |||
| 'owner' => UserFactory::random(), | |||
| 'task' => TaskFactory::random(), | |||
| 'type' => self::faker()->randomElement(TaskNoteContactType::cases()), | |||
| 'contact' => ContactFactory::random() | |||
| ]; | |||
| } | |||
| @@ -0,0 +1,63 @@ | |||
| <?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\QueryBuilder; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| use Doctrine\Persistence\ManagerRegistry; | |||
| use Psr\Log\LoggerInterface; | |||
| #[ApiFilter(ContactNameFilter::class)] | |||
| class ContactNameFilter extends AbstractFilter | |||
| { | |||
| public const FILTER_NAME = "nameSearch"; | |||
| 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 User-Tabelle | |||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||
| // Case-insensitive Suche nach Vorname oder Nachname, der den Wert enthält | |||
| $queryBuilder->andWhere( | |||
| $queryBuilder->expr()->orX( | |||
| $queryBuilder->expr()->like('LOWER(' . $rootAlias . '.firstName)', ':searchTerm'), | |||
| $queryBuilder->expr()->like('LOWER(' . $rootAlias . '.lastName)', ':searchTerm') | |||
| ) | |||
| ) | |||
| ->setParameter('searchTerm', '%' . strtolower($value) . '%'); | |||
| } | |||
| } | |||
| public function getDescription(string $resourceClass): array | |||
| { | |||
| return [ | |||
| self::FILTER_NAME => [ | |||
| 'property' => self::FILTER_NAME, | |||
| 'type' => 'string', | |||
| 'required' => false, | |||
| 'swagger' => [ | |||
| 'description' => 'Filter users that have the search term in their first name or last name', | |||
| 'type' => 'string', | |||
| ], | |||
| ], | |||
| ]; | |||
| } | |||
| } | |||
| @@ -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(PartnerProductUnassignedFilter::class)] | |||
| class PartnerProductUnassignedFilter extends AbstractFilter | |||
| { | |||
| public const FILTER_NAME = "productPartnerUnassigned"; | |||
| 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 !== 'unassignedContactId') { | |||
| return; | |||
| } | |||
| if ($value) { | |||
| // Alias für das Produkt | |||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||
| // Join mit PartnerProduct | |||
| $queryBuilder->leftJoin("$rootAlias.contactPartnerProducts", 'cpp', Join::WITH, 'cpp.contact = :contact_id') | |||
| ->andWhere('cpp.partnerProduct IS NULL') | |||
| ->setParameter('contact_id', $value); | |||
| } | |||
| } | |||
| public function getDescription(string $resourceClass): array | |||
| { | |||
| return [ | |||
| self::FILTER_NAME => [ | |||
| 'property' => self::FILTER_NAME, | |||
| 'type' => 'boolean', | |||
| 'required' => false, | |||
| 'swagger' => [ | |||
| 'description' => 'Filter partner products that are not assigned to a given contact id', | |||
| 'type' => 'integer', // Hier wird der Datentyp auf 'integer' gesetzt | |||
| 'format' => 'contact_id', // Optional: Format 'partner_id' angeben, um klarzustellen, dass es sich um eine Partner-ID handelt | |||
| ], | |||
| ], | |||
| ]; | |||
| } | |||
| } | |||
| @@ -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(ProductUnassignedFilter::class)] | |||
| class ProductUnassignedFilter extends AbstractFilter | |||
| { | |||
| public const FILTER_NAME = "partnerIdUnassigned"; | |||
| 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 !== 'unassignedPartnerId') { | |||
| return; | |||
| } | |||
| if ($value) { | |||
| // Alias für das Produkt | |||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||
| // Join mit PartnerProduct | |||
| $queryBuilder->leftJoin("$rootAlias.partnerProducts", 'pp', Join::WITH, 'pp.partner = :partner_id') | |||
| ->andWhere('pp.product IS NULL') | |||
| ->setParameter('partner_id', $value); | |||
| } | |||
| } | |||
| public function getDescription(string $resourceClass): array | |||
| { | |||
| return [ | |||
| self::FILTER_NAME => [ | |||
| 'property' => self::FILTER_NAME, | |||
| 'type' => 'boolean', | |||
| 'required' => false, | |||
| 'swagger' => [ | |||
| 'description' => 'Filter products that are not assigned to a given partner id', | |||
| 'type' => 'integer', // Hier wird der Datentyp auf 'integer' gesetzt | |||
| 'format' => 'partner_id', // Optional: Format 'partner_id' angeben, um klarzustellen, dass es sich um eine Partner-ID handelt | |||
| ], | |||
| ], | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| <?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(UserNameFilter::class)] | |||
| class UserNameFilter extends AbstractFilter | |||
| { | |||
| public const FILTER_NAME = "nameSearch"; | |||
| 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 User-Tabelle | |||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||
| // Case-insensitive Suche nach Vorname oder Nachname, der den Wert enthält | |||
| $queryBuilder->andWhere( | |||
| $queryBuilder->expr()->orX( | |||
| $queryBuilder->expr()->like('LOWER(' . $rootAlias . '.firstName)', ':searchTerm'), | |||
| $queryBuilder->expr()->like('LOWER(' . $rootAlias . '.lastName)', ':searchTerm') | |||
| ) | |||
| ) | |||
| ->setParameter('searchTerm', '%' . strtolower($value) . '%'); | |||
| } | |||
| } | |||
| public function getDescription(string $resourceClass): array | |||
| { | |||
| return [ | |||
| self::FILTER_NAME => [ | |||
| 'property' => 'firstLastName', | |||
| 'type' => 'string', | |||
| 'required' => false, | |||
| 'swagger' => [ | |||
| 'description' => 'Filter users that have the search term in their first name or last name', | |||
| 'type' => 'string', | |||
| ], | |||
| ], | |||
| ]; | |||
| } | |||
| } | |||
| @@ -3,6 +3,7 @@ | |||
| namespace App\Mapper; | |||
| use App\ApiResource\TaskNoteApi; | |||
| use App\Entity\Contact; | |||
| use App\Entity\Task; | |||
| use App\Entity\TaskNote; | |||
| use App\Entity\User; | |||
| @@ -59,6 +60,12 @@ class TaskNoteApiToEntityMapper implements MapperInterface | |||
| assert($entity instanceof TaskNote); | |||
| $entity->setMessage($dto->message); | |||
| $entity->setType($dto->contactType); | |||
| if ($dto->contactIri) { | |||
| $entity->setContact($this->microMapper->map($dto->contactIri, Contact::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ])); | |||
| } | |||
| return $entity; | |||
| } | |||
| @@ -2,6 +2,7 @@ | |||
| namespace App\Mapper; | |||
| use App\ApiResource\ContactApi; | |||
| use App\ApiResource\TaskApi; | |||
| use App\ApiResource\TaskNoteApi; | |||
| use App\ApiResource\UserApi; | |||
| @@ -46,6 +47,14 @@ class TaskNoteEntityToApiMapper implements MapperInterface | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| $dto->contact = $this->microMapper->map($entity->getContact(), ContactApi::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| $dto->contactIri = $this->microMapper->map($entity->getContact(), ContactApi::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| $dto->contactType = $entity->getType(); | |||
| $dto->createdAt = $entity->getCreatedAt(); | |||