|
@@ -9,7 +9,8 @@ use SimpleXMLElement;
|
|
|
use Livewire\WithFileUploads;
|
|
use Livewire\WithFileUploads;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
-
|
|
|
|
|
|
|
+use App\Services\RecordFileService;
|
|
|
|
|
+use App\Jobs\ProcessRecordAttachment;
|
|
|
|
|
|
|
|
class RecordOUT extends Component
|
|
class RecordOUT extends Component
|
|
|
{
|
|
{
|
|
@@ -63,6 +64,7 @@ class RecordOUT extends Component
|
|
|
$add = false,
|
|
$add = false,
|
|
|
$is_paid = false;
|
|
$is_paid = false;
|
|
|
public $attachment;
|
|
public $attachment;
|
|
|
|
|
+ public $attachment_old;
|
|
|
|
|
|
|
|
public $filterSupplier = 0, $filterPaymentMethod = 0, $filterCausals = [], $filterFrom = '', $filterTo = '', $filterCommercial = 0;
|
|
public $filterSupplier = 0, $filterPaymentMethod = 0, $filterCausals = [], $filterFrom = '', $filterTo = '', $filterCommercial = 0;
|
|
|
|
|
|
|
@@ -89,6 +91,9 @@ class RecordOUT extends Component
|
|
|
public $vats = array();
|
|
public $vats = array();
|
|
|
|
|
|
|
|
public $numero_fattura;
|
|
public $numero_fattura;
|
|
|
|
|
+ public $attachmentUploadStatus = 'none';
|
|
|
|
|
+ public $uploadProgress = 0;
|
|
|
|
|
+ public $uploadStartTime = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $rules = [
|
|
protected $rules = [
|
|
@@ -105,6 +110,13 @@ class RecordOUT extends Component
|
|
|
'rows.*.causal_id.required' => 'La causale è obbligatoria'
|
|
'rows.*.causal_id.required' => 'La causale è obbligatoria'
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
+ protected $recordFileService;
|
|
|
|
|
+
|
|
|
|
|
+ public function boot()
|
|
|
|
|
+ {
|
|
|
|
|
+ $this->recordFileService = app(RecordFileService::class);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function getSupplierProperty()
|
|
public function getSupplierProperty()
|
|
|
{
|
|
{
|
|
|
$ret = null;
|
|
$ret = null;
|
|
@@ -130,10 +142,12 @@ class RecordOUT extends Component
|
|
|
$this->payment_method_id = null;
|
|
$this->payment_method_id = null;
|
|
|
$this->date = date("Y-m-d");
|
|
$this->date = date("Y-m-d");
|
|
|
$this->data_pagamento = date("Y-m-d");
|
|
$this->data_pagamento = date("Y-m-d");
|
|
|
- //$this->attachment = null;
|
|
|
|
|
|
|
+ $this->attachment = null;
|
|
|
|
|
+ $this->attachment_old = null;
|
|
|
$this->numero_fattura = null;
|
|
$this->numero_fattura = null;
|
|
|
$this->type = 'OUT';
|
|
$this->type = 'OUT';
|
|
|
$this->commercial = 1;
|
|
$this->commercial = 1;
|
|
|
|
|
+ $this->dataId = null;
|
|
|
$this->rows = array();
|
|
$this->rows = array();
|
|
|
$this->rows[] = array(
|
|
$this->rows[] = array(
|
|
|
'causal_id' => null,
|
|
'causal_id' => null,
|
|
@@ -146,7 +160,6 @@ class RecordOUT extends Component
|
|
|
);
|
|
);
|
|
|
$this->emit('load-data-table');
|
|
$this->emit('load-data-table');
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
public function getCausale($records, $indentation)
|
|
public function getCausale($records, $indentation)
|
|
|
{
|
|
{
|
|
|
foreach ($records as $record) {
|
|
foreach ($records as $record) {
|
|
@@ -180,7 +193,6 @@ class RecordOUT extends Component
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$this->vats = \App\Models\Vat::select('id', 'name', 'value')->orderBy('value')->get();
|
|
$this->vats = \App\Models\Vat::select('id', 'name', 'value')->orderBy('value')->get();
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public function mount()
|
|
public function mount()
|
|
@@ -286,7 +298,7 @@ class RecordOUT extends Component
|
|
|
if (false) {
|
|
if (false) {
|
|
|
if ($this->hasFilter) {
|
|
if ($this->hasFilter) {
|
|
|
|
|
|
|
|
- $datas = \App\Models\Record::where('type', 'OUT')->with('supplier', 'payment_method','is_paid');
|
|
|
|
|
|
|
+ $datas = \App\Models\Record::where('type', 'OUT')->with('supplier', 'payment_method', 'is_paid');
|
|
|
if ($this->filterSupplier > 0) {
|
|
if ($this->filterSupplier > 0) {
|
|
|
$datas = $datas->where('supplier_id', $this->filterSupplier);
|
|
$datas = $datas->where('supplier_id', $this->filterSupplier);
|
|
|
}
|
|
}
|
|
@@ -363,78 +375,178 @@ class RecordOUT extends Component
|
|
|
$this->emit('setEdit', true);
|
|
$this->emit('setEdit', true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
public function store()
|
|
public function store()
|
|
|
{
|
|
{
|
|
|
|
|
+ $this->emit('start-loading', 'Validazione dati...');
|
|
|
$this->emit('refresh');
|
|
$this->emit('refresh');
|
|
|
- /*
|
|
|
|
|
- if ($this->attachment) {
|
|
|
|
|
- Log::info("Attachment: " . json_encode($this->attachment));
|
|
|
|
|
- $name = md5($this->attachment . microtime()) . '.' . $this->attachment->extension();
|
|
|
|
|
- $this->attachment->storeAs('public', $name);
|
|
|
|
|
- } */
|
|
|
|
|
|
|
|
|
|
- if($this->numero_fattura == null || $this->numero_fattura == '') {
|
|
|
|
|
|
|
+ if ($this->numero_fattura == null || $this->numero_fattura == '') {
|
|
|
$this->numero_fattura = 'USC-' . date('Ymd');
|
|
$this->numero_fattura = 'USC-' . date('Ymd');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
if (empty($this->data_pagamento) || $this->data_pagamento == '1970-01-01') {
|
|
if (empty($this->data_pagamento) || $this->data_pagamento == '1970-01-01') {
|
|
|
$this->data_pagamento = null;
|
|
$this->data_pagamento = null;
|
|
|
- Log::info("Setting data_pagamento to NULL in store");
|
|
|
|
|
$is_paid = false;
|
|
$is_paid = false;
|
|
|
} else {
|
|
} else {
|
|
|
- Log::info("Using data_pagamento: " . $this->data_pagamento);
|
|
|
|
|
$is_paid = true;
|
|
$is_paid = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ $fileSize = $this->attachment->getSize();
|
|
|
|
|
+ $fileName = $this->attachment->getClientOriginalName();
|
|
|
|
|
+ $mimeType = $this->attachment->getMimeType();
|
|
|
|
|
+ $maxSize = 50 * 1024 * 1024;
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("=== FILE VALIDATION ===");
|
|
|
|
|
+ Log::info("File: {$fileName}");
|
|
|
|
|
+ Log::info("Size: " . round($fileSize / 1024 / 1024, 2) . " MB");
|
|
|
|
|
+ Log::info("MIME: {$mimeType}");
|
|
|
|
|
+
|
|
|
|
|
+ if ($fileSize > $maxSize) {
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+ $this->emit('flash-error', 'File troppo grande. Dimensione massima: 50MB');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $allowedMimes = [
|
|
|
|
|
+ 'image/jpeg',
|
|
|
|
|
+ 'image/jpg',
|
|
|
|
|
+ 'image/png',
|
|
|
|
|
+ 'image/gif',
|
|
|
|
|
+ 'image/webp',
|
|
|
|
|
+ 'application/pdf',
|
|
|
|
|
+ 'application/msword',
|
|
|
|
|
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
|
|
+ 'text/xml',
|
|
|
|
|
+ 'application/xml',
|
|
|
|
|
+ 'text/plain',
|
|
|
|
|
+ 'text/csv',
|
|
|
|
|
+ 'application/vnd.ms-excel',
|
|
|
|
|
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ if (!in_array($mimeType, $allowedMimes)) {
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+ $this->emit('flash-error', 'Tipo di file non supportato');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("File validation passed");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$this->validate();
|
|
$this->validate();
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
|
|
+ $this->emit('update-loading', 'Salvataggio record...');
|
|
|
|
|
+
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
$record = \App\Models\Record::create([
|
|
$record = \App\Models\Record::create([
|
|
|
'member_id' => $this->member_id,
|
|
'member_id' => $this->member_id,
|
|
|
'supplier_id' => $this->supplier_id,
|
|
'supplier_id' => $this->supplier_id,
|
|
|
'payment_method_id' => $this->payment_method_id,
|
|
'payment_method_id' => $this->payment_method_id,
|
|
|
'date' => $this->date,
|
|
'date' => $this->date,
|
|
|
- 'data_pagamento' =>$this->data_pagamento,
|
|
|
|
|
- //'attachment' => $this->attachment,
|
|
|
|
|
|
|
+ 'data_pagamento' => $this->data_pagamento,
|
|
|
|
|
+ 'attachment' => '',
|
|
|
'type' => $this->type,
|
|
'type' => $this->type,
|
|
|
- 'amount' => $this->currencyToDouble($this->amount),
|
|
|
|
|
|
|
+ 'amount' => 0,
|
|
|
'commercial' => $this->commercial,
|
|
'commercial' => $this->commercial,
|
|
|
'numero_fattura' => $this->numero_fattura,
|
|
'numero_fattura' => $this->numero_fattura,
|
|
|
'is_paid' => $is_paid,
|
|
'is_paid' => $is_paid,
|
|
|
|
|
+ 'attachment_status' => $this->attachment ? 'pending' : 'none',
|
|
|
]);
|
|
]);
|
|
|
- Log::info("Record data being inserted: " . json_encode($record));
|
|
|
|
|
|
|
|
|
|
$this->dataId = $record->id;
|
|
$this->dataId = $record->id;
|
|
|
|
|
+ Log::info("Record created with ID: {$this->dataId}");
|
|
|
|
|
+
|
|
|
$tot = 0;
|
|
$tot = 0;
|
|
|
|
|
+ $rowsData = [];
|
|
|
|
|
+
|
|
|
foreach ($this->rows as $row) {
|
|
foreach ($this->rows as $row) {
|
|
|
foreach ($row["when"] as $x => $y) {
|
|
foreach ($row["when"] as $x => $y) {
|
|
|
$row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
|
|
$row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
$imponibile = isset($row["imponibile"]) ? $this->currencyToDouble($row["imponibile"]) : null;
|
|
$imponibile = isset($row["imponibile"]) ? $this->currencyToDouble($row["imponibile"]) : null;
|
|
|
- Log::info("Imponibile store: " . $imponibile);
|
|
|
|
|
$aliquota_iva = isset($row["aliquota_iva"]) ? floatval(str_replace('%', '', $row["aliquota_iva"])) : null;
|
|
$aliquota_iva = isset($row["aliquota_iva"]) ? floatval(str_replace('%', '', $row["aliquota_iva"])) : null;
|
|
|
- Log::info("Aliquota IVA store: " . $aliquota_iva);
|
|
|
|
|
- \App\Models\RecordRow::create([
|
|
|
|
|
|
|
+ $amount = $this->currencyToDouble($row["amount"]);
|
|
|
|
|
+
|
|
|
|
|
+ $rowsData[] = [
|
|
|
'record_id' => $this->dataId,
|
|
'record_id' => $this->dataId,
|
|
|
'causal_id' => $row["causal_id"],
|
|
'causal_id' => $row["causal_id"],
|
|
|
'note' => $row["note"],
|
|
'note' => $row["note"],
|
|
|
- 'amount' => $this->currencyToDouble($row["amount"]),
|
|
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
'imponibile' => $imponibile,
|
|
'imponibile' => $imponibile,
|
|
|
'aliquota_iva' => $aliquota_iva,
|
|
'aliquota_iva' => $aliquota_iva,
|
|
|
'commercial' => $row["commercial"],
|
|
'commercial' => $row["commercial"],
|
|
|
- 'when' => json_encode($row["when"])
|
|
|
|
|
- ]);
|
|
|
|
|
- $tot += $this->currencyToDouble($row["amount"]);
|
|
|
|
|
|
|
+ 'when' => json_encode($row["when"]),
|
|
|
|
|
+ 'created_at' => now(),
|
|
|
|
|
+ 'updated_at' => now()
|
|
|
|
|
+ ];
|
|
|
|
|
+ $tot += $amount;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ \App\Models\RecordRow::insert($rowsData);
|
|
|
$record->amount = $tot;
|
|
$record->amount = $tot;
|
|
|
$record->save();
|
|
$record->save();
|
|
|
|
|
|
|
|
- session()->flash('success', 'Movimento creato');
|
|
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+ Log::info("✅ Database transaction committed");
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ $this->emit('update-loading', 'Preparazione file per elaborazione...');
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ Log::info("=== STARTING FILE PROCESSING ===");
|
|
|
|
|
+
|
|
|
|
|
+ $tempPath = $this->recordFileService->storeTemporarily($this->attachment);
|
|
|
|
|
+ $originalFileName = $this->attachment->getClientOriginalName();
|
|
|
|
|
+
|
|
|
|
|
+ Log::info(" File stored temporarily at: {$tempPath}");
|
|
|
|
|
+
|
|
|
|
|
+ $clientName = session('clientName', 'default');
|
|
|
|
|
+
|
|
|
|
|
+ ProcessRecordAttachment::dispatch(
|
|
|
|
|
+ $record->id,
|
|
|
|
|
+ $tempPath,
|
|
|
|
|
+ $originalFileName,
|
|
|
|
|
+ 'out',
|
|
|
|
|
+ $clientName
|
|
|
|
|
+ )->onQueue('attachments');
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("File processing job dispatched for record {$record->id}");
|
|
|
|
|
+ } catch (\Exception $ex) {
|
|
|
|
|
+ Log::error("Failed to process file: " . $ex->getMessage());
|
|
|
|
|
+ Log::error("Stack trace: " . $ex->getTraceAsString());
|
|
|
|
|
+
|
|
|
|
|
+ DB::table('records')
|
|
|
|
|
+ ->where('id', $record->id)
|
|
|
|
|
+ ->update(['attachment_status' => 'failed']);
|
|
|
|
|
+
|
|
|
|
|
+ session()->flash('warning', 'Record creato ma elaborazione allegato fallita. Prova a modificare il record e caricare nuovamente il file.');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ session()->flash('success', 'Movimento creato con successo. L\'allegato verrà elaborato in background. Aggiorna la pagina tra qualche secondo per vedere lo stato.');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ session()->flash('success', 'Movimento creato con successo.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$this->resetFields();
|
|
$this->resetFields();
|
|
|
$this->add = false;
|
|
$this->add = false;
|
|
|
$this->emit('setEdit', false);
|
|
$this->emit('setEdit', false);
|
|
|
} catch (\Exception $ex) {
|
|
} catch (\Exception $ex) {
|
|
|
- $this->emit('flash-error', 'Errore (' . $ex->getMessage() . ')');
|
|
|
|
|
|
|
+ DB::rollback();
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+
|
|
|
|
|
+ Log::error("Store error: " . $ex->getMessage());
|
|
|
|
|
+ Log::error("Stack trace: " . $ex->getTraceAsString());
|
|
|
|
|
+ $this->emit('flash-error', 'Errore durante il salvataggio: ' . $ex->getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -455,6 +567,31 @@ class RecordOUT extends Component
|
|
|
return $value;
|
|
return $value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function removeAttachment()
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($this->attachment_old) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $this->recordFileService->deleteAttachment($this->attachment_old);
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->dataId) {
|
|
|
|
|
+ DB::table('records')
|
|
|
|
|
+ ->where('id', $this->dataId)
|
|
|
|
|
+ ->update([
|
|
|
|
|
+ 'attachment' => '',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->attachment_old = '';
|
|
|
|
|
+ $this->attachmentUploadStatus = 'none';
|
|
|
|
|
+
|
|
|
|
|
+ session()->flash('success', 'Allegato rimosso con successo');
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ Log::error("Error removing attachment: " . $e->getMessage());
|
|
|
|
|
+ $this->emit('flash-error', 'Errore durante la rimozione dell\'allegato');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function edit($id)
|
|
public function edit($id)
|
|
|
{
|
|
{
|
|
|
if (!isset($_GET["from"]) && $this->fromPage == '')
|
|
if (!isset($_GET["from"]) && $this->fromPage == '')
|
|
@@ -462,25 +599,36 @@ class RecordOUT extends Component
|
|
|
$this->emit('setEdit', true);
|
|
$this->emit('setEdit', true);
|
|
|
$this->emit('load-select');
|
|
$this->emit('load-select');
|
|
|
$this->emit('hide-search');
|
|
$this->emit('hide-search');
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
$record = \App\Models\Record::findOrFail($id);
|
|
$record = \App\Models\Record::findOrFail($id);
|
|
|
if (!$record) {
|
|
if (!$record) {
|
|
|
$this->emit('flash-error', 'Movimento non trovato');
|
|
$this->emit('flash-error', 'Movimento non trovato');
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+
|
|
|
$this->member_id = $record->member_id;
|
|
$this->member_id = $record->member_id;
|
|
|
$this->supplier_id = $record->supplier_id;
|
|
$this->supplier_id = $record->supplier_id;
|
|
|
$this->payment_method_id = $record->payment_method_id;
|
|
$this->payment_method_id = $record->payment_method_id;
|
|
|
$this->date = date("Y-m-d", strtotime($record->date));
|
|
$this->date = date("Y-m-d", strtotime($record->date));
|
|
|
- $this->data_pagamento = $record->data_pagamento;
|
|
|
|
|
|
|
+ $this->data_pagamento = $record->data_pagamento;
|
|
|
$this->type = $record->type;
|
|
$this->type = $record->type;
|
|
|
$this->numero_fattura = $record->numero_fattura;
|
|
$this->numero_fattura = $record->numero_fattura;
|
|
|
- //$attachment = $record->attachment;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (!empty($record->attachment) && $record->attachment !== null && $record->attachment !== '') {
|
|
|
|
|
+ $this->attachment_old = $record->attachment;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->attachment_old = '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->attachment = null;
|
|
|
|
|
+
|
|
|
$this->commercial = $record->commercial;
|
|
$this->commercial = $record->commercial;
|
|
|
$this->dataId = $record->id;
|
|
$this->dataId = $record->id;
|
|
|
$this->update = true;
|
|
$this->update = true;
|
|
|
$this->add = false;
|
|
$this->add = false;
|
|
|
|
|
|
|
|
$this->rows = [];
|
|
$this->rows = [];
|
|
|
|
|
+ $this->recordFileService->createRecordFolders($record->id, 'OUT');
|
|
|
|
|
|
|
|
$recordRows = \App\Models\RecordRow::where('record_id', $this->dataId)->get();
|
|
$recordRows = \App\Models\RecordRow::where('record_id', $this->dataId)->get();
|
|
|
|
|
|
|
@@ -526,30 +674,88 @@ class RecordOUT extends Component
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
$this->rows[] = $rowData;
|
|
$this->rows[] = $rowData;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("EDIT DEBUG - Final attachment_old value: '" . $this->attachment_old . "'");
|
|
|
|
|
+
|
|
|
|
|
+ $this->emit('refresh');
|
|
|
}
|
|
}
|
|
|
} catch (\Exception $ex) {
|
|
} catch (\Exception $ex) {
|
|
|
$this->emit('flash-error', 'Errore (' . $ex->getMessage() . ')');
|
|
$this->emit('flash-error', 'Errore (' . $ex->getMessage() . ')');
|
|
|
|
|
+ Log::error("EDIT ERROR: " . $ex->getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public function update()
|
|
public function update()
|
|
|
{
|
|
{
|
|
|
|
|
+ $this->emit('start-loading', 'Validazione dati...');
|
|
|
$this->emit('refresh');
|
|
$this->emit('refresh');
|
|
|
- $this->validate();
|
|
|
|
|
- if (empty($this->data_pagamento) || $this->data_pagamento == '') {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->numero_fattura == null || $this->numero_fattura == '') {
|
|
|
|
|
+ $this->numero_fattura = 'USC-' . date('Ymd');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($this->data_pagamento) || $this->data_pagamento == '1970-01-01') {
|
|
|
$this->data_pagamento = null;
|
|
$this->data_pagamento = null;
|
|
|
- Log::info("Data pagamento vuota, imposto a NULL in update");
|
|
|
|
|
$is_paid = false;
|
|
$is_paid = false;
|
|
|
} else {
|
|
} else {
|
|
|
- Log::info("Data pagamento in update: " . $this->data_pagamento);
|
|
|
|
|
$is_paid = true;
|
|
$is_paid = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ $fileSize = $this->attachment->getSize();
|
|
|
|
|
+ $fileName = $this->attachment->getClientOriginalName();
|
|
|
|
|
+ $mimeType = $this->attachment->getMimeType();
|
|
|
|
|
+ $maxSize = 50 * 1024 * 1024;
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("=== FILE VALIDATION (UPDATE) ===");
|
|
|
|
|
+ Log::info("File: {$fileName}");
|
|
|
|
|
+ Log::info("Size: " . round($fileSize / 1024 / 1024, 2) . " MB");
|
|
|
|
|
+ Log::info("MIME: {$mimeType}");
|
|
|
|
|
+
|
|
|
|
|
+ if ($fileSize > $maxSize) {
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+ $this->emit('flash-error', 'File troppo grande. Dimensione massima: 50MB');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $allowedMimes = [
|
|
|
|
|
+ 'image/jpeg',
|
|
|
|
|
+ 'image/jpg',
|
|
|
|
|
+ 'image/png',
|
|
|
|
|
+ 'image/gif',
|
|
|
|
|
+ 'image/webp',
|
|
|
|
|
+ 'application/pdf',
|
|
|
|
|
+ 'application/msword',
|
|
|
|
|
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
|
|
+ 'text/xml',
|
|
|
|
|
+ 'application/xml',
|
|
|
|
|
+ 'text/plain',
|
|
|
|
|
+ 'text/csv',
|
|
|
|
|
+ 'application/vnd.ms-excel',
|
|
|
|
|
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ if (!in_array($mimeType, $allowedMimes)) {
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+ $this->emit('flash-error', 'Tipo di file non supportato');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("File validation passed");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->validate();
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
- \App\Models\Record::whereId($this->dataId)->update([
|
|
|
|
|
|
|
+ $this->emit('update-loading', 'Aggiornamento record...');
|
|
|
|
|
+
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ $record = \App\Models\Record::findOrFail($this->dataId);
|
|
|
|
|
+
|
|
|
|
|
+ $record->update([
|
|
|
'member_id' => $this->member_id,
|
|
'member_id' => $this->member_id,
|
|
|
'supplier_id' => $this->supplier_id,
|
|
'supplier_id' => $this->supplier_id,
|
|
|
'payment_method_id' => $this->payment_method_id,
|
|
'payment_method_id' => $this->payment_method_id,
|
|
@@ -557,12 +763,12 @@ class RecordOUT extends Component
|
|
|
'data_pagamento' => $this->data_pagamento,
|
|
'data_pagamento' => $this->data_pagamento,
|
|
|
'type' => $this->type,
|
|
'type' => $this->type,
|
|
|
'commercial' => $this->commercial,
|
|
'commercial' => $this->commercial,
|
|
|
- 'is_paid' => $is_paid,
|
|
|
|
|
'numero_fattura' => $this->numero_fattura,
|
|
'numero_fattura' => $this->numero_fattura,
|
|
|
- //'attachment' => $this->attachment,
|
|
|
|
|
|
|
+ 'is_paid' => $is_paid,
|
|
|
|
|
+ 'attachment_status' => $this->attachment ? 'pending' : ($this->attachment_old ? 'completed' : 'none'),
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
- $tot = 0;
|
|
|
|
|
|
|
+ Log::info("Record updated with ID: {$this->dataId}");
|
|
|
|
|
|
|
|
$existingRows = \App\Models\RecordRow::where('record_id', $this->dataId)
|
|
$existingRows = \App\Models\RecordRow::where('record_id', $this->dataId)
|
|
|
->select('id', 'quantita', 'numero_linea')
|
|
->select('id', 'quantita', 'numero_linea')
|
|
@@ -572,42 +778,32 @@ class RecordOUT extends Component
|
|
|
|
|
|
|
|
\App\Models\RecordRow::where('record_id', $this->dataId)->delete();
|
|
\App\Models\RecordRow::where('record_id', $this->dataId)->delete();
|
|
|
|
|
|
|
|
|
|
+ $tot = 0;
|
|
|
|
|
+ $newRowsData = [];
|
|
|
|
|
+
|
|
|
foreach ($this->rows as $row) {
|
|
foreach ($this->rows as $row) {
|
|
|
foreach ($row["when"] as $x => $y) {
|
|
foreach ($row["when"] as $x => $y) {
|
|
|
$row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
|
|
$row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $imponibile = null;
|
|
|
|
|
- if (isset($row["imponibile"]) && $row["imponibile"] !== null && $row["imponibile"] !== '') {
|
|
|
|
|
- $imponibile = $this->currencyToDouble($row["imponibile"]);
|
|
|
|
|
- Log::info("Imponibile: " . $imponibile);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $aliquota_iva = null;
|
|
|
|
|
- if (isset($row["aliquota_iva"]) && $row["aliquota_iva"] !== null && $row["aliquota_iva"] !== '') {
|
|
|
|
|
- $aliquota_iva = floatval(str_replace('%', '', $row["aliquota_iva"]));
|
|
|
|
|
- Log::info("Aliquota IVA: " . $aliquota_iva);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ $imponibile = isset($row["imponibile"]) ? $this->currencyToDouble($row["imponibile"]) : null;
|
|
|
|
|
+ $aliquota_iva = isset($row["aliquota_iva"]) ? floatval(str_replace('%', '', $row["aliquota_iva"])) : null;
|
|
|
$amount = $this->currencyToDouble($row["amount"]);
|
|
$amount = $this->currencyToDouble($row["amount"]);
|
|
|
-
|
|
|
|
|
- $imposta = null;
|
|
|
|
|
- if ($imponibile !== null) {
|
|
|
|
|
- $imposta = $amount - $imponibile;
|
|
|
|
|
- Log::info("Imposta calculated: " . $imposta);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ $imposta = $imponibile !== null ? $amount - $imponibile : null;
|
|
|
|
|
|
|
|
$recordRowData = [
|
|
$recordRowData = [
|
|
|
'record_id' => $this->dataId,
|
|
'record_id' => $this->dataId,
|
|
|
'causal_id' => $row["causal_id"],
|
|
'causal_id' => $row["causal_id"],
|
|
|
'note' => $row["note"],
|
|
'note' => $row["note"],
|
|
|
- 'amount' => $this->currencyToDouble($row["amount"]),
|
|
|
|
|
- 'commercial' => $row["commercial"],
|
|
|
|
|
- 'when' => json_encode($row["when"]),
|
|
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
'imponibile' => $imponibile,
|
|
'imponibile' => $imponibile,
|
|
|
'aliquota_iva' => $aliquota_iva,
|
|
'aliquota_iva' => $aliquota_iva,
|
|
|
'imposta' => $imposta,
|
|
'imposta' => $imposta,
|
|
|
|
|
+ 'commercial' => $row["commercial"],
|
|
|
|
|
+ 'when' => json_encode($row["when"]),
|
|
|
'divisa' => 'EUR',
|
|
'divisa' => 'EUR',
|
|
|
|
|
+ 'created_at' => now(),
|
|
|
|
|
+ 'updated_at' => now()
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
if (isset($row["id"]) && isset($existingRows[$row["id"]])) {
|
|
if (isset($row["id"]) && isset($existingRows[$row["id"]])) {
|
|
@@ -616,21 +812,74 @@ class RecordOUT extends Component
|
|
|
$recordRowData['numero_linea'] = $existingRow['numero_linea'];
|
|
$recordRowData['numero_linea'] = $existingRow['numero_linea'];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Log::info("RecordRowData: " . json_encode($recordRowData));
|
|
|
|
|
- \App\Models\RecordRow::create($recordRowData);
|
|
|
|
|
- $tot += $this->currencyToDouble($row["amount"]);
|
|
|
|
|
|
|
+ $newRowsData[] = $recordRowData;
|
|
|
|
|
+ $tot += $amount;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ \App\Models\RecordRow::insert($newRowsData);
|
|
|
|
|
+ $record->amount = $tot;
|
|
|
|
|
+ $record->save();
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+ Log::info("Database transaction committed");
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ $this->emit('update-loading', 'Preparazione file per elaborazione...');
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ Log::info("=== STARTING FILE PROCESSING (UPDATE) ===");
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->attachment_old) {
|
|
|
|
|
+ $this->recordFileService->deleteAttachment($this->attachment_old);
|
|
|
|
|
+ Log::info("Old attachment deleted: {$this->attachment_old}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $tempPath = $this->recordFileService->storeTemporarily($this->attachment);
|
|
|
|
|
+ $originalFileName = $this->attachment->getClientOriginalName();
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("File stored temporarily at: {$tempPath}");
|
|
|
|
|
+
|
|
|
|
|
+ $clientName = session('clientName', 'default');
|
|
|
|
|
+
|
|
|
|
|
+ ProcessRecordAttachment::dispatch(
|
|
|
|
|
+ $record->id,
|
|
|
|
|
+ $tempPath,
|
|
|
|
|
+ $originalFileName,
|
|
|
|
|
+ 'out',
|
|
|
|
|
+ $clientName
|
|
|
|
|
+ )->onQueue('attachments');
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("File processing job dispatched for record {$record->id}");
|
|
|
|
|
+ } catch (\Exception $ex) {
|
|
|
|
|
+ Log::error("Failed to process file: " . $ex->getMessage());
|
|
|
|
|
+ Log::error("Stack trace: " . $ex->getTraceAsString());
|
|
|
|
|
+
|
|
|
|
|
+ DB::table('records')
|
|
|
|
|
+ ->where('id', $record->id)
|
|
|
|
|
+ ->update(['attachment_status' => 'failed']);
|
|
|
|
|
+
|
|
|
|
|
+ session()->flash('warning', 'Record aggiornato ma elaborazione allegato fallita. Prova a modificare il record e caricare nuovamente il file.');
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $rec = \App\Models\Record::findOrFail($this->dataId);
|
|
|
|
|
- $rec->amount = $tot;
|
|
|
|
|
- $rec->save();
|
|
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->attachment) {
|
|
|
|
|
+ session()->flash('success', 'Movimento aggiornato con successo. L\'allegato verrà elaborato in background. Aggiorna la pagina tra qualche secondo per vedere lo stato.');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ session()->flash('success', 'Movimento aggiornato con successo.');
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- session()->flash('success', 'Movimento aggiornato');
|
|
|
|
|
$this->resetFields();
|
|
$this->resetFields();
|
|
|
$this->update = false;
|
|
$this->update = false;
|
|
|
$this->emit('setEdit', false);
|
|
$this->emit('setEdit', false);
|
|
|
} catch (\Exception $ex) {
|
|
} catch (\Exception $ex) {
|
|
|
- $this->emit('flash-error', 'Errore (' . $ex->getMessage() . ')');
|
|
|
|
|
|
|
+ DB::rollback();
|
|
|
|
|
+ $this->emit('stop-loading');
|
|
|
|
|
+
|
|
|
|
|
+ Log::error("Update error: " . $ex->getMessage());
|
|
|
|
|
+ Log::error("Stack trace: " . $ex->getTraceAsString());
|
|
|
|
|
+ $this->emit('flash-error', 'Errore durante l\'aggiornamento: ' . $ex->getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -645,18 +894,28 @@ class RecordOUT extends Component
|
|
|
public function delete($id)
|
|
public function delete($id)
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
- \App\Models\Record::find($id)->delete();
|
|
|
|
|
|
|
+ $record = \App\Models\Record::find($id);
|
|
|
|
|
+ if ($record->attachment) {
|
|
|
|
|
+ $this->recordFileService->deleteAttachment($record->attachment);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $record->delete();
|
|
|
session()->flash('success', "Movimento eliminato");
|
|
session()->flash('success', "Movimento eliminato");
|
|
|
} catch (\Exception $e) {
|
|
} catch (\Exception $e) {
|
|
|
$this->emit('flash-error', 'Errore (' . $e->getMessage() . ')');
|
|
$this->emit('flash-error', 'Errore (' . $e->getMessage() . ')');
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
public function multipleDelete()
|
|
public function multipleDelete()
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
foreach ($this->multipleIds as $id) {
|
|
foreach ($this->multipleIds as $id) {
|
|
|
- \App\Models\Record::find($id)->delete();
|
|
|
|
|
|
|
+ $record = \App\Models\Record::find($id);
|
|
|
|
|
+
|
|
|
|
|
+ if ($record->attachment) {
|
|
|
|
|
+ $this->recordFileService->deleteAttachment($record->attachment);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $record->delete();
|
|
|
}
|
|
}
|
|
|
} catch (\Exception $e) {
|
|
} catch (\Exception $e) {
|
|
|
$this->emit('flash-error', 'Errore (' . $e->getMessage() . ')');
|
|
$this->emit('flash-error', 'Errore (' . $e->getMessage() . ')');
|
|
@@ -664,6 +923,15 @@ class RecordOUT extends Component
|
|
|
$this->multipleAction = '';
|
|
$this->multipleAction = '';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function getAttachmentUrl($filePath)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!$filePath) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $this->recordFileService->getAttachmentUrl($filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function currencyToDouble($val)
|
|
function currencyToDouble($val)
|
|
|
{
|
|
{
|
|
|
$x = str_replace("€", "", $val);
|
|
$x = str_replace("€", "", $val);
|
|
@@ -749,10 +1017,10 @@ class RecordOUT extends Component
|
|
|
public function importReceipts()
|
|
public function importReceipts()
|
|
|
{
|
|
{
|
|
|
$this->validate([
|
|
$this->validate([
|
|
|
- //'receiptFiles.*' => 'required|mimes:xml|max:2048',
|
|
|
|
|
'selectedCausal' => 'required|exists:causals,id',
|
|
'selectedCausal' => 'required|exists:causals,id',
|
|
|
]);
|
|
]);
|
|
|
Log::info("Importazione ricevute: " . json_encode($this->receiptFiles));
|
|
Log::info("Importazione ricevute: " . json_encode($this->receiptFiles));
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
$importCount = 0;
|
|
$importCount = 0;
|
|
|
$updateCount = 0;
|
|
$updateCount = 0;
|
|
@@ -771,6 +1039,7 @@ class RecordOUT extends Component
|
|
|
try {
|
|
try {
|
|
|
$fileName = $receiptFile->getClientOriginalName();
|
|
$fileName = $receiptFile->getClientOriginalName();
|
|
|
Log::info("Elaborazione file: " . $fileName);
|
|
Log::info("Elaborazione file: " . $fileName);
|
|
|
|
|
+
|
|
|
// Carica e analizza il file XML
|
|
// Carica e analizza il file XML
|
|
|
$xmlString = file_get_contents($receiptFile->getRealPath());
|
|
$xmlString = file_get_contents($receiptFile->getRealPath());
|
|
|
$xml = simplexml_load_string($xmlString);
|
|
$xml = simplexml_load_string($xmlString);
|
|
@@ -792,7 +1061,7 @@ class RecordOUT extends Component
|
|
|
// Estrai i dati dalla fattura elettronica
|
|
// Estrai i dati dalla fattura elettronica
|
|
|
$fatturaData = $this->extractFatturaData($xml);
|
|
$fatturaData = $this->extractFatturaData($xml);
|
|
|
|
|
|
|
|
- // Trova o crea il fornitorez
|
|
|
|
|
|
|
+ // Trova o crea il fornitore
|
|
|
$supplier = $this->findOrCreateSupplier($fatturaData);
|
|
$supplier = $this->findOrCreateSupplier($fatturaData);
|
|
|
|
|
|
|
|
// Trova il metodo di pagamento
|
|
// Trova il metodo di pagamento
|
|
@@ -808,16 +1077,27 @@ class RecordOUT extends Component
|
|
|
$record = $this->updateRecord($existingRecord, $paymentMethodId, $fatturaData);
|
|
$record = $this->updateRecord($existingRecord, $paymentMethodId, $fatturaData);
|
|
|
$isUpdate = true;
|
|
$isUpdate = true;
|
|
|
$updateCount++;
|
|
$updateCount++;
|
|
|
- $updatedFiles[] = $fileName; // Aggiungiamo il nome del file alla lista degli aggiornati
|
|
|
|
|
|
|
+ $updatedFiles[] = $fileName;
|
|
|
Log::info("Fattura aggiornata con successo: {$fatturaData['numeroFattura']}, Fornitore: {$supplier->name}");
|
|
Log::info("Fattura aggiornata con successo: {$fatturaData['numeroFattura']}, Fornitore: {$supplier->name}");
|
|
|
} else {
|
|
} else {
|
|
|
// Crea un nuovo record
|
|
// Crea un nuovo record
|
|
|
$record = $this->createRecord($supplier->id, $paymentMethodId, $fatturaData);
|
|
$record = $this->createRecord($supplier->id, $paymentMethodId, $fatturaData);
|
|
|
$importCount++;
|
|
$importCount++;
|
|
|
- $importedFiles[] = $fileName; // Aggiungiamo il nome del file alla lista degli importati
|
|
|
|
|
|
|
+ $importedFiles[] = $fileName;
|
|
|
Log::info("Fattura importata con successo: {$fatturaData['numeroFattura']}, Fornitore: {$supplier->name}");
|
|
Log::info("Fattura importata con successo: {$fatturaData['numeroFattura']}, Fornitore: {$supplier->name}");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ $this->recordFileService->createRecordFolders($record->id, 'OUT');
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $xmlAttachmentPath = $this->recordFileService->uploadXmlReceipt($receiptFile, $record->id, 'OUT');
|
|
|
|
|
+ $record->update(['attachment' => $xmlAttachmentPath]);
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("XML receipt stored as attachment: " . $xmlAttachmentPath);
|
|
|
|
|
+ } catch (\Exception $ex) {
|
|
|
|
|
+ Log::warning("Could not store XML as attachment: " . $ex->getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Crea il record row
|
|
// Crea il record row
|
|
|
$this->createRecordRow($record->id, $fatturaData);
|
|
$this->createRecordRow($record->id, $fatturaData);
|
|
|
|
|
|
|
@@ -1104,7 +1384,7 @@ class RecordOUT extends Component
|
|
|
|
|
|
|
|
if ($record->data_pagamento != null) {
|
|
if ($record->data_pagamento != null) {
|
|
|
$record->is_paid = true;
|
|
$record->is_paid = true;
|
|
|
- }else {
|
|
|
|
|
|
|
+ } else {
|
|
|
$record->is_paid = false;
|
|
$record->is_paid = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1439,7 +1719,8 @@ class RecordOUT extends Component
|
|
|
$this->reset(['receiptFiles']);
|
|
$this->reset(['receiptFiles']);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function getFriendlyErrorMessage($errorMessage) {
|
|
|
|
|
|
|
+ private function getFriendlyErrorMessage($errorMessage)
|
|
|
|
|
+ {
|
|
|
// Errore di parsing XML iniziale
|
|
// Errore di parsing XML iniziale
|
|
|
if (strpos($errorMessage, "simplexml_load_string(): Entity: line 1: parser error : Start tag expected, '<' not found") !== false) {
|
|
if (strpos($errorMessage, "simplexml_load_string(): Entity: line 1: parser error : Start tag expected, '<' not found") !== false) {
|
|
|
return "Il file non è in formato valido. Potrebbe essere danneggiato o in un formato diverso.";
|
|
return "Il file non è in formato valido. Potrebbe essere danneggiato o in un formato diverso.";
|
|
@@ -1456,8 +1737,10 @@ class RecordOUT extends Component
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Errori di struttura interna
|
|
// Errori di struttura interna
|
|
|
- if (strpos($errorMessage, "Undefined index") !== false ||
|
|
|
|
|
- strpos($errorMessage, "Trying to get property") !== false) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ strpos($errorMessage, "Undefined index") !== false ||
|
|
|
|
|
+ strpos($errorMessage, "Trying to get property") !== false
|
|
|
|
|
+ ) {
|
|
|
return "La fattura è incompleta o non contiene tutti i dati necessari.";
|
|
return "La fattura è incompleta o non contiene tutti i dati necessari.";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1468,14 +1751,11 @@ class RecordOUT extends Component
|
|
|
public function getVats()
|
|
public function getVats()
|
|
|
{
|
|
{
|
|
|
$vats = array();
|
|
$vats = array();
|
|
|
- foreach($this->rows as $r)
|
|
|
|
|
- {
|
|
|
|
|
- if ($r["amount"] != null && $r["amount"] != "" && $r["vat_id"] > 0)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ foreach ($this->rows as $r) {
|
|
|
|
|
+ if ($r["amount"] != null && $r["amount"] != "" && $r["vat_id"] > 0) {
|
|
|
$vat = getVatValue($this->currencyToDouble($r["amount"]), $r["vat_id"]);
|
|
$vat = getVatValue($this->currencyToDouble($r["amount"]), $r["vat_id"]);
|
|
|
$vatName = "";
|
|
$vatName = "";
|
|
|
- foreach($this->vats as $v)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ foreach ($this->vats as $v) {
|
|
|
if ($v->id == $r["vat_id"])
|
|
if ($v->id == $r["vat_id"])
|
|
|
$vatName = $v->name;
|
|
$vatName = $v->name;
|
|
|
}
|
|
}
|
|
@@ -1519,39 +1799,95 @@ class RecordOUT extends Component
|
|
|
return $newVat->id;
|
|
return $newVat->id;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-public function viewData($id)
|
|
|
|
|
-{
|
|
|
|
|
- Log::info("Visualizzazione dati per ID: " . $id);
|
|
|
|
|
- try {
|
|
|
|
|
- $record = \App\Models\Record::with(['supplier', 'payment_method', 'rows.causal'])->findOrFail($id);
|
|
|
|
|
|
|
+ public function viewData($id)
|
|
|
|
|
+ {
|
|
|
|
|
+ Log::info("Visualizzazione dati per ID: " . $id);
|
|
|
|
|
+ try {
|
|
|
|
|
+ $record = \App\Models\Record::with(['supplier', 'payment_method', 'rows.causal'])->findOrFail($id);
|
|
|
|
|
|
|
|
- if (!$record) {
|
|
|
|
|
- $this->emit('flash-error', 'Movimento non trovato');
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ if (!$record) {
|
|
|
|
|
+ $this->emit('flash-error', 'Movimento non trovato');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $record->formatted_date = date("d/m/Y", strtotime($record->date));
|
|
|
|
|
+ $record->formatted_data_pagamento = $record->data_pagamento ? date("d/m/Y", strtotime($record->data_pagamento)) : 'Non impostata';
|
|
|
|
|
+ $record->supplier_name = $record->supplier ? $record->supplier->name : 'N/A';
|
|
|
|
|
+ $record->payment_method_name = $record->payment_method ? $record->payment_method->name : 'N/A';
|
|
|
|
|
+ $record->formatted_amount = formatPrice($record->amount);
|
|
|
|
|
+ $record->payment_status = $record->is_paid ? 'Pagato' : 'Da Pagare';
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($record->rows as $row) {
|
|
|
|
|
+ $row->causal_name = $row->causal ? $row->causal->getTree() : 'N/A';
|
|
|
|
|
+ $row->formatted_imponibile = $row->imponibile ? formatPrice($row->imponibile) : 'N/A';
|
|
|
|
|
+ $row->iva = $row->aliquota_iva ? formatPrice($row->aliquota_iva) : 'N/A';
|
|
|
|
|
+ $row->formatted_imposta = $row->imposta ? formatPrice($row->imposta) : 'N/A';
|
|
|
|
|
+ $row->formatted_amount = formatPrice($row->amount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($record->attachment) {
|
|
|
|
|
+ $record->attachment_url = $this->getAttachmentUrl($record->attachment);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Log::info("Emitting show-record-details event");
|
|
|
|
|
+ $this->dispatchBrowserEvent('show-record-details', ['record' => $record]);
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ Log::error("Errore nel caricamento dei dettagli: " . $e->getMessage());
|
|
|
|
|
+ $this->emit('flash-error', 'Errore nel caricamento dei dettagli: ' . $e->getMessage());
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getUploadProgressProperty()
|
|
|
|
|
+ {
|
|
|
|
|
+ return $this->uploadProgress;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- $record->formatted_date = date("d/m/Y", strtotime($record->date));
|
|
|
|
|
- $record->formatted_data_pagamento = $record->data_pagamento ? date("d/m/Y", strtotime($record->data_pagamento)) : 'Non impostata';
|
|
|
|
|
- $record->supplier_name = $record->supplier ? $record->supplier->name : 'N/A';
|
|
|
|
|
- $record->payment_method_name = $record->payment_method ? $record->payment_method->name : 'N/A';
|
|
|
|
|
- $record->formatted_amount = formatPrice($record->amount);
|
|
|
|
|
- $record->payment_status = $record->is_paid ? 'Pagato' : 'Da Pagare';
|
|
|
|
|
-
|
|
|
|
|
- foreach ($record->rows as $row) {
|
|
|
|
|
- $row->causal_name = $row->causal ? $row->causal->getTree() : 'N/A';
|
|
|
|
|
- $row->formatted_imponibile = $row->imponibile ? formatPrice($row->imponibile) : 'N/A';
|
|
|
|
|
- $row->iva = $row->aliquota_iva ? formatPrice($row->aliquota_iva) : 'N/A';
|
|
|
|
|
- $row->formatted_imposta = $row->imposta ? formatPrice($row->imposta) : 'N/A';
|
|
|
|
|
- $row->formatted_amount = formatPrice($row->amount);
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get upload status
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getUploadStatusProperty()
|
|
|
|
|
+ {
|
|
|
|
|
+ return $this->attachmentUploadStatus;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Check if file upload is in progress
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getIsUploadingProperty()
|
|
|
|
|
+ {
|
|
|
|
|
+ return $this->attachmentUploadStatus === 'pending';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get estimated upload time remaining (in seconds)
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getEstimatedTimeRemainingProperty()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!$this->uploadStartTime || $this->uploadProgress <= 0) {
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Log::info("Emitting show-record-details event");
|
|
|
|
|
- $this->dispatchBrowserEvent('show-record-details', ['record' => $record]);
|
|
|
|
|
|
|
+ $elapsed = microtime(true) - $this->uploadStartTime;
|
|
|
|
|
+ $rate = $this->uploadProgress / $elapsed;
|
|
|
|
|
+ $remaining = (100 - $this->uploadProgress) / $rate;
|
|
|
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
- Log::error("Errore nel caricamento dei dettagli: " . $e->getMessage());
|
|
|
|
|
- $this->emit('flash-error', 'Errore nel caricamento dei dettagli: ' . $e->getMessage());
|
|
|
|
|
|
|
+ return max(0, round($remaining));
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get file upload speed (KB/s)
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getUploadSpeedProperty()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!$this->uploadStartTime || !$this->attachment) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $elapsed = microtime(true) - $this->uploadStartTime;
|
|
|
|
|
+ $fileSize = $this->attachment->getSize();
|
|
|
|
|
+ $uploadedBytes = ($this->uploadProgress / 100) * $fileSize;
|
|
|
|
|
+ $speed = $uploadedBytes / $elapsed; // bytes per second
|
|
|
|
|
+
|
|
|
|
|
+ return round($speed / 1024, 1); // KB per second
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|