diff --git a/MAES.Fiskal2.Tests/Fiskal2Tests.cs b/MAES.Fiskal2.Tests/Fiskal2Tests.cs new file mode 100644 index 0000000..61af6ca --- /dev/null +++ b/MAES.Fiskal2.Tests/Fiskal2Tests.cs @@ -0,0 +1,71 @@ +using System.Security.Cryptography.X509Certificates; +using MAES.Fiskal2.Posrednici; + +namespace MAES.Fiskal2.Tests; + +public class SuperTests +{ + readonly List posrednici = + [ + new Super + { + BusinessGuid = Environment.GetEnvironmentVariable("SUPER_BUSINESS_GUID") ?? throw new InvalidOperationException("SUPER_BUSINESS_GUID environment variable is not set."), + Username = Environment.GetEnvironmentVariable("SUPER_USERNAME") ?? throw new InvalidOperationException("SUPER_USERNAME environment variable is not set."), + Password = Environment.GetEnvironmentVariable("SUPER_PASSWORD") ?? throw new InvalidOperationException("SUPER_PASSWORD environment variable is not set."), + IsDev = true + }, + // new EPoslovanje + // { + // OIB = Environment.GetEnvironmentVariable("EPOSLOVANJE_OIB") ?? throw new InvalidOperationException("EPOSLOVANJE_OIB environment variable is not set."), + // Username = Environment.GetEnvironmentVariable("EPOSLOVANJE_USERNAME") ?? throw new InvalidOperationException("EPOSLOVANJE_USERNAME environment variable is not set."), + // Password = Environment.GetEnvironmentVariable("EPOSLOVANJE_PASSWORD") ?? throw new InvalidOperationException("EPOSLOVANJE_PASSWORD environment variable is not set."), + // IsDev = true + // }, + // new Fina + // { + // OIB = Environment.GetEnvironmentVariable("FINA_OIB") ?? throw new InvalidOperationException("FINA_OIB environment variable is not set."), + // Certificate = ..., + // IsDev = true + // }, + // new MER + // { + // OIB = Environment.GetEnvironmentVariable("MER_OIB") ?? throw new InvalidOperationException("MER_OIB environment variable is not set."), + // Username = Environment.GetEnvironmentVariable("MER_USERNAME") ?? throw new InvalidOperationException("MER_USERNAME environment variable is not set."), + // Password = Environment.GetEnvironmentVariable("MER_PASSWORD") ?? throw new InvalidOperationException("MER_PASSWORD environment variable is not set."), + // IsDev = true + // } + ]; + + [Fact] + public async Task SendInvoiceUBL() + { + foreach (var posrednik in posrednici.Where(p => p is not Fina)) + { + await posrednik.EvidentirajUBLAsync(File.ReadAllText("ubl.xml")); + + var izlazni = await posrednik.IzlazniListAsync(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow); + Assert.NotNull(izlazni); + + var first = izlazni.FirstOrDefault(); + if(first != null) + { + Assert.NotNull(await posrednik.IzlazniPdfAsync(first.Id)); + Assert.NotNull(await posrednik.IzlazniUBLAsync(first.Id)); + + await posrednik.EvidentirajUplatuAsync(first.Id, DateTime.UtcNow, 100, NacinPlacanja.TransakcijskiRaCun); + } + + var ulazni = await posrednik.UlazniListAsync(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow); + Assert.NotNull(ulazni); + + var firstUlazni = ulazni.FirstOrDefault(); + if(firstUlazni != null) + { + Assert.NotNull(await posrednik.UlazniPdfAsync(firstUlazni.Id)); + Assert.NotNull(await posrednik.UlazniUBLAsync(firstUlazni.Id)); + + await posrednik.OdbijRacunAsync(firstUlazni.Id, RazlogOdbijanja.NeusklađenostKojaNeUtjeceNaObracunPoreza, "Nedostaje OIB"); + } + } + } +} \ No newline at end of file diff --git a/MAES.Fiskal2.Tests/SuperTests.cs b/MAES.Fiskal2.Tests/SuperTests.cs deleted file mode 100644 index e3522b0..0000000 --- a/MAES.Fiskal2.Tests/SuperTests.cs +++ /dev/null @@ -1,17 +0,0 @@ -using MAES.Fiskal2.Posrednici; - -namespace MAES.Fiskal2.Tests; - -public class SuperTests -{ - Super super = new () - { - BusinessGuid = Environment.GetEnvironmentVariable("SUPER_BUSINESS_GUID") ?? throw new InvalidOperationException("SUPER_BUSINESS_GUID environment variable is not set."), - Username = Environment.GetEnvironmentVariable("SUPER_USERNAME") ?? throw new InvalidOperationException("SUPER_USERNAME environment variable is not set."), - Password = Environment.GetEnvironmentVariable("SUPER_PASSWORD") ?? throw new InvalidOperationException("SUPER_PASSWORD environment variable is not set."), - IsDev = true - }; - - [Fact] - public async Task SendInvoiceUBL() => await super.EvidentirajUBLAsync(File.ReadAllText("ubl.xml")); -} \ No newline at end of file diff --git a/MAES.Fiskal2/FinaReference.cs b/MAES.Fiskal2/FinaReference.cs new file mode 100644 index 0000000..b12cf41 --- /dev/null +++ b/MAES.Fiskal2/FinaReference.cs @@ -0,0 +1,2034 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 + +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ServiceModel.ServiceContractAttribute(Namespace="http://fina.hr/eracun/b2b/ws/pki/v0.1", ConfigurationName="eRacunB2BPortType")] +public interface eRacunB2BPortType +{ + + [System.ServiceModel.OperationContractAttribute(Action="http://fina.hr/eracun/b2b/Echo", ReplyAction="*")] + [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] + System.Threading.Tasks.Task echoAsync(echoRequest request); + + [System.ServiceModel.OperationContractAttribute(Action="http://fina.hr/eracun/b2b/SendB2BOutgoingInvoice", ReplyAction="*")] + [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] + System.Threading.Tasks.Task sendB2BOutgoingInvoiceAsync(sendB2BOutgoingInvoiceRequest request); + + [System.ServiceModel.OperationContractAttribute(Action="http://fina.hr/eracun/b2g/SendB2BOutgoingInvoiceReporting", ReplyAction="*")] + [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] + System.Threading.Tasks.Task sendB2BOutgoingInvoiceReportingAsync(sendB2BOutgoingInvoiceReportingRequest request); + + [System.ServiceModel.OperationContractAttribute(Action="http://fina.hr/eracun/b2b/GetB2BOutgoingInvoiceStatus", ReplyAction="*")] + [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] + System.Threading.Tasks.Task getB2BOutgoingInvoiceStatusAsync(getB2BOutgoingInvoiceStatusRequest request); +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1")] +public partial class EchoMsg +{ + + private HeaderSupplierType headerSupplierField; + + private EchoMsgData dataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public HeaderSupplierType HeaderSupplier + { + get + { + return this.headerSupplierField; + } + set + { + this.headerSupplierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public EchoMsgData Data + { + get + { + return this.dataField; + } + set + { + this.dataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1")] +public partial class HeaderSupplierType +{ + + private string messageIDField; + + private string supplierIDField; + + private string additionalSupplierIDField; + + private string eRPIDField; + + private string messageTypeField; + + private string messageAttributesField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string MessageID + { + get + { + return this.messageIDField; + } + set + { + this.messageIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string SupplierID + { + get + { + return this.supplierIDField; + } + set + { + this.supplierIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public string AdditionalSupplierID + { + get + { + return this.additionalSupplierIDField; + } + set + { + this.additionalSupplierIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public string ERPID + { + get + { + return this.eRPIDField; + } + set + { + this.eRPIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=4)] + public string MessageType + { + get + { + return this.messageTypeField; + } + set + { + this.messageTypeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=5)] + public string MessageAttributes + { + get + { + return this.messageAttributesField; + } + set + { + this.messageAttributesField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1")] +public partial class DocumentStatusType +{ + + private DocumentStatusTypeStatusCode statusCodeField; + + private string statusTextField; + + private System.DateTime statusTimestampField; + + private bool statusTimestampFieldSpecified; + + private string noteField; + + private decimal partialAmountField; + + private bool partialAmountFieldSpecified; + + private string documentCurrencyCodeField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public DocumentStatusTypeStatusCode StatusCode + { + get + { + return this.statusCodeField; + } + set + { + this.statusCodeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string StatusText + { + get + { + return this.statusTextField; + } + set + { + this.statusTextField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public System.DateTime StatusTimestamp + { + get + { + return this.statusTimestampField; + } + set + { + this.statusTimestampField = value; + } + } + + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + public bool StatusTimestampSpecified + { + get + { + return this.statusTimestampFieldSpecified; + } + set + { + this.statusTimestampFieldSpecified = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public string Note + { + get + { + return this.noteField; + } + set + { + this.noteField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=4)] + public decimal PartialAmount + { + get + { + return this.partialAmountField; + } + set + { + this.partialAmountField = value; + } + } + + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + public bool PartialAmountSpecified + { + get + { + return this.partialAmountFieldSpecified; + } + set + { + this.partialAmountFieldSpecified = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=5)] + public string DocumentCurrencyCode + { + get + { + return this.documentCurrencyCodeField; + } + set + { + this.documentCurrencyCodeField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1")] +public enum DocumentStatusTypeStatusCode +{ + + /// + RECEIVED, + + /// + PAYMENT_RECEIVED, + + /// + RECEIVING_CONFIRMED, + + /// + APPROVED, + + /// + REJECTED, + + /// + PAYMENT_FULFILLED, + + /// + PAYMENT_PARTIALLY_FULFILLED, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1")] +public partial class MessageAckType +{ + + private string messageIDField; + + private string messageAckIDField; + + private string messageTypeField; + + private AckStatusType ackStatusField; + + private int ackStatusCodeField; + + private string ackStatusTextField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string MessageID + { + get + { + return this.messageIDField; + } + set + { + this.messageIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string MessageAckID + { + get + { + return this.messageAckIDField; + } + set + { + this.messageAckIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=2)] + public string MessageType + { + get + { + return this.messageTypeField; + } + set + { + this.messageTypeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public AckStatusType AckStatus + { + get + { + return this.ackStatusField; + } + set + { + this.ackStatusField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=4)] + public int AckStatusCode + { + get + { + return this.ackStatusCodeField; + } + set + { + this.ackStatusCodeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=5)] + public string AckStatusText + { + get + { + return this.ackStatusTextField; + } + set + { + this.ackStatusTextField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1")] +public enum AckStatusType +{ + + /// + ACCEPTED, + + /// + MSG_NOT_VALID, + + /// + SYSTEM_ERROR, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1")] +public partial class EchoMsgData +{ + + private EchoMsgDataEchoData echoDataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public EchoMsgDataEchoData EchoData + { + get + { + return this.echoDataField; + } + set + { + this.echoDataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1")] +public partial class EchoMsgDataEchoData +{ + + private string echoField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string Echo + { + get + { + return this.echoField; + } + set + { + this.echoField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1")] +public partial class EchoAckMsg +{ + + private MessageAckType messageAckField; + + private EchoAckMsgEchoData echoDataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public MessageAckType MessageAck + { + get + { + return this.messageAckField; + } + set + { + this.messageAckField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public EchoAckMsgEchoData EchoData + { + get + { + return this.echoDataField; + } + set + { + this.echoDataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1")] +public partial class EchoAckMsgEchoData +{ + + private string echoField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string Echo + { + get + { + return this.echoField; + } + set + { + this.echoField = value; + } + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class echoRequest +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1", Order=0)] + public EchoMsg EchoMsg; + + public echoRequest() + { + } + + public echoRequest(EchoMsg EchoMsg) + { + this.EchoMsg = EchoMsg; + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class echoResponse +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/Echo/v0.1", Order=0)] + public EchoAckMsg EchoAckMsg; + + public echoResponse() + { + } + + public echoResponse(EchoAckMsg EchoAckMsg) + { + this.EchoAckMsg = EchoAckMsg; + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceMsg +{ + + private HeaderSupplierType headerSupplierField; + + private SendB2BOutgoingInvoiceMsgData dataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public HeaderSupplierType HeaderSupplier + { + get + { + return this.headerSupplierField; + } + set + { + this.headerSupplierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceMsgData Data + { + get + { + return this.dataField; + } + set + { + this.dataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceMsgData +{ + + private SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelope b2BOutgoingInvoiceEnvelopeField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelope B2BOutgoingInvoiceEnvelope + { + get + { + return this.b2BOutgoingInvoiceEnvelopeField; + } + set + { + this.b2BOutgoingInvoiceEnvelopeField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelope +{ + + private SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard xMLStandardField; + + private SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier specificationIdentifierField; + + private string supplierInvoiceIDField; + + private string buyerIDField; + + private string additionalBuyerIDField; + + private byte[] itemField; + + private ItemChoiceType itemElementNameField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard XMLStandard + { + get + { + return this.xMLStandardField; + } + set + { + this.xMLStandardField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier SpecificationIdentifier + { + get + { + return this.specificationIdentifierField; + } + set + { + this.specificationIdentifierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public string BuyerID + { + get + { + return this.buyerIDField; + } + set + { + this.buyerIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=4)] + public string AdditionalBuyerID + { + get + { + return this.additionalBuyerIDField; + } + set + { + this.additionalBuyerIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute("CreditNoteEnvelope", typeof(byte[]), DataType="base64Binary", Order=5)] + [System.Xml.Serialization.XmlElementAttribute("InvoiceEnvelope", typeof(byte[]), DataType="base64Binary", Order=5)] + [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")] + public byte[] Item + { + get + { + return this.itemField; + } + set + { + this.itemField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=6)] + [System.Xml.Serialization.XmlIgnoreAttribute()] + public ItemChoiceType ItemElementName + { + get + { + return this.itemElementNameField; + } + set + { + this.itemElementNameField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public enum SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard +{ + + /// + UBL, + + /// + CII, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public enum SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier +{ + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017")] + urnceneuen169312017, + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0")] + urnceneuen169312017complianturnfdcpeppoleu2017poaccbilling30, + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017#compliant#urn:mfin.gov.hr:cius-2025:1.0#conformant#urn:mf" + + "in.gov.hr:ext-2025:1.0")] + urnceneuen169312017complianturnmfingovhrcius202510conformanturnmfingovhrext202510, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1", IncludeInSchema=false)] +public enum ItemChoiceType +{ + + /// + CreditNoteEnvelope, + + /// + InvoiceEnvelope, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceAckMsg +{ + + private MessageAckType messageAckField; + + private SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelope b2BOutgoingInvoiceEnvelopeField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public MessageAckType MessageAck + { + get + { + return this.messageAckField; + } + set + { + this.messageAckField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelope B2BOutgoingInvoiceEnvelope + { + get + { + return this.b2BOutgoingInvoiceEnvelopeField; + } + set + { + this.b2BOutgoingInvoiceEnvelopeField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelope +{ + + private SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing b2BOutgoingInvoiceProcessingField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing B2BOutgoingInvoiceProcessing + { + get + { + return this.b2BOutgoingInvoiceProcessingField; + } + set + { + this.b2BOutgoingInvoiceProcessingField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing +{ + + private object itemField; + + /// + [System.Xml.Serialization.XmlElementAttribute("CorrectB2BOutgoingInvoice", typeof(SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingCorrectB2BOutgoingInvoice), Order=0)] + [System.Xml.Serialization.XmlElementAttribute("IncorrectB2BOutgoingInvoice", typeof(SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingIncorrectB2BOutgoingInvoice), Order=0)] + public object Item + { + get + { + return this.itemField; + } + set + { + this.itemField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingCorrectB2BOutgoingInvoice +{ + + private string supplierInvoiceIDField; + + private string invoiceIDField; + + private System.DateTime invoiceTimestampField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=1)] + public string InvoiceID + { + get + { + return this.invoiceIDField; + } + set + { + this.invoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public System.DateTime InvoiceTimestamp + { + get + { + return this.invoiceTimestampField; + } + set + { + this.invoiceTimestampField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1")] +public partial class SendB2BOutgoingInvoiceAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingIncorrectB2BOutgoingInvoice +{ + + private string supplierInvoiceIDField; + + private string errorCodeField; + + private string errorMessageField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string ErrorCode + { + get + { + return this.errorCodeField; + } + set + { + this.errorCodeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public string ErrorMessage + { + get + { + return this.errorMessageField; + } + set + { + this.errorMessageField = value; + } + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class sendB2BOutgoingInvoiceRequest +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1", Order=0)] + public SendB2BOutgoingInvoiceMsg SendB2BOutgoingInvoiceMsg; + + public sendB2BOutgoingInvoiceRequest() + { + } + + public sendB2BOutgoingInvoiceRequest(SendB2BOutgoingInvoiceMsg SendB2BOutgoingInvoiceMsg) + { + this.SendB2BOutgoingInvoiceMsg = SendB2BOutgoingInvoiceMsg; + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class sendB2BOutgoingInvoiceResponse +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoice/v0.1", Order=0)] + public SendB2BOutgoingInvoiceAckMsg SendB2BOutgoingInvoiceAckMsg; + + public sendB2BOutgoingInvoiceResponse() + { + } + + public sendB2BOutgoingInvoiceResponse(SendB2BOutgoingInvoiceAckMsg SendB2BOutgoingInvoiceAckMsg) + { + this.SendB2BOutgoingInvoiceAckMsg = SendB2BOutgoingInvoiceAckMsg; + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingMsg +{ + + private HeaderSupplierType headerSupplierField; + + private SendB2BOutgoingInvoiceReportingMsgData dataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public HeaderSupplierType HeaderSupplier + { + get + { + return this.headerSupplierField; + } + set + { + this.headerSupplierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceReportingMsgData Data + { + get + { + return this.dataField; + } + set + { + this.dataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingMsgData +{ + + private SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelope b2BOutgoingInvoiceEnvelopeField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelope B2BOutgoingInvoiceEnvelope + { + get + { + return this.b2BOutgoingInvoiceEnvelopeField; + } + set + { + this.b2BOutgoingInvoiceEnvelopeField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelope +{ + + private SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard xMLStandardField; + + private SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier specificationIdentifierField; + + private string supplierInvoiceIDField; + + private string buyerIDField; + + private string additionalBuyerIDField; + + private byte[] itemField; + + private ItemChoiceType1 itemElementNameField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard XMLStandard + { + get + { + return this.xMLStandardField; + } + set + { + this.xMLStandardField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier SpecificationIdentifier + { + get + { + return this.specificationIdentifierField; + } + set + { + this.specificationIdentifierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public string BuyerID + { + get + { + return this.buyerIDField; + } + set + { + this.buyerIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=4)] + public string AdditionalBuyerID + { + get + { + return this.additionalBuyerIDField; + } + set + { + this.additionalBuyerIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute("CreditNoteEnvelope", typeof(byte[]), DataType="base64Binary", Order=5)] + [System.Xml.Serialization.XmlElementAttribute("InvoiceEnvelope", typeof(byte[]), DataType="base64Binary", Order=5)] + [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")] + public byte[] Item + { + get + { + return this.itemField; + } + set + { + this.itemField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=6)] + [System.Xml.Serialization.XmlIgnoreAttribute()] + public ItemChoiceType1 ItemElementName + { + get + { + return this.itemElementNameField; + } + set + { + this.itemElementNameField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public enum SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard +{ + + /// + UBL, + + /// + CII, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public enum SendB2BOutgoingInvoiceReportingMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier +{ + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017")] + urnceneuen169312017, + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0")] + urnceneuen169312017complianturnfdcpeppoleu2017poaccbilling30, + + /// + [System.Xml.Serialization.XmlEnumAttribute("urn:cen.eu:en16931:2017#compliant#urn:mfin.gov.hr:cius-2025:1.0#conformant#urn:mf" + + "in.gov.hr:ext-2025:1.0")] + urnceneuen169312017complianturnmfingovhrcius202510conformanturnmfingovhrext202510, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1", IncludeInSchema=false)] +public enum ItemChoiceType1 +{ + + /// + CreditNoteEnvelope, + + /// + InvoiceEnvelope, +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingAckMsg +{ + + private MessageAckType messageAckField; + + private SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelope b2BOutgoingInvoiceEnvelopeField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public MessageAckType MessageAck + { + get + { + return this.messageAckField; + } + set + { + this.messageAckField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelope B2BOutgoingInvoiceEnvelope + { + get + { + return this.b2BOutgoingInvoiceEnvelopeField; + } + set + { + this.b2BOutgoingInvoiceEnvelopeField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelope +{ + + private SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing b2BOutgoingInvoiceProcessingField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing B2BOutgoingInvoiceProcessing + { + get + { + return this.b2BOutgoingInvoiceProcessingField; + } + set + { + this.b2BOutgoingInvoiceProcessingField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessing +{ + + private object itemField; + + /// + [System.Xml.Serialization.XmlElementAttribute("CorrectB2BOutgoingInvoice", typeof(SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingCorrectB2BOutgoingInvoice), Order=0)] + [System.Xml.Serialization.XmlElementAttribute("IncorrectB2BOutgoingInvoice", typeof(SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingIncorrectB2BOutgoingInvoice), Order=0)] + public object Item + { + get + { + return this.itemField; + } + set + { + this.itemField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingCorrectB2BOutgoingInvoice +{ + + private string supplierInvoiceIDField; + + private string invoiceIDField; + + private System.DateTime invoiceTimestampField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=1)] + public string InvoiceID + { + get + { + return this.invoiceIDField; + } + set + { + this.invoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public System.DateTime InvoiceTimestamp + { + get + { + return this.invoiceTimestampField; + } + set + { + this.invoiceTimestampField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1")] +public partial class SendB2BOutgoingInvoiceReportingAckMsgB2BOutgoingInvoiceEnvelopeB2BOutgoingInvoiceProcessingIncorrectB2BOutgoingInvoice +{ + + private string supplierInvoiceIDField; + + private string errorCodeField; + + private string errorMessageField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string ErrorCode + { + get + { + return this.errorCodeField; + } + set + { + this.errorCodeField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public string ErrorMessage + { + get + { + return this.errorMessageField; + } + set + { + this.errorMessageField = value; + } + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class sendB2BOutgoingInvoiceReportingRequest +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1", Order=0)] + public SendB2BOutgoingInvoiceReportingMsg SendB2BOutgoingInvoiceReportingMsg; + + public sendB2BOutgoingInvoiceReportingRequest() + { + } + + public sendB2BOutgoingInvoiceReportingRequest(SendB2BOutgoingInvoiceReportingMsg SendB2BOutgoingInvoiceReportingMsg) + { + this.SendB2BOutgoingInvoiceReportingMsg = SendB2BOutgoingInvoiceReportingMsg; + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class sendB2BOutgoingInvoiceReportingResponse +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/SendB2BOutgoingInvoiceReporting/v0.1", Order=0)] + public SendB2BOutgoingInvoiceReportingAckMsg SendB2BOutgoingInvoiceReportingAckMsg; + + public sendB2BOutgoingInvoiceReportingResponse() + { + } + + public sendB2BOutgoingInvoiceReportingResponse(SendB2BOutgoingInvoiceReportingAckMsg SendB2BOutgoingInvoiceReportingAckMsg) + { + this.SendB2BOutgoingInvoiceReportingAckMsg = SendB2BOutgoingInvoiceReportingAckMsg; + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1")] +public partial class GetB2BOutgoingInvoiceStatusMsg +{ + + private HeaderSupplierType headerSupplierField; + + private GetB2BOutgoingInvoiceStatusMsgData dataField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public HeaderSupplierType HeaderSupplier + { + get + { + return this.headerSupplierField; + } + set + { + this.headerSupplierField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public GetB2BOutgoingInvoiceStatusMsgData Data + { + get + { + return this.dataField; + } + set + { + this.dataField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1")] +public partial class GetB2BOutgoingInvoiceStatusMsgData +{ + + private GetB2BOutgoingInvoiceStatusMsgDataB2BOutgoingInvoiceStatus b2BOutgoingInvoiceStatusField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public GetB2BOutgoingInvoiceStatusMsgDataB2BOutgoingInvoiceStatus B2BOutgoingInvoiceStatus + { + get + { + return this.b2BOutgoingInvoiceStatusField; + } + set + { + this.b2BOutgoingInvoiceStatusField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1")] +public partial class GetB2BOutgoingInvoiceStatusMsgDataB2BOutgoingInvoiceStatus +{ + + private string supplierInvoiceIDField; + + private string invoiceYearField; + + private bool documentCurrencyCodeField; + + private bool documentCurrencyCodeFieldSpecified; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=1)] + public string InvoiceYear + { + get + { + return this.invoiceYearField; + } + set + { + this.invoiceYearField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=2)] + public bool DocumentCurrencyCode + { + get + { + return this.documentCurrencyCodeField; + } + set + { + this.documentCurrencyCodeField = value; + } + } + + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + public bool DocumentCurrencyCodeSpecified + { + get + { + return this.documentCurrencyCodeFieldSpecified; + } + set + { + this.documentCurrencyCodeFieldSpecified = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1")] +public partial class GetB2BOutgoingInvoiceStatusAckMsg +{ + + private MessageAckType messageAckField; + + private GetB2BOutgoingInvoiceStatusAckMsgB2BOutgoingInvoiceStatus b2BOutgoingInvoiceStatusField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=0)] + public MessageAckType MessageAck + { + get + { + return this.messageAckField; + } + set + { + this.messageAckField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public GetB2BOutgoingInvoiceStatusAckMsgB2BOutgoingInvoiceStatus B2BOutgoingInvoiceStatus + { + get + { + return this.b2BOutgoingInvoiceStatusField; + } + set + { + this.b2BOutgoingInvoiceStatusField = value; + } + } +} + +/// +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1")] +public partial class GetB2BOutgoingInvoiceStatusAckMsgB2BOutgoingInvoiceStatus +{ + + private string supplierIDField; + + private string additionalSupplierIDField; + + private string invoiceIDField; + + private string supplierInvoiceIDField; + + private System.DateTime invoiceTimestampField; + + private DocumentStatusType[] documentStatusField; + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=0)] + public string SupplierID + { + get + { + return this.supplierIDField; + } + set + { + this.supplierIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=1)] + public string AdditionalSupplierID + { + get + { + return this.additionalSupplierIDField; + } + set + { + this.additionalSupplierIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=2)] + public string InvoiceID + { + get + { + return this.invoiceIDField; + } + set + { + this.invoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=3)] + public string SupplierInvoiceID + { + get + { + return this.supplierInvoiceIDField; + } + set + { + this.supplierInvoiceIDField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute(Order=4)] + public System.DateTime InvoiceTimestamp + { + get + { + return this.invoiceTimestampField; + } + set + { + this.invoiceTimestampField = value; + } + } + + /// + [System.Xml.Serialization.XmlElementAttribute("DocumentStatus", Namespace="http://fina.hr/eracun/b2b/invoicewebservicecomponents/v0.1", Order=5)] + public DocumentStatusType[] DocumentStatus + { + get + { + return this.documentStatusField; + } + set + { + this.documentStatusField = value; + } + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class getB2BOutgoingInvoiceStatusRequest +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1", Order=0)] + public GetB2BOutgoingInvoiceStatusMsg GetB2BOutgoingInvoiceStatusMsg; + + public getB2BOutgoingInvoiceStatusRequest() + { + } + + public getB2BOutgoingInvoiceStatusRequest(GetB2BOutgoingInvoiceStatusMsg GetB2BOutgoingInvoiceStatusMsg) + { + this.GetB2BOutgoingInvoiceStatusMsg = GetB2BOutgoingInvoiceStatusMsg; + } +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] +[System.ServiceModel.MessageContractAttribute(IsWrapped=false)] +public partial class getB2BOutgoingInvoiceStatusResponse +{ + + [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://fina.hr/eracun/b2b/pki/GetB2BOutgoingInvoiceStatus/v0.1", Order=0)] + public GetB2BOutgoingInvoiceStatusAckMsg GetB2BOutgoingInvoiceStatusAckMsg; + + public getB2BOutgoingInvoiceStatusResponse() + { + } + + public getB2BOutgoingInvoiceStatusResponse(GetB2BOutgoingInvoiceStatusAckMsg GetB2BOutgoingInvoiceStatusAckMsg) + { + this.GetB2BOutgoingInvoiceStatusAckMsg = GetB2BOutgoingInvoiceStatusAckMsg; + } +} + +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +public interface eRacunB2BPortTypeChannel : eRacunB2BPortType, System.ServiceModel.IClientChannel +{ +} + +[System.Diagnostics.DebuggerStepThroughAttribute()] +[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "8.0.0")] +public partial class eRacunB2BPortTypeClient : System.ServiceModel.ClientBase, eRacunB2BPortType +{ + + /// + /// Implement this partial method to configure the service endpoint. + /// + /// The endpoint to configure + /// The client credentials + static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials); + + public eRacunB2BPortTypeClient() : + base(eRacunB2BPortTypeClient.GetDefaultBinding(), eRacunB2BPortTypeClient.GetDefaultEndpointAddress()) + { + this.Endpoint.Name = EndpointConfiguration.eRacunB2BPortType.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public eRacunB2BPortTypeClient(EndpointConfiguration endpointConfiguration) : + base(eRacunB2BPortTypeClient.GetBindingForEndpoint(endpointConfiguration), eRacunB2BPortTypeClient.GetEndpointAddress(endpointConfiguration)) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public eRacunB2BPortTypeClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : + base(eRacunB2BPortTypeClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress)) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public eRacunB2BPortTypeClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : + base(eRacunB2BPortTypeClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public eRacunB2BPortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) + { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + System.Threading.Tasks.Task eRacunB2BPortType.echoAsync(echoRequest request) + { + return base.Channel.echoAsync(request); + } + + public System.Threading.Tasks.Task echoAsync(EchoMsg EchoMsg) + { + echoRequest inValue = new echoRequest(); + inValue.EchoMsg = EchoMsg; + return ((eRacunB2BPortType)(this)).echoAsync(inValue); + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + System.Threading.Tasks.Task eRacunB2BPortType.sendB2BOutgoingInvoiceAsync(sendB2BOutgoingInvoiceRequest request) + { + return base.Channel.sendB2BOutgoingInvoiceAsync(request); + } + + public System.Threading.Tasks.Task sendB2BOutgoingInvoiceAsync(SendB2BOutgoingInvoiceMsg SendB2BOutgoingInvoiceMsg) + { + sendB2BOutgoingInvoiceRequest inValue = new sendB2BOutgoingInvoiceRequest(); + inValue.SendB2BOutgoingInvoiceMsg = SendB2BOutgoingInvoiceMsg; + return ((eRacunB2BPortType)(this)).sendB2BOutgoingInvoiceAsync(inValue); + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + System.Threading.Tasks.Task eRacunB2BPortType.sendB2BOutgoingInvoiceReportingAsync(sendB2BOutgoingInvoiceReportingRequest request) + { + return base.Channel.sendB2BOutgoingInvoiceReportingAsync(request); + } + + public System.Threading.Tasks.Task sendB2BOutgoingInvoiceReportingAsync(SendB2BOutgoingInvoiceReportingMsg SendB2BOutgoingInvoiceReportingMsg) + { + sendB2BOutgoingInvoiceReportingRequest inValue = new sendB2BOutgoingInvoiceReportingRequest(); + inValue.SendB2BOutgoingInvoiceReportingMsg = SendB2BOutgoingInvoiceReportingMsg; + return ((eRacunB2BPortType)(this)).sendB2BOutgoingInvoiceReportingAsync(inValue); + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + System.Threading.Tasks.Task eRacunB2BPortType.getB2BOutgoingInvoiceStatusAsync(getB2BOutgoingInvoiceStatusRequest request) + { + return base.Channel.getB2BOutgoingInvoiceStatusAsync(request); + } + + public System.Threading.Tasks.Task getB2BOutgoingInvoiceStatusAsync(GetB2BOutgoingInvoiceStatusMsg GetB2BOutgoingInvoiceStatusMsg) + { + getB2BOutgoingInvoiceStatusRequest inValue = new getB2BOutgoingInvoiceStatusRequest(); + inValue.GetB2BOutgoingInvoiceStatusMsg = GetB2BOutgoingInvoiceStatusMsg; + return ((eRacunB2BPortType)(this)).getB2BOutgoingInvoiceStatusAsync(inValue); + } + + public virtual System.Threading.Tasks.Task OpenAsync() + { + return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action(((System.ServiceModel.ICommunicationObject)(this)).EndOpen)); + } + + #if !NET6_0_OR_GREATER + public virtual System.Threading.Tasks.Task CloseAsync() + { + return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action(((System.ServiceModel.ICommunicationObject)(this)).EndClose)); + } + #endif + + private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration) + { + if ((endpointConfiguration == EndpointConfiguration.eRacunB2BPortType)) + { + System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding(); + result.MaxBufferSize = int.MaxValue; + result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max; + result.MaxReceivedMessageSize = int.MaxValue; + result.AllowCookies = true; + return result; + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration) + { + if ((endpointConfiguration == EndpointConfiguration.eRacunB2BPortType)) + { + return new System.ServiceModel.EndpointAddress("http://address/SendB2BOutgoingInvoicePKIWebService"); + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.Channels.Binding GetDefaultBinding() + { + return eRacunB2BPortTypeClient.GetBindingForEndpoint(EndpointConfiguration.eRacunB2BPortType); + } + + private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress() + { + return eRacunB2BPortTypeClient.GetEndpointAddress(EndpointConfiguration.eRacunB2BPortType); + } + + public enum EndpointConfiguration + { + + eRacunB2BPortType, + } +} diff --git a/MAES.Fiskal2/IPosrednik.cs b/MAES.Fiskal2/IPosrednik.cs deleted file mode 100644 index 2fb4490..0000000 --- a/MAES.Fiskal2/IPosrednik.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Text.Json.Serialization; -using MAES.Fiskal2.Posrednici; - -namespace MAES.Fiskal2; - -/// -/// Sučelje koje opisuje osnovne operacije za posrednike hrvatskog e-fiskalizacijskog sustava. -/// -[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] -[JsonDerivedType(typeof(Super), "Super")] -[JsonDerivedType(typeof(EPoslovanje), "EPoslovanje")] -[JsonDerivedType(typeof(Fina), "Fina")] -public interface IPosrednik -{ - /// - /// Dohvaća XML/UBL sadržaj ulaznog računa po njegovom identifikatoru. - /// - /// Identifikator ulaznog računa. - /// Token za otkazivanje operacije. - /// XML/UBL sadržaj računa kao tekst. - public Task UlazniUBLAsync(string id, CancellationToken token = default); - - /// - /// Dohvaća PDF sadržaj ulaznog računa po njegovom identifikatoru. - /// - /// Identifikator ulaznog računa. - /// Token za otkazivanje operacije. - /// PDF sadržaj računa kao bajtni niz. - public Task UlazniPdfAsync(string id, CancellationToken token = default); - - /// - /// Dohvaća popis ulaznih e-računa u zadanom vremenskom rasponu. - /// - /// Početni datum vremenskog raspona. - /// Krajnji datum vremenskog raspona. - /// Token za otkazivanje operacije. - /// Popis ulaznih e-računa. - public Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default); - - /// - /// Dohvaća XML/UBL sadržaj izlaznog računa po njegovom identifikatoru. - /// - /// Identifikator izlaznog računa. - /// Token za otkazivanje operacije. - /// XML/UBL sadržaj računa kao tekst. - public Task IzlazniUBLAsync(string id, CancellationToken token = default); - - /// - /// Dohvaća PDF sadržaj izlaznog računa po njegovom identifikatoru. - /// - /// Identifikator izlaznog računa. - /// Token za otkazivanje operacije. - /// PDF sadržaj računa kao bajtni niz. - public Task IzlazniPdfAsync(string id, CancellationToken token = default); - - /// - /// Dohvaća popis izlaznih e-računa u zadanom vremenskom rasponu. - /// - /// Početni datum vremenskog raspona. - /// Krajnji datum vremenskog raspona. - /// Token za otkazivanje operacije. - /// Popis izlaznih e-računa. - public Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default); - - /// - /// Evidentira ulazni UBL dokument u fiskalizacijski sustav. - /// - /// UBL XML dokument ulaznog računa. - /// Token za otkazivanje operacije. - public Task EvidentirajUBLAsync(string ubl, CancellationToken token = default); - - /// - /// Evidentira uplatu za račun po njegovom identifikatoru. - /// - /// Identifikator računa čiju uplatu treba evidentirati. - /// Datum uplate. - /// Iznos uplate. - /// Način plaćanja. - /// Token za otkazivanje operacije. - public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default); - - /// - /// Odbija račun u fiskalizacijskom procesu prema zadanom identifikatoru. - /// - /// Identifikator računa koji se odbija. - /// Razlog odbijanja računa. - /// Opis razloga odbijanja. - /// Token za otkazivanje operacije. - public Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default); -} \ No newline at end of file diff --git a/MAES.Fiskal2/MAES.Fiskal2.csproj b/MAES.Fiskal2/MAES.Fiskal2.csproj index a61df78..ff3278d 100644 --- a/MAES.Fiskal2/MAES.Fiskal2.csproj +++ b/MAES.Fiskal2/MAES.Fiskal2.csproj @@ -10,7 +10,7 @@ MAES.Fiskal2 - 0.2.0 + 0.3.0 Roko Tomović MAES C# biblioteka za rad s Hrvatskim fiskalnim posrednicima @@ -22,6 +22,9 @@ + + + diff --git a/MAES.Fiskal2/Posrednici/EPoslovanje.cs b/MAES.Fiskal2/Posrednici/EPoslovanje.cs index 27ae26a..0340c6f 100644 --- a/MAES.Fiskal2/Posrednici/EPoslovanje.cs +++ b/MAES.Fiskal2/Posrednici/EPoslovanje.cs @@ -7,16 +7,8 @@ namespace MAES.Fiskal2.Posrednici; /// /// Implementacija posrednika za ePoslovanje, https://eposlovanje.hr/ /// -public class EPoslovanje : IPosrednik +public class EPoslovanje : Posrednik { - const string URI = "https://eracun.eposlovanje.hr"; - const string URI_DEV = "https://test.eposlovanje.hr"; - - /// - /// Označava je li povezivanje na razvojni (test) API endpoint. - /// - public bool IsDev { get; set; } - /// /// OIB poslovnog subjekta. /// @@ -32,11 +24,20 @@ public class EPoslovanje : IPosrednik /// public string Password { get; set; } = ""; + /// + /// Inicijalizira novog ePoslovanje posrednika s definiranim URI postavkama za produkcijsko i razvojno okruženje. + /// + public EPoslovanje() + { + UriProd = "https://eracun.eposlovanje.hr"; + UriDev = "https://test.eposlovanje.hr"; + } + HttpClient createClient() { var client = new HttpClient { - BaseAddress = new Uri(IsDev ? URI_DEV : URI) + BaseAddress = new Uri(Uri) }; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); @@ -48,14 +49,16 @@ async Task apiKey() { using var client = createClient(); - var request = new HttpRequestMessage(HttpMethod.Post, "/api/v2/account/apikey"); - request.Content = new StringContent(JsonSerializer.Serialize(new + var request = new HttpRequestMessage(HttpMethod.Post, "/api/v2/account/apikey") { - username = Username, - password = Password, - vatId = OIB, - softwareId = "MAES.Fiskal2" - }), Encoding.UTF8, "application/json"); + Content = new StringContent(JsonSerializer.Serialize(new + { + username = Username, + password = Password, + vatId = OIB, + softwareId = "MAES.Fiskal2" + }), Encoding.UTF8, "application/json") + }; var response = await client.SendAsync(request); var json = await response.Content.ReadAsStringAsync(); @@ -100,19 +103,19 @@ async Task changeStatusAsync(string id, int status, string? note = null, double? /// /// Dohvaća XML/UBL sadržaj ulaznog računa. /// - public async Task UlazniUBLAsync(string id, CancellationToken token = default) => + public override async Task UlazniUBLAsync(string id, CancellationToken token = default) => (await sendRequest(HttpMethod.Get, $"/api/v2/document/get/{id}", null, token)).RootElement.GetProperty("document").GetString()!; /// /// Dohvaća PDF sadržaj ulaznog računa. /// - public async Task UlazniPdfAsync(string id, CancellationToken token = default) => + public override async Task UlazniPdfAsync(string id, CancellationToken token = default) => Convert.FromBase64String((await sendRequest(HttpMethod.Get, $"/api/v2/document/visualization/{id}", null, token)).RootElement.GetProperty("pdf").GetString()!); /// /// Dohvaća popis ulaznih e-računa. /// - public async Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) + public override async Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) { var doc = await sendRequest(HttpMethod.Get, $"/api/v2/document/incoming?insertedFrom={from:O}&insertedTo={to:O}&limit=1000&offset=0", null, token); @@ -137,19 +140,19 @@ public async Task> UlazniListAsync(DateTime from, Date /// /// Dohvaća XML/UBL sadržaj izlaznog računa. /// - public Task IzlazniUBLAsync(string id, CancellationToken token = default) - => UlazniUBLAsync(id, token); + public override async Task IzlazniUBLAsync(string id, CancellationToken token = default) + => await UlazniUBLAsync(id, token); /// /// Dohvaća PDF sadržaj izlaznog računa. /// - public Task IzlazniPdfAsync(string id, CancellationToken token = default) - => UlazniPdfAsync(id, token); + public override async Task IzlazniPdfAsync(string id, CancellationToken token = default) + => await UlazniPdfAsync(id, token); /// /// Dohvaća popis izlaznih e-računa. /// - public async Task> IzlazniListAsync( + public override async Task> IzlazniListAsync( DateTime from, DateTime to, CancellationToken token = default) @@ -177,7 +180,7 @@ public async Task> IzlazniListAsync( /// /// Evidentira UBL dokument u ePoslovanje sustav. /// - public async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) => await sendRequest(HttpMethod.Post, "/api/v2/document/send", new + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) => await sendRequest(HttpMethod.Post, "/api/v2/document/send", new { document = ubl, softwareId = "MAES.Blagajna" @@ -186,7 +189,7 @@ public async Task> IzlazniListAsync( /// /// Evidentira uplatu za račun. /// - public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) + public override Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) { var status = amount > 0 ? 8 : 7; // 8: partialno, 7: potpuno return changeStatusAsync(id, status, partialPaymentAmount: status == 8 ? amount : null, token: token); @@ -195,6 +198,6 @@ public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, Naci /// /// Odbija račun. /// - public Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default) => + public override Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default) => changeStatusAsync(id, status: 6, $"{razlog}: {opis}", token: token); } \ No newline at end of file diff --git a/MAES.Fiskal2/Posrednici/Fina.cs b/MAES.Fiskal2/Posrednici/Fina.cs index 0c70206..7f789fa 100644 --- a/MAES.Fiskal2/Posrednici/Fina.cs +++ b/MAES.Fiskal2/Posrednici/Fina.cs @@ -1,21 +1,81 @@ +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Xml.Linq; + namespace MAES.Fiskal2.Posrednici; /// -/// Implementacija informacijskog posrednika FINA za razmjenu e-računa. +/// Implementacija informacijskog posrednika FINA za razmjenu e-računa. Ovo je ili najgori servis ikada ili sam ja retardiran, ali FINA ne dozvoljava dohvat liste računa, PDF-a ili UBL-a. Jedino što se može je poslati račun /// -public class Fina : IPosrednik +public class Fina : Posrednik { + + /// + /// OIB poslovnog subjekta. + /// + public string OIB { get; set; } = ""; + + /// + /// X.509 certifikat koji se koristi za autentikaciju prema FINA e-Račun sustavu. + /// + public X509Certificate2? Certificate { get; set; } + + /// + /// Inicijalizira novog FINA posrednika s definiranim URI postavkama za produkcijsko i razvojno okruženje. + /// + public Fina() + { + UriProd = "https://eracun.fina.hr/eracun-b2b/services/eRacunB2BPortType"; + UriDev = "https://eracun-test.fina.hr/eracun-b2b/services/eRacunB2BPortType"; + } + /// /// Evidentira i šalje UBL/XML dokument prema FINA e-Račun sustavu. /// /// UBL/XML sadržaj dokumenta. /// Cancellation token. /// Asinkrona operacija slanja dokumenta. - public Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) { - throw new NotImplementedException(); + var xml = XDocument.Parse(ubl); + var supplierInvoiceId = GetInvoiceId(xml); + var buyerId = GetBuyerId(xml); + + var msg = new SendB2BOutgoingInvoiceMsg + { + HeaderSupplier = new HeaderSupplierType + { + MessageID = Guid.NewGuid().ToString("N"), + SupplierID = OIB, + ERPID = "MAES.Fiskal2", + MessageType = "1" + }, + + Data = new SendB2BOutgoingInvoiceMsgData + { + B2BOutgoingInvoiceEnvelope = new () + { + XMLStandard = SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeXMLStandard.UBL, + SpecificationIdentifier = SendB2BOutgoingInvoiceMsgDataB2BOutgoingInvoiceEnvelopeSpecificationIdentifier.urnceneuen169312017complianturnmfingovhrcius202510conformanturnmfingovhrext202510, + SupplierInvoiceID = supplierInvoiceId, + BuyerID = buyerId, + AdditionalBuyerID = null, + Item = Encoding.UTF8.GetBytes(ubl), + ItemElementName = ItemChoiceType.InvoiceEnvelope + } + } + }; + + using var client = new eRacunB2BPortTypeClient(eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, Uri); + + var res = await client.sendB2BOutgoingInvoiceAsync(msg); + + if (res.SendB2BOutgoingInvoiceAckMsg.MessageAck.AckStatus != AckStatusType.ACCEPTED) + throw new Exception(res.SendB2BOutgoingInvoiceAckMsg.MessageAck.AckStatusText); } + + /// /// Evidentira uplatu za dokument unutar FINA sustava. /// @@ -24,11 +84,8 @@ public Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) /// Iznos uplate. /// Način plaćanja. /// Cancellation token. - /// Asinkrona operacija evidentiranja uplate. - public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) => + throw new NotSupportedException("Evidentiranje uplata nije podržano u FINA posredniku"); /// /// Dohvaća popis izlaznih e-računa za zadani period. @@ -37,10 +94,8 @@ public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, Naci /// Završni datum pretrage. /// Cancellation token. /// Popis izlaznih e-računa. - public Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => + throw new NotSupportedException("Lista izlaznih računa nije dostupna u FINA posredniku"); /// /// Dohvaća PDF vizualizaciju izlaznog dokumenta. @@ -48,10 +103,8 @@ public Task> IzlazniListAsync(DateTime from, DateTime /// ID dokumenta. /// Cancellation token. /// PDF dokument kao byte array. - public Task IzlazniPdfAsync(string id, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override Task IzlazniPdfAsync(string id, CancellationToken token = default) => + throw new NotSupportedException("PDF izlaznih računa nije dostupan u FINA posredniku"); /// /// Dohvaća UBL/XML sadržaj izlaznog dokumenta. @@ -59,10 +112,8 @@ public Task IzlazniPdfAsync(string id, CancellationToken token = default /// ID dokumenta. /// Cancellation token. /// UBL/XML sadržaj dokumenta. - public Task IzlazniUBLAsync(string id, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override Task IzlazniUBLAsync(string id, CancellationToken token = default) => + throw new NotSupportedException("UBL izlaznih računa nije dostupan u FINA posredniku"); /// /// Odbija dokument uz zadani razlog i opis. @@ -72,7 +123,7 @@ public Task IzlazniUBLAsync(string id, CancellationToken token = default /// Dodatni opis odbijanja. /// Cancellation token. /// Asinkrona operacija odbijanja dokumenta. - public Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default) + public override Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default) { throw new NotImplementedException(); } @@ -84,10 +135,8 @@ public Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, Canc /// Završni datum pretrage. /// Cancellation token. /// Popis ulaznih e-računa. - public Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => + throw new NotSupportedException("Lista ulaznih računa nije dostupna u FINA posredniku"); /// /// Dohvaća PDF vizualizaciju ulaznog dokumenta. @@ -95,10 +144,8 @@ public Task> UlazniListAsync(DateTime from, DateTime t /// ID dokumenta. /// Cancellation token. /// PDF dokument kao byte array. - public Task UlazniPdfAsync(string id, CancellationToken token = default) - { - throw new NotImplementedException(); - } + public override Task UlazniPdfAsync(string id, CancellationToken token = default) => + throw new NotSupportedException("PDF ulaznih računa nije dostupan u FINA posredniku"); /// /// Dohvaća UBL/XML sadržaj ulaznog dokumenta. @@ -106,8 +153,41 @@ public Task UlazniPdfAsync(string id, CancellationToken token = default) /// ID dokumenta. /// Cancellation token. /// UBL/XML sadržaj dokumenta. - public Task UlazniUBLAsync(string id, CancellationToken token = default) + public override Task UlazniUBLAsync(string id, CancellationToken token = default) => + throw new NotSupportedException("UBL ulaznih računa nije dostupan u FINA posredniku"); + + static string GetInvoiceId(XDocument xml) { - throw new NotImplementedException(); + XNamespace cbc = + "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"; + + return xml.Root? + .Element(cbc + "ID")? + .Value + ?? throw new InvalidOperationException("UBL nema Invoice ID."); + } + + static string GetBuyerId(XDocument xml) + { + XNamespace cac = + "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"; + XNamespace cbc = + "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"; + + return xml.Root? + .Element(cac + "AccountingCustomerParty")? + .Descendants(cbc + "CompanyID") + .FirstOrDefault()? + .Value + ?? throw new InvalidOperationException("UBL nema BuyerID."); } + + eRacunB2BPortTypeClient CreateClient() => new (eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, Uri); + + HeaderSupplierType Header() => new() + { + MessageID = Guid.NewGuid().ToString(), + ERPID = "MAES.Fiskal2", + SupplierID = OIB + }; } \ No newline at end of file diff --git a/MAES.Fiskal2/Posrednici/MER.cs b/MAES.Fiskal2/Posrednici/MER.cs new file mode 100644 index 0000000..7d53a9e --- /dev/null +++ b/MAES.Fiskal2/Posrednici/MER.cs @@ -0,0 +1,188 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; + +namespace MAES.Fiskal2.Posrednici; + +/// +/// Implementacija posrednika za Moj-eRačun, servis za slanje i obradu elektroničkih računa. +/// Omogućuje evidentiranje UBL/XML dokumenata putem demo ili produkcijskog API-ja. +/// +public class MER : Posrednik +{ + /// + /// Korisničko ime za autentifikaciju na Moj-eRačun API-u. + /// + public string Username { get; set; } = ""; + + /// + /// Lozinka za autentifikaciju na Moj-eRačun API-u. + /// + public string Password { get; set; } = ""; + + /// + /// OIB poslovnog subjekta pošiljatelja. + /// + public string OIB { get; set; } = ""; + + /// + /// Inicijalizira novog Moj-eRačun posrednika s definiranim URI adresama + /// za produkcijsko i razvojno okruženje. + /// + public MER() + { + UriProd = "https://www.moj-eracun.hr"; + UriDev = "https://demo.moj-eracun.hr"; + } + + async Task sendRequest(HttpMethod method, string url, object? body, CancellationToken token) + { + var client = new HttpClient + { + BaseAddress = new Uri(Uri) + }; + + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + var req = new HttpRequestMessage(method, url); + if (body != null) req.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"); + + var res = await client.SendAsync(req, token); + var json = await res.Content.ReadAsStringAsync(); + + if (!res.IsSuccessStatusCode) throw new HttpRequestException(json); + + return json; + } + + /// + /// Šalje UBL/XML dokument izlaznog e-računa na Moj-eRačun servis. + /// Dokument se validira i obrađuje, a u slučaju uspješnog slanja + /// servis generira jedinstveni identifikator dokumenta. + /// + /// UBL XML sadržaj e-računa. + /// Token za otkazivanje operacije. + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken cancellationToken = default) =>await sendRequest(HttpMethod.Post, "/apis/v2/send", new + { + Username, + Password, + CompanyId = OIB, + SoftwareId = "MAES.Fiskal2", + File = Convert.ToBase64String(Encoding.UTF8.GetBytes(ubl)) + }, cancellationToken); + + /// + /// Dohvat ulaznog UBL dokumenta. + /// + /// Identifikator dokumenta. + /// Token za otkazivanje operacije. + public override async Task UlazniUBLAsync(string id, CancellationToken cancellationToken = default) => await sendRequest(HttpMethod.Post, $"/apis/v2/receive", new + { + Username, + Password, + CompanyId = OIB, + SoftwareId = "MAES.Fiskal2", + ElectronicId = id + }, cancellationToken); + + /// + /// Dohvat PDF prikaza ulaznog računa trenutno nije podržan putem Moj-eRačun integracije. + /// + /// Identifikator dokumenta. + /// Token za otkazivanje operacije. + public override Task UlazniPdfAsync( + string id, + CancellationToken cancellationToken = default) + => throw new NotSupportedException(); + + /// + /// Dohvat popisa ulaznih e-računa trenutno nije podržan putem Moj-eRačun integracije. + /// + /// Početni datum raspona. + /// Završni datum raspona. + /// Token za otkazivanje operacije. + public override Task> UlazniListAsync( + DateTime from, + DateTime to, + CancellationToken cancellationToken = default) + => throw new NotSupportedException(); + + /// + /// Dohvat izlaznog UBL dokumenta. + /// + /// Identifikator dokumenta. + /// Token za otkazivanje operacije. + public override async Task IzlazniUBLAsync(string id, CancellationToken cancellationToken = default) => await UlazniUBLAsync(id, cancellationToken); + + /// + /// Dohvat PDF prikaza izlaznog računa trenutno nije podržan putem Moj-eRačun integracije. + /// + /// Identifikator dokumenta. + /// Token za otkazivanje operacije. + public override Task IzlazniPdfAsync( + string id, + CancellationToken cancellationToken = default) + => throw new NotSupportedException(); + + /// + /// Dohvat popisa izlaznih e-računa trenutno nije podržan putem Moj-eRačun integracije. + /// + /// Početni datum raspona. + /// Završni datum raspona. + /// Token za otkazivanje operacije. + public override Task> IzlazniListAsync( + DateTime from, + DateTime to, + CancellationToken cancellationToken = default) + => throw new NotSupportedException(); + + /// + /// Evidentira uplatu za račun po njegovom identifikatoru. + /// + /// Identifikator računa. + /// Datum uplate. + /// Iznos uplate. + /// Način plaćanja. + /// Token za otkazivanje operacije. + public override async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken cancellationToken = default) + { + await sendRequest(HttpMethod.Post, $"/api/fiscalization/markPaid", new + { + Username, + Password, + CompanyId = OIB, + SoftwareId = "MAES.Fiskal2", + ElectronicId = id, + PaymentDate = date.ToString("yyyy-MM-dd"), + PaymentAmount = amount, + PaymentMethod = "T" // TODO: ovo treba mapirati iz NacinPlacanja enum-a + }, cancellationToken); + } + + /// + /// Odbijanje računa trenutno nije podržano putem Moj-eRačun integracije. + /// + /// Identifikator računa. + /// Razlog odbijanja. + /// Opis razloga odbijanja. + /// Token za otkazivanje operacije. + public override async Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken cancellationToken = default) + { + await sendRequest(HttpMethod.Post, $"/api/fiscalization/rejectWithoutElectronicID", new + { + Username, + Password, + CompanyId = OIB, + SoftwareId = "MAES.Fiskal2", + ElectronicId = id, + RejectionDate = DateTime.Now, + RejectionReasonDescription = opis, + RejectionReasonType = razlog switch + { + RazlogOdbijanja.NeusklađenostKojaNeUtjeceNaObracunPoreza => "N", + RazlogOdbijanja.NeusklađenostKojaUtjeceNaObracunPoreza => "U", + _ => "O" + } + }, cancellationToken); + } +} \ No newline at end of file diff --git a/MAES.Fiskal2/Posrednici/Parra.cs b/MAES.Fiskal2/Posrednici/Parra.cs new file mode 100644 index 0000000..28413f9 --- /dev/null +++ b/MAES.Fiskal2/Posrednici/Parra.cs @@ -0,0 +1,203 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; + +namespace MAES.Fiskal2.Posrednici; + +/// +/// Implementacija posrednika Parra v1.1. https://api.parra.hr/docs/#api-v11 +/// +public class Parra : Posrednik +{ + /// + /// OIB poslovnog subjekta. + /// + public string OIB { get; set; } = ""; + + /// + /// Korisničko ime za autentifikaciju. + /// + public string Username { get; set; } = ""; + + /// + /// Lozinka za autentifikaciju. + /// + public string Password { get; set; } = ""; + + /// + /// Inicijalizira novog Parra posrednika s definiranim URI postavkama za produkcijsko i razvojno okruženje. + /// + public Parra() + { + UriProd = "https://api.parra.hr"; + UriDev = ""; + } + + HttpClient createClient() + { + var client = new HttpClient + { + BaseAddress = new Uri(Uri) + }; + + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + return client; + } + + async Task apiKey() + { + using var client = createClient(); + + var request = new HttpRequestMessage(HttpMethod.Post, "/api/v2/account/apikey") + { + Content = new StringContent(JsonSerializer.Serialize(new + { + username = Username, + password = Password, + vatId = OIB, + softwareId = "MAES.Fiskal2" + }), Encoding.UTF8, "application/json") + }; + + var response = await client.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) + throw new HttpRequestException(json); + + using var doc = JsonDocument.Parse(json); + return doc.RootElement.GetProperty("apiKey").GetString()!; + } + + async Task sendRequest(HttpMethod method, string url, object? body, CancellationToken token) + { + using var client = createClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await apiKey()); + + var req = new HttpRequestMessage(method, url); + if (body != null) req.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"); + + var res = await client.SendAsync(req, token); + var json = await res.Content.ReadAsStringAsync(); + + if (!res.IsSuccessStatusCode) throw new HttpRequestException(json); + + return JsonDocument.Parse(json); + } + + async Task changeStatusAsync(string id, int status, string? note = null, double? partialPaymentAmount = null, CancellationToken token = default) + { + var body = new Dictionary + { + ["status"] = status, + ["changedOn"] = DateTimeOffset.Now.ToString("O") + }; + + if (!string.IsNullOrWhiteSpace(note)) body["note"] = note; + if (partialPaymentAmount.HasValue) body["partialPaymentAmount"] = partialPaymentAmount.Value; + + await sendRequest(HttpMethod.Post, $"/api/v2/document/changestatus/{id}", body, token); + } + + /// + /// Dohvaća XML/UBL sadržaj ulaznog računa. + /// + public override async Task UlazniUBLAsync(string id, CancellationToken token = default) => + (await sendRequest(HttpMethod.Get, $"/api/v2/document/get/{id}", null, token)).RootElement.GetProperty("document").GetString()!; + + /// + /// Dohvaća PDF sadržaj ulaznog računa. + /// + public override async Task UlazniPdfAsync(string id, CancellationToken token = default) => + Convert.FromBase64String((await sendRequest(HttpMethod.Get, $"/api/v2/document/visualization/{id}", null, token)).RootElement.GetProperty("pdf").GetString()!); + + /// + /// Dohvaća popis ulaznih e-računa. + /// + public override async Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) + { + var doc = await sendRequest(HttpMethod.Get, $"/api/v2/document/incoming?insertedFrom={from:O}&insertedTo={to:O}&limit=1000&offset=0", null, token); + + var list = new List(); + + foreach (var item in doc.RootElement.EnumerateArray()) + { + list.Add(new UlazniERacun + { + Id = item.GetProperty("id").GetInt64().ToString(), + Datum = item.GetProperty("issuedOn").GetDateTime(), + Broj = item.GetProperty("documentId").GetString()!, + Status = UlazniERacunStatus.Zaprimljeno, // TODO: ovo treba popravit + Partner = item.GetProperty("customerPartyName").GetString()!, + PartnerOIB = item.GetProperty("customerPartyVATId").GetString()! + }); + } + + return list; + } + + /// + /// Dohvaća XML/UBL sadržaj izlaznog računa. + /// + public override async Task IzlazniUBLAsync(string id, CancellationToken token = default) + => await UlazniUBLAsync(id, token); + + /// + /// Dohvaća PDF sadržaj izlaznog računa. + /// + public override async Task IzlazniPdfAsync(string id, CancellationToken token = default) + => await UlazniPdfAsync(id, token); + + /// + /// Dohvaća popis izlaznih e-računa. + /// + public override async Task> IzlazniListAsync( + DateTime from, + DateTime to, + CancellationToken token = default) + { + var doc = await sendRequest(HttpMethod.Get, $"/api/v2/document/outgoing?insertedFrom={from:O}&insertedTo={to:O}&limit=1000&offset=0", null, token); + + var list = new List(); + + foreach (var item in doc.RootElement.EnumerateArray()) + { + list.Add(new IzlazniERacun + { + Id = item.GetProperty("id").GetInt64().ToString(), + Broj = item.GetProperty("documentId").GetString()!, + Datum = item.GetProperty("issuedOn").GetDateTime(), + PartnerNaziv = item.GetProperty("customerPartyName").GetString()!, + PartnerOIB = item.GetProperty("customerPartyVATId").GetString()!, + Status = IzlazniERacunStatus.Poslano // TODO: ovo treba popravit + }); + } + + return list; + } + + /// + /// Evidentira UBL dokument u ePoslovanje sustav. + /// + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) => await sendRequest(HttpMethod.Post, "/api/v2/document/send", new + { + document = ubl, + softwareId = "MAES.Blagajna" + }, token); + + /// + /// Evidentira uplatu za račun. + /// + public override Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) + { + var status = amount > 0 ? 8 : 7; // 8: partialno, 7: potpuno + return changeStatusAsync(id, status, partialPaymentAmount: status == 8 ? amount : null, token: token); + } + + /// + /// Odbija račun. + /// + public override Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken token = default) => + changeStatusAsync(id, status: 6, $"{razlog}: {opis}", token: token); +} \ No newline at end of file diff --git a/MAES.Fiskal2/Posrednici/Super.cs b/MAES.Fiskal2/Posrednici/Super.cs index 1b33a9f..b782748 100644 --- a/MAES.Fiskal2/Posrednici/Super.cs +++ b/MAES.Fiskal2/Posrednici/Super.cs @@ -1,5 +1,4 @@ using System.Net.Http.Headers; -using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; @@ -8,16 +7,8 @@ namespace MAES.Fiskal2.Posrednici; /// /// Implementacija posrednika za Super, https://www.super.hr/ /// -public class Super : IPosrednik +public class Super : Posrednik { - const string URI = "https://api.super.hr/"; - const string URI_DEV = "https://apitest.super.hr/"; - - /// - /// Označava je li povezivanje na razvojni (test) API endpoint. - /// - public bool IsDev { get; set; } - /// /// Jedinstveni identifikator poslovnog subjekta u Super sustavu. /// @@ -35,10 +26,19 @@ public class Super : IPosrednik static KeyValuePair? token = null; + /// + /// Inicijalizira novog Super posrednika s definiranim URI postavkama za produkcijsko i razvojno okruženje. + /// + public Super() + { + UriProd = "https://api.super.hr/"; + UriDev = "https://apitest.super.hr/"; + } + async Task postRequest(string uri, Dictionary body, CancellationToken cancellationToken) { using var client = new HttpClient(); - client.BaseAddress = new Uri(IsDev ? URI_DEV : URI); + client.BaseAddress = new Uri(Uri); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); if (token == null || DateTime.UtcNow >= token.Value.Value) @@ -83,7 +83,7 @@ async Task postRequest(string uri, Dictionary body /// Identifikator ulaznog računa. /// Token za otkazivanje operacije. /// XML/UBL sadržaj računa kao tekst. - public async Task UlazniUBLAsync(string id, CancellationToken cancellationToken = default) + public override async Task UlazniUBLAsync(string id, CancellationToken cancellationToken = default) { var jDoc = await postRequest("api/Invoice/GetInvoice", new Dictionary { @@ -100,7 +100,7 @@ public async Task UlazniUBLAsync(string id, CancellationToken cancellati /// Identifikator ulaznog računa. /// Token za otkazivanje operacije. /// PDF sadržaj računa kao bajtni niz. - public async Task UlazniPdfAsync(string id, CancellationToken cancellationToken = default) => Convert.FromBase64String((await postRequest("api/Invoice/GetInvoiceDetailVisualization", new Dictionary + public override async Task UlazniPdfAsync(string id, CancellationToken cancellationToken = default) => Convert.FromBase64String((await postRequest("api/Invoice/GetInvoiceDetailVisualization", new Dictionary { ["Guid"] = id.ToString() }, cancellationToken)).RootElement.GetProperty("invoiceDetailVisualization").GetString()!); @@ -112,7 +112,7 @@ public async Task UlazniUBLAsync(string id, CancellationToken cancellati /// Krajnji datum vremenskog raspona. /// Token za otkazivanje operacije. /// Popis ulaznih e-računa. - public async Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken cancellationToken = default) + public override async Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken cancellationToken = default) { var jsonDocument = await postRequest("api/Invoice/GetInvoiceList", new Dictionary { @@ -141,7 +141,7 @@ public async Task> UlazniListAsync(DateTime from, Date /// Identifikator izlaznog računa. /// Token za otkazivanje operacije. /// XML/UBL sadržaj računa kao tekst. - public async Task IzlazniUBLAsync(string id, CancellationToken cancellationToken = default) + public override async Task IzlazniUBLAsync(string id, CancellationToken cancellationToken = default) { var jDoc = await postRequest("api/SendingInvoice/GetSendingInvoice", new Dictionary { @@ -159,7 +159,7 @@ public async Task IzlazniUBLAsync(string id, CancellationToken cancellat /// Identifikator izlaznog računa. /// Token za otkazivanje operacije. /// PDF sadržaj računa kao bajtni niz. - public async Task IzlazniPdfAsync(string id, CancellationToken cancellationToken = default) + public override async Task IzlazniPdfAsync(string id, CancellationToken cancellationToken = default) { var jDoc = await postRequest("api/SendingInvoice/GetSendingInvoiceDetailVisualization", new Dictionary { @@ -180,7 +180,7 @@ public async Task IzlazniPdfAsync(string id, CancellationToken cancellat /// Krajnji datum vremenskog raspona. /// Token za otkazivanje operacije. /// Popis izlaznih e-računa. - public async Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken cancellationToken) + public override async Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken cancellationToken) { var jsonDocument = await postRequest("api/SendingInvoice/GetSendingInvoiceList", new Dictionary { @@ -208,7 +208,7 @@ public async Task> IzlazniListAsync(DateTime from, Da /// /// UBL XML dokument ulaznog računa. /// Token za otkazivanje operacije. - public async Task EvidentirajUBLAsync(string ubl, CancellationToken cancellationToken = default) => await postRequest("api/SendingInvoice/GetSendingInvoiceList", new Dictionary + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken cancellationToken = default) => await postRequest("api/SendingInvoice/GetSendingInvoiceList", new Dictionary { ["Base64EncodedUbl"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(ubl)), ["UblDocumentType"] = "1", // 1 = račun, 2 = odobrenje @@ -222,7 +222,7 @@ public async Task> IzlazniListAsync(DateTime from, Da /// Iznos uplate. /// Način plaćanja. /// Token za otkazivanje operacije. - public async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken cancellationToken = default) + public override async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken cancellationToken = default) { await postRequest("api/Invoice/SetInvoicePayment", new Dictionary { @@ -237,7 +237,7 @@ public async Task EvidentirajUplatuAsync(string id, DateTime date, double amount /// Razlog odbijanja računa. /// Opis razloga odbijanja. /// Token za otkazivanje operacije. - public async Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken cancellationToken = default) + public override async Task OdbijRacunAsync(string id, RazlogOdbijanja razlog, string opis, CancellationToken cancellationToken = default) { await postRequest("api/SendingInvoice/RejectSendingInvoice", new Dictionary { diff --git a/MAES.Fiskal2/Posrednik.cs b/MAES.Fiskal2/Posrednik.cs new file mode 100644 index 0000000..730d3b7 --- /dev/null +++ b/MAES.Fiskal2/Posrednik.cs @@ -0,0 +1,154 @@ +using System.Text.Json.Serialization; +using MAES.Fiskal2.Posrednici; + +namespace MAES.Fiskal2; + +/// +/// Bazna implementacija posrednika za komunikaciju sa servisom fiskalizacije / eRačuna. +/// Sadrži zajedničke URI postavke i definira osnovne operacije za rad s ulaznim i izlaznim eRačunima. +/// +[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] +[JsonDerivedType(typeof(Super), "Super")] +[JsonDerivedType(typeof(EPoslovanje), "EPoslovanje")] +[JsonDerivedType(typeof(Fina), "Fina")] +public abstract class Posrednik +{ + /// + /// Označava koristi li se razvojno okruženje. + /// Ako je true, koristi se ; inače . + /// + public bool IsDev { get; set; } + + /// + /// Produkcijski URI servisa. + /// + protected string UriProd { private get; set; } = ""; + + /// + /// URI razvojnog (testnog) okruženja servisa. + /// + protected string UriDev { private get; set; } = ""; + + /// + /// Aktivni URI servisa ovisno o odabranom okruženju. + /// + protected string Uri => IsDev ? UriDev : UriProd; + + /// + /// Evidentira izlazni eRačun na temelju UBL sadržaja. + /// + /// UBL XML sadržaj računa. + /// Token za otkazivanje operacije. + public virtual Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Evidentira uplatu za postojeći račun. + /// + /// Identifikator računa. + /// Datum i vrijeme uplate. + /// Iznos uplate. + /// Način plaćanja. + /// Token za otkazivanje operacije. + public virtual Task EvidentirajUplatuAsync( + string id, + DateTime date, + double amount, + NacinPlacanja paymentMethod, + CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Dohvaća popis izlaznih eRačuna unutar zadanog razdoblja. + /// + /// Početni datum razdoblja. + /// Završni datum razdoblja. + /// Token za otkazivanje operacije. + /// Kolekcija izlaznih eRačuna. + public virtual Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => throw new NotImplementedException(); + + /// + /// Dohvaća popis izlaznih eRačuna unutar zadanog razdoblja. + /// + /// Stranica rezultata. + /// Broj rezultata po stranici. + /// Token za otkazivanje operacije. + /// Kolekcija izlaznih eRačuna. + public virtual Task> IzlazniListAsync(int page, int pageSize, CancellationToken token = default) => throw new NotImplementedException(); + + /// + /// Dohvaća PDF prikaz izlaznog računa. + /// + /// Identifikator računa. + /// Token za otkazivanje operacije. + /// Sadržaj PDF dokumenta kao niz bajtova. + public virtual Task IzlazniPdfAsync( + string id, + CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Dohvaća UBL XML izlaznog računa. + /// + /// Identifikator računa. + /// Token za otkazivanje operacije. + /// UBL XML sadržaj računa. + public virtual Task IzlazniUBLAsync( + string id, + CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Odbija račun uz navedeni razlog i opis. + /// + /// Identifikator računa. + /// Razlog odbijanja. + /// Dodatni opis odbijanja. + /// Token za otkazivanje operacije. + public virtual Task OdbijRacunAsync( + string id, + RazlogOdbijanja razlog, + string opis, + CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Dohvaća popis ulaznih eRačuna unutar zadanog razdoblja. + /// + /// Početni datum razdoblja. + /// Završni datum razdoblja. + /// Token za otkazivanje operacije. + /// Kolekcija ulaznih eRačuna. + public virtual Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => throw new NotImplementedException(); + + /// + /// Dohvaća popis ulaznih eRačuna unutar zadanog razdoblja. + /// + /// Stranica rezultata. + /// Broj rezultata po stranici. + /// Token za otkazivanje operacije. + /// Kolekcija ulaznih eRačuna. + public virtual Task> UlazniListAsync(int page, int pageSize, CancellationToken token = default) => throw new NotImplementedException(); + + /// + /// Dohvaća PDF prikaz ulaznog računa. + /// + /// Identifikator računa. + /// Token za otkazivanje operacije. + /// Sadržaj PDF dokumenta kao niz bajtova. + public virtual Task UlazniPdfAsync( + string id, + CancellationToken token = default) => + throw new NotImplementedException(); + + /// + /// Dohvaća UBL XML ulaznog računa. + /// + /// Identifikator računa. + /// Token za otkazivanje operacije. + /// UBL XML sadržaj računa. + public virtual Task UlazniUBLAsync( + string id, + CancellationToken token = default) => + throw new NotImplementedException(); +} \ No newline at end of file diff --git a/README.md b/README.md index ad6cc59..f82bee2 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ MAES.Fiskal2 je C# biblioteka za rad s Hrvatskim fiskalnim posrednicima. Cilj pr ## Što projekt radi -Projekt definira zajedničko sučelje `IPosrednik` koje opisuje osnovne operacije za posrednike fiskalizacije: +Projekt definira zajedničku abstraktnu klasu `Posrednik` koja opisuje osnovne operacije za posrednike fiskalizacije: - dohvat ulaznih i izlaznih e-računa - dohvat UBL i PDF sadržaja računa @@ -24,15 +24,19 @@ Modeli `UlazniERacun` i `IzlazniERacun` predstavljaju minimalne informacije o ra U `Posrednici/` direktoriju nalaze se konkretne implementacije -| Značajka / posrednik | `Super` | `EPoslovanje` | `Fina` | -|---|:---:|:---:|:---:| -| Dohvat ulaznih e-računa | ✅ | ✅ | ❌ | -| Dohvat izlaznih e-računa | ✅ | ✅ | ❌ | -| Dohvat UBL sadržaja | ✅ | ✅ | ❌ | -| Dohvat PDF sadržaja | ✅ | ✅ | ❌ | -| Evidentiranje UBL dokumenta | ✅ | ✅ | ❌ | -| Evidentiranje uplate | ✅ | ✅ | ❌ | -| Odbijanje računa | ✅ | ✅ | ❌ | +| Značajka / posrednik | `Super` | `EPoslovanje` | `Fina` | `Moj eRačun` | `Redok` | `Parra` | +|---|:---:|:---:|:---:|:---:|:---:|:---:| +| Dohvat ulaznih e-računa | ✅ | ✅ | ❌* | ❌ | ❌ | ❌ | +| Dohvat izlaznih e-računa | ✅ | ✅ | ❌* | ❌ | ❌ | ❌ | +| Dohvat UBL sadržaja | ✅ | ✅ | ❌* | ✅ | ❌ | ❌ | +| Dohvat PDF sadržaja | ✅ | ✅ | ❌* | ❌** | ❌ | ❌ | +| Evidentiranje UBL dokumenta | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | +| Evidentiranje uplate | ✅ | ✅ | ❌* | ❌ | ❌ | ❌ | +| Odbijanje računa | ✅ | ✅ | ❌* | ❌ | ❌ | ❌ | + +\* Fina nema pola ovih api callova ili su na nekom drugom endpointu treba vidit + +\*\* MER ne podržava dohvat PDF byte[] ## Instalacija @@ -52,11 +56,10 @@ Ili direktno u datoteku `.csproj`: ## Inicijalizacija posrednika -### Primjer inicijalizacije Super.hr posrednika: - ```csharp using MAES.Fiskal2.Posrednici; +// Super.hr var posrednik = new Super { IsDev = true, @@ -64,13 +67,8 @@ var posrednik = new Super Username = "...", Password = "..." }; -``` - -### Primjer inicijalizacije eposlovanje.hr posrednika: - -```csharp -using MAES.Fiskal2.Posrednici; +// ePoslovanje var posrednik = new EPoslovanje { IsDev = true, @@ -78,19 +76,61 @@ var posrednik = new EPoslovanje Username = "...", Password = "..." }; + +// Fina +var posrednik = new Fina +{ + IsDev = true, + OIB = "...", + Certificate = ... +}; + +// Moj eRačun +var posrednik = new MER +{ + IsDev = true, + Username = "...", + Password = "...", + OIB = "..." +}; ``` +### Primjer korištenja posrednika + +```csharp +// dohvat računa u razdoblju zadnjih mj. dana ili dohvati paginacijom zavisi sto posrednik podržava +var racuni = posrednik.UlazniListAsync(DateTime.Now.AddMonths(-1), DateTime.Now); +var racuni = posrednik.UlazniListAsync(1, 20); + +var racun = racuni.FirstOrDefault(); +if(racun != null) +{ + // dohvat ubl stringa i pdf byteova + string ubl = await posrednik.UlazniUBLAsync(racun.Id); + byte[] pdf = await posrednik.UlazniPdfAsync(racun.Id); +} + +// evidentiranje računa +posrednik.EvidentirajUBLAsync(ubl); +``` + +> Neki posrednici nemaju podržane sve metode, neki nemaju sve fieldove u modelima tipa UlazniERacun i sl. Mora se voditi računa o tome... + ## Dostupne metode > Svaka metoda ima na kraju CancellationToken kojeg je poželjno postaviti, ali se može izostaviti -Sučelje `IPosrednik` nudi sljedeće metode: +Abstraktna klasa `Posrednik` nudi sljedeće metode: ### Dohvat ulaznih e-računa - `Task> UlazniListAsync(DateTime from, DateTime to)` Dohvaća popis ulaznih računa u vremenskom rasponu +- `Task> UlazniListAsync(int page, int pageSize)` + + Dohvaća popis ulaznih računa (pagination) + - `Task UlazniUBLAsync(string id)` Dohvaća XML/UBL sadržaj ulaznog računa @@ -104,6 +144,10 @@ Sučelje `IPosrednik` nudi sljedeće metode: Dohvaća popis izlaznih računa u vremenskom rasponu +- `Task> IzlazniListAsync(int page, int pageSize)` + + Dohvaća popis izlaznih računa (pagination) + - `Task IzlazniUBLAsync(string id)` Dohvaća XML/UBL sadržaj izlaznog računa @@ -118,11 +162,11 @@ Sučelje `IPosrednik` nudi sljedeće metode: Evidentira UBL dokument -- `Task EvidentirajUplatuAsync(string id)` +- `Task EvidentirajUplatuAsync(string id, DateTime datum, double iznos, NacinPlacanja nacinPlacanja)` Evidentira uplatu za račun -- `Task OdbijRacunAsync(string id)` +- `Task OdbijRacunAsync(string id, RazlogOdbijana razlog, string opis)` Odbija račun