webmoney/backend/app/Models/ImportMapping.php

125 lines
3.6 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ImportMapping extends Model
{
protected $fillable = [
'user_id',
'name',
'bank_name',
'file_type',
'header_row',
'data_start_row',
'date_format',
'decimal_separator',
'thousands_separator',
'column_mappings',
'default_account_id',
'default_category_id',
'default_cost_center_id',
'is_active',
];
protected $casts = [
'column_mappings' => 'array',
'header_row' => 'integer',
'data_start_row' => 'integer',
'is_active' => 'boolean',
];
/**
* System fields that can be mapped
* Nota: O campo balance é usado APENAS para gerar o hash de duplicidade,
* NÃO é armazenado na BD para não interferir no cálculo dinâmico de saldo.
*/
public const MAPPABLE_FIELDS = [
'effective_date' => ['label' => 'Data Efetiva', 'required' => true, 'type' => 'date'],
'planned_date' => ['label' => 'Data Planejada', 'required' => false, 'type' => 'date'],
'description' => ['label' => 'Descrição', 'required' => true, 'type' => 'string'],
'amount' => ['label' => 'Valor', 'required' => true, 'type' => 'decimal'],
'balance' => ['label' => 'Saldo (apenas para duplicidade)', 'required' => false, 'type' => 'decimal'],
'type' => ['label' => 'Tipo (Crédito/Débito)', 'required' => false, 'type' => 'string'],
'notes' => ['label' => 'Observações', 'required' => false, 'type' => 'string'],
'reference' => ['label' => 'Referência', 'required' => false, 'type' => 'string'],
'category' => ['label' => 'Categoria', 'required' => false, 'type' => 'string'],
];
/**
* Supported file types
*/
public const FILE_TYPES = ['xlsx', 'xls', 'csv', 'ofx', 'pdf'];
/**
* Common date formats
*/
public const DATE_FORMATS = [
'd/m/Y' => 'DD/MM/AAAA (31/12/2025)',
'm/d/Y' => 'MM/DD/AAAA (12/31/2025)',
'Y-m-d' => 'AAAA-MM-DD (2025-12-31)',
'd-m-Y' => 'DD-MM-AAAA (31-12-2025)',
'd.m.Y' => 'DD.MM.AAAA (31.12.2025)',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function defaultAccount(): BelongsTo
{
return $this->belongsTo(Account::class, 'default_account_id');
}
public function defaultCategory(): BelongsTo
{
return $this->belongsTo(Category::class, 'default_category_id');
}
public function defaultCostCenter(): BelongsTo
{
return $this->belongsTo(CostCenter::class, 'default_cost_center_id');
}
public function importLogs(): HasMany
{
return $this->hasMany(ImportLog::class);
}
/**
* Get the column mapping for a specific field
*/
public function getMappingForField(string $field): ?array
{
return $this->column_mappings[$field] ?? null;
}
/**
* Check if a field is mapped
*/
public function hasFieldMapping(string $field): bool
{
return isset($this->column_mappings[$field]) && !empty($this->column_mappings[$field]['columns']);
}
/**
* Scope for active mappings
*/
public function scopeActive($query)
{
return $query->where('is_active', true);
}
/**
* Scope for specific file type
*/
public function scopeForFileType($query, string $type)
{
return $query->where('file_type', $type);
}
}