Initial commit: Horux Backend API

- API REST para gestion de facturas electronicas mexicanas (CFDI)
- Laravel 9 con autenticacion OAuth 2.0 (Passport)
- Integracion con Syntage, Clerk y Facturama
- 30 modelos Eloquent, 39 controladores
- Documentacion completa en /docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 07:44:29 +00:00
commit 61320b44d8
191 changed files with 22895 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
<?php
namespace App\Imports;
use App\Models\Invoice;
use App\Models\Rfc;
use App\Models\InvoiceType;
use App\Models\PaymentType;
use App\Models\PaymentMethod;
use App\Models\Usage;
use App\Models\Currency;
use App\Models\CancellationType;
use App\Models\Taxpayer;
use App\Models\TaxRegime;
use App\Models\Status;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithStartRow;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class InvoicesImport implements ToModel, WithChunkReading, WithHeadingRow, WithStartRow
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
protected $rfc;
public function __construct($rfc)
{
$this->rfc = $rfc;
}
/**
* Método para indicar desde qué fila comenzar a leer.
*/
public function startRow(): int
{
return 2; // Si tienes encabezados, comienza en la fila 2
}
public function model(array $row)
{
$rfc = Rfc::where('rfc', $this->rfc)->firstOrCreate([
'rfc' => $this->rfc
]);
$type = InvoiceType::where('id', $this->emptyToNull($row['type']))->firstOrCreate([
'id' => $row['type']
]);
if ($this->emptyToNull($row['usage'])) {
$usage = Usage::where('id', strip_tags($row['usage']))->firstOrCreate([
'id' => $row['usage']
]); }
if ($this->emptyToNull($row['paymenttype'])) {
$payment_type = PaymentType::where('id', strip_tags($row['paymenttype']))->firstOrCreate([
'id' => $row['paymenttype']
]); }
if ($this->emptyToNull($row['paymentmethod'])) {
$payment_method = PaymentMethod::where('id', strip_tags($row['paymentmethod']))->firstOrCreate([
'id' => $row['paymentmethod']
]); }
if ($this->emptyToNull($row['currency'])) {
$currency = Currency::where('id', strip_tags($row['currency']))->firstOrCreate([
'id' => $row['currency']
]); }
if ($this->emptyToNull($row['status'])) {
$status = Status::where('description', strip_tags($row['status']))->firstOrCreate([
'description' => $row['status']
]); }
if ($this->emptyToNull($row['cancellationstatus'])) {
$cancellationType = CancellationType::where('description', strip_tags($row['cancellationstatus']))->firstOrCreate([
'description' => $row['cancellationstatus']
]); }
if ($this->emptyToNull($row['cancellationprocessstatus'])) {
$cancelStatus = Status::where('description', strip_tags($row['cancellationprocessstatus']))->firstOrCreate([
'description' => $row['cancellationprocessstatus']
]); }
$issuerRfc = Rfc::where('rfc', strip_tags($row['issuerrfc']))->first();
if (!$issuerRfc) {
$issuerRfc = new Rfc();
$issuerRfc->rfc = $row['issuerrfc'];
$issuerRfc->save();
}
$receiverRfc = Rfc::where('rfc', strip_tags($row['receiverrfc']))->first();
if (!$receiverRfc) {
$receiverRfc = new Rfc();
$receiverRfc->rfc = $row['receiverrfc'];
$receiverRfc->save();
}
return Invoice::updateOrCreate(
['id' => $row['uuid']],
[
'rfc_id' => $rfc->id,
'version' => $this->emptyToNull($row['version']),
'invoice_type_id' => $this->emptyToNull($row['type']),
'usage_id' => $this->emptyToNull($row['usage']),
'payment_type_id' => $this->emptyToNull($row['paymenttype']),
'payment_method_id' => $this->emptyToNull($row['paymentmethod']),
'zip_code' => $this->emptyToNull($row['placeofissue']),
'currency_id' => $this->emptyToNull($row['currency']),
'exchange_rate' => $this->emptyToNull($row['exchangerate']),
'status_id' => $this->emptyToNull($status->id),
'pac' => $this->emptyToNull($row['pac']),
'issued_at' => Carbon::createFromFormat('Y-m-d H:i:s', $row['issuedat']),
'certified_at' => Carbon::createFromFormat('Y-m-d H:i:s', $row['certifiedat']),
'cancellation_type_id' => $cancellationType->id,
'cancellation_status_id' => $this->emptyToNull($row['cancellationprocessstatus'] ? $cancelStatus->id : null),
'cancelled_at' => $this->emptyToNull($row['canceledat'] ? Carbon::createFromFormat('Y-m-d H:i:s', $row['canceledat']) : null),
'discount' => $this->emptyToNull($row['discount']),
'tax' => $this->emptyToNull($row['tax']),
'subtotal' => $this->emptyToNull($row['subtotal']),
'total' => $this->emptyToNull($row['total']),
'paid_amount' => $this->emptyToNull($row['paidamount']),
'due_amount' => $this->emptyToNull($row['dueamount']),
'fully_paid_at' => $this->emptyToNull($row['fullypaidat'] ? Carbon::createFromFormat('Y-m-d H:i:s', $row['fullypaidat']) : null),
'last_payment_date' => $this->emptyToNull($row['lastpaymentdate'] ? Carbon::createFromFormat('Y-m-d H:i:s', $row['lastpaymentdate']) : null),
'issuer_rfc_id' => $this->emptyToNull($issuerRfc->id),
'issuer_name' => $this->emptyToNull($row['issuername']),
'receiver_rfc_id' => $receiverRfc->id,
'receiver_name' => $this->emptyToNull($row['receivername']),
'is_issuer' => $this->emptyToNull($row['isissuer']),
'is_receiver' => $this->emptyToNull($row['isreceiver']),
'internal_id' => $this->emptyToNull($row['internalidentifier']),
'reference' => $this->emptyToNull($row['reference']),
'credited_amount' => $this->emptyToNull($row['creditedamount'] ? $row['creditedamount'] : null),
'subtotal_credited_amount' => $this->emptyToNull($row['subtotalcreditedamount'] ? $row['subtotalcreditedamount'] : null),
'applied_taxes' => $this->emptyToNull($row['appliedtaxes']),
'total_transferred_taxes' => $this->emptyToNull($row['totaltransferredtaxes']),
'transferred_local_taxes' => $this->emptyToNull($row['transferredlocaltaxes']),
'transferred_vat' => $this->emptyToNull($row['transferredvalueaddedtax']),
'transferred_sin_tax' => $this->emptyToNull($row['transferredsintax']),
'total_retained_taxes' => $this->emptyToNull($row['totalretainedtaxes']),
'retained_local_taxes' => $this->emptyToNull($row['retainedlocaltaxes']),
'retained_vat' => $this->emptyToNull($row['retainedvalueaddedtax']),
'retained_income_tax' => $this->emptyToNull($row['retainedincometax']),
'retained_sin_tax' => $this->emptyToNull($row['retainedsintax'])
]
);
}
private function emptyToNull($value)
{
return $value === '' ? null : $value;
}
/**
* Devuelve el tamaño del chunk (en filas) a leer.
*/
public function chunkSize(): int
{
return 5000; // Ajusta el tamaño según tus necesidades
}
}