Updates for factuare invoices

This commit is contained in:
David Bomba 2023-05-08 19:11:14 +10:00
parent 0f4113ca57
commit f2df6c2e79
6 changed files with 201 additions and 71 deletions

View File

@ -212,6 +212,9 @@ class FacturaEInvoice extends AbstractService
}
if(count($data) == 0)
$data[Facturae::TAX_IVA] = 0;
return $data;
}
@ -258,29 +261,30 @@ class FacturaEInvoice extends AbstractService
$company = $this->invoice->company;
$seller = new FacturaeParty([
"isLegalEntity" => true, // Se asume true si se omite
"taxNumber" => $company->settings->vat_number,
"name" => $company->present()->name(),
"address" => $company->settings->address1,
"postCode" => $company->settings->postal_code,
"town" => $company->settings->city,
"province" => $company->settings->state,
"countryCode" => $company->country()->iso_3166_3, // Se asume España si se omite
"book" => "0", // Libro
"merchantRegister" => "RG", // Registro Mercantil
"sheet" => "1", // Hoja
"folio" => "2", // Folio
"section" => "3", // Sección
"volume" => "4", // Tomo
"email" => $company->settings->email,
"phone" => $company->settings->phone,
"fax" => "",
"website" => $company->settings->website,
"contactPeople" => $company->owner()->present()->name(),
// "cnoCnae" => "04647", // Clasif. Nacional de Act. Económicas
// "ineTownCode" => "280796" // Cód. de municipio del INE
"isLegalEntity" => true, // Se asume true si se omite
"taxNumber" => $company->settings->vat_number,
"name" => substr($company->present()->name(), 0, 40),
"address" => substr($company->settings->address1, 0, 80),
"postCode" => substr($this->invoice->client->postal_code, 0, 5),
"town" => substr($company->settings->city, 0, 50),
"province" => substr($company->settings->state, 0, 20),
"countryCode" => $company->country()->iso_3166_3, // Se asume España si se omite
"book" => "0", // Libro
"merchantRegister" => "RG", // Registro Mercantil
"sheet" => "1", // Hoja
"folio" => "2", // Folio
"section" => "3", // Sección
"volume" => "4", // Tomo
"email" => substr($company->settings->email, 0, 60),
"phone" => substr($company->settings->phone, 0, 15),
"fax" => "",
"website" => substr($company->settings->website, 0, 50),
"contactPeople" => substr($company->owner()->present()->name(), 0, 40),
// "cnoCnae" => "04647", // Clasif. Nacional de Act. Económicas
// "ineTownCode" => "280796" // Cód. de municipio del INE
]);
$this->fac->setSeller($seller);
return $this;
@ -292,19 +296,19 @@ class FacturaEInvoice extends AbstractService
$buyer = new FacturaeParty([
"isLegalEntity" => $this->invoice->client->has_valid_vat_number,
"taxNumber" => $this->invoice->client->vat_number,
"name" => $this->invoice->client->present()->name(),
"firstSurname" => $this->invoice->client->present()->first_name(),
"lastSurname" => $this->invoice->client->present()->last_name(),
"address" => $this->invoice->client->address1,
"postCode" => $this->invoice->client->postal_code,
"town" => $this->invoice->client->city,
"province" => $this->invoice->client->state,
"name" => substr($this->invoice->client->present()->name(),0, 40),
"firstSurname" => substr($this->invoice->client->present()->first_name(),0, 40),
"lastSurname" => substr($this->invoice->client->present()->last_name(),0, 40),
"address" => substr($this->invoice->client->address1,0, 80),
"postCode" => substr($this->invoice->client->postal_code,0,5),
"town" => substr($this->invoice->client->city,0, 50),
"province" => substr($this->invoice->client->state,0, 20),
"countryCode" => $this->invoice->client->country->iso_3166_3, // Se asume España si se omite
"email" => $this->invoice->client->present()->email(),
"phone" => $this->invoice->client->present()->phone(),
"email" => substr($this->invoice->client->present()->email(),0, 60),
"phone" => substr($this->invoice->client->present()->phone(),0, 15),
"fax" => "",
"website" => substr($this->invoice->client->present()->website(), 0 ,60),
"contactPeople" => $this->invoice->client->present()->first_name()." ".$this->invoice->client->present()->last_name(),
"contactPeople" => substr($this->invoice->client->present()->first_name()." ".$this->invoice->client->present()->last_name(), 0, 40),
// "cnoCnae" => "04791", // Clasif. Nacional de Act. Económicas
// "ineTownCode" => "280796" // Cód. de municipio del INE
]);

View File

@ -16907,9 +16907,10 @@ components:
type: number
example: 8.00
line_items:
description: "Array of line items included in the invoice"
type: object
example: "[{item1}, {item2}]"
type: array
description: 'An array of objects which define the line items of the invoice'
items:
$ref: '#/components/schemas/InvoiceItem'
discount:
description: "The discount applied to the invoice"
type: number
@ -17324,83 +17325,116 @@ components:
quantity:
type: integer
example: 1
description: 'The quantity of the product offered for this line item'
cost:
type: number
format: float
example: 10.00
description: 'The cost of the product offered for this line item'
product_key:
type: string
example: 'Product key'
description: 'The product key of the product offered for this line item (Referred to as Product in the product tab)'
product_cost:
type: number
format: float
example: 10.00
description: 'The cost of the product offered for this line item (Referred to as Cost in the product tab)'
notes:
type: string
example: 'Item notes'
description: 'The notes/description for the product offered for this line item'
discount:
type: number
format: float
example: 5.00
description: 'The discount applied to the product offered for this line item'
is_amount_discount:
type: boolean
example: false
description: 'Indicates whether the discount applied to the product offered for this line item is a fixed amount or a percentage'
tax_name1:
type: string
example: 'Tax name 1'
example: 'GST'
description: 'The name of the first tax applied to the product offered for this line item'
tax_rate1:
type: number
format: float
example: 10.00
description: 'The rate of the first tax applied to the product offered for this line item'
tax_name2:
type: string
example: 'Tax name 2'
example: 'VAT'
description: 'The name of the second tax applied to the product offered for this line item'
tax_rate2:
type: number
format: float
example: 5.00
description: 'The rate of the second tax applied to the product offered for this line item'
tax_name3:
type: string
example: 'Tax name 3'
example: 'CA Sales Tax'
description: 'The name of the third tax applied to the product offered for this line item'
tax_rate3:
type: number
format: float
example: 3.00
description: 'The rate of the third tax applied to the product offered for this line item'
sort_id:
type: string
example: '0'
description: 'Deprecated'
deprecated: true
line_total:
type: number
format: float
example: 10.00
description: 'The total amount of the product offered for this line item'
readOnly: true
gross_line_total:
type: number
format: float
example: 15.00
description: 'The total amount of the product offered for this line item before discounts'
readOnly: true
tax_amount:
type: number
format: float
example: 1.00
description: 'The total amount of tax applied to the product offered for this line item'
readOnly: true
date:
type: string
format: date-time
example: '2023-03-19T00:00:00Z'
description: 'Deprecated'
deprecated: true
custom_value1:
type: string
example: 'Custom value 1'
description: 'The first custom value of the product offered for this line item'
custom_value2:
type: string
example: 'Custom value 2'
description: 'The second custom value of the product offered for this line item'
custom_value3:
type: string
example: 'Custom value 3'
description: 'The third custom value of the product offered for this line item'
custom_value4:
type: string
example: 'Custom value 4'
description: 'The fourth custom value of the product offered for this line item'
type_id:
type: string
example: '1'
description: '1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee, 6 expense'
default: '1'
tax_id:
type: string
example: '1'
default: '1'
description: 'The tax ID of the product: 1 product, 2 service, 3 digital, 4 shipping, 5 exempt, 5 reduced tax, 7 override, 8 zero rate, 9 reverse tax'
CompanyUser:
properties:
permissions:
@ -19431,17 +19465,17 @@ components:
cost:
type: number
format: double
description: 'The cost of the product.'
description: 'The cost of the product. (Your purchase price for this product)'
example: 10.0
price:
type: number
format: double
description: 'The price of the product.'
description: 'The price of the product that you are charging.'
example: 20.0
quantity:
type: number
format: double
description: 'The quantity of the product.'
description: 'The quantity of the product. (used as a default)'
example: 5.0
tax_name1:
type: string

View File

@ -73,9 +73,10 @@
type: number
example: 8.00
line_items:
description: "Array of line items included in the invoice"
type: object
example: "[{item1}, {item2}]"
type: array
description: 'An array of objects which define the line items of the invoice'
items:
$ref: '#/components/schemas/InvoiceItem'
discount:
description: "The discount applied to the invoice"
type: number

View File

@ -4,80 +4,113 @@
quantity:
type: integer
example: 1
description: 'The quantity of the product offered for this line item'
cost:
type: number
format: float
example: 10.00
description: 'The cost of the product offered for this line item'
product_key:
type: string
example: 'Product key'
description: 'The product key of the product offered for this line item (Referred to as Product in the product tab)'
product_cost:
type: number
format: float
example: 10.00
description: 'The cost of the product offered for this line item (Referred to as Cost in the product tab)'
notes:
type: string
example: 'Item notes'
description: 'The notes/description for the product offered for this line item'
discount:
type: number
format: float
example: 5.00
description: 'The discount applied to the product offered for this line item'
is_amount_discount:
type: boolean
example: false
description: 'Indicates whether the discount applied to the product offered for this line item is a fixed amount or a percentage'
tax_name1:
type: string
example: 'Tax name 1'
example: 'GST'
description: 'The name of the first tax applied to the product offered for this line item'
tax_rate1:
type: number
format: float
example: 10.00
description: 'The rate of the first tax applied to the product offered for this line item'
tax_name2:
type: string
example: 'Tax name 2'
example: 'VAT'
description: 'The name of the second tax applied to the product offered for this line item'
tax_rate2:
type: number
format: float
example: 5.00
description: 'The rate of the second tax applied to the product offered for this line item'
tax_name3:
type: string
example: 'Tax name 3'
example: 'CA Sales Tax'
description: 'The name of the third tax applied to the product offered for this line item'
tax_rate3:
type: number
format: float
example: 3.00
description: 'The rate of the third tax applied to the product offered for this line item'
sort_id:
type: string
example: '0'
description: 'Deprecated'
deprecated: true
line_total:
type: number
format: float
example: 10.00
description: 'The total amount of the product offered for this line item'
readOnly: true
gross_line_total:
type: number
format: float
example: 15.00
description: 'The total amount of the product offered for this line item before discounts'
readOnly: true
tax_amount:
type: number
format: float
example: 1.00
description: 'The total amount of tax applied to the product offered for this line item'
readOnly: true
date:
type: string
format: date-time
example: '2023-03-19T00:00:00Z'
description: 'Deprecated'
deprecated: true
custom_value1:
type: string
example: 'Custom value 1'
description: 'The first custom value of the product offered for this line item'
custom_value2:
type: string
example: 'Custom value 2'
description: 'The second custom value of the product offered for this line item'
custom_value3:
type: string
example: 'Custom value 3'
description: 'The third custom value of the product offered for this line item'
custom_value4:
type: string
example: 'Custom value 4'
description: 'The fourth custom value of the product offered for this line item'
type_id:
type: string
example: '1'
description: '1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee, 6 expense'
description: '1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee, 6 expense'
default: '1'
tax_id:
type: string
example: '1'
default: '1'
description: 'The tax ID of the product: 1 product, 2 service, 3 digital, 4 shipping, 5 exempt, 5 reduced tax, 7 override, 8 zero rate, 9 reverse tax'

View File

@ -55,17 +55,17 @@
cost:
type: number
format: double
description: 'The cost of the product.'
description: 'The cost of the product. (Your purchase price for this product)'
example: 10.0
price:
type: number
format: double
description: 'The price of the product.'
description: 'The price of the product that you are charging.'
example: 20.0
quantity:
type: number
format: double
description: 'The quantity of the product.'
description: 'The quantity of the product. (used as a default)'
example: 5.0
tax_name1:
type: string

View File

@ -13,8 +13,6 @@ namespace Tests\Feature\EInvoice;
use Tests\TestCase;
use Tests\MockAccountData;
use Http\Message\CookieJar;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use App\Services\Invoice\EInvoice\FacturaEInvoice;
use Illuminate\Routing\Middleware\ThrottleRequests;
@ -51,29 +49,89 @@ class FacturaeTest extends TestCase
nlog($f->run());
// $this->assertTrue($this->validateInvoiceXML($path));
$this->assertTrue($this->validateInvoiceXML($path));
}
// private function validateInvoiceXML($path) {
// protected function validateInvoiceXML($path, $validateSignature=false) {
// // Prepare file to upload
// if (function_exists('curl_file_create')) {
// $postFile = curl_file_create($path);
// } else {
// $postFile = "@" . realpath($path);
// }
// // Send upload request
// $ch = curl_init();
// curl_setopt_array($ch, array(
// CURLOPT_RETURNTRANSFER => true,
// CURLOPT_FOLLOWLOCATION => true,
// CURLOPT_URL => "http://plataforma.firma-e.com/VisualizadorFacturae/index2.jsp",
// CURLOPT_POST => 1,
// CURLOPT_POSTFIELDS => array(
// "referencia" => $postFile,
// "valContable" => "on",
// "valFirma" => $validateSignature ? "on" : "off",
// "aceptarCondiciones" => "on",
// "submit" => "Siguiente"
// ),
// CURLOPT_COOKIEJAR => base_path()."/cookie.txt"
// ));
// $res = curl_exec($ch);
// curl_close($ch);
// unset($ch);
// nlog($res);
// if (strpos($res, "window.open('facturae.jsp'") === false) {
// $this->expectException(\UnexpectedValueException::class);
// }
// // Fetch results
// $ch = curl_init();
// curl_setopt_array($ch, array(
// CURLOPT_RETURNTRANSFER => true,
// CURLOPT_FOLLOWLOCATION => true,
// CURLOPT_URL => "http://plataforma.firma-e.com/VisualizadorFacturae/facturae.jsp",
// CURLOPT_COOKIEFILE => base_path()."/cookie.txt"
// ));
// $res = curl_exec($ch);
// curl_close($ch);
// unset($ch);
// nlog($res);
// // Validate results
// $this->assertNotEmpty($res, 'Invalid Validator Response');
// $this->assertNotEmpty(strpos($res, 'euro_ok.png'), 'Invalid XML Format');
// if ($validateSignature) {
// $this->assertNotEmpty(strpos($res, '>Nivel de Firma Válido<'), 'Invalid Signature');
// }
// if (strpos($res, '>Sellos de Tiempo<') !== false) {
// $this->assertNotEmpty(strpos($res, '>XAdES_T<'), 'Invalid Timestamp');
// }
// }
// private function validateInvoiceXML($path)
// {
// $client = new \GuzzleHttp\Client(['cookies' => true]);
// $response = $client->request('POST', 'https://face.gob.es/api/v1/herramientas/validador',[
// 'multipart' => [
// [
// 'name' => 'validador[factura]',
// 'contents' => Storage::get($path),
// ],
// ]
// ]);
// $response = $client->request('POST', 'http://plataforma.firma-e.com/VisualizadorFacturae/facturae.jsp');
// $body = $response->getBody();
// $stringBody = (string) $body;
// echo print_r($stringBody,1);
// $jar = (new \GuzzleHttp\Cookie\CookieJar())->toArray();
// echo print_r($jar);
// $response = Http::withCookies($jar, '.ninja.test')->attach(
// 'xmlFile',
// Storage::get($path),
// basename($path)
// )->post('https://viewer.facturadirecta.com/dp/viewer/upload.void'); // Instance of Guzzle/CookieJar
// echo print_r($jar);
// $response = Http::withCookies($jar, '.ninja.test')->post('https://viewer.facturadirecta.com/dp/viewer/viewer.void');
// echo print_r($response->body(), 1);
// }
// }
}