Ensure tax codes that are sent are correct
This commit is contained in:
parent
084f0fea25
commit
70dea557f5
|
|
@ -158,12 +158,16 @@ class EntityLevel implements EntityLevelInterface
|
|||
continue;
|
||||
}
|
||||
|
||||
if($field == 'vat_number' && $client->classification == 'individual') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$errors[] = ['field' => $field, 'label' => ctrans("texts.{$field}")];
|
||||
|
||||
}
|
||||
|
||||
//If not an individual, you MUST have a VAT number if you are in the EU
|
||||
if (!$this->validString($client->vat_number)) {
|
||||
if ($client->classification != 'individual' && !$this->validString($client->vat_number)) {
|
||||
$errors[] = ['field' => 'vat_number', 'label' => ctrans("texts.vat_number")];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,17 @@ class Desglose extends BaseXmlModel
|
|||
{
|
||||
$root = $this->createElement($doc, 'Desglose');
|
||||
|
||||
// If we have a DetalleDesglose object, use it
|
||||
// If we have DetalleDesglose objects in the desgloseIVA array, use them
|
||||
if ($this->desgloseIVA !== null && is_array($this->desgloseIVA) && count($this->desgloseIVA) > 0) {
|
||||
foreach ($this->desgloseIVA as $detalleDesglose) {
|
||||
if ($detalleDesglose instanceof DetalleDesglose) {
|
||||
$root->appendChild($detalleDesglose->toXml($doc));
|
||||
}
|
||||
}
|
||||
return $root;
|
||||
}
|
||||
|
||||
// If we have a single DetalleDesglose object, use it
|
||||
if ($this->detalleDesglose !== null) {
|
||||
$root->appendChild($this->detalleDesglose->toXml($doc));
|
||||
return $root;
|
||||
|
|
@ -48,29 +58,28 @@ class Desglose extends BaseXmlModel
|
|||
$this->desgloseFactura['CalificacionOperacion'] ?? 'S1'));
|
||||
|
||||
// Add TipoImpositivo if present
|
||||
if (isset($this->desgloseFactura['TipoImpositivo'])) {
|
||||
if (isset($this->desgloseFactura['TipoImpositivo']) && $this->desgloseFactura['CalificacionOperacion'] == 'S1') {
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'TipoImpositivo',
|
||||
number_format((float)$this->desgloseFactura['TipoImpositivo'], 2, '.', '')));
|
||||
} else {
|
||||
// Default TipoImpositivo
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'TipoImpositivo', '21.00'));
|
||||
}
|
||||
// else {
|
||||
// // Default TipoImpositivo
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'TipoImpositivo', '0'));
|
||||
// }
|
||||
|
||||
// Convert BaseImponible to BaseImponibleOimporteNoSujeto if needed
|
||||
$baseImponible = isset($this->desgloseFactura['BaseImponible'])
|
||||
? $this->desgloseFactura['BaseImponible']
|
||||
: ($this->desgloseFactura['BaseImponibleOimporteNoSujeto'] ?? '100.00');
|
||||
: ($this->desgloseFactura['BaseImponibleOimporteNoSujeto'] ?? '0');
|
||||
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto',
|
||||
number_format((float)$baseImponible, 2, '.', '')));
|
||||
|
||||
// Convert Cuota to CuotaRepercutida if needed
|
||||
$cuota = isset($this->desgloseFactura['Cuota'])
|
||||
? $this->desgloseFactura['Cuota']
|
||||
: ($this->desgloseFactura['CuotaRepercutida'] ?? '21.00');
|
||||
|
||||
if(isset($this->desgloseFactura['Cuota']) && $this->desgloseFactura['CalificacionOperacion'] == 'S1'){
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'CuotaRepercutida',
|
||||
number_format((float)$cuota, 2, '.', '')));
|
||||
number_format((float)$this->desgloseFactura['Cuota'], 2, '.', '')));
|
||||
}
|
||||
|
||||
// Add TipoRecargoEquivalencia if present
|
||||
if (isset($this->desgloseFactura['TipoRecargoEquivalencia'])) {
|
||||
|
|
@ -110,7 +119,7 @@ class Desglose extends BaseXmlModel
|
|||
// Convert BaseImponible to BaseImponibleOimporteNoSujeto if needed
|
||||
$baseImponible = isset($desglose['BaseImponible'])
|
||||
? $desglose['BaseImponible']
|
||||
: ($desglose['BaseImponibleOimporteNoSujeto'] ?? '100.00');
|
||||
: ($desglose['BaseImponibleOimporteNoSujeto'] ?? '0');
|
||||
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto',
|
||||
number_format((float)$baseImponible, 2, '.', '')));
|
||||
|
|
@ -118,7 +127,7 @@ class Desglose extends BaseXmlModel
|
|||
// Convert Cuota to CuotaRepercutida if needed
|
||||
$cuota = isset($desglose['Cuota'])
|
||||
? $desglose['Cuota']
|
||||
: ($desglose['CuotaRepercutida'] ?? '21.00');
|
||||
: ($desglose['CuotaRepercutida'] ?? '0');
|
||||
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'CuotaRepercutida',
|
||||
number_format((float)$cuota, 2, '.', '')));
|
||||
|
|
@ -147,7 +156,7 @@ class Desglose extends BaseXmlModel
|
|||
// Convert BaseImponible to BaseImponibleOimporteNoSujeto if needed
|
||||
$baseImponible = isset($this->desgloseIVA['BaseImponible'])
|
||||
? $this->desgloseIVA['BaseImponible']
|
||||
: ($this->desgloseIVA['BaseImponibleOimporteNoSujeto'] ?? '100.00');
|
||||
: ($this->desgloseIVA['BaseImponibleOimporteNoSujeto'] ?? '');
|
||||
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto',
|
||||
number_format((float)$baseImponible, 2, '.', '')));
|
||||
|
|
@ -155,7 +164,7 @@ class Desglose extends BaseXmlModel
|
|||
// Convert Cuota to CuotaRepercutida if needed
|
||||
$cuota = isset($this->desgloseIVA['Cuota'])
|
||||
? $this->desgloseIVA['Cuota']
|
||||
: ($this->desgloseIVA['CuotaRepercutida'] ?? '21.00');
|
||||
: ($this->desgloseIVA['CuotaRepercutida'] ?? '0');
|
||||
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'CuotaRepercutida',
|
||||
number_format((float)$cuota, 2, '.', '')));
|
||||
|
|
@ -164,16 +173,16 @@ class Desglose extends BaseXmlModel
|
|||
}
|
||||
}
|
||||
|
||||
// If we still don't have any data, create a default DetalleDesglose
|
||||
if (!$detalleDesglose->hasChildNodes()) {
|
||||
// Create a default DetalleDesglose with basic IVA information
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'Impuesto', '01'));
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'ClaveRegimen', '01'));
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'CalificacionOperacion', 'S1'));
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'TipoImpositivo', '21.00'));
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto', '100.00'));
|
||||
$detalleDesglose->appendChild($this->createElement($doc, 'CuotaRepercutida', '21.00'));
|
||||
}
|
||||
// // If we still don't have any data, create a default DetalleDesglose
|
||||
// if (!$detalleDesglose->hasChildNodes()) {
|
||||
// // Create a default DetalleDesglose with basic IVA information
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'Impuesto', '01'));
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'ClaveRegimen', '01'));
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'CalificacionOperacion', 'S1'));
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'TipoImpositivo', '0'));
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto', '0'));
|
||||
// $detalleDesglose->appendChild($this->createElement($doc, 'CuotaRepercutida', '0'));
|
||||
// }
|
||||
|
||||
$root->appendChild($detalleDesglose);
|
||||
return $root;
|
||||
|
|
@ -291,6 +300,12 @@ class Desglose extends BaseXmlModel
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function addDesgloseIVA(DetalleDesglose $desgloseIVA): self
|
||||
{
|
||||
$this->desgloseIVA[] = $desgloseIVA;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDesgloseIGIC(): ?array
|
||||
{
|
||||
return $this->desgloseIGIC;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,21 @@ class DetalleDesglose extends BaseXmlModel
|
|||
|
||||
// Add IVA details directly under DetalleDesglose
|
||||
$root->appendChild($this->createElement($doc, 'Impuesto', $this->desgloseIVA['Impuesto']));
|
||||
|
||||
if(isset($this->desgloseIVA['ClaveRegimen']) && in_array($this->desgloseIVA['ClaveRegimen'], ['01','03'])){
|
||||
$root->appendChild($this->createElement($doc, 'ClaveRegimen', $this->desgloseIVA['ClaveRegimen']));
|
||||
$root->appendChild($this->createElement($doc, 'CalificacionOperacion', $this->desgloseIVA['CalificacionOperacion'] ?? 'S1'));
|
||||
}
|
||||
|
||||
$root->appendChild($this->createElement($doc, 'CalificacionOperacion', $this->desgloseIVA['CalificacionOperacion']));
|
||||
|
||||
if(isset($this->desgloseIVA['TipoImpositivo']) && $this->desgloseIVA['CalificacionOperacion'] == 'S1') {
|
||||
$root->appendChild($this->createElement($doc, 'TipoImpositivo', (string)$this->desgloseIVA['TipoImpositivo']));
|
||||
}
|
||||
$root->appendChild($this->createElement($doc, 'BaseImponibleOimporteNoSujeto', (string)$this->desgloseIVA['BaseImponible']));
|
||||
|
||||
if(isset($this->desgloseIVA['Cuota']) && $this->desgloseIVA['CalificacionOperacion'] == 'S1') {
|
||||
$root->appendChild($this->createElement($doc, 'CuotaRepercutida', (string)$this->desgloseIVA['Cuota']));
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class IDOtro extends BaseXmlModel
|
|||
* @param string $id Identifier value, e.g., passport number, tax ID, or placeholder
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(private string $codigoPais = 'ES', private string $idType = '07', private string $id = 'NO_DISPONIBLE')
|
||||
public function __construct(private string $codigoPais = 'ES', private string $idType = '06', private string $id = 'NO_DISPONIBLE')
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use App\Services\EDocument\Standards\Verifactu\Models\IDOtro;
|
|||
use App\Services\EDocument\Standards\Verifactu\Models\Desglose;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\IDFactura;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\Encadenamiento;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\DetalleDesglose;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\RegistroAnterior;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\SistemaInformatico;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\PersonaFisicaJuridica;
|
||||
|
|
@ -58,7 +59,9 @@ class RegistroAlta
|
|||
'01' => 'IVA (Impuesto sobre el Valor Añadido)', // Value Added Tax - Standard Spanish VAT
|
||||
'02' => 'IPSI (Impuesto sobre la Producción, los Servicios y la Importación)', // Production, Services and Import Tax - Ceuta and Melilla
|
||||
'03' => 'IGIC (Impuesto General Indirecto Canario)', // Canary Islands General Indirect Tax
|
||||
'05' => 'Otros (Others)' // Other taxes
|
||||
'05' => 'Otros (Others)', // Other taxes
|
||||
'06' => 'IAE', //local taxes - rarely used
|
||||
'07' => 'Non-Vat / Exempt operations'
|
||||
];
|
||||
|
||||
private array $clave_regimen_codes = [
|
||||
|
|
@ -141,9 +144,10 @@ class RegistroAlta
|
|||
->setNombreRazon($this->invoice->client->present()->name());
|
||||
}
|
||||
else {
|
||||
$locationData = $this->invoice->location();
|
||||
$locationData = $this->invoice->service()->location();
|
||||
|
||||
$destinatario = new IDOtro();
|
||||
$destinatario->setNombreRazon($this->invoice->client->present()->name());
|
||||
$destinatario->setCodigoPais($locationData['country_code']);
|
||||
|
||||
$br = new \App\DataMapper\Tax\BaseRule();
|
||||
|
|
@ -168,18 +172,60 @@ class RegistroAlta
|
|||
|
||||
foreach ($taxes as $tax) {
|
||||
|
||||
$desglose_iva[] = [
|
||||
$desglose_iva = [
|
||||
'Impuesto' => $this->calculateTaxType($tax['name']), //tax type
|
||||
'ClaveRegimen' => '01', //tax regime classification code
|
||||
'CalificacionOperacion' => 'S1', //operation classification code
|
||||
'BaseImponibleOimporteNoSujeto' => $tax['base_amount'] ?? $this->calc->getNetSubtotal(), // taxable base amount
|
||||
'ClaveRegimen' => $this->calculateRegimeClassification($tax['name']), //tax regime classification code
|
||||
'CalificacionOperacion' => $this->calculateOperationClassification($tax['name']), //operation classification code
|
||||
'BaseImponible' => $tax['base_amount'] ?? $this->calc->getNetSubtotal(), // taxable base amount - fixed: key matches DetalleDesglose::toXml()
|
||||
'TipoImpositivo' => $tax['tax_rate'], // Tax Rate
|
||||
'CuotaRepercutida' => $tax['total'] // Tax Amount
|
||||
'Cuota' => $tax['total'] // Tax Amount - fixed: key matches DetalleDesglose::toXml()
|
||||
];
|
||||
|
||||
$detalle_desglose = new DetalleDesglose();
|
||||
$detalle_desglose->setDesgloseIVA($desglose_iva);
|
||||
$desglose->addDesgloseIVA($detalle_desglose);
|
||||
|
||||
};
|
||||
|
||||
$desglose->setDesgloseIVA($desglose_iva);
|
||||
if(count($taxes) == 0) {
|
||||
nlog("tax count = 0");
|
||||
$client_country_code = $this->invoice->client->country->iso_3166_2;
|
||||
|
||||
$impuesto = 'S2';
|
||||
$clave_regimen = '08';
|
||||
$calificacion = 'S1';
|
||||
|
||||
$br = new \App\DataMapper\Tax\BaseRule();
|
||||
|
||||
if (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification != 'individual') {
|
||||
$impuesto = '05';
|
||||
$clave_regimen = '05';
|
||||
$calificacion = 'N2';
|
||||
}
|
||||
elseif (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification == 'individual') {
|
||||
$impuesto = '08';
|
||||
$clave_regimen = '05';
|
||||
$calificacion = 'N2';
|
||||
}
|
||||
else{
|
||||
$impuesto = '08';
|
||||
$clave_regimen = '01';
|
||||
$calificacion = 'N2';
|
||||
}
|
||||
|
||||
$desglose_iva = [
|
||||
'Impuesto' => $impuesto, //tax type
|
||||
'ClaveRegimen' => $clave_regimen, //tax regime classification code
|
||||
'CalificacionOperacion' => $calificacion, //operation classification code
|
||||
'BaseImponible' => $this->calc->getNetSubtotal(), // taxable base amount - fixed: key matches DetalleDesglose::toXml()
|
||||
|
||||
];
|
||||
|
||||
$detalle_desglose = new DetalleDesglose();
|
||||
$detalle_desglose->setDesgloseIVA($desglose_iva);
|
||||
$desglose->addDesgloseIVA($detalle_desglose);
|
||||
|
||||
}
|
||||
|
||||
$this->v_invoice->setDesglose($desglose);
|
||||
|
||||
|
|
@ -261,8 +307,12 @@ class RegistroAlta
|
|||
return $this->v_invoice;
|
||||
}
|
||||
|
||||
private function calculateTaxType(string $tax_name): string
|
||||
private function calculateRegimeClassification(string $tax_name): string
|
||||
{
|
||||
$client_country_code = $this->invoice->client->country->iso_3166_2;
|
||||
|
||||
if($client_country_code == 'ES') {
|
||||
|
||||
if(stripos($tax_name, 'iva') !== false) {
|
||||
return '01';
|
||||
}
|
||||
|
|
@ -282,4 +332,60 @@ class RegistroAlta
|
|||
return '01';
|
||||
}
|
||||
|
||||
$br = new \App\DataMapper\Tax\BaseRule();
|
||||
if (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification != 'individual') {
|
||||
return '08';
|
||||
} elseif (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification == 'individual') {
|
||||
return '05';
|
||||
}
|
||||
|
||||
return '07';
|
||||
|
||||
}
|
||||
|
||||
private function calculateTaxType(string $tax_name): string
|
||||
{
|
||||
$client_country_code = $this->invoice->client->country->iso_3166_2;
|
||||
|
||||
if($client_country_code == 'ES') {
|
||||
|
||||
if(stripos($tax_name, 'iva') !== false) {
|
||||
return '01';
|
||||
}
|
||||
|
||||
if(stripos($tax_name, 'igic') !== false) {
|
||||
return '03';
|
||||
}
|
||||
|
||||
if(stripos($tax_name, 'ipsi') !== false) {
|
||||
return '02';
|
||||
}
|
||||
|
||||
if(stripos($tax_name, 'otros') !== false) {
|
||||
return '05';
|
||||
}
|
||||
|
||||
return '01';
|
||||
}
|
||||
|
||||
$br = new \App\DataMapper\Tax\BaseRule();
|
||||
if (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification != 'individual') {
|
||||
return '08';
|
||||
}
|
||||
elseif (in_array($client_country_code, $br->eu_country_codes) && $this->invoice->client->classification == 'individual') {
|
||||
return '05';
|
||||
}
|
||||
|
||||
return '07';
|
||||
}
|
||||
|
||||
private function calculateOperationClassification(string $tax_name): string
|
||||
{
|
||||
if($this->invoice->client->country_id == 724 || stripos($tax_name, 'iva') !== false) {
|
||||
return 'S1';
|
||||
}
|
||||
|
||||
return 'N2';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ class SendToAeat implements ShouldQueue
|
|||
$verifactu = new Verifactu($invoice);
|
||||
|
||||
$document = (new RegistroAlta($invoice))->run()->getInvoice();
|
||||
|
||||
$document->setNumSerieFactura($invoice->backup->parent_invoice_number);
|
||||
$last_hash = $invoice->company->verifactu_logs()->first();
|
||||
|
||||
$huella = $this->cancellationHash($document, $last_hash->hash);
|
||||
|
|
|
|||
|
|
@ -714,6 +714,7 @@ class InvoiceService
|
|||
if($new_model && $this->invoice->amount >= 0) {
|
||||
$this->invoice->backup->document_type = 'F1';
|
||||
$this->invoice->backup->adjustable_amount = $this->invoice->amount;
|
||||
$this->invoice->backup->parent_invoice_number = $this->invoice->number;
|
||||
$this->invoice->saveQuietly();
|
||||
}
|
||||
elseif(isset($invoice_array['modified_invoice_id'])) {
|
||||
|
|
@ -726,6 +727,7 @@ class InvoiceService
|
|||
//Update the client balance by the delta amount from the previous invoice to this one.
|
||||
$this->invoice->backup->parent_invoice_id = $modified_invoice->hashed_id;
|
||||
$this->invoice->backup->document_type = 'R2';
|
||||
$this->invoice->backup->parent_invoice_number = $modified_invoice->number;
|
||||
$this->invoice->saveQuietly();
|
||||
|
||||
$this->invoice->client->service()->updateBalance(round(($this->invoice->amount - $modified_invoice->amount), 2));
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@
|
|||
"friendsofphp/php-cs-fixer": "^3.14",
|
||||
"laracasts/cypress": "^3.0",
|
||||
"larastan/larastan": "^2",
|
||||
"laravel/boost": "^1.0",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^8.1",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "df5805c56ea07b9fe22be83885c67387",
|
||||
"content-hash": "a6ef0e9ae03d968020a5c8a976835ad9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adrienrn/php-mimetyper",
|
||||
|
|
@ -18381,6 +18381,196 @@
|
|||
],
|
||||
"time": "2025-06-10T22:06:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/boost",
|
||||
"version": "v1.0.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/boost.git",
|
||||
"reference": "ad025a2f2325ccdc5f52e926dab4e0c1d2c6def9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/boost/zipball/ad025a2f2325ccdc5f52e926dab4e0c1d2c6def9",
|
||||
"reference": "ad025a2f2325ccdc5f52e926dab4e0c1d2c6def9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^7.9",
|
||||
"illuminate/console": "^10.0|^11.0|^12.0",
|
||||
"illuminate/contracts": "^10.0|^11.0|^12.0",
|
||||
"illuminate/routing": "^10.0|^11.0|^12.0",
|
||||
"illuminate/support": "^10.0|^11.0|^12.0",
|
||||
"laravel/mcp": "^0.1.0",
|
||||
"laravel/prompts": "^0.1.9|^0.3",
|
||||
"laravel/roster": "^0.2",
|
||||
"php": "^8.1|^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.14|^1.23",
|
||||
"mockery/mockery": "^1.6",
|
||||
"orchestra/testbench": "^8.22.0|^9.0|^10.0",
|
||||
"pestphp/pest": "^2.0|^3.0",
|
||||
"phpstan/phpstan": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Boost\\BoostServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Boost\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Laravel Boost accelerates AI-assisted development to generate high-quality, Laravel-specific code.",
|
||||
"homepage": "https://github.com/laravel/boost",
|
||||
"keywords": [
|
||||
"ai",
|
||||
"dev",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/boost/issues",
|
||||
"source": "https://github.com/laravel/boost"
|
||||
},
|
||||
"time": "2025-08-13T19:51:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/mcp",
|
||||
"version": "v0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/mcp.git",
|
||||
"reference": "417890c0d8032af9a46a86d16651bbe13946cddf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/mcp/zipball/417890c0d8032af9a46a86d16651bbe13946cddf",
|
||||
"reference": "417890c0d8032af9a46a86d16651bbe13946cddf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/console": "^10.0|^11.0|^12.0",
|
||||
"illuminate/contracts": "^10.0|^11.0|^12.0",
|
||||
"illuminate/http": "^10.0|^11.0|^12.0",
|
||||
"illuminate/routing": "^10.0|^11.0|^12.0",
|
||||
"illuminate/support": "^10.0|^11.0|^12.0",
|
||||
"illuminate/validation": "^10.0|^11.0|^12.0",
|
||||
"php": "^8.1|^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.14",
|
||||
"orchestra/testbench": "^8.22.0|^9.0|^10.0",
|
||||
"phpstan/phpstan": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Mcp": "Laravel\\Mcp\\Server\\Facades\\Mcp"
|
||||
},
|
||||
"providers": [
|
||||
"Laravel\\Mcp\\Server\\McpServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Mcp\\": "src/",
|
||||
"Workbench\\App\\": "workbench/app/",
|
||||
"Laravel\\Mcp\\Tests\\": "tests/",
|
||||
"Laravel\\Mcp\\Server\\": "src/Server/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "The easiest way to add MCP servers to your Laravel app.",
|
||||
"homepage": "https://github.com/laravel/mcp",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"laravel",
|
||||
"mcp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/mcp/issues",
|
||||
"source": "https://github.com/laravel/mcp"
|
||||
},
|
||||
"time": "2025-08-12T07:09:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/roster",
|
||||
"version": "v0.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/roster.git",
|
||||
"reference": "caeed7609b02c00c3f1efec52812d8d87c5d4096"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/roster/zipball/caeed7609b02c00c3f1efec52812d8d87c5d4096",
|
||||
"reference": "caeed7609b02c00c3f1efec52812d8d87c5d4096",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/console": "^10.0|^11.0|^12.0",
|
||||
"illuminate/contracts": "^10.0|^11.0|^12.0",
|
||||
"illuminate/routing": "^10.0|^11.0|^12.0",
|
||||
"illuminate/support": "^10.0|^11.0|^12.0",
|
||||
"php": "^8.1|^8.2",
|
||||
"symfony/yaml": "^6.4|^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.14",
|
||||
"mockery/mockery": "^1.6",
|
||||
"orchestra/testbench": "^8.22.0|^9.0|^10.0",
|
||||
"pestphp/pest": "^2.0|^3.0",
|
||||
"phpstan/phpstan": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Roster\\RosterServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Roster\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Detect packages & approaches in use within a Laravel project",
|
||||
"homepage": "https://github.com/laravel/roster",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/roster/issues",
|
||||
"source": "https://github.com/laravel/roster"
|
||||
},
|
||||
"time": "2025-08-13T15:00:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "1.6.12",
|
||||
|
|
|
|||
Loading…
Reference in New Issue