
| Path : /home/gujo45me/public_html/warmicha1/app/Helpers/ |
| Disable Functions : exec,passthru,shell_exec,system System : Linux server-604606.appsiete.com 3.10.0-1160.119.1.el7.tuxcare.els25.x86_64 #1 SMP Wed Oct 1 17:37:27 UTC 2025 x86_64 [ Home ][ Zone-h ][ Jumping ][ Symlink ][ Mass Depes ][ Command ] |
| Current File : /home/gujo45me/public_html/warmicha1/app/Helpers/sunat.php |
<?php
//para servidor:
require_once "../sunat/librerias/robrichards/src/xmlseclibs.php";
require_once "../sunat/librerias/pclzip/pclzip.lib.php";
require_once "../sunat/librerias/feedsoap/feedSoap.php";
include_once "../pdf/letras/NumeroALetras.php";
use RobRichards\XMLSecLibs\XMLSecurityDSig;
use RobRichards\XMLSecLibs\XMLSecurityKey;
function wsdlURL()
{
//URL BETA para enviar las solicitudes a SUNAT
$beta = 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService?wsdl';
//URL PRODUCCION para enviar las solicitudes a SUNAT
$prod = realpath(base_path().'/sunat/webservice/production.xml');
if (env('URL_SUNAT') == "BETA") {
return $beta;
} else {
return $prod;
}
}
function wsdlURL_Guia()
{
//URL BETA para enviar las solicitudes a SUNAT
$beta_guia = 'https://e-beta.sunat.gob.pe/ol-ti-itemision-guia-gem-beta/billService?wsdl';
//URL PRODUCCION para enviar las solicitudes a SUNAT
$prod_guia = 'https://e-guiaremision.sunat.gob.pe/ol-ti-itemision-guia-gem/billService?wsdl';
if (env('URL_SUNAT') == "BETA") {
return $beta_guia;
} else {
return $prod_guia;
}
}
function wsdlURL_Cdr()
{
//$cdr = 'https://www.sunat.gob.pe/ol-it-wsconscpegem/billConsultService?wsdl';
$cdr = 'https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService?wsdl';
return $cdr;
}
function soapCall($wsdlURL, $callFunction = "", $XMLString)
{
$client = new feedSoap($wsdlURL, array('trace' => true));
$reply = $client->SoapClientCall($XMLString);
$client->__call("$callFunction", array(), array());
return $client->__getLastResponse();
}
function obtenerArchivosPEM()
{
//Contraseña del certificado
$contraseña = env('CERTIFICADO_PASSWORD');
//Nombre del certificado con el formato .pfx
$nombreArchivo = base_path()."/sunat/credenciales/certificado/certificado.pfx";
//Devolvemos el el certificado como un string (cadena)
$pkcs12 = file_get_contents($nombreArchivo);
//Declaramos un arreglo para recuperar los certificados
$certificados = array();
//Pasamos los parámetros
$respuesta = openssl_pkcs12_read($pkcs12, $certificados, $contraseña);
//Si la respuesta es TRUE es porque se ha recuperado correctamente los certificados
if ($respuesta) {
$publicKeyPem = $certificados['cert']; //Archivo público
$privateKeyPem = $certificados['pkey']; //Archivo privado
//guardo la clave publica y privada en mi directorio en formato .pem
file_put_contents(base_path()."/sunat/credenciales/llaves/private_key.pem", $privateKeyPem);
file_put_contents(base_path()."/sunat/credenciales/llaves/public_key.pem", $publicKeyPem);
chmod(base_path()."/sunat/credenciales/llaves/private_key.pem", 0777);
chmod(base_path()."/sunat/credenciales/llaves/public_key.pem", 0777);
echo "- Llaves digitales creadas";
}
else {
echo "- Error al crear llaves digitales";
}
}
/*****************************************************************************************************************/
/* CREAR FACTURA BOLETA XML
/*****************************************************************************************************************/
function crearComprobanteXML(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent>'
.'</ext:ExtensionContent>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.1</cbc:UBLVersionID>'
.'<cbc:CustomizationID>2.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['comprobante']['nombre'].'</cbc:ID>'
.'<cbc:IssueDate>'.$data['comprobante']['fecha'].'</cbc:IssueDate>'
.'<cbc:IssueTime>'.$data['comprobante']['hora'].'</cbc:IssueTime>';
if ($data['comprobante']['tipo_venta'] == 'DETRACCION') { // 1001: PARA DETRACCION
$invoice.= '<cbc:InvoiceTypeCode listID="1001" listName="Tipo de Documento" name="Tipo de Operacion"
listSchemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo51">'.$data['comprobante']['tipo_comprobante'].'</cbc:InvoiceTypeCode>';
}
else{ //0101 - RETENCION Y NORMAL
$invoice.= '<cbc:InvoiceTypeCode listID="0101" listName="Tipo de Documento" name="Tipo de Operacion"
listSchemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo51">'.$data['comprobante']['tipo_comprobante'].'</cbc:InvoiceTypeCode>';
}
if ($data['comprobante']['tipo_venta'] == 'DETRACCION') {
$invoice.= '<cbc:Note languageLocaleID="2006">Operacion sujeta a detraccion</cbc:Note>';
}
$invoice.= '<cbc:Note languageLocaleID="1000">'.NumeroALetras::convertir($data['comprobante']['total'], 'soles', 'centimos').'</cbc:Note>'
.'<cbc:DocumentCurrencyCode listID="ISO 4217 Alpha" listName="Currency" listAgencyName="United Nations Economic Commission for Europe">PEN</cbc:DocumentCurrencyCode>'
.'<cbc:LineCountNumeric>'.sizeof($data['detalle']).'</cbc:LineCountNumeric>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#SignatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'<cac:RegistrationAddress>'
.'<cbc:AddressTypeCode>0000</cbc:AddressTypeCode>'
.'</cac:RegistrationAddress>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>'
.'<cac:AccountingCustomerParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['comprobante']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['comprobante']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['comprobante']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingCustomerParty>';
if ($data['comprobante']['tipo_venta'] == 'DETRACCION') {
$invoice.= '<cac:PaymentMeans>'
.'<cbc:ID>Detraccion</cbc:ID>'
.'<cbc:PaymentMeansCode listName="Medio de pago" listAgencyName="PE:SUNAT" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo59">'.$data['comprobante']['codigo_medios_pago'].'</cbc:PaymentMeansCode>'
.'<cac:PayeeFinancialAccount>'
.'<cbc:ID>'.$data['empresa']['cuenta_detraccion'].'</cbc:ID>'
.'</cac:PayeeFinancialAccount>'
.'</cac:PaymentMeans>'
.'<cac:PaymentTerms>'
.'<cbc:ID>Detraccion</cbc:ID>'
.'<cbc:PaymentMeansID schemeName="Codigo de detraccion" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo54">'.$data['comprobante']['codigo_detraccion'].'</cbc:PaymentMeansID>'
.'<cbc:PaymentPercent>'.$data['comprobante']['porcentaje_detraccion'].'</cbc:PaymentPercent>'
.'<cbc:Amount currencyID="PEN">'.$data['comprobante']['detraccion_total'].'</cbc:Amount>'
.'</cac:PaymentTerms>';
}
//Inicio Tipo de Pago
$invoice.= '<cac:PaymentTerms>'
.'<cbc:ID>FormaPago</cbc:ID>'
.'<cbc:PaymentMeansID>'.$data['comprobante']['tipo_pago'].'</cbc:PaymentMeansID>';
if ($data['comprobante']['tipo_pago'] == 'Credito') {
$invoice.= '<cbc:Amount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:Amount>';
}
$invoice.= '</cac:PaymentTerms>';
//Fin Tipo de Pago
//Inicio CUOTAS
if ($data['comprobante']['nro_cuotas'] > 0 && $data['comprobante']['tipo_pago'] == 'Credito') {
for ($i=0; $i < sizeof($data['cuotas']) ; $i++) {
$invoice.= '<cac:PaymentTerms>'
.'<cbc:ID>FormaPago</cbc:ID>'
.'<cbc:PaymentMeansID>'.$data['cuotas'][$i]['nombre_cuota'].'</cbc:PaymentMeansID>'
.'<cbc:Amount currencyID="PEN">'.$data['cuotas'][$i]['monto_cuota'].'</cbc:Amount>'
.'<cbc:PaymentDueDate>'.$data['cuotas'][$i]['fecha_pago_cuota'].'</cbc:PaymentDueDate>'
.'</cac:PaymentTerms>';
}
}
//Fin CUOTAS
//PARA RETENCION
if ($data['comprobante']['tipo_venta'] == 'RETENCION') {
$invoice.= '<cac:AllowanceCharge>'
.'<cbc:ChargeIndicator>false</cbc:ChargeIndicator>'
.'<cbc:AllowanceChargeReasonCode listAgencyName="PE:SUNAT" listName="Cargo/descuento" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo53">62</cbc:AllowanceChargeReasonCode>'
.'<cbc:MultiplierFactorNumeric>'.$data['comprobante']['porcentaje_retencion'].'</cbc:MultiplierFactorNumeric>'
.'<cbc:Amount currencyID="PEN">'.$data['comprobante']['retencion_total'].'</cbc:Amount>'
.'<cbc:BaseAmount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:BaseAmount>'
.'</cac:AllowanceCharge>';
}
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['igv_total'].'</cbc:TaxAmount>';
if ($data['comprobante']['afecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_afecto'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['igv_total'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">S</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['exonerado'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_exonerado'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_exonerado'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">E</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['inafecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_inafecto'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_inafecto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">O</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['tiene_icbper'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['total_icbper'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:LegalMonetaryTotal>'
// Subtotal
.'<cbc:LineExtensionAmount currencyID="PEN">'.($data['comprobante']['total']-$data['comprobante']['igv_total']).'</cbc:LineExtensionAmount>'
//Total incluye IGV
.'<cbc:TaxInclusiveAmount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:TaxInclusiveAmount>'
// Total de descuentos
.'<cbc:AllowanceTotalAmount currencyID="PEN">0.00</cbc:AllowanceTotalAmount>'
//Total de otros cargos
.'<cbc:ChargeTotalAmount currencyID="PEN">0.00</cbc:ChargeTotalAmount>'
//Monto a pagar, PayableAmount = TaxInclusiveAmount(allowance Applied) + ChargeTotalAmount - PrepaidAmount
.'<cbc:PayableAmount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:PayableAmount>'
.'</cac:LegalMonetaryTotal>';
for ($i=0; $i < sizeof($data['detalle']) ; $i++) {
$invoice.= '<cac:InvoiceLine>'
.'<cbc:ID>'.($i+1).'</cbc:ID>'
.'<cbc:InvoicedQuantity unitCode="NIU" unitCodeListID="UN/ECE rec 20" unitCodeListAgencyName="United Nations Economic Commission for Europe">'.$data['detalle'][$i]['cantidad'].'</cbc:InvoicedQuantity>'
.'<cbc:LineExtensionAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal'].'</cbc:LineExtensionAmount>' //subtotal neto
.'<cbc:FreeOfChargeIndicator>false</cbc:FreeOfChargeIndicator>'
.'<cac:PricingReference>'
.'<cac:AlternativeConditionPrice>'
.'<cbc:PriceAmount currencyID="PEN">'.number_format(($data['detalle'][$i]['precio_unitario'] - ($data['detalle'][$i]['descuento'])/$data['detalle'][$i]['cantidad']), 2, ".", "").'</cbc:PriceAmount>' //precio unitario neto + igv gravado
.'<cbc:PriceTypeCode listName="Tipo de Precio" listAgencyName="PE:SUNAT" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo16">01</cbc:PriceTypeCode>'
.'</cac:AlternativeConditionPrice>'
.'</cac:PricingReference>';
if ($data['detalle'][$i]['descuento_neto'] != "0.00") {
$invoice.= '<cac:AllowanceCharge>'
.'<cbc:ChargeIndicator>false</cbc:ChargeIndicator>'
.'<cbc:AllowanceChargeReasonCode>00</cbc:AllowanceChargeReasonCode>'
.'<cbc:MultiplierFactorNumeric>'.$data['detalle'][$i]['factor_descuento'].'</cbc:MultiplierFactorNumeric>'
.'<cbc:Amount currencyID="PEN">'.$data['detalle'][$i]['descuento_neto'].'</cbc:Amount>'
.'<cbc:BaseAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal_descuento'].'</cbc:BaseAmount>'
.'</cac:AllowanceCharge>';
}
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeAgencyName="United Nations Economic Commission for Europe" schemeID="UN/ECE 5305" schemeName="Tax Category Identifier">S</cbc:ID>'
.'<cbc:Percent>'.$data['detalle'][$i]['valor_impuesto'].'</cbc:Percent>';
if ($data['detalle'][$i]['situacion_impuesto'] == "AFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">10</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeID="UN/ECE 5153" schemeName="Codigo de tributos">1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "EXONERADO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">20</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeID="UN/ECE 5153" schemeName="Codigo de tributos">9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "INAFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">30</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeID="UN/ECE 5153" schemeName="Codigo de tributos">9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
$invoice.= '</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
if ($data['detalle'][$i]['tiene_icbper'] == 1) {
$invoice .= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal_icbper'].'</cbc:TaxAmount>'
.'<cbc:BaseUnitMeasure unitCode="NIU">'.$data['detalle'][$i]['cantidad_icbper'].'</cbc:BaseUnitMeasure>'
.'<cbc:PerUnitAmount currencyID="PEN">'.$data['comprobante']['valor_icbper'].'</cbc:PerUnitAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo05">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:Item>'
.'<cbc:Description><![CDATA['.$data['detalle'][$i]['descripcion'].']]></cbc:Description>'
.'</cac:Item>'
.'<cac:Price>'
.'<cbc:PriceAmount currencyID="PEN">'.$data['detalle'][$i]['precio_unitario_neto'].'</cbc:PriceAmount>'
.'</cac:Price>'
.'</cac:InvoiceLine>';
}
$invoice.='</Invoice>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR NOTA DE CREDITO XML
/*****************************************************************************************************************/
function crearNotaCreditoXML(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<CreditNote xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent>'
.'</ext:ExtensionContent>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.1</cbc:UBLVersionID>'
.'<cbc:CustomizationID>2.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['nota']['nombre'].'</cbc:ID>'
.'<cbc:IssueDate>'.$data['nota']['fecha'].'</cbc:IssueDate>'
.'<cbc:IssueTime>'.$data['nota']['hora'].'</cbc:IssueTime>'
.'<cbc:DocumentCurrencyCode>PEN</cbc:DocumentCurrencyCode>'
.'<cac:DiscrepancyResponse>'
.'<cbc:ReferenceID>'.$data['comprobante']['nombre'] .'</cbc:ReferenceID>'
.'<cbc:ResponseCode>'.$data['nota']['id_motivo'].'</cbc:ResponseCode>'
.'<cbc:Description><![CDATA['.$data['nota']['descripcion'].']]></cbc:Description>'
.'</cac:DiscrepancyResponse>'
.'<cac:BillingReference>'
.'<cac:InvoiceDocumentReference>'
.'<cbc:ID>'.$data['comprobante']['nombre'].'</cbc:ID>'
.'<cbc:DocumentTypeCode>'.$data['comprobante']['tipo_comprobante'].'</cbc:DocumentTypeCode>'
.'</cac:InvoiceDocumentReference>'
.'</cac:BillingReference>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#SignatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'<cac:RegistrationAddress>'
.'<cbc:AddressTypeCode>0000</cbc:AddressTypeCode>'
.'</cac:RegistrationAddress>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>'
.'<cac:AccountingCustomerParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['comprobante']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['comprobante']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['comprobante']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingCustomerParty>';
//Inicio Tipo de Pago
if ($data['comprobante']['tipo_pago'] == 'Credito') {
$invoice.= '<cac:PaymentTerms>'
.'<cbc:ID>FormaPago</cbc:ID>'
.'<cbc:PaymentMeansID>'.$data['comprobante']['tipo_pago'].'</cbc:PaymentMeansID>'
.'<cbc:Amount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:Amount>'
.'</cac:PaymentTerms>';
}
//Fin Tipo de Pago
//Inicio CUOTAS
if ($data['comprobante']['nro_cuotas'] > 0 && $data['comprobante']['tipo_pago'] == 'Credito') {
for ($i=0; $i < sizeof($data['cuotas']) ; $i++) {
$invoice.= '<cac:PaymentTerms>'
.'<cbc:ID>FormaPago</cbc:ID>'
.'<cbc:PaymentMeansID>'.$data['cuotas'][$i]['nombre_cuota'].'</cbc:PaymentMeansID>'
.'<cbc:Amount currencyID="PEN">'.$data['cuotas'][$i]['monto_cuota'].'</cbc:Amount>'
.'<cbc:PaymentDueDate>'.$data['cuotas'][$i]['fecha_pago_cuota'].'</cbc:PaymentDueDate>'
.'</cac:PaymentTerms>';
}
}
//Fin CUOTAS
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto'].'</cbc:TaxAmount>';
if ($data['comprobante']['afecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.($data['comprobante']['subtotal_afecto']).'</cbc:TaxableAmount>' //subtotal neto + descuento neto
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">S</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['exonerado'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.($data['comprobante']['subtotal_exonerado']).'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_exonerado'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">E</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['inafecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.($data['comprobante']['subtotal_inafecto']).'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_inafecto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">O</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['tiene_icbper'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['total_icbper'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:LegalMonetaryTotal>'
// Subtotal
.'<cbc:LineExtensionAmount currencyID="PEN">'.($data['comprobante']['total']-$data['comprobante']['impuesto']).'</cbc:LineExtensionAmount>'
// Total de descuentos
.'<cbc:AllowanceTotalAmount currencyID="PEN">0.00</cbc:AllowanceTotalAmount>'
//Total de otros cargos
.'<cbc:ChargeTotalAmount currencyID="PEN">0.00</cbc:ChargeTotalAmount>'
//Monto a pagar, PayableAmount = TaxInclusiveAmount(allowance Applied) + ChargeTotalAmount - PrepaidAmount
.'<cbc:PayableAmount currencyID="PEN">'.($data['comprobante']['total']).'</cbc:PayableAmount>'
.'</cac:LegalMonetaryTotal>';
for ($i=0; $i < sizeof($data['detalle']) ; $i++) {
$invoice.= '<cac:CreditNoteLine>'
.'<cbc:ID>'.($i+1).'</cbc:ID>'
.'<cbc:CreditedQuantity unitCode="NIU" unitCodeListAgencyName="United Nations Economic Commission for Europe" unitCodeListID="UN/ECE rec 20">'.$data['detalle'][$i]['cantidad'].'</cbc:CreditedQuantity>'
.'<cbc:LineExtensionAmount currencyID="PEN">'.($data['detalle'][$i]['subtotal']).'</cbc:LineExtensionAmount>' //nuevo subtotal neto + descuento_neto o subtotal neto sin descuento
.'<cac:PricingReference>'
.'<cac:AlternativeConditionPrice>'
.'<cbc:PriceAmount currencyID="PEN">'.number_format($data['detalle'][$i]['precio_unitario'], 2, ".", "").'</cbc:PriceAmount>'
.'<cbc:PriceTypeCode listAgencyName="PE:SUNAT" listName="Tipo de Precio" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo16">01</cbc:PriceTypeCode>'
.'</cac:AlternativeConditionPrice>'
.'</cac:PricingReference>';
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.($data['detalle'][$i]['subtotal']).'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:Percent>'.$data['detalle'][$i]['valor_impuesto'].'</cbc:Percent>';
if ($data['detalle'][$i]['situacion_impuesto'] == "AFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">10</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "EXONERADO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">20</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "INAFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">30</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
$invoice.= '</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
if ($data['detalle'][$i]['tiene_icbper'] == 1) {
$invoice .= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal_icbper'].'</cbc:TaxAmount>'
.'<cbc:BaseUnitMeasure unitCode="NIU">'.$data['detalle'][$i]['cantidad_icbper'].'</cbc:BaseUnitMeasure>'
.'<cbc:PerUnitAmount currencyID="PEN">'.$data['comprobante']['valor_icbper'].'</cbc:PerUnitAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo05">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:Item>'
.'<cbc:Description><![CDATA['.$data['detalle'][$i]['descripcion'].']]></cbc:Description>'
.'</cac:Item>'
.'<cac:Price>'
.'<cbc:PriceAmount currencyID="PEN">'.number_format($data['detalle'][$i]['precio_unitario_neto'], 6, ".", "").'</cbc:PriceAmount>'
.'</cac:Price>'
.'</cac:CreditNoteLine>';
}
$invoice.='</CreditNote>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR NOTA DE DEBITO XML
/*****************************************************************************************************************/
function crearNotaDebitoXML(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<DebitNote xmlns="urn:oasis:names:specification:ubl:schema:xsd:DebitNote-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent>'
.'</ext:ExtensionContent>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.1</cbc:UBLVersionID>'
.'<cbc:CustomizationID>2.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['nota']['nombre'].'</cbc:ID>'
.'<cbc:IssueDate>'.$data['nota']['fecha'].'</cbc:IssueDate>'
.'<cbc:IssueTime>'.$data['nota']['hora'].'</cbc:IssueTime>'
.'<cbc:DocumentCurrencyCode>PEN</cbc:DocumentCurrencyCode>'
.'<cac:DiscrepancyResponse>'
.'<cbc:ReferenceID>'.$data['comprobante']['nombre'] .'</cbc:ReferenceID>'
.'<cbc:ResponseCode>'.$data['nota']['id_motivo'].'</cbc:ResponseCode>'
.'<cbc:Description><![CDATA['.$data['nota']['descripcion'].']]></cbc:Description>'
.'</cac:DiscrepancyResponse>'
.'<cac:BillingReference>'
.'<cac:InvoiceDocumentReference>'
.'<cbc:ID>'.$data['comprobante']['nombre'].'</cbc:ID>'
.'<cbc:DocumentTypeCode>'.$data['comprobante']['tipo_comprobante'].'</cbc:DocumentTypeCode>'
.'</cac:InvoiceDocumentReference>'
.'</cac:BillingReference>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#SignatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'<cac:RegistrationAddress>'
.'<cbc:AddressTypeCode>0000</cbc:AddressTypeCode>'
.'</cac:RegistrationAddress>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>'
.'<cac:AccountingCustomerParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['comprobante']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['comprobante']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['comprobante']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingCustomerParty>'
.'<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto'].'</cbc:TaxAmount>';
if ($data['comprobante']['afecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_afecto'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_afecto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">S</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['exonerado'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_exonerado'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_exonerado'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">E</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['inafecto'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['comprobante']['subtotal_inafecto'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['impuesto_inafecto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:ID schemeID="UN/ECE 5305" schemeName="Tax Category Identifier" schemeAgencyName="United Nations Economic Commission for Europe">O</cbc:ID>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
if ($data['comprobante']['tiene_icbper'] == 1) {
$invoice.= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['comprobante']['total_icbper'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:RequestedMonetaryTotal>'
// Total de otros cargos
.'<cbc:ChargeTotalAmount currencyID="PEN">0</cbc:ChargeTotalAmount>'
//Monto a pagar, PayableAmount = TaxInclusiveAmount + ChargeTotalAmount
.'<cbc:PayableAmount currencyID="PEN">'.$data['comprobante']['total'].'</cbc:PayableAmount>'
.'</cac:RequestedMonetaryTotal>';
for ($i=0; $i < sizeof($data['detalle']) ; $i++) {
$invoice.= '<cac:DebitNoteLine>'
.'<cbc:ID>'.($i+1).'</cbc:ID>'
.'<cbc:DebitedQuantity unitCode="NIU">'.$data['detalle'][$i]['cantidad'].'</cbc:DebitedQuantity>'
.'<cbc:LineExtensionAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal'].'</cbc:LineExtensionAmount>'
.'<cac:PricingReference>'
.'<cac:AlternativeConditionPrice>'
.'<cbc:PriceAmount currencyID="PEN">'.$data['detalle'][$i]['precio_unitario'] .'</cbc:PriceAmount>'
.'<cbc:PriceTypeCode>01</cbc:PriceTypeCode>'
.'</cac:AlternativeConditionPrice>'
.'</cac:PricingReference>'
.'<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxSubtotal>'
.'<cbc:TaxableAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal'].'</cbc:TaxableAmount>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cbc:Percent>'.$data['detalle'][$i]['valor_impuesto'].'</cbc:Percent>';
if ($data['detalle'][$i]['situacion_impuesto'] == "AFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">10</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "EXONERADO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">20</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>9997</cbc:ID>'
.'<cbc:Name>EXO</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
if ($data['detalle'][$i]['situacion_impuesto'] == "INAFECTO") {
$invoice.= '<cbc:TaxExemptionReasonCode listAgencyName="PE:SUNAT" listName="Afectacion del IGV" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07">30</cbc:TaxExemptionReasonCode>'
.'<cac:TaxScheme>'
.'<cbc:ID>9998</cbc:ID>'
.'<cbc:Name>INA</cbc:Name>'
.'<cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>'
.'</cac:TaxScheme>';
}
$invoice.= '</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
if ($data['detalle'][$i]['tiene_icbper'] == 1) {
$invoice .= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['detalle'][$i]['subtotal_icbper'].'</cbc:TaxAmount>'
.'<cbc:BaseUnitMeasure unitCode="NIU">'.$data['detalle'][$i]['cantidad_icbper'].'</cbc:BaseUnitMeasure>'
.'<cbc:PerUnitAmount currencyID="PEN">'.$data['comprobante']['valor_icbper'].'</cbc:PerUnitAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo05">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'<cac:Item>'
.'<cbc:Description><![CDATA['.$data['detalle'][$i]['descripcion'].']]></cbc:Description>'
.'</cac:Item>'
.'<cac:Price>'
.'<cbc:PriceAmount currencyID="PEN">'.$data['detalle'][$i]['precio_unitario_neto'].'</cbc:PriceAmount>'
.'</cac:Price>'
.'</cac:DebitNoteLine>';
}
$invoice.='</DebitNote>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR GUIA REMISION XML 2.0
/*****************************************************************************************************************/
function crearGuiaXML(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<DespatchAdvice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:DespatchAdvice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' //bloque nuevo
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent>'
.'</ext:ExtensionContent>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.1</cbc:UBLVersionID>'
.'<cbc:CustomizationID>2.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['guia']['nombre'].'</cbc:ID>'
.'<cbc:IssueDate>'.$data['guia']['fecha'].'</cbc:IssueDate>'
.'<cbc:IssueTime>'.$data['guia']['hora'].'</cbc:IssueTime>' // ojooooooooooo nuevo agregar campo en XMLController
.'<cbc:DespatchAdviceTypeCode>'.$data['guia']['tipo_comprobante'].'</cbc:DespatchAdviceTypeCode>'
.'<cbc:Note>'.$data['guia']['motivo'].'</cbc:Note>'
.'<cac:Signature>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>' //ojo va ruc de empresa y no IDSignKG
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>'.$data['empresa']['ruc'].'</cbc:URI>' //ojo va ruc de empresa y no #SignatureKG
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:DespatchSupplierParty>'
.'<cbc:CustomerAssignedAccountID schemeID="6">'.$data['empresa']['ruc'].'</cbc:CustomerAssignedAccountID>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>' //bloque nuevo
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:DespatchSupplierParty>'
.'<cac:DeliveryCustomerParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['comprobante']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['comprobante']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>' // bloque nuevo
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['comprobante']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:DeliveryCustomerParty>'
.'<cac:Shipment>'
.'<cbc:ID>Sunat_Envio</cbc:ID>' //nuevo
.'<cbc:HandlingCode listAgencyName="PE:SUNAT" listName="Motivo de traslado" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo20">01</cbc:HandlingCode>' //nuevo bloque
.'<cbc:GrossWeightMeasure unitCode="KGM">100.00</cbc:GrossWeightMeasure>'
.'<cac:ShipmentStage>'
.'<cbc:TransportModeCode listName="Modalidad de traslado" listAgencyName="PE:SUNAT" listURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo18">02</cbc:TransportModeCode>' //nuevo OJOOO 02
.'<cac:TransitPeriod>'
.'<cbc:StartDate>'.$data['guia']['fecha_traslado'].'</cbc:StartDate>'
.'</cac:TransitPeriod>'
.'<cac:DriverPerson>' //nuevo
.'<cbc:ID schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06" schemeName="Documento de Identidad" schemeID="1" schemeAgencyName="PE:SUNAT">'.$data['guia']['dni_chofer'].'</cbc:ID>'
.'<cbc:FirstName>'.$data['guia']['nombre_chofer'].'</cbc:FirstName>'
.'<cbc:FamilyName>'.$data['guia']['apellido_chofer'].'</cbc:FamilyName>'
.'<cbc:JobTitle>Principal</cbc:JobTitle>'
.'<cac:IdentityDocumentReference>'
.'<cbc:ID>'.$data['guia']['licencia'].'</cbc:ID>'
.'</cac:IdentityDocumentReference>'
.'</cac:DriverPerson>'
.'</cac:ShipmentStage>'
.'<cac:Delivery>'
.'<cac:DeliveryAddress>'
.'<cbc:ID schemeAgencyName="PE:INEI" schemeName="Ubigeos">150101</cbc:ID>'
.'<cac:AddressLine>'
.'<cbc:Line><![CDATA['.$data['guia']['punto_llegada'].']]></cbc:Line>'
.'</cac:AddressLine>'
.'</cac:DeliveryAddress>'
.'<cac:Despatch>'
.'<cac:DespatchAddress>'
.'<cbc:ID schemeAgencyName="PE:INEI" schemeName="Ubigeos">'.$data['empresa']['ubigeo'].'</cbc:ID>'
.'<cac:AddressLine>'
.'<cbc:Line><![CDATA['.$data['guia']['punto_partida'].']]></cbc:Line>'
.'</cac:AddressLine>'
.'</cac:DespatchAddress>'
.'</cac:Despatch>' //nuevo bloque
.'</cac:Delivery>'
.'<cac:TransportHandlingUnit>' //nuevo bloque
.'<cac:TransportEquipment>'
.'<cbc:ID>'.$data['guia']['marca_placa'].'</cbc:ID>'
.'</cac:TransportEquipment>'
.'</cac:TransportHandlingUnit>'
.'</cac:Shipment>';
for ($i=0; $i < sizeof($data['detalle']) ; $i++) {
$invoice.= '<cac:DespatchLine>'
.'<cbc:ID>'.($i+1).'</cbc:ID>'
.'<cbc:DeliveredQuantity unitCode="NIU" unitCodeListID="UN/ECE rec 20" unitCodeListAgencyName="United Nations Economic Commission for Europe">'.$data['detalle'][$i]['cantidad'].'</cbc:DeliveredQuantity>'
.'<cac:OrderLineReference>'
.'<cbc:LineID>1</cbc:LineID>'
.'</cac:OrderLineReference>'
.'<cac:Item>'
.'<cbc:Description><![CDATA['.$data['detalle'][$i]['descripcion'].']]></cbc:Description>' //nuevo
.'<cac:SellersItemIdentification>'
.'<cbc:ID>'.$data['detalle'][$i]['id_producto'].'</cbc:ID>'
.'</cac:SellersItemIdentification>'
.'</cac:Item>'
.'</cac:DespatchLine>';
}
$invoice.='</DespatchAdvice>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR GUIA TRAMSPORTISTA XML 2.0
/*****************************************************************************************************************/
function crearGuiaXMLTransportista(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<DespatchAdvice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:DespatchAdvice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' //bloque nuevo
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent>'
.'</ext:ExtensionContent>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.1</cbc:UBLVersionID>'
.'<cbc:CustomizationID>2.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['guia']['nombre'].'</cbc:ID>'
.'<cbc:IssueDate>'.$data['guia']['fecha'].'</cbc:IssueDate>'
.'<cbc:IssueTime>'.$data['guia']['hora'].'</cbc:IssueTime>' // ojooooooooooo nuevo agregar campo en XMLController
.'<cbc:DespatchAdviceTypeCode>'.$data['guia']['tipo_comprobante'].'</cbc:DespatchAdviceTypeCode>'
.'<cbc:Note>Obs: '.$data['guia']['observacion'].'</cbc:Note>'
.'<cac:Signature>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>' //ojo va ruc de empresa y no IDSignKG
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>'.$data['empresa']['ruc'].'</cbc:URI>' //ojo va ruc de empresa y no #SignatureKG
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
// DATOS DEL EMISOR (TRANSPORTISTA) - MI EMPRESA
.'<cac:DespatchSupplierParty>'
.'<cbc:CustomerAssignedAccountID schemeID="6">'.$data['empresa']['ruc'].'</cbc:CustomerAssignedAccountID>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>' //bloque nuevo
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:DespatchSupplierParty>'
// DATOS DEL RECEPTOR (DESTINATARIO)
.'<cac:DeliveryCustomerParty>'
.'<cac:Party>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['destinatario']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['destinatario']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>' // bloque nuevo
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['destinatario']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:DeliveryCustomerParty>'
// DATOS DEL TRASLADO
.'<cac:Shipment>'
.'<cbc:ID>Sunat_Envio</cbc:ID>' //nuevo
.'<cbc:GrossWeightMeasure unitCode="KGM">'.$data['guia']['peso'].'</cbc:GrossWeightMeasure>'; //peso
//DATOS DEL SUBCONTRATADOR
if ($data['guia']['motivo'] == "SI") {
$invoice.= '<cac:Consignment>'
.'<cbc:ID>SUNAT_Envio</cbc:ID>'
.'<cac:LogisticsOperatorParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="6" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['guia']['documento_transportista'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName>'.$data['guia']['nombre_transportista'].'</cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:LogisticsOperatorParty>'
.'</cac:Consignment>';
}
$invoice.= '<cac:ShipmentStage>'
.'<cac:TransitPeriod>'
.'<cbc:StartDate>'.$data['guia']['fecha_traslado'].'</cbc:StartDate>'
.'</cac:TransitPeriod>'
.'<cac:DriverPerson>' //nuevo
.'<cbc:ID schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06" schemeName="Documento de Identidad" schemeID="1" schemeAgencyName="PE:SUNAT">'.$data['guia']['dni_chofer'].'</cbc:ID>'
.'<cbc:FirstName>'.$data['guia']['nombre_chofer'].'</cbc:FirstName>'
.'<cbc:FamilyName>'.$data['guia']['apellido_chofer'].'</cbc:FamilyName>'
.'<cbc:JobTitle>Principal</cbc:JobTitle>'
.'<cac:IdentityDocumentReference>'
.'<cbc:ID>'.$data['guia']['licencia'].'</cbc:ID>'
.'</cac:IdentityDocumentReference>'
.'</cac:DriverPerson>'
.'</cac:ShipmentStage>'
//DIRECCION DEL PUNTO DE LLEGADA
.'<cac:Delivery>'
.'<cac:DeliveryAddress>'
.'<cbc:ID schemeAgencyName="PE:INEI" schemeName="Ubigeos">150101</cbc:ID>'
.'<cac:AddressLine>'
.'<cbc:Line><![CDATA['.$data['guia']['punto_llegada'].']]></cbc:Line>'
.'</cac:AddressLine>'
.'</cac:DeliveryAddress>'
//DIRECCION DEL PUNTO DE PARTIDA
.'<cac:Despatch>'
.'<cac:DespatchAddress>'
.'<cbc:ID schemeAgencyName="PE:INEI" schemeName="Ubigeos">'.$data['empresa']['ubigeo'].'</cbc:ID>'
.'<cac:AddressLine>'
.'<cbc:Line><![CDATA['.$data['guia']['punto_partida'].']]></cbc:Line>'
.'</cac:AddressLine>'
.'</cac:DespatchAddress>'
// DATOS DEL REMITENTE
.'<cac:DespatchParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID schemeID="'.$data['comprobante']['tipo_doc_cliente'].'" schemeName="Documento de Identidad" schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06">'.$data['comprobante']['num_doc_cliente'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['comprobante']['nombre_cliente'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:DespatchParty>'
.'</cac:Despatch>' //nuevo bloque
.'</cac:Delivery>'
.'<cac:TransportHandlingUnit>' //nuevo bloque
.'<cac:TransportEquipment>'
.'<cbc:ID>'.$data['guia']['marca_placa'].'</cbc:ID>'
.'</cac:TransportEquipment>'
.'</cac:TransportHandlingUnit>'
.'</cac:Shipment>';
for ($i=0; $i < sizeof($data['detalle']) ; $i++) {
$invoice.= '<cac:DespatchLine>'
.'<cbc:ID>'.($i+1).'</cbc:ID>'
.'<cbc:DeliveredQuantity unitCode="NIU" unitCodeListID="UN/ECE rec 20" unitCodeListAgencyName="United Nations Economic Commission for Europe">'.$data['detalle'][$i]['cantidad'].'</cbc:DeliveredQuantity>'
.'<cac:OrderLineReference>'
.'<cbc:LineID>1</cbc:LineID>'
.'</cac:OrderLineReference>'
.'<cac:Item>'
.'<cbc:Description><![CDATA['.$data['detalle'][$i]['descripcion'].']]></cbc:Description>' //nuevo
.'<cac:SellersItemIdentification>'
.'<cbc:ID>'.$data['detalle'][$i]['id_producto'].'</cbc:ID>'
.'</cac:SellersItemIdentification>'
.'</cac:Item>'
.'</cac:DespatchLine>';
}
$invoice.='</DespatchAdvice>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR COMUNICACION DE BAJA
/*****************************************************************************************************************/
function crearBajaXML(array $data)
{
$invoice='<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>'
.'<VoidedDocuments
xmlns="urn:sunat:names:specification:ubl:peru:schema:xsd:VoidedDocuments-1"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent/>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.0</cbc:UBLVersionID>'
.'<cbc:CustomizationID>1.0</cbc:CustomizationID>'
.'<cbc:ID>'.$data['baja']['nombre'].'</cbc:ID>'
.'<cbc:ReferenceDate>'.$data['baja']['fecha_referencia'].'</cbc:ReferenceDate>'
.'<cbc:IssueDate>'.$data['baja']['fecha'].'</cbc:IssueDate>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#signatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cbc:CustomerAssignedAccountID>'.$data['empresa']['ruc'].'</cbc:CustomerAssignedAccountID>'
.'<cbc:AdditionalAccountID>6</cbc:AdditionalAccountID>'
.'<cac:Party>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>'
.'<sac:VoidedDocumentsLine>'
.'<cbc:LineID>1</cbc:LineID>'
.'<cbc:DocumentTypeCode>'.$data['baja']['tipo_comprobante'].'</cbc:DocumentTypeCode>'
.'<sac:DocumentSerialID>'.$data['baja']['serie'].'</sac:DocumentSerialID>'
.'<sac:DocumentNumberID>'.$data['baja']['numero'].'</sac:DocumentNumberID>'
.'<sac:VoidReasonDescription><![CDATA['.$data['baja']['motivo'].']]></sac:VoidReasonDescription>'
.'</sac:VoidedDocumentsLine>';
$invoice.='</VoidedDocuments>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR RESUMEN DIARIO DE BOLETAS XML
/*****************************************************************************************************************/
function crearResumenXML(array $data)
{
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<SummaryDocuments
xmlns="urn:sunat:names:specification:ubl:peru:schema:xsd:SummaryDocuments-1"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent/>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.0</cbc:UBLVersionID>'
.'<cbc:CustomizationID>1.1</cbc:CustomizationID>'
.'<cbc:ID>'.$data['resumen']['nombre'].'</cbc:ID>'
.'<cbc:ReferenceDate>'.$data['comprobante']['fecha'].'</cbc:ReferenceDate>'
.'<cbc:IssueDate>'.$data['resumen']['fecha'].'</cbc:IssueDate>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#signatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cbc:CustomerAssignedAccountID>'.$data['empresa']['ruc'].'</cbc:CustomerAssignedAccountID>'
.'<cbc:AdditionalAccountID>6</cbc:AdditionalAccountID>'
.'<cac:Party>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>';
for ($i=0; $i < sizeof($data['boleta']) ; $i++) {
$invoice.= '<sac:SummaryDocumentsLine>'
.'<cbc:LineID>'.($i+1).'</cbc:LineID>'
.'<cbc:DocumentTypeCode>'.$data['boleta'][$i]['tipo_comprobante'].'</cbc:DocumentTypeCode>'
.'<cbc:ID>'.$data['boleta'][$i]['nombre'].'</cbc:ID>'
.'<cac:AccountingCustomerParty>'
.'<cbc:CustomerAssignedAccountID>'.$data['boleta'][$i]['num_doc_cliente'].'</cbc:CustomerAssignedAccountID>'
.'<cbc:AdditionalAccountID>'.$data['boleta'][$i]['tipo_doc_cliente'].'</cbc:AdditionalAccountID>'
.'</cac:AccountingCustomerParty>'
.'<cac:Status>'
.'<cbc:ConditionCode>1</cbc:ConditionCode>'
.'</cac:Status>'
.'<sac:TotalAmount currencyID="PEN">'.$data['boleta'][$i]['total'].'</sac:TotalAmount>';
//GRAVADO
if ($data['boleta'][$i]['subtotal_afecto'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_afecto'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>01</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
//EXONERADO
if ($data['boleta'][$i]['subtotal_exonerado'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_exonerado'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>02</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
//INAFECTO
if ($data['boleta'][$i]['subtotal_inafecto'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_inafecto'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>03</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID>1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
if ($data['boleta'][$i]['tiene_icbper'] == 1) {
$invoice .= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_icbper'].'</cbc:TaxAmount>'
.'<cbc:BaseUnitMeasure unitCode="NIU">'.$data['boleta'][$i]['cantidad_icbper'].'</cbc:BaseUnitMeasure>'
.'<cbc:PerUnitAmount currencyID="PEN">'.$data['comprobante']['valor_icbper'].'</cbc:PerUnitAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo05">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice .= '</cac:TaxTotal>'
.'</sac:SummaryDocumentsLine>';
}
$invoice.='</SummaryDocuments>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* CREAR RESUMEN DIARIO DE NOTAS DE CREDITO
/*****************************************************************************************************************/
function crearResumenNotaXML(array $data)
{
$invoice='<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>'
.'<SummaryDocuments
xmlns="urn:sunat:names:specification:ubl:peru:schema:xsd:SummaryDocuments-1"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
.'<ext:UBLExtensions>'
.'<ext:UBLExtension>'
.'<ext:ExtensionContent/>'
.'</ext:UBLExtension>'
.'</ext:UBLExtensions>'
.'<cbc:UBLVersionID>2.0</cbc:UBLVersionID>'
.'<cbc:CustomizationID>1.1</cbc:CustomizationID>'
.'<cbc:ID>'.$data['resumen']['nombre'].'</cbc:ID>'
.'<cbc:ReferenceDate>'.$data['comprobante']['fecha'].'</cbc:ReferenceDate>'
.'<cbc:IssueDate>'.$data['resumen']['fecha'].'</cbc:IssueDate>'
.'<cac:Signature>'
.'<cbc:ID>IDSignKG</cbc:ID>'
.'<cac:SignatoryParty>'
.'<cac:PartyIdentification>'
.'<cbc:ID>'.$data['empresa']['ruc'].'</cbc:ID>'
.'</cac:PartyIdentification>'
.'<cac:PartyName>'
.'<cbc:Name><![CDATA['.$data['empresa']['razon_social'].']]></cbc:Name>'
.'</cac:PartyName>'
.'</cac:SignatoryParty>'
.'<cac:DigitalSignatureAttachment>'
.'<cac:ExternalReference>'
.'<cbc:URI>#signatureKG</cbc:URI>'
.'</cac:ExternalReference>'
.'</cac:DigitalSignatureAttachment>'
.'</cac:Signature>'
.'<cac:AccountingSupplierParty>'
.'<cbc:CustomerAssignedAccountID>'.$data['empresa']['ruc'].'</cbc:CustomerAssignedAccountID>'
.'<cbc:AdditionalAccountID>6</cbc:AdditionalAccountID>'
.'<cac:Party>'
.'<cac:PartyLegalEntity>'
.'<cbc:RegistrationName><![CDATA['.$data['empresa']['razon_social'].']]></cbc:RegistrationName>'
.'</cac:PartyLegalEntity>'
.'</cac:Party>'
.'</cac:AccountingSupplierParty>';
for ($i=0; $i < sizeof($data['boleta']) ; $i++) {
$invoice.= '<sac:SummaryDocumentsLine>'
.'<cbc:LineID>'.($i+1).'</cbc:LineID>'
.'<cbc:DocumentTypeCode>'.$data['nota'][$i]['tipo_comprobante'].'</cbc:DocumentTypeCode>' //Nota de Credito 07
.'<cbc:ID>'.$data['nota'][$i]['nombre'].'</cbc:ID>' //Nombre de la nota
.'<cac:AccountingCustomerParty>'
.'<cbc:CustomerAssignedAccountID>'.$data['boleta'][$i]['num_doc_cliente'].'</cbc:CustomerAssignedAccountID>'
.'<cbc:AdditionalAccountID>'.$data['boleta'][$i]['tipo_doc_cliente'].'</cbc:AdditionalAccountID>'
.'</cac:AccountingCustomerParty>'
.'<cac:BillingReference>'
.'<cac:InvoiceDocumentReference>'
.'<cbc:ID>'.$data['boleta'][$i]['nombre'].'</cbc:ID>' //Nombre de la boleta afectado
.'<cbc:DocumentTypeCode>'.$data['boleta'][$i]['tipo_comprobante'].'</cbc:DocumentTypeCode>' // 03 boleta
.'</cac:InvoiceDocumentReference>'
.'</cac:BillingReference>'
.'<cac:Status>'
.'<cbc:ConditionCode>1</cbc:ConditionCode>'
.'</cac:Status>'
.'<sac:TotalAmount currencyID="PEN">'.$data['boleta'][$i]['total'].'</sac:TotalAmount>';
//GRAVADO
if ($data['boleta'][$i]['subtotal_afecto'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_afecto'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>01</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
//EXONERADO
if ($data['boleta'][$i]['subtotal_exonerado'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_exonerado'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>02</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
//INAFECTO
if ($data['boleta'][$i]['subtotal_inafecto'] != 0) {
$invoice.= '<sac:BillingPayment>'
.'<cbc:PaidAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_inafecto'].'</cbc:PaidAmount>'
.'<cbc:InstructionID>03</cbc:InstructionID>'
.'</sac:BillingPayment>';
}
$invoice.= '<cac:TaxTotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['impuesto'].'</cbc:TaxAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID>1000</cbc:ID>'
.'<cbc:Name>IGV</cbc:Name>'
.'<cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
if ($data['boleta'][$i]['tiene_icbper'] == 1) {
$invoice .= '<cac:TaxSubtotal>'
.'<cbc:TaxAmount currencyID="PEN">'.$data['boleta'][$i]['subtotal_icbper'].'</cbc:TaxAmount>'
.'<cbc:BaseUnitMeasure unitCode="NIU">'.$data['boleta'][$i]['cantidad_icbper'].'</cbc:BaseUnitMeasure>'
.'<cbc:PerUnitAmount currencyID="PEN">'.$data['comprobante']['valor_icbper'].'</cbc:PerUnitAmount>'
.'<cac:TaxCategory>'
.'<cac:TaxScheme>'
.'<cbc:ID schemeAgencyName="PE:SUNAT" schemeURI="urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo05">7152</cbc:ID>'
.'<cbc:Name>ICBPER</cbc:Name>'
.'<cbc:TaxTypeCode>OTH</cbc:TaxTypeCode>'
.'</cac:TaxScheme>'
.'</cac:TaxCategory>'
.'</cac:TaxSubtotal>';
}
$invoice.= '</cac:TaxTotal>'
.'</sac:SummaryDocumentsLine>';
}
$invoice.='</SummaryDocuments>';
$nombreFactura = $data['archivo'];
$fichero=fopen(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* FIRMAR XML
/*****************************************************************************************************************/
function firmarComprobante(array $data)
{
$nombreFactura = $data['archivo'];
$doc = new DOMDocument();
$doc->load(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml");
$objDSig = new XMLSecurityDSig();
$objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
$objDSig->addReference(
$doc,
XMLSecurityDSig::SHA1,
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'),
array('force_uri' => true)
);
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
$objKey->loadKey(base_path()."/sunat/credenciales/llaves/private_key.pem", true);
$objDSig->sign($objKey);
$objDSig->add509Cert(file_get_contents(base_path()."/sunat/credenciales/llaves/public_key.pem"), true, false, array('subjectName' => true));
$objDSig->appendSignature($doc->getElementsByTagName('ExtensionContent')->item(0));
$doc->save(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml");
chmod(base_path()."/sunat/xml/".$data['carpeta']."/".$nombreFactura.".xml", 0777);
}
/*****************************************************************************************************************/
/* COMPRIMIR XML
/*****************************************************************************************************************/
function comprimirComprobante(array $data)
{
$NomArch = base_path()."/sunat/xml/".$data['carpeta']."/".$data['archivo'];
if (file_exists($NomArch.".zip")) {
unlink($NomArch.".zip");
}
$zip = new PclZip($NomArch.".zip");
$zip->add($NomArch.".xml", PCLZIP_OPT_REMOVE_PATH, base_path()."/sunat/xml/".$data['carpeta']."/");
chmod($NomArch.".zip", 0777);
}
/*****************************************************************************************************************/
/* ENVIAR XML
/*****************************************************************************************************************/
function enviarComprobante(array $data)
{
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/xml/".$data['carpeta']."/".$NomArch;
//Estructura del XML para la conexión OJOOO UsernameToken CLAVE SOL
$XMLString = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.sunat.gob.pe" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>'.$data['empresa']['ruc'].''.env("USUARIO_SECUNDARIO").'</wsse:Username>
<wsse:Password>'.env("PASSWORD_SECUNDARIO").'</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:sendBill>
<fileName>'.$NomArch.'.zip</fileName>
<contentFile>'.base64_encode(file_get_contents($rutaArch.'.zip')).'</contentFile>
</ser:sendBill>
</soapenv:Body>
</soapenv:Envelope>';
try {
if ($data['carpeta'] == "guias") {
$result = soapCall(wsdlURL_Guia(), $callFunction = "sendBill", $XMLString);
}
else {
$result = soapCall(wsdlURL(), $callFunction = "sendBill", $XMLString);
}
//Descargamos el Archivo Response
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml","w+");
fputs($archivo, $result);
fclose($archivo);
//LEEMOS EL ARCHIVO XML
$xml = simplexml_load_file(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml");
foreach ($xml->xpath('//applicationResponse') as $response){ }
//AQUI DESCARGAMOS EL ARCHIVO CDR(CONSTANCIA DE RECEPCIÓN)
$cdr=base64_decode($response);
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip","w+");
fputs($archivo,$cdr);
fclose($archivo);
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip", 0777);
//Descomprimimos respuesta de SUNAT
$archive = new PclZip(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip");
if ($archive->extract(PCLZIP_OPT_PATH, "../sunat/cdr/".$data['carpeta']."")==0){ // por defecto extrae en la carpeta public, por redirigimos asi
die("Error : ".$archive->errorInfo(true));
}else{
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".xml", 0777);
}
//Eliminamos el Archivo Response
unlink(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml");
$data['respuesta'] = "ENVIADO";
return $data;
} catch (SoapFault $fault) {
if ($fault->faultcode == "soap-env:Client.1032" || $fault->faultcode == "soap-env:Client.1033") {
$data = consultaCdrComprobante($data);
return $data;
}
else
{
$data['respuesta'] = "NO ENVIADO";
$data['mensaje'] = "ERROR (".$fault->faultcode."): ".$fault->faultstring;
$data['estado'] = "NO ENVIADO";
return $data;
}
}
}
function enviarResumen(array $data)
{
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/xml/".$data['carpeta']."/".$NomArch;
//Estructura del XML para la conexión OJOOO UsernameToken CLAVE SOL
$XMLString='<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.sunat.gob.pe" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>'.$data['empresa']['ruc'].''.env("USUARIO_SECUNDARIO").'</wsse:Username>
<wsse:Password>'.env("PASSWORD_SECUNDARIO").'</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:sendSummary>
<fileName>'.$NomArch.'.zip</fileName>
<contentFile>'.base64_encode(file_get_contents($rutaArch.'.zip')).'</contentFile>
</ser:sendSummary>
</soapenv:Body>
</soapenv:Envelope>';
try {
$result = soapCall( wsdlURL(), $callFunction = "sendSummary", $XMLString);
//Descargamos el Archivo Response
$responseFile=fopen(base_path()."/sunat/tickets/T-".$NomArch.".xml", "w+");
fwrite($responseFile, $result);
fclose($responseFile);
$data['mensaje'] = "El comprobante fue enviado correctamente";
$data['estado'] = "PENDIENTE";
$data['code'] = "0"; // ESTADO 98
return $data;
} catch (SoapFault $fault) {
$data['mensaje'] = "ERROR (".$fault->faultcode."): ".$fault->faultstring;
$data['estado'] = "NO ENVIADO";
$data['code'] = "".$fault->faultcode.""; // ESTADO 98
return $data;
}
}
/*****************************************************************************************************************/
/* CONSULTA DE TICKETS
/*****************************************************************************************************************/
function consultaTicketResumen(array $data)
{
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/xml/".$data['carpeta']."/".$NomArch;
//Extraemos el codigo del ticket
$xml = simplexml_load_file(base_path().'/sunat/tickets/T-'.$NomArch.'.xml');
foreach ($xml->xpath('//ticket') as $ticketNro){ }
$XMLString='<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.sunat.gob.pe" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>'.$data['empresa']['ruc'].''.env("USUARIO_SECUNDARIO").'</wsse:Username>
<wsse:Password>'.env("PASSWORD_SECUNDARIO").'</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:getStatus>
<ticket>'.$ticketNro.'</ticket>
</ser:getStatus>
</soapenv:Body>
</soapenv:Envelope>';
try {
$result=soapCall(wsdlURL(), $callFunction='getStatus', $XMLString);
$responseFile=fopen(base_path().'/sunat/tickets/C'.$NomArch.'.xml', 'w+');
fwrite($responseFile, $result);
fclose($responseFile);
//Extraemos la respuesta del ticket
$xml = simplexml_load_file(base_path().'/sunat/tickets/C'.$NomArch.'.xml');
foreach ($xml->xpath('//status/content') as $response){ }
$cdr=base64_decode($response);
$archivo = fopen(base_path().'/sunat/tickets/R'.$NomArch.'.zip','w+');
fputs($archivo,$cdr);
fclose($archivo);
chmod(base_path().'/sunat/tickets/R'.$NomArch.'.zip', 0777);
//Descomprimimos respuesta de SUNAT
$extract = new ZipArchive();
$extract->open(base_path().'/sunat/tickets/R'.$NomArch.'.zip');
$extract->extractTo(base_path()."/sunat/cdr/".$data['carpeta']."/");
$extract->close();
//Eliminamos el Archivo Response
unlink(base_path().'/sunat/tickets/C'.$NomArch.'.xml');
unlink(base_path().'/sunat/tickets/R'.$NomArch.'.zip');
$data['respuesta'] = "ENVIADO";
return $data;
} catch (SoapFault $fault) {
$data['respuesta'] = "NO ENVIADO";
$data['mensaje'] = "ERROR (".$fault->faultcode."): ".$fault->faultstring;
$data['estado'] = "NO ENVIADO";
return $data;
}
}
/*****************************************************************************************************************/
/* CONSULTA DE CDR
/*****************************************************************************************************************/
function consultaCdrComprobante(array $data)
{
$NomArch = $data['archivo'];
$XMLString='<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:ser="http://service.sunat.gob.pe"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>'.$data['empresa']['ruc'].''.env("USUARIO_SECUNDARIO").'</wsse:Username>
<wsse:Password>'.env("PASSWORD_SECUNDARIO").'</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:getStatusCdr>
<rucComprobante>'.$data['empresa']['ruc'].'</rucComprobante>
<tipoComprobante>'.$data['comprobante']['tipo_comprobante'].'</tipoComprobante>
<serieComprobante>'.$data['comprobante']['serie'].'</serieComprobante>
<numeroComprobante>'.$data['comprobante']['numero'].'</numeroComprobante>
</ser:getStatusCdr>
</soapenv:Body>
</soapenv:Envelope>';
try {
$result=soapCall(wsdlURL_Cdr(), $callFunction='getStatusCdr', $XMLString);
//Descargamos el Archivo Response
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml","w+");
fputs($archivo, $result);
fclose($archivo);
//LEEMOS EL ARCHIVO XML
$xml = simplexml_load_file(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml");
//INICIO DE EXCEPCION - PARA EL CASO QUE NO TENGA CDR
foreach ($xml->xpath('//statusCdr/statusCode') as $code){ }
if($code=='0125'){
$data['respuesta'] = "NO ENVIADO";
$data['mensaje'] = "ERROR (".$code."): No se pudo obtener la constancia";
$data['estado'] = "RECHAZADO";
return $data;
}
else{
foreach ($xml->xpath('//statusCdr/content') as $response){ }
//AQUI DESCARGAMOS EL ARCHIVO CDR(CONSTANCIA DE RECEPCIÓN)
$cdr=base64_decode($response);
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip","w+");
fputs($archivo,$cdr);
fclose($archivo);
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip", 0777);
//Descomprimimos respuesta de SUNAT
$archive = new PclZip(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip");
if ($archive->extract(PCLZIP_OPT_PATH, "../sunat/cdr/".$data['carpeta']."")==0) { // por defecto extrae en la carpeta public, por redirigimos asi
die("Error : ".$archive->errorInfo(true));
}else{
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".xml", 0777);
}
//Eliminamos el Archivo Response
unlink(base_path()."/sunat/cdr/".$data['carpeta']."/C".$NomArch.".xml");
$data['respuesta'] = "ENVIADO";
return $data;
}
//FIN DE EXCEPCION - PARA EL CASO QUE NO TENGA CDR
} catch (SoapFault $fault) {
$data['respuesta'] = "NO ENVIADO";
$data['mensaje'] = "ERROR (".$fault->faultcode."): ".$fault->faultstring;
$data['estado'] = "NO ENVIADO";
return $data;
}
}
/*****************************************************************************************************************/
/* RESPUESTA DE SUNAT
/*****************************************************************************************************************/
function respuestaComprobante(array $data)
{
//Extraemos la respuesta del Servidor
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch;
$xml = file_get_contents($rutaArch.'.xml');
$DOM = new DOMDocument('1.0', 'ISO-8859-1');
$DOM->preserveWhiteSpace = FALSE;
$DOM->loadXML($xml);
$DocXML = $DOM->getElementsByTagName('ResponseCode');
foreach($DocXML as $Nodo){
$codigo = $Nodo->nodeValue;
}
$DocXML = $DOM->getElementsByTagName('Description');
foreach($DocXML as $Nodo){
$mensaje = $Nodo->nodeValue;
}
if ($codigo == 0) {
$data['estado'] = 'ACEPTADO'; //ACEPTADO| RECHAZADO
}
else {
$data['estado'] = 'RECHAZADO'; //ACEPTADO| RECHAZADO
}
$data['mensaje'] = $mensaje; //Description
return $data;
}
function respuestaResumen(array $data)
{
//Extraemos la respuesta del Servidor
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch;
$xml = file_get_contents($rutaArch.'.xml');
$DOM = new DOMDocument('1.0', 'ISO-8859-1');
$DOM->preserveWhiteSpace = FALSE;
$DOM->loadXML($xml);
$DocXML = $DOM->getElementsByTagName('ResponseCode');
foreach($DocXML as $Nodo){
$codigo = $Nodo->nodeValue;
}
$DocXML = $DOM->getElementsByTagName('Description');
foreach($DocXML as $Nodo){
$mensaje = $Nodo->nodeValue;
}
if ($codigo == 0) {
$data['estado'] = 'ACEPTADO'; //ACEPTADO| RECHAZADO
$data['mensaje'] = $mensaje; //Description
}
//else {
elseif ($codigo == 2223) {
$data['estado'] = 'ACEPTADO';
$data['mensaje'] = $mensaje .' ('. $codigo .')'; //Resumen ya enviado
}
elseif ($codigo == 2282) {
$data['estado'] = 'ACEPTADO';
$data['mensaje'] = $mensaje .' ('. $codigo .')'; //Resumen ya enviado
}
else{
$data['estado'] = 'RECHAZADO';
$data['mensaje'] = $mensaje .' ('. $codigo .')'; //Description
}
//}
return $data;
}
/*****************************************************************************************************************/
/* ENVIAR GUIA XML VIA REST 2.0
/*****************************************************************************************************************/
function urlGuia()
{
if (env('URL_SUNAT') == "BETA") {
$url['post'] = 'https://gre-test.nubefact.com/v1/contribuyente/gem/comprobantes/';
$url['get'] = 'https://gre-test.nubefact.com/v1/contribuyente/gem/comprobantes/envios/';
} else {
$url['post'] = 'https://api-cpe.sunat.gob.pe/v1/contribuyente/gem/comprobantes/';
$url['get'] = 'https://api-cpe.sunat.gob.pe/v1/contribuyente/gem/comprobantes/envios/';
}
return $url;
}
function obtenerCredencialesGuia()
{
if (env('URL_SUNAT') == "BETA") {
$data['url'] = 'https://gre-test.nubefact.com/v1/clientessol/';
$data['id_cliente'] = 'test-85e5b0ae-255c-4891-a595-0b98c65c9854';
$data['clave'] = 'test-Hty/M6QshYvPgItX2P0+Kw==';
$data['usuario'] = 'MODDATOS';
$data['password'] = 'MODDATOS';
} else {
$data['url'] = 'https://api-seguridad.sunat.gob.pe/v1/clientessol/';
$data['id_cliente'] = env('ID_CLIENTE');
$data['clave'] = env('CLAVE');
$data['usuario'] = env('USUARIO_SECUNDARIO');
$data['password'] = env('PASSWORD_SECUNDARIO');
}
return $data;
}
function enviarGuia(array $data)
{
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/xml/".$data['carpeta']."/".$NomArch.".zip";
$restURL = urlGuia();
$url = $restURL['post'].$NomArch; //Para enviar XML
$hash = hash_file('sha256', $rutaArch);
$base64 = base64_encode(file_get_contents($rutaArch));
$array= array(
"archivo" => array(
"nomArchivo" => $NomArch.".zip",
"arcGreZip" => $base64,
"hashZip" => $hash
)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($array));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: Bearer '.$data['token']
));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response);
if( isset($result->numTicket) ){
$invoice='<?xml version="1.0" encoding="UTF-8"?>'
.'<Ticket xmlns:ser="http://service.sunat.gob.pe">'
.'<ser:ResponseCode>'.$result->numTicket.'</ser:ResponseCode>'
.'<ser:Description>'.$result->fecRecepcion.'</ser:Description>'
.'</Ticket>';
$fichero=fopen(base_path()."/sunat/tickets/T-".$NomArch.".xml", 'w');
fwrite($fichero, $invoice);
fclose($fichero);
chmod( base_path()."/sunat/tickets/T-".$NomArch.".xml", 0777);
$data['respuesta'] = "ENVIADO";
$data['mensaje'] = "El comprobante fue enviado, esta pendiente la obtencion del CDR";
$data['estado'] = "PENDIENTE";
return $data;
} else {
$data['respuesta'] = "NO ENVIADO";
$data['mensaje'] = "ERROR (".$result->errors[0]->cod."): ".$result->errors[0]->msg;
$data['estado'] = "NO ENVIADO";
return $data;
}
}
function consultaTicketGuia(array $data)
{
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/tickets/T-".$NomArch.".xml";
$xml = file_get_contents($rutaArch);
$DOM = new DOMDocument('1.0', 'ISO-8859-1');
$DOM->preserveWhiteSpace = FALSE;
$DOM->loadXML($xml);
$DocXML = $DOM->getElementsByTagName('ResponseCode');
foreach($DocXML as $Nodo){
$ticket = $Nodo->nodeValue;
}
$restURL = urlGuia();
$url = $restURL['get'].$ticket; //para obtener el CDR
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer '.$data['token']
),
));
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response);
if( $result->codRespuesta == 0 ){
$cdr=base64_decode($result->arcCdr);
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip","w+");
fputs($archivo,$cdr);
fclose($archivo);
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip", 0777);
$archive = new PclZip(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip"); //Descomprimimos respuesta de SUNAT
if ($archive->extract(PCLZIP_OPT_PATH, "../sunat/cdr/".$data['carpeta']."")==0){ // por defecto extrae en la carpeta public, por eso redirigimos asi
die("Error : ".$archive->errorInfo(true));
}else{chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".xml", 0777);}
$data['mensaje'] = "El comprobante ha sido aceptado";
$data['estado'] = "ACEPTADO";
return $data;
} elseif ($result->codRespuesta == 98 ) {
$data['mensaje'] = "El envio del comprobante se encuentra en proceso";
$data['estado'] = "PENDIENTE";
return $data;
} elseif ( $result->codRespuesta == 99 && isset($result->arcCdr) ) {
$cdr=base64_decode($result->arcCdr);
$archivo = fopen(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip","w+");
fputs($archivo,$cdr);
fclose($archivo);
chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip", 0777);
$archive = new PclZip(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".zip"); //Descomprimimos respuesta de SUNAT
if ($archive->extract(PCLZIP_OPT_PATH, "../sunat/cdr/".$data['carpeta']."")==0){ // por defecto extrae en la carpeta public, por eso redirigimos asi
die("Error : ".$archive->errorInfo(true));
}else{ chmod(base_path()."/sunat/cdr/".$data['carpeta']."/R-".$NomArch.".xml", 0777);}
$data['mensaje'] = "MSG (".$result->error->numError."): ".$result->error->desError;
$data['estado'] = "RECHAZADO";
return $data;
} else {
$data['mensaje'] = "ERROR (".$result->error->numError."): ".$result->error->desError;
$data['estado'] = "RECHAZADO";
return $data;
}
}
/*****************************************************************************************************************/
/* XML DE FACTURAS EXISTE
/*****************************************************************************************************************/
function existeFactura(array $data)
{
//Extraemos el nombre del archivo
$NomArch = $data['archivo'];
$rutaArch = base_path()."/sunat/xml/".$data['carpeta']."/".$NomArch.".zip";
if (file_exists($rutaArch)) {
return true;
} else {
return false;
}
}