Adds support for comprobantesatv4

This commit is contained in:
Moises Leos
2024-07-15 15:31:36 -06:00
parent 7fe578f894
commit cad32d50a9
10 changed files with 1864 additions and 14 deletions

View File

@@ -1,7 +1,11 @@

// NOTA: El código generado puede requerir, como mínimo, .NET Framework 4.5 o .NET Core/Standard 2.0.
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using static System.Net.WebRequestMethods;
namespace ComprobanteSATv3
{
@@ -64,6 +68,19 @@ namespace ComprobanteSATv3
private string confirmacionField;
public static Comprobante DeserializeFile(string strFile)
{
Comprobante result = null;
using (var reader = new FileStream(strFile, FileMode.Open))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Comprobante));
result = (Comprobante)xmlSerializer.Deserialize(reader);
}
return result;
}
/// <remarks/>
public ComprobanteCfdiRelacionados CfdiRelacionados
{
@@ -133,6 +150,7 @@ namespace ComprobanteSATv3
/// <remarks/>
[XmlArray("Complemento")]
[XmlArrayItem(ElementName = "TimbreFiscalDigital", Namespace = "http://www.sat.gob.mx/TimbreFiscalDigital", Type = typeof(TimbreFiscalDigital))]
[XmlArrayItem(ElementName = "Nomina", Namespace = "http://www.sat.gob.mx/nomina12", Type = typeof(Nomina))]
public object[] Complemento
{
get

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VerificaFactura
namespace ComprobanteSATv4
{
// NOTA: El código generado puede requerir, como mínimo, .NET Framework 4.5 o .NET Core/Standard 2.0.
@@ -28,7 +28,7 @@ namespace VerificaFactura
private ComprobanteImpuestos impuestosField;
private object complementoField;
private object[] complementoField;
private object addendaField;
@@ -151,7 +151,7 @@ namespace VerificaFactura
}
/// <remarks/>
public object Complemento
public object[] Complemento
{
get
{

View File

@@ -0,0 +1,69 @@
using System;
namespace FireflyIII.Common
{
public enum TransactionTypeEnum
{
withdrawal,
deposit,
transfer,
reconcilation,
opening_balance
}
public class Rootobject
{
public bool error_if_duplicate_hash { get; set; }
public bool apply_rules { get; set; }
public bool fire_webhooks { get; set; }
public string? group_title { get; set; }
public Transaction[] transactions { get; set; }
}
public class Transaction
{
public TransactionTypeEnum type { get; set; }
public DateTime date { get; set; }
public string amount { get; set; } = "0";
public string description { get; set; } = "";
public int? order { get; set; }
public string? currency_id { get; set; }
public string? currency_code { get; set; }
public string? foreign_amount { get; set; }
public string? foreign_currency_id { get; set; }
public string? foreign_currency_code { get; set; }
public string? budget_id { get; set; }
public string? category_id { get; set; }
public string? category_name { get; set; }
public string? source_id { get; set; }
public string? source_name { get; set; }
public string? destination_id { get; set; }
public string? destination_name { get; set; }
public bool? reconciled { get; set; }
public int? piggy_bank_id { get; set; }
public string? piggy_bank_name { get; set; }
public string? bill_id { get; set; }
public string? bill_name { get; set; }
public object? tags { get; set; }
public string? notes { get; set; }
public string? internal_reference { get; set; }
public string? external_id { get; set; }
public string? external_url { get; set; }
public string? bunq_payment_id { get; set; }
public string? sepa_cc { get; set; }
public string? sepa_ct_op { get; set; }
public string? sepa_ct_id { get; set; }
public string? sepa_db { get; set; }
public string? sepa_country { get; set; }
public string? sepa_ep { get; set; }
public string? sepa_ci { get; set; }
public string? sepa_batch_id { get; set; }
public DateTime? interest_date { get; set; }
public DateTime? book_date { get; set; }
public DateTime? process_date { get; set; }
public DateTime? due_date { get; set; }
public DateTime? payment_date { get; set; }
public DateTime? invoice_date { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Remove="FireFlyCommon.cs" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,31 @@
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [ "withdrawal", "deposit", "transfer", "reconciliation", "opening balance" ]
},
"date": {
"type": "string",
"format": "date-time"
},
"amount": {
"type": "string"
},
"description": {
"type": "string"
},
"source_id": {
"type": [ "string", "null" ]
},
"source_name": {
"type": [ "string", "null" ]
},
"destination_id": {
"type": [ "string", "null" ]
},
"destination_name": {
"type": [ "string", "null" ]
}
}
}

View File

@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VerificaFacturaTest", "Veri
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VerificaFactura", "VerificaFactura\VerificaFactura.csproj", "{660142B7-9D91-4E2C-960D-CE6991FD07B3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAT.Common", "SAT.Common\SAT.Common.csproj", "{6D0974D5-D1C9-45C4-9380-7FA0CB10BB73}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{660142B7-9D91-4E2C-960D-CE6991FD07B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{660142B7-9D91-4E2C-960D-CE6991FD07B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{660142B7-9D91-4E2C-960D-CE6991FD07B3}.Release|Any CPU.Build.0 = Release|Any CPU
{6D0974D5-D1C9-45C4-9380-7FA0CB10BB73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D0974D5-D1C9-45C4-9380-7FA0CB10BB73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D0974D5-D1C9-45C4-9380-7FA0CB10BB73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D0974D5-D1C9-45C4-9380-7FA0CB10BB73}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -39,6 +39,7 @@ namespace VerificaFactura
comprobante = (Comprobante)xmlSerializer.Deserialize(fStream);
var nominas = comprobante?.Complemento?.Where(n => n.GetType() == typeof(Nomina)).Cast<Nomina>().ToList();
timbreFiscal = (TimbreFiscalDigital)comprobante?.Complemento?.FirstOrDefault(n => n.GetType() == typeof(TimbreFiscalDigital));
if (comprobante != null && timbreFiscal != null)

1623
VerificaFactura/Nomina.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -43,13 +43,13 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ComprobanteSATv3.cs" />
<Compile Include="Connected Services\ConsultaCFDIService\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.svcmap</DependentUpon>
</Compile>
<Compile Include="ConsultaCFDI.cs" />
<Compile Include="Nomina.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,43 +1,133 @@
using System;
using ComprobanteSATv3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using static System.Net.WebRequestMethods;
namespace VerificaFactura
{
internal class Program
{
static List<string> conceptos = new List<string>();
static void Main(string[] args)
{
var service = new ConsultaCFDI();
string file1 = @"C:\Users\User\Downloads\0a242490-7113-4121-a7ad-f78e6977817f.xml";
bool valido1 = false;
string file1 = @"C:\Users\User\Downloads\A534669.xml";
string[] files = new string[]{
@"C:\Users\User\Downloads\acn\2022\01\56918641-1DB5-4B14-96AC-515A26CECA14.xml",
@"C:\Users\User\Downloads\acn\2022\01\A8EC84BA-1DA3-4CE1-9172-946ACD49C5F6.xml",
@"C:\Users\User\Downloads\acn\2022\01\AC424156-2B5F-47E1-BCA6-6E015A44BAEB.xml",
@"C:\Users\User\Downloads\acn\2022\01\F97837DC-2641-4EC5-A7A3-69B64148B17C.xml",
string file2 = @"C:\Users\User\Downloads\110296ts.xml";
bool valido2 = false;
@"C:\Users\User\Downloads\acn\2022\02\392F792B-BF0B-4B34-98B5-A4F94D4E8116.xml",
@"C:\Users\User\Downloads\acn\2022\03\0E3C295F-2773-4597-A211-06CF22F28D85.xml",
@"C:\Users\User\Downloads\acn\2022\03\96DC0C58-8B09-4AE6-A100-FA3EF9C3BD54.xml",
@"C:\Users\User\Downloads\acn\2022\04\2774ECEB-1D7F-43BF-8D58-A17C6BBAD47A.xml",
@"C:\Users\User\Downloads\acn\2022\04\951171CB-2002-4D0C-B034-FFBD55ADBE52.xml",
@"C:\Users\User\Downloads\acn\2022\05\83F95505-C4D6-4D0E-ACB9-EC96EABDDD47.xml",
@"C:\Users\User\Downloads\acn\2022\05\9198CD9A-EA3F-432F-9AD6-679383F1D5B1.xml",
@"C:\Users\User\Downloads\acn\2022\05\F79AD2FC-38B2-451E-9238-CB93911A9DEB.xml",
@"C:\Users\User\Downloads\acn\2022\06\6FFF155D-9BDA-4D62-8322-D3532A2AB200.xml",
@"C:\Users\User\Downloads\acn\2022\06\7F55C248-4EE6-44FC-81B5-A872BFD77050.xml",
@"C:\Users\User\Downloads\acn\2022\07\6E7388CC-CD33-4D8D-88EA-6D3A790A401F.xml",
@"C:\Users\User\Downloads\acn\2022\07\46AD3E85-D3E5-48D0-9606-C7676CD79F62.xml",
@"C:\Users\User\Downloads\acn\2022\08\033EF55A-0A3F-45BB-8D95-859D40B01017.xml",
@"C:\Users\User\Downloads\acn\2022\08\24784442-2368-40D8-9BDD-215CFF146EB9.xml",
@"C:\Users\User\Downloads\acn\2022\09\0A4CB045-FA24-48F3-98F7-F006AA7A64E2.xml",
@"C:\Users\User\Downloads\acn\2022\09\2493063B-6F7E-4132-992E-5EEC9DE18CFF.xml",
@"C:\Users\User\Downloads\acn\2022\10\3BF046AC-9AE2-41BE-8891-8B14F13D554E.xml",
@"C:\Users\User\Downloads\acn\2022\10\F36C992B-D6C7-47F6-926A-220B0C4F6C17.xml",
@"C:\Users\User\Downloads\acn\2022\11\7FFF9620-8071-43A6-81AF-D48D796A6F70.xml",
@"C:\Users\User\Downloads\acn\2022\11\22B4FD3D-712B-423D-B671-E053E01EAFB0.xml",
@"C:\Users\User\Downloads\acn\2022\11\17859E0E-560D-4417-AA7E-31067DC34C51.xml",
@"C:\Users\User\Downloads\acn\2022\12\46E1FD5B-E41B-4BC0-A071-199C51CD351F.xml",
@"C:\Users\User\Downloads\acn\2022\12\CD3D9A72-A071-41B7-8153-209FC108C8B6.xml",
};
bool valido1 = false;
try
{
foreach(var f in files)
{
GetTransactions(f);
}
conceptos.Sort();
conceptos.Distinct().ToList().ForEach(c => Console.WriteLine(c));
return;
using (var reader = new FileStream(file1, FileMode.Open))
{
valido1 = service.Validar(reader);
}
Console.WriteLine($"File: {file1}, Valid: {valido1}");
var fContents = File.ReadAllText(file2);
valido2 = service.Validar(fContents);
Console.WriteLine($"File: {file2}, Valid: {valido2}");
}
catch(Exception ex)
{
}
}
static void GetTransactions(string file1)
{
var result = Comprobante.DeserializeFile(file1);
var nominas = result.Complemento.Where(c => c.GetType() == typeof(Nomina)).Cast<Nomina>().ToList();
var timbreFiscal = (TimbreFiscalDigital)result.Complemento.FirstOrDefault(t => t.GetType() == typeof(TimbreFiscalDigital));
Console.WriteLine($"Timbre Fiscal: {timbreFiscal.UUID}, Emisor: {result.Emisor.Rfc}, {result.Emisor.Nombre}, Fecha: {result.Fecha}" + Environment.NewLine);
foreach (var nomina in nominas)
{
// Percepciones
if (nomina.Percepciones?.Percepcion != null)
{
foreach (var p in nomina.Percepciones.Percepcion)
{
Console.WriteLine($"Concepto: {p.Concepto}, ImporteGravado: {p.ImporteGravado}, ImporteExento: {p.ImporteExento}, TipoPercepcion: {p.TipoPercepcion}");
conceptos.Add(p.Concepto);
}
}
// Deducciones
if (nomina.Deducciones?.Deduccion != null)
{
foreach (var d in nomina.Deducciones.Deduccion)
{
Console.WriteLine($"Concepto: {d.Concepto}, Importe: {d.Importe}, TipoDeducion: {d.TipoDeduccion}");
conceptos.Add(d.Concepto);
}
}
// Otros Pagos
if (nomina.OtrosPagos != null)
{
foreach (var o in nomina.OtrosPagos)
{
Console.WriteLine($"Concepto: {o.Concepto}, Importe: {o.Importe}, TipoOtrosPagos: {o.TipoOtroPago}");
conceptos.Add(o.Concepto);
}
}
Console.WriteLine("----" + Environment.NewLine);
}
}
}
}