Prechádzať zdrojové kódy

fix the details and implement a new endpoints

gdias 1 týždeň pred
rodič
commit
b839915a20

+ 36 - 0
controllers/CompanySummaryController.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\CompanySummaryModel;
+use Psr\Http\Message\ServerRequestInterface;
+
+class CompanySummaryController
+{
+    private CompanySummaryModel $summaryModel;
+
+    public function __construct()
+    {
+        $this->summaryModel = new CompanySummaryModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+        if ($companyId <= 0) {
+            return ResponseLib::sendFail('Authenticated company not found', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        try {
+            $summary = $this->summaryModel->getSummary($companyId);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to fetch company summary: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return ResponseLib::sendOk([
+            'company_id' => $companyId,
+            'summary' => $summary,
+        ], 'S_COMPANY_SUMMARY');
+    }
+}

+ 27 - 0
controllers/OrderbookTransferController.php

@@ -3,9 +3,11 @@
 namespace Controllers;
 
 use Libs\ResponseLib;
+use Models\CprModel;
 use Models\OrderbookModel;
 use Models\OrderbookTransferModel;
 use Models\PaymentModel;
+use Models\TokenModel;
 use Models\WalletModel;
 use Psr\Http\Message\ServerRequestInterface;
 use Respect\Validation\Exceptions\ValidationException;
@@ -18,6 +20,8 @@ class OrderbookTransferController
     private WalletModel $walletModel;
     private OrderbookTransferModel $orderbookTransferModel;
     private TokenTransferService $tokenTransferService;
+    private TokenModel $tokenModel;
+    private CprModel $cprModel;
 
     public function __construct()
     {
@@ -25,6 +29,8 @@ class OrderbookTransferController
         $this->walletModel = new WalletModel();
         $this->orderbookTransferModel = new OrderbookTransferModel();
         $this->tokenTransferService = new TokenTransferService();
+        $this->tokenModel = new TokenModel();
+        $this->cprModel = new CprModel();
     }
 
     public function __invoke(ServerRequestInterface $request)
@@ -71,6 +77,26 @@ class OrderbookTransferController
             return ResponseLib::sendFail('Orderbook não encontrado', ['token_external_id' => $tokenExternalId], 'E_NOT_FOUND')->withStatus(404);
         }
 
+        $tokenId = (int)($orderbook['token_id'] ?? 0);
+        if ($tokenId <= 0) {
+            return ResponseLib::sendFail('Orderbook sem token associado', [], 'E_ORDERBOOK_TOKEN')->withStatus(409);
+        }
+
+        try {
+            $token = $this->tokenModel->findById($tokenId);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Falha ao carregar token vinculado: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        if (!$token) {
+            return ResponseLib::sendFail('Token associado ao orderbook não encontrado', ['token_id' => $tokenId], 'E_TOKEN_NOT_FOUND')->withStatus(404);
+        }
+
+        $cprId = (int)($token['cpr_id'] ?? 0);
+        if ($cprId <= 0) {
+            return ResponseLib::sendFail('Token não está vinculado a uma CPR', ['token_id' => $tokenId], 'E_CPR_NOT_FOUND')->withStatus(409);
+        }
+
         if ((int)$orderbook['company_id'] !== $companyId) {
             return ResponseLib::sendFail('Orderbook não pertence à empresa autenticada', [], 'E_FORBIDDEN')->withStatus(403);
         }
@@ -98,6 +124,7 @@ class OrderbookTransferController
         try {
             $transferResult = $this->tokenTransferService->transferFrom($serverAddress, (string)$wallet['wallet_address'], $tokenExternalId);
             $this->orderbookTransferModel->markCompleted((int)$orderbook['orderbook_id']);
+            $this->cprModel->updateCompanyId($cprId, $companyId);
         } catch (\Throwable $e) {
             return ResponseLib::sendFail('Falha ao transferir token: ' . $e->getMessage(), [], 'E_TRANSFER')->withStatus(500);
         }

+ 6 - 1
controllers/RegisterCprController.php

@@ -46,6 +46,11 @@ class RegisterCprController
             return ResponseLib::sendFail('Authenticated user not found', [], 'E_VALIDATE')->withStatus(401);
         }
 
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+        if ($companyId <= 0) {
+            return ResponseLib::sendFail('Authenticated company not found', [], 'E_VALIDATE')->withStatus(401);
+        }
+
         $statusId = $this->statusModel->getIdByStatus('pending');
         if ($statusId === null) {
             return ResponseLib::sendFail('Pending status not found', [], 'E_DATABASE')->withStatus(500);
@@ -64,7 +69,7 @@ class RegisterCprController
         }
 
         try {
-            $record = $this->cprModel->create($body, $statusId, $paymentId);
+            $record = $this->cprModel->create($body, $statusId, $paymentId, $userId, $companyId);
         } catch (\InvalidArgumentException $e) {
             return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
         } catch (\Throwable $e) {

+ 82 - 0
models/CompanySummaryModel.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace Models;
+
+class CompanySummaryModel
+{
+    private \PDO $pdo;
+
+    public function __construct()
+    {
+        if (isset($GLOBALS['pdo']) && $GLOBALS['pdo'] instanceof \PDO) {
+            $this->pdo = $GLOBALS['pdo'];
+            return;
+        }
+
+        throw new \RuntimeException('Global PDO connection not initialized');
+    }
+
+    public function getSummary(int $companyId): array
+    {
+        return [
+            'total_tokens' => $this->countCompanyTokens($companyId),
+            'active_operations' => $this->countActiveOperations($companyId),
+            'total_cprs' => $this->countCompanyCprs($companyId),
+            'total_users' => $this->countCompanyUsers($companyId),
+        ];
+    }
+
+    private function countCompanyTokens(int $companyId): int
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT COUNT(*)
+             FROM "token" t
+             INNER JOIN "wallet" w ON w.wallet_id = t.wallet_id
+             WHERE w.company_id = :company_id'
+        );
+
+        $stmt->execute(['company_id' => $companyId]);
+
+        return (int)$stmt->fetchColumn();
+    }
+
+    private function countActiveOperations(int $companyId): int
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT COUNT(*)
+             FROM "orderbook" o
+             INNER JOIN "wallet" w ON w.wallet_id = o.wallet_id
+             WHERE w.company_id = :company_id
+               AND o.status_id = :status_open'
+        );
+
+        $stmt->execute([
+            'company_id' => $companyId,
+            'status_open' => OrderbookModel::STATUS_OPEN,
+        ]);
+
+        return (int)$stmt->fetchColumn();
+    }
+
+    private function countCompanyCprs(int $companyId): int
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT COUNT(*) FROM "cpr" WHERE company_id = :company_id'
+        );
+
+        $stmt->execute(['company_id' => $companyId]);
+
+        return (int)$stmt->fetchColumn();
+    }
+
+    private function countCompanyUsers(int $companyId): int
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT COUNT(*) FROM "user" WHERE company_id = :company_id'
+        );
+
+        $stmt->execute(['company_id' => $companyId]);
+
+        return (int)$stmt->fetchColumn();
+    }
+}

+ 21 - 0
models/CprModel.php

@@ -174,6 +174,27 @@ class CprModel
         ]);
     }
 
+    public function updateCompanyId(int $cprId, int $companyId): void
+    {
+        if ($cprId <= 0) {
+            throw new \InvalidArgumentException('Invalid CPR id provided');
+        }
+
+        if ($companyId <= 0) {
+            throw new \InvalidArgumentException('Invalid company id provided');
+        }
+
+        $stmt = $this->pdo->prepare('UPDATE "cpr" SET company_id = :company_id WHERE cpr_id = :cpr_id');
+        $stmt->execute([
+            'company_id' => $companyId,
+            'cpr_id' => $cprId,
+        ]);
+
+        if ($stmt->rowCount() === 0) {
+            throw new \RuntimeException('CPR record not found for update');
+        }
+    }
+
     private function normalizeChildrenCodes($value): string
     {
         if (is_array($value)) {

+ 3 - 1
models/OrderbookModel.php

@@ -115,7 +115,9 @@ class OrderbookModel
                 t.token_commodities_amount,
                 c."cpr_deliveryPlace_city_name" AS cityName,
                 c.cpr_product_quantity AS cprProductQuantity,
-                c.cpr_measure_unit_name AS measureUnitName
+                c.cpr_measure_unit_name AS measureUnitName,
+                c.cpr_packaging_way_name AS packagingName,
+                c.cpr_maturity_date AS maturityDate
             FROM "orderbook" o
             LEFT JOIN "token" t ON t.token_id = o.token_id
             LEFT JOIN "cpr" c ON c.cpr_id = t.cpr_id

+ 36 - 1
models/TokenModel.php

@@ -49,7 +49,15 @@ class TokenModel
                        t.commodities_id,
                        t.cpr_id,
                        t.user_id,
-                       c.cpr_product_name
+                       c.cpr_product_name,
+                       c."cpr_deliveryPlace_state_acronym",
+                       c."cpr_deliveryPlace_city_name",
+                       c.cpr_issue_value,
+                       c.cpr_packaging_way_name,
+                       c.cpr_product_quantity,
+                       c.cpr_measure_unit_name,
+                       c.cpr_production_place_name,
+                       c.cpr_maturity_date
                 FROM "token" t
                 INNER JOIN "wallet" w ON w.wallet_id = t.wallet_id
                 LEFT JOIN "cpr" c ON c.cpr_id = t.cpr_id
@@ -94,6 +102,33 @@ class TokenModel
         return $record ?: null;
     }
 
+    public function findById(int $tokenId): ?array
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT token_id,
+                    token_external_id,
+                    token_commodities_amount,
+                    token_commodities_value,
+                    token_uf,
+                    token_city,
+                    token_content,
+                    token_flag,
+                    wallet_id,
+                    chain_id,
+                    commodities_id,
+                    cpr_id,
+                    user_id
+             FROM "token"
+             WHERE token_id = :token_id
+             LIMIT 1'
+        );
+
+        $stmt->execute(['token_id' => $tokenId]);
+        $record = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+        return $record ?: null;
+    }
+
     public function updateCommoditiesValue(int $tokenId, float $value): void
     {
         $stmt = $this->pdo->prepare(

+ 1 - 0
public/index.php

@@ -69,6 +69,7 @@ $app->post('/cpr/create', $authJwt, \Controllers\RegisterCprController::class);
 $app->post('/cpr/history', $authJwt, \Controllers\CprQueryController::class);
 
 $app->post('/wallet/tokens', $authJwt, \Controllers\WalletTokensController::class);
+$app->post('/company/summary', $authJwt, \Controllers\CompanySummaryController::class);
 $app->post('/token/get', $authJwt, \Controllers\TokenGetController::class);
 $app->post('/token/orderbook', $authJwt, \Controllers\TokenOrderbookController::class);
 $app->post('/orderbook/filter', $authJwt, \Controllers\OrderbookFilterController::class);