Compare commits
5 Commits
2043e5b643
...
d5a43fc9bb
| Author | SHA1 | Date | |
|---|---|---|---|
| d5a43fc9bb | |||
| 0de2aba538 | |||
| 5ec6e49af2 | |||
| 8d920d5f65 | |||
| 342b0afdbb |
+1
-1
Submodule Inventory_frontend updated: ac860d3165...5ab63e8b27
@@ -0,0 +1,31 @@
|
|||||||
|
<?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 Version20260323141052 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add type column to documents table and classify existing documents by mimeType';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql("DO \$\$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'documents' AND column_name = 'type') THEN ALTER TABLE documents ADD COLUMN type VARCHAR(20) NOT NULL DEFAULT 'documentation'; END IF; END \$\$");
|
||||||
|
$this->addSql("UPDATE documents SET type = 'photo' WHERE mimetype LIKE 'image/%'");
|
||||||
|
$this->addSql("UPDATE documents SET type = 'autre' WHERE type = 'documentation' AND mimetype NOT LIKE 'application/pdf' AND mimetype NOT LIKE 'image/%'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE documents DROP COLUMN IF EXISTS type');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -121,6 +121,7 @@ class DocumentQueryController extends AbstractController
|
|||||||
'composantId' => $document->getComposant()?->getId(),
|
'composantId' => $document->getComposant()?->getId(),
|
||||||
'pieceId' => $document->getPiece()?->getId(),
|
'pieceId' => $document->getPiece()?->getId(),
|
||||||
'productId' => $document->getProduct()?->getId(),
|
'productId' => $document->getProduct()?->getId(),
|
||||||
|
'type' => $document->getType()->value,
|
||||||
'createdAt' => $document->getCreatedAt()->format(DATE_ATOM),
|
'createdAt' => $document->getCreatedAt()->format(DATE_ATOM),
|
||||||
'updatedAt' => $document->getUpdatedAt()->format(DATE_ATOM),
|
'updatedAt' => $document->getUpdatedAt()->format(DATE_ATOM),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Doctrine;
|
||||||
|
|
||||||
|
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
|
||||||
|
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
|
||||||
|
use ApiPlatform\Metadata\Operation;
|
||||||
|
use App\Entity\Composant;
|
||||||
|
use App\Entity\Piece;
|
||||||
|
use App\Entity\Product;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
|
use function in_array;
|
||||||
|
use function is_string;
|
||||||
|
|
||||||
|
final class SearchByNameOrReferenceExtension implements QueryCollectionExtensionInterface
|
||||||
|
{
|
||||||
|
private const SUPPORTED_CLASSES = [
|
||||||
|
Piece::class,
|
||||||
|
Composant::class,
|
||||||
|
Product::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private readonly RequestStack $requestStack,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function applyToCollection(
|
||||||
|
QueryBuilder $queryBuilder,
|
||||||
|
QueryNameGeneratorInterface $queryNameGenerator,
|
||||||
|
string $resourceClass,
|
||||||
|
?Operation $operation = null,
|
||||||
|
array $context = [],
|
||||||
|
): void {
|
||||||
|
if (!in_array($resourceClass, self::SUPPORTED_CLASSES, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = $this->requestStack->getCurrentRequest();
|
||||||
|
if (null === $request) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$q = $request->query->get('q', '');
|
||||||
|
if (!is_string($q) || '' === trim($q)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$escaped = addcslashes(trim($q), '%_');
|
||||||
|
$paramName = $queryNameGenerator->generateParameterName('searchQ');
|
||||||
|
$alias = $queryBuilder->getRootAliases()[0];
|
||||||
|
|
||||||
|
$queryBuilder
|
||||||
|
->andWhere(sprintf('LOWER(%s.name) LIKE :%s OR LOWER(%s.reference) LIKE :%s', $alias, $paramName, $alias, $paramName))
|
||||||
|
->setParameter($paramName, '%'.strtolower($escaped).'%')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,9 +12,11 @@ use ApiPlatform\Metadata\ApiResource;
|
|||||||
use ApiPlatform\Metadata\Delete;
|
use ApiPlatform\Metadata\Delete;
|
||||||
use ApiPlatform\Metadata\Get;
|
use ApiPlatform\Metadata\Get;
|
||||||
use ApiPlatform\Metadata\GetCollection;
|
use ApiPlatform\Metadata\GetCollection;
|
||||||
|
use ApiPlatform\Metadata\Patch;
|
||||||
use ApiPlatform\Metadata\Post;
|
use ApiPlatform\Metadata\Post;
|
||||||
use ApiPlatform\Metadata\Put;
|
use ApiPlatform\Metadata\Put;
|
||||||
use App\Entity\Trait\CuidEntityTrait;
|
use App\Entity\Trait\CuidEntityTrait;
|
||||||
|
use App\Enum\DocumentType;
|
||||||
use App\Repository\DocumentRepository;
|
use App\Repository\DocumentRepository;
|
||||||
use App\State\DocumentUploadProcessor;
|
use App\State\DocumentUploadProcessor;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
@@ -46,6 +48,7 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
|||||||
inputFormats: ['multipart' => ['multipart/form-data']],
|
inputFormats: ['multipart' => ['multipart/form-data']],
|
||||||
),
|
),
|
||||||
new Put(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
new Put(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
||||||
|
new Patch(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
||||||
new Delete(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
new Delete(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
||||||
],
|
],
|
||||||
paginationClientItemsPerPage: true,
|
paginationClientItemsPerPage: true,
|
||||||
@@ -105,6 +108,10 @@ class Document
|
|||||||
#[Groups(['document:list'])]
|
#[Groups(['document:list'])]
|
||||||
private ?Site $site = null;
|
private ?Site $site = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::STRING, length: 20, enumType: DocumentType::class)]
|
||||||
|
#[Groups(['document:list', 'document:read', 'composant:read', 'piece:read', 'product:read'])]
|
||||||
|
private DocumentType $type = DocumentType::DOCUMENTATION;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')]
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')]
|
||||||
#[Groups(['document:list'])]
|
#[Groups(['document:list'])]
|
||||||
private DateTimeImmutable $createdAt;
|
private DateTimeImmutable $createdAt;
|
||||||
@@ -237,4 +244,16 @@ class Document
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getType(): DocumentType
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setType(DocumentType $type): static
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Enum;
|
||||||
|
|
||||||
|
enum DocumentType: string
|
||||||
|
{
|
||||||
|
case DOCUMENTATION = 'documentation';
|
||||||
|
case DEVIS = 'devis';
|
||||||
|
case FACTURE = 'facture';
|
||||||
|
case PLAN = 'plan';
|
||||||
|
case PHOTO = 'photo';
|
||||||
|
case AUTRE = 'autre';
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ namespace App\State;
|
|||||||
use ApiPlatform\Metadata\Operation;
|
use ApiPlatform\Metadata\Operation;
|
||||||
use ApiPlatform\State\ProcessorInterface;
|
use ApiPlatform\State\ProcessorInterface;
|
||||||
use App\Entity\Document;
|
use App\Entity\Document;
|
||||||
|
use App\Enum\DocumentType;
|
||||||
use App\Service\DocumentStorageService;
|
use App\Service\DocumentStorageService;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
@@ -76,6 +77,10 @@ final class DocumentUploadProcessor implements ProcessorInterface
|
|||||||
$document->setMimeType($mimeType);
|
$document->setMimeType($mimeType);
|
||||||
$document->setSize((int) $size);
|
$document->setSize((int) $size);
|
||||||
|
|
||||||
|
$typeValue = $request->request->get('type', 'documentation');
|
||||||
|
$docType = DocumentType::tryFrom($typeValue) ?? DocumentType::DOCUMENTATION;
|
||||||
|
$document->setType($docType);
|
||||||
|
|
||||||
// Handle entity relations from form fields
|
// Handle entity relations from form fields
|
||||||
$this->setRelationsFromRequest($document, $request);
|
$this->setRelationsFromRequest($document, $request);
|
||||||
|
|
||||||
|
|||||||
@@ -290,10 +290,13 @@ abstract class AbstractApiTestCase extends ApiTestCase
|
|||||||
return $machine;
|
return $machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createComposant(string $name = 'Composant Test', ?ModelType $type = null): Composant
|
protected function createComposant(string $name = 'Composant Test', ?string $reference = null, ?ModelType $type = null): Composant
|
||||||
{
|
{
|
||||||
$c = new Composant();
|
$c = new Composant();
|
||||||
$c->setName($name);
|
$c->setName($name);
|
||||||
|
if (null !== $reference) {
|
||||||
|
$c->setReference($reference);
|
||||||
|
}
|
||||||
if (null !== $type) {
|
if (null !== $type) {
|
||||||
$c->setTypeComposant($type);
|
$c->setTypeComposant($type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class ModelTypeSyncControllerTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$this->createComposant('C1', $mt);
|
$this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
$client = $this->createGestionnaireClient();
|
$client = $this->createGestionnaireClient();
|
||||||
$client->request('POST', '/api/model_types/'.$mt->getId().'/sync-preview', [
|
$client->request('POST', '/api/model_types/'.$mt->getId().'/sync-preview', [
|
||||||
@@ -102,7 +102,7 @@ class ModelTypeSyncControllerTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$this->createComposant('C1', $mt);
|
$this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
// Add a skeleton requirement (simulates a PATCH that already happened)
|
// Add a skeleton requirement (simulates a PATCH that already happened)
|
||||||
$em = $this->getEntityManager();
|
$em = $this->getEntityManager();
|
||||||
@@ -131,7 +131,7 @@ class ModelTypeSyncControllerTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
||||||
|
|
||||||
// No skeleton requirements → slot is orphaned
|
// No skeleton requirements → slot is orphaned
|
||||||
@@ -152,7 +152,7 @@ class ModelTypeSyncControllerTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
||||||
|
|
||||||
$client = $this->createGestionnaireClient();
|
$client = $this->createGestionnaireClient();
|
||||||
@@ -194,7 +194,7 @@ class ModelTypeSyncControllerTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$this->createComposant('C1', $mt);
|
$this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
$em = $this->getEntityManager();
|
$em = $this->getEntityManager();
|
||||||
$req = new SkeletonPieceRequirement();
|
$req = new SkeletonPieceRequirement();
|
||||||
|
|||||||
@@ -114,6 +114,58 @@ class DocumentTest extends AbstractApiTestCase
|
|||||||
$this->assertJsonContains(['totalItems' => 1]);
|
$this->assertJsonContains(['totalItems' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPatchType(): void
|
||||||
|
{
|
||||||
|
$doc = $this->createDocumentInDb();
|
||||||
|
|
||||||
|
$client = $this->createGestionnaireClient();
|
||||||
|
$client->request('PATCH', self::iri('documents', $doc->getId()), [
|
||||||
|
'headers' => ['Content-Type' => 'application/merge-patch+json'],
|
||||||
|
'json' => ['type' => 'devis'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['type' => 'devis']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatchNameAndType(): void
|
||||||
|
{
|
||||||
|
$doc = $this->createDocumentInDb();
|
||||||
|
|
||||||
|
$client = $this->createGestionnaireClient();
|
||||||
|
$client->request('PATCH', self::iri('documents', $doc->getId()), [
|
||||||
|
'headers' => ['Content-Type' => 'application/merge-patch+json'],
|
||||||
|
'json' => ['name' => 'new-name', 'type' => 'facture'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['name' => 'new-name', 'type' => 'facture']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetItemIncludesType(): void
|
||||||
|
{
|
||||||
|
$doc = $this->createDocumentInDb();
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', self::iri('documents', $doc->getId()));
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['type' => 'documentation']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testViewerCannotPatch(): void
|
||||||
|
{
|
||||||
|
$doc = $this->createDocumentInDb();
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('PATCH', self::iri('documents', $doc->getId()), [
|
||||||
|
'headers' => ['Content-Type' => 'application/merge-patch+json'],
|
||||||
|
'json' => ['type' => 'devis'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertResponseStatusCodeSame(403);
|
||||||
|
}
|
||||||
|
|
||||||
private function createDocumentInDb(?string $machineId = null, ?string $siteId = null): Document
|
private function createDocumentInDb(?string $machineId = null, ?string $siteId = null): Document
|
||||||
{
|
{
|
||||||
$doc = new Document();
|
$doc = new Document();
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ class MachineTest extends AbstractApiTestCase
|
|||||||
$productType = $this->createModelType('Huile', 'HUILE-SLOT', ModelCategory::PRODUCT);
|
$productType = $this->createModelType('Huile', 'HUILE-SLOT', ModelCategory::PRODUCT);
|
||||||
$compType = $this->createModelType('Pompe', 'POMPE-SLOT', ModelCategory::COMPONENT);
|
$compType = $this->createModelType('Pompe', 'POMPE-SLOT', ModelCategory::COMPONENT);
|
||||||
|
|
||||||
$composant = $this->createComposant('Composant avec slots', $compType);
|
$composant = $this->createComposant('Composant avec slots', null, $compType);
|
||||||
$piece = $this->createPiece('Joint sélectionné', 'REF-JS', $pieceType);
|
$piece = $this->createPiece('Joint sélectionné', 'REF-JS', $pieceType);
|
||||||
$product = $this->createProduct('Huile sélectionnée', 'REF-HS', $productType);
|
$product = $this->createProduct('Huile sélectionnée', 'REF-HS', $productType);
|
||||||
|
|
||||||
|
|||||||
@@ -109,4 +109,66 @@ class FilterTest extends AbstractApiTestCase
|
|||||||
$this->assertResponseIsSuccessful();
|
$this->assertResponseIsSuccessful();
|
||||||
$this->assertJsonContains(['totalItems' => 1]);
|
$this->assertJsonContains(['totalItems' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOrSearchByNameOnPieces(): void
|
||||||
|
{
|
||||||
|
$this->createPiece('Joint torique', 'REF-JT-001');
|
||||||
|
$this->createPiece('Roulement', 'REF-RL-002');
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', '/api/pieces?q=joint');
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['totalItems' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrSearchByReferenceOnPieces(): void
|
||||||
|
{
|
||||||
|
$this->createPiece('Joint torique', 'REF-JT-001');
|
||||||
|
$this->createPiece('Roulement', 'REF-RL-002');
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', '/api/pieces?q=RL-002');
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['totalItems' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrSearchMatchesBothNameAndReference(): void
|
||||||
|
{
|
||||||
|
$this->createComposant('Pompe REF-X', 'REF-POMPE-01');
|
||||||
|
$this->createComposant('Vanne', 'REF-VANNE-01');
|
||||||
|
$this->createComposant('Moteur', 'POMPE-MOTEUR');
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', '/api/composants?q=pompe');
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['totalItems' => 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrSearchEmptyQueryReturnsAll(): void
|
||||||
|
{
|
||||||
|
$this->createProduct('Produit A', 'REF-A');
|
||||||
|
$this->createProduct('Produit B', 'REF-B');
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', '/api/products?q=');
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$data = $client->getResponse()->toArray();
|
||||||
|
$this->assertGreaterThanOrEqual(2, $data['totalItems']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrSearchOnProducts(): void
|
||||||
|
{
|
||||||
|
$this->createProduct('Huile moteur', 'HM-500');
|
||||||
|
$this->createProduct('Graisse', 'GR-100');
|
||||||
|
|
||||||
|
$client = $this->createViewerClient();
|
||||||
|
$client->request('GET', '/api/products?q=HM-500');
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$this->assertJsonContains(['totalItems' => 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$this->createComposant('C1', $mt);
|
$this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
$result = $this->strategy->preview($mt, [
|
$result = $this->strategy->preview($mt, [
|
||||||
'pieces' => [['typePieceId' => $pieceType->getId(), 'position' => 0]],
|
'pieces' => [['typePieceId' => $pieceType->getId(), 'position' => 0]],
|
||||||
@@ -58,7 +58,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
||||||
|
|
||||||
$result = $this->strategy->preview($mt, [
|
$result = $this->strategy->preview($mt, [
|
||||||
@@ -75,7 +75,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
||||||
|
|
||||||
$result = $this->strategy->preview($mt, [
|
$result = $this->strategy->preview($mt, [
|
||||||
@@ -92,7 +92,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
$em = $this->getEntityManager();
|
$em = $this->getEntityManager();
|
||||||
$req = new SkeletonPieceRequirement();
|
$req = new SkeletonPieceRequirement();
|
||||||
@@ -115,7 +115,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$piece = $this->createPiece('P1', 'P1-REF', $pieceType);
|
$piece = $this->createPiece('P1', 'P1-REF', $pieceType);
|
||||||
$slot = $this->createComposantPieceSlot($composant, $pieceType, $piece, 5, 0);
|
$slot = $this->createComposantPieceSlot($composant, $pieceType, $piece, 5, 0);
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
$this->createComposantPieceSlot($composant, $pieceType, null, 1, 0);
|
||||||
|
|
||||||
// No skeleton requirements -> slot should be deleted
|
// No skeleton requirements -> slot should be deleted
|
||||||
@@ -158,7 +158,7 @@ class ComposantSyncStrategyTest extends AbstractApiTestCase
|
|||||||
{
|
{
|
||||||
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
$mt = $this->createModelType('Comp Cat', 'CC-001', ModelCategory::COMPONENT);
|
||||||
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
$pieceType = $this->createModelType('Piece Type', 'PT-001', ModelCategory::PIECE);
|
||||||
$composant = $this->createComposant('C1', $mt);
|
$composant = $this->createComposant('C1', null, $mt);
|
||||||
|
|
||||||
$em = $this->getEntityManager();
|
$em = $this->getEntityManager();
|
||||||
$req = new SkeletonPieceRequirement();
|
$req = new SkeletonPieceRequirement();
|
||||||
|
|||||||
Reference in New Issue
Block a user