Explorar el Código

feat: adiciona tabs financeiras, hgistorico e midia

ebagabee hace 2 semanas
padre
commit
5a6065ee1f

+ 32 - 0
app/Http/Controllers/UnitFinancialController.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\UnitFinancialService;
+use App\Http\Requests\UnitFinancialRequest;
+use App\Http\Resources\UnitFinancialResource;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class UnitFinancialController extends Controller
+{
+    public function __construct(
+        protected UnitFinancialService $service,
+    ) {}
+
+    public function show(Request $request): JsonResponse
+    {
+        $item = $this->service->getByUnitId($request->integer('unit_id'));
+        return $this->successResponse(payload: $item ? new UnitFinancialResource($item) : null);
+    }
+
+    public function upsert(UnitFinancialRequest $request): JsonResponse
+    {
+        $validated = $request->validated();
+        $unitId    = $validated['unit_id'];
+        unset($validated['unit_id']);
+
+        $item = $this->service->upsert($unitId, $validated);
+        return $this->successResponse(payload: new UnitFinancialResource($item), message: __('messages.updated'));
+    }
+}

+ 46 - 0
app/Http/Controllers/UnitHistoryController.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\UnitHistoryService;
+use App\Http\Requests\UnitHistoryRequest;
+use App\Http\Resources\UnitHistoryResource;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class UnitHistoryController extends Controller
+{
+    public function __construct(
+        protected UnitHistoryService $service,
+    ) {}
+
+    public function index(Request $request): JsonResponse
+    {
+        $items = $this->service->getByUnitId($request->integer('unit_id'));
+        return $this->successResponse(payload: UnitHistoryResource::collection($items));
+    }
+
+    public function store(UnitHistoryRequest $request): JsonResponse
+    {
+        $item = $this->service->create($request->validated());
+        return $this->successResponse(payload: new UnitHistoryResource($item), message: __('messages.created'), code: 201);
+    }
+
+    public function show(int $id): JsonResponse
+    {
+        $item = $this->service->findById($id);
+        return $this->successResponse(payload: new UnitHistoryResource($item));
+    }
+
+    public function update(UnitHistoryRequest $request, int $id): JsonResponse
+    {
+        $item = $this->service->update($id, $request->validated());
+        return $this->successResponse(payload: new UnitHistoryResource($item), message: __('messages.updated'));
+    }
+
+    public function destroy(int $id): JsonResponse
+    {
+        $this->service->delete($id);
+        return $this->successResponse(message: __('messages.deleted'), code: 204);
+    }
+}

+ 46 - 0
app/Http/Controllers/UnitMediaController.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\UnitMediaService;
+use App\Http\Requests\UnitMediaRequest;
+use App\Http\Resources\UnitMediaResource;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class UnitMediaController extends Controller
+{
+    public function __construct(
+        protected UnitMediaService $service,
+    ) {}
+
+    public function index(Request $request): JsonResponse
+    {
+        $items = $this->service->getByUnitId($request->integer('unit_id'));
+        return $this->successResponse(payload: UnitMediaResource::collection($items));
+    }
+
+    public function store(UnitMediaRequest $request): JsonResponse
+    {
+        $item = $this->service->create($request->validated());
+        return $this->successResponse(payload: new UnitMediaResource($item), message: __('messages.created'), code: 201);
+    }
+
+    public function show(int $id): JsonResponse
+    {
+        $item = $this->service->findById($id);
+        return $this->successResponse(payload: new UnitMediaResource($item));
+    }
+
+    public function update(UnitMediaRequest $request, int $id): JsonResponse
+    {
+        $item = $this->service->update($id, $request->validated());
+        return $this->successResponse(payload: new UnitMediaResource($item), message: __('messages.updated'));
+    }
+
+    public function destroy(int $id): JsonResponse
+    {
+        $this->service->delete($id);
+        return $this->successResponse(message: __('messages.deleted'), code: 204);
+    }
+}

+ 29 - 0
app/Http/Requests/UnitFinancialRequest.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class UnitFinancialRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        return [
+            'unit_id'               => 'required|integer|exists:units,id',
+            'tax_regime'            => 'nullable|string|max:50',
+            'bank'                  => 'nullable|string|max:100',
+            'agency'                => 'nullable|string|max:20',
+            'account'               => 'nullable|string|max:30',
+            'account_type'          => 'nullable|string|max:20',
+            'account_holder'        => 'nullable|string|max:255',
+            'pix_key'               => 'nullable|string|max:255',
+            'billing_method'        => 'nullable|string|max:50',
+            'due_date'              => 'nullable|string|max:10',
+            'financial_email'       => 'nullable|email|max:255',
+            'group'                 => 'nullable|string|max:100',
+            'maintenance_fee'       => 'nullable|numeric|min:0',
+            'marketing_fund'        => 'nullable|numeric|min:0',
+            'tbr'                   => 'nullable|numeric|min:0',
+        ];
+    }
+}

+ 20 - 0
app/Http/Requests/UnitHistoryRequest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class UnitHistoryRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        $isUpdate = $this->isMethod('PUT') || $this->isMethod('PATCH');
+
+        return [
+            'unit_id'               => ($isUpdate ? 'sometimes|' : 'required|') . 'integer|exists:units,id',
+            'title'                 => 'required|string|max:255',
+            'content'               => 'nullable|string',
+            'visible_to_franchisee' => 'boolean',
+        ];
+    }
+}

+ 20 - 0
app/Http/Requests/UnitMediaRequest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class UnitMediaRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        $isUpdate = $this->isMethod('PUT') || $this->isMethod('PATCH');
+
+        return [
+            'unit_id'               => 'required|integer|exists:units,id',
+            'title'                 => 'required|string|max:255',
+            'file'                  => ($isUpdate ? 'nullable' : 'required') . '|file|max:51200',
+            'visible_to_franchisee' => 'boolean',
+        ];
+    }
+}

+ 35 - 0
app/Http/Resources/UnitFinancialResource.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use App\Models\UnitFinancial;
+
+class UnitFinancialResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'               => $this->id,
+            'unit_id'          => $this->unit_id,
+            'tax_regime'       => $this->tax_regime,
+            'bank'             => $this->bank,
+            'agency'           => $this->agency,
+            'account'          => $this->account,
+            'account_type'     => $this->account_type,
+            'account_holder'   => $this->account_holder,
+            'pix_key'          => $this->pix_key,
+            'billing_method'   => $this->billing_method,
+            'due_date'         => $this->due_date,
+            'financial_email'  => $this->financial_email,
+            'group'            => $this->group,
+            'maintenance_fee'  => $this->maintenance_fee,
+            'marketing_fund'   => $this->marketing_fund,
+            'tbr'              => $this->tbr,
+            'created_at'       => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
+            'updated_at'       => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
+        ];
+    }
+}

+ 34 - 0
app/Http/Resources/UnitHistoryResource.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use App\Models\UnitHistory;
+
+class UnitHistoryResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'                    => $this->id,
+            'unit_id'               => $this->unit_id,
+            'title'                 => $this->title,
+            'content'               => $this->content,
+            'visible_to_franchisee' => $this->visible_to_franchisee,
+            'created_at'            => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
+            'updated_at'            => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * @param \Illuminate\Database\Eloquent\Collection<UnitHistory> $resource
+     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<UnitHistoryResource>
+     */
+    public static function collection($resource): AnonymousResourceCollection
+    {
+        return parent::collection($resource);
+    }
+}

+ 36 - 0
app/Http/Resources/UnitMediaResource.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use Illuminate\Support\Facades\Storage;
+use App\Models\UnitMedia;
+
+class UnitMediaResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'                    => $this->id,
+            'unit_id'               => $this->unit_id,
+            'title'                 => $this->title,
+            'file_url'              => $this->file_url ? Storage::url($this->file_url) : null,
+            'mime_type'             => $this->mime_type,
+            'visible_to_franchisee' => $this->visible_to_franchisee,
+            'created_at'            => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
+            'updated_at'            => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * @param \Illuminate\Database\Eloquent\Collection<UnitMedia> $resource
+     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<UnitMediaResource>
+     */
+    public static function collection($resource): AnonymousResourceCollection
+    {
+        return parent::collection($resource);
+    }
+}

+ 53 - 0
app/Models/UnitFinancial.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property int $unit_id
+ * @property string|null $tax_regime
+ * @property string|null $bank
+ * @property string|null $agency
+ * @property string|null $account
+ * @property string|null $account_type
+ * @property string|null $account_holder
+ * @property string|null $pix_key
+ * @property string|null $billing_method
+ * @property string|null $due_date
+ * @property string|null $financial_email
+ * @property string|null $group
+ * @property float|null $maintenance_fee
+ * @property float|null $marketing_fund
+ * @property float|null $tbr
+ * @property \Carbon\Carbon $created_at
+ * @property \Carbon\Carbon $updated_at
+ * @property \Carbon\Carbon|null $deleted_at
+ * @property-read \App\Models\Unit $unit
+ */
+class UnitFinancial extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = 'unit_financials';
+
+    protected $guarded = ['id'];
+
+    protected $casts = [
+        'maintenance_fee' => 'decimal:2',
+        'marketing_fund'  => 'decimal:2',
+        'tbr'             => 'decimal:2',
+        'created_at'      => 'datetime',
+        'updated_at'      => 'datetime',
+        'deleted_at'      => 'datetime',
+    ];
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class, 'unit_id');
+    }
+}

+ 40 - 0
app/Models/UnitHistory.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property int $unit_id
+ * @property string $title
+ * @property string|null $content
+ * @property bool $visible_to_franchisee
+ * @property \Carbon\Carbon $created_at
+ * @property \Carbon\Carbon $updated_at
+ * @property \Carbon\Carbon|null $deleted_at
+ * @property-read \App\Models\Unit $unit
+ */
+class UnitHistory extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = 'unit_histories';
+
+    protected $guarded = ['id'];
+
+    protected $casts = [
+        'visible_to_franchisee' => 'boolean',
+        'created_at'            => 'datetime',
+        'updated_at'            => 'datetime',
+        'deleted_at'            => 'datetime',
+    ];
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class, 'unit_id');
+    }
+}

+ 41 - 0
app/Models/UnitMedia.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property int $unit_id
+ * @property string $title
+ * @property string $file_url
+ * @property string|null $mime_type
+ * @property bool $visible_to_franchisee
+ * @property \Carbon\Carbon $created_at
+ * @property \Carbon\Carbon $updated_at
+ * @property \Carbon\Carbon|null $deleted_at
+ * @property-read \App\Models\Unit $unit
+ */
+class UnitMedia extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = 'unit_media';
+
+    protected $guarded = ['id'];
+
+    protected $casts = [
+        'visible_to_franchisee' => 'boolean',
+        'created_at'            => 'datetime',
+        'updated_at'            => 'datetime',
+        'deleted_at'            => 'datetime',
+    ];
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class, 'unit_id');
+    }
+}

+ 25 - 0
app/Services/UnitFinancialService.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\UnitFinancial;
+
+class UnitFinancialService
+{
+    public function getByUnitId(int $unitId): ?UnitFinancial
+    {
+        return UnitFinancial::where('unit_id', $unitId)->first();
+    }
+
+    public function upsert(int $unitId, array $data): UnitFinancial
+    {
+        $model = UnitFinancial::where('unit_id', $unitId)->first();
+
+        if ($model) {
+            $model->update($data);
+            return $model->fresh();
+        }
+
+        return UnitFinancial::create(array_merge($data, ['unit_id' => $unitId]));
+    }
+}

+ 49 - 0
app/Services/UnitHistoryService.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\UnitHistory;
+use Illuminate\Database\Eloquent\Collection;
+
+class UnitHistoryService
+{
+    public function getByUnitId(int $unitId): Collection
+    {
+        return UnitHistory::where('unit_id', $unitId)
+            ->orderBy('created_at', 'desc')
+            ->get();
+    }
+
+    public function findById(int $id): ?UnitHistory
+    {
+        return UnitHistory::find($id);
+    }
+
+    public function create(array $data): UnitHistory
+    {
+        return UnitHistory::create($data);
+    }
+
+    public function update(int $id, array $data): ?UnitHistory
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        $model->update($data);
+        return $model->fresh();
+    }
+
+    public function delete(int $id): bool
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return false;
+        }
+
+        return $model->delete();
+    }
+}

+ 71 - 0
app/Services/UnitMediaService.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\UnitMedia;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Storage;
+
+class UnitMediaService
+{
+    public function getByUnitId(int $unitId): Collection
+    {
+        return UnitMedia::where('unit_id', $unitId)
+            ->orderBy('created_at', 'desc')
+            ->get();
+    }
+
+    public function findById(int $id): ?UnitMedia
+    {
+        return UnitMedia::find($id);
+    }
+
+    public function create(array $data): UnitMedia
+    {
+        $file     = $data['file'];
+        $title    = $data['title'];
+        $fileUrl  = $file->store('unit-media');
+        $mimeType = $file->getMimeType();
+
+        return UnitMedia::create([
+            'unit_id'               => $data['unit_id'],
+            'title'                 => $title,
+            'file_url'              => $fileUrl,
+            'mime_type'             => $mimeType,
+            'visible_to_franchisee' => $data['visible_to_franchisee'] ?? false,
+        ]);
+    }
+
+    public function update(int $id, array $data): ?UnitMedia
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        if (isset($data['file'])) {
+            Storage::delete($model->file_url);
+            $file              = $data['file'];
+            $data['file_url']  = $file->store('unit-media');
+            $data['mime_type'] = $file->getMimeType();
+            unset($data['file']);
+        }
+
+        $model->update($data);
+        return $model->fresh();
+    }
+
+    public function delete(int $id): bool
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return false;
+        }
+
+        Storage::delete($model->file_url);
+
+        return $model->delete();
+    }
+}

+ 28 - 0
database/migrations/2026_04_16_155237_create_unit_histories_table.php

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::create('unit_histories', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('unit_id')->constrained('units')->onDelete('cascade');
+            $table->string('title');
+            $table->text('content')->nullable();
+            $table->boolean('visible_to_franchisee')->default(false);
+            $table->timestamps();
+            $table->softDeletes();
+
+            $table->index('unit_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('unit_histories');
+    }
+};

+ 39 - 0
database/migrations/2026_04_16_155239_create_unit_financials_table.php

@@ -0,0 +1,39 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::create('unit_financials', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('unit_id')->constrained('units')->onDelete('cascade');
+            $table->string('tax_regime')->nullable();
+            $table->string('bank')->nullable();
+            $table->string('agency')->nullable();
+            $table->string('account')->nullable();
+            $table->string('account_type')->nullable();
+            $table->string('account_holder')->nullable();
+            $table->string('pix_key')->nullable();
+            $table->string('billing_method')->nullable();
+            $table->string('due_date')->nullable();
+            $table->string('financial_email')->nullable();
+            $table->string('group')->nullable();
+            $table->decimal('maintenance_fee', 10, 2)->nullable();
+            $table->decimal('marketing_fund', 10, 2)->nullable();
+            $table->decimal('tbr', 10, 2)->nullable();
+            $table->timestamps();
+            $table->softDeletes();
+
+            $table->index('unit_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('unit_financials');
+    }
+};

+ 29 - 0
database/migrations/2026_04_16_155239_create_unit_media_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::create('unit_media', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('unit_id')->constrained('units')->onDelete('cascade');
+            $table->string('title');
+            $table->string('file_url');
+            $table->string('mime_type')->nullable();
+            $table->boolean('visible_to_franchisee')->default(false);
+            $table->timestamps();
+            $table->softDeletes();
+
+            $table->index('unit_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('unit_media');
+    }
+};

+ 9 - 0
routes/authRoutes/unit_financial.php

@@ -0,0 +1,9 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\UnitFinancialController;
+
+Route::controller(UnitFinancialController::class)->prefix('unit-financial')->group(function () {
+    Route::get('/', 'show')->middleware('permission:unit,view');
+    Route::post('/', 'upsert')->middleware('permission:unit,edit');
+});

+ 12 - 0
routes/authRoutes/unit_history.php

@@ -0,0 +1,12 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\UnitHistoryController;
+
+Route::controller(UnitHistoryController::class)->prefix('unit-history')->group(function () {
+    Route::get('/', 'index')->middleware('permission:unit,view');
+    Route::post('/', 'store')->middleware('permission:unit,add');
+    Route::get('/{id}', 'show')->middleware('permission:unit,view');
+    Route::put('/{id}', 'update')->middleware('permission:unit,edit');
+    Route::delete('/{id}', 'destroy')->middleware('permission:unit,delete');
+});

+ 12 - 0
routes/authRoutes/unit_media.php

@@ -0,0 +1,12 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\UnitMediaController;
+
+Route::controller(UnitMediaController::class)->prefix('unit-media')->group(function () {
+    Route::get('/', 'index')->middleware('permission:unit,view');
+    Route::post('/', 'store')->middleware('permission:unit,add');
+    Route::get('/{id}', 'show')->middleware('permission:unit,view');
+    Route::put('/{id}', 'update')->middleware('permission:unit,edit');
+    Route::delete('/{id}', 'destroy')->middleware('permission:unit,delete');
+});