From 5ffc76593b33567077349fcf8ec52be3d7e44390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Sun, 24 May 2026 15:37:44 +0200 Subject: [PATCH 01/10] dodan fina reference --- MAES.Fiskal2/FinaReference.cs | 2034 ++++++++++++++++++++++++++++++ MAES.Fiskal2/MAES.Fiskal2.csproj | 3 + 2 files changed, 2037 insertions(+) create mode 100644 MAES.Fiskal2/FinaReference.cs diff --git a/MAES.Fiskal2/FinaReference.cs b/MAES.Fiskal2/FinaReference.cs new file mode 100644 index 0000000..89fd61e --- /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. +// +//------------------------------------------------------------------------------ + + + +[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/MAES.Fiskal2.csproj b/MAES.Fiskal2/MAES.Fiskal2.csproj index a61df78..5da8e7a 100644 --- a/MAES.Fiskal2/MAES.Fiskal2.csproj +++ b/MAES.Fiskal2/MAES.Fiskal2.csproj @@ -22,6 +22,9 @@ + + + From 98f63d745edc578f7ce8166d22a64c29ed79f926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Sun, 24 May 2026 16:51:13 +0200 Subject: [PATCH 02/10] scaffoldano slanje ubla preko fina posrednika --- MAES.Fiskal2/FinaReference.cs | 2 +- MAES.Fiskal2/MAES.Fiskal2.csproj | 2 +- MAES.Fiskal2/Posrednici/Fina.cs | 89 +++++++++++++++++++++++++++++++- README.md | 2 +- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/MAES.Fiskal2/FinaReference.cs b/MAES.Fiskal2/FinaReference.cs index 89fd61e..b12cf41 100644 --- a/MAES.Fiskal2/FinaReference.cs +++ b/MAES.Fiskal2/FinaReference.cs @@ -7,7 +7,7 @@ // //------------------------------------------------------------------------------ - +#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")] diff --git a/MAES.Fiskal2/MAES.Fiskal2.csproj b/MAES.Fiskal2/MAES.Fiskal2.csproj index 5da8e7a..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 diff --git a/MAES.Fiskal2/Posrednici/Fina.cs b/MAES.Fiskal2/Posrednici/Fina.cs index 0c70206..9aacda8 100644 --- a/MAES.Fiskal2/Posrednici/Fina.cs +++ b/MAES.Fiskal2/Posrednici/Fina.cs @@ -1,3 +1,6 @@ +using System.Text; +using System.Xml.Linq; + namespace MAES.Fiskal2.Posrednici; /// @@ -5,17 +8,73 @@ namespace MAES.Fiskal2.Posrednici; /// public class Fina : IPosrednik { + +#region Parametri posrednika + + 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. + /// + public string OIB { get; set; } = ""; + +#endregion + /// /// 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 async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) { - throw new NotImplementedException(); + var xml = XDocument.Parse(ubl); + + // TODO: izvuci iz svog UBL modela ili configa + 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, IsDev ? URI_DEV : 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. /// @@ -110,4 +169,30 @@ public Task UlazniUBLAsync(string id, CancellationToken token = default) { throw new NotImplementedException(); } + + static string GetInvoiceId(XDocument xml) + { + 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."); + } } \ No newline at end of file diff --git a/README.md b/README.md index ad6cc59..e133100 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ U `Posrednici/` direktoriju nalaze se konkretne implementacije | Dohvat izlaznih e-računa | ✅ | ✅ | ❌ | | Dohvat UBL sadržaja | ✅ | ✅ | ❌ | | Dohvat PDF sadržaja | ✅ | ✅ | ❌ | -| Evidentiranje UBL dokumenta | ✅ | ✅ | ❌ | +| Evidentiranje UBL dokumenta | ✅ | ✅ | ✅ | | Evidentiranje uplate | ✅ | ✅ | ❌ | | Odbijanje računa | ✅ | ✅ | ❌ | From 772e29244b561db9f8dd93aa00a69d9369fa450f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Sun, 24 May 2026 17:11:42 +0200 Subject: [PATCH 03/10] doradjen Fina.cs, wtf ova fina nema skoro pa nista podrzano samo mozes racun poslat --- MAES.Fiskal2/Posrednici/Fina.cs | 60 +++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/MAES.Fiskal2/Posrednici/Fina.cs b/MAES.Fiskal2/Posrednici/Fina.cs index 9aacda8..fd40b10 100644 --- a/MAES.Fiskal2/Posrednici/Fina.cs +++ b/MAES.Fiskal2/Posrednici/Fina.cs @@ -84,9 +84,32 @@ public async Task EvidentirajUBLAsync(string ubl, CancellationToken token = defa /// Način plaćanja. /// Cancellation token. /// Asinkrona operacija evidentiranja uplate. - public Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) + public async Task EvidentirajUplatuAsync( + string id, + DateTime date, + double amount, + NacinPlacanja paymentMethod, + CancellationToken token = default) { - throw new NotImplementedException(); + var msg = new SendB2BOutgoingInvoiceReportingMsg + { + HeaderSupplier = Header(), + Data = new() + { + B2BOutgoingInvoiceEnvelope = new() + { + SupplierInvoiceID = id, + //TODO: wtf je ovo + } + } + }; + + using var client = CreateClient(); + + var res = await client.sendB2BOutgoingInvoiceReportingAsync(msg); + + if (res.SendB2BOutgoingInvoiceReportingAckMsg.MessageAck.AckStatus != AckStatusType.ACCEPTED) + throw new Exception(res.SendB2BOutgoingInvoiceReportingAckMsg.MessageAck.AckStatusText); } /// @@ -96,10 +119,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 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. @@ -143,10 +164,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 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. @@ -154,10 +173,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 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. @@ -165,10 +182,8 @@ 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) - { - throw new NotImplementedException(); - } + public Task UlazniUBLAsync(string id, CancellationToken token = default) => + throw new NotSupportedException("UBL ulaznih računa nije dostupan u FINA posredniku"); static string GetInvoiceId(XDocument xml) { @@ -195,4 +210,13 @@ static string GetBuyerId(XDocument xml) .Value ?? throw new InvalidOperationException("UBL nema BuyerID."); } + + eRacunB2BPortTypeClient CreateClient() => new (eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, IsDev ? URI_DEV : URI); + + HeaderSupplierType Header() => new() + { + MessageID = Guid.NewGuid().ToString(), + ERPID = "MAES.Fiskal2", + SupplierID = OIB + }; } \ No newline at end of file From 0023635f59c654ecbb089494834f4ca8c77a396b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Mon, 25 May 2026 15:11:43 +0200 Subject: [PATCH 04/10] napravljena fina do kraja :S, dodan posrednik.cs, mozda treba uklonit iposrednik nebitaj je i ovako i onako --- MAES.Fiskal2/Posrednici/Fina.cs | 63 +++++++-------- MAES.Fiskal2/Posrednik.cs | 137 ++++++++++++++++++++++++++++++++ README.md | 47 +++++++++-- 3 files changed, 205 insertions(+), 42 deletions(-) create mode 100644 MAES.Fiskal2/Posrednik.cs diff --git a/MAES.Fiskal2/Posrednici/Fina.cs b/MAES.Fiskal2/Posrednici/Fina.cs index fd40b10..732cfed 100644 --- a/MAES.Fiskal2/Posrednici/Fina.cs +++ b/MAES.Fiskal2/Posrednici/Fina.cs @@ -1,3 +1,4 @@ +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml.Linq; @@ -6,25 +7,27 @@ namespace MAES.Fiskal2.Posrednici; /// /// Implementacija informacijskog posrednika FINA za razmjenu e-računa. /// -public class Fina : IPosrednik +public class Fina : Posrednik { -#region Parametri posrednika - - 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. + /// OIB poslovnog subjekta. /// - public bool IsDev { get; set; } + public string OIB { get; set; } = ""; /// - /// OIB poslovnog subjekta. + /// X.509 certifikat koji se koristi za autentikaciju prema FINA e-Račun sustavu. /// - public string OIB { get; set; } = ""; + public X509Certificate2? Certificate { get; set; } -#endregion + /// + /// Inicijalizira novi primjerak FINA posrednika s unaprijed 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. @@ -32,11 +35,9 @@ public class Fina : IPosrednik /// UBL/XML sadržaj dokumenta. /// Cancellation token. /// Asinkrona operacija slanja dokumenta. - public async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) + public override async Task EvidentirajUBLAsync(string ubl, CancellationToken token = default) { var xml = XDocument.Parse(ubl); - - // TODO: izvuci iz svog UBL modela ili configa var supplierInvoiceId = GetInvoiceId(xml); var buyerId = GetBuyerId(xml); @@ -65,7 +66,7 @@ public async Task EvidentirajUBLAsync(string ubl, CancellationToken token = defa } }; - using var client = new eRacunB2BPortTypeClient(eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, IsDev ? URI_DEV : URI); + using var client = new eRacunB2BPortTypeClient(eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, Uri); var res = await client.sendB2BOutgoingInvoiceAsync(msg); @@ -83,13 +84,7 @@ public async Task EvidentirajUBLAsync(string ubl, CancellationToken token = defa /// Iznos uplate. /// Način plaćanja. /// Cancellation token. - /// Asinkrona operacija evidentiranja uplate. - public async Task EvidentirajUplatuAsync( - string id, - DateTime date, - double amount, - NacinPlacanja paymentMethod, - CancellationToken token = default) + public override async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) { var msg = new SendB2BOutgoingInvoiceReportingMsg { @@ -119,7 +114,7 @@ public async Task EvidentirajUplatuAsync( /// Završni datum pretrage. /// Cancellation token. /// Popis izlaznih e-računa. - public Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => + public override Task> IzlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => throw new NotSupportedException("Lista izlaznih računa nije dostupna u FINA posredniku"); /// @@ -128,10 +123,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. @@ -139,10 +132,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. @@ -152,7 +143,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(); } @@ -164,7 +155,7 @@ 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) => + public override Task> UlazniListAsync(DateTime from, DateTime to, CancellationToken token = default) => throw new NotSupportedException("Lista ulaznih računa nije dostupna u FINA posredniku"); /// @@ -173,7 +164,7 @@ public Task> UlazniListAsync(DateTime from, DateTime t /// ID dokumenta. /// Cancellation token. /// PDF dokument kao byte array. - public Task UlazniPdfAsync(string id, CancellationToken token = default) => + public override Task UlazniPdfAsync(string id, CancellationToken token = default) => throw new NotSupportedException("PDF ulaznih računa nije dostupan u FINA posredniku"); /// @@ -182,7 +173,7 @@ 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) @@ -211,7 +202,7 @@ static string GetBuyerId(XDocument xml) ?? throw new InvalidOperationException("UBL nema BuyerID."); } - eRacunB2BPortTypeClient CreateClient() => new (eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, IsDev ? URI_DEV : URI); + eRacunB2BPortTypeClient CreateClient() => new (eRacunB2BPortTypeClient.EndpointConfiguration.eRacunB2BPortType, Uri); HeaderSupplierType Header() => new() { diff --git a/MAES.Fiskal2/Posrednik.cs b/MAES.Fiskal2/Posrednik.cs new file mode 100644 index 0000000..20ba3db --- /dev/null +++ b/MAES.Fiskal2/Posrednik.cs @@ -0,0 +1,137 @@ +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. +/// +public abstract class Posrednik : IPosrednik +{ + /// + /// 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 { get; set; } = ""; + + /// + /// URI razvojnog (testnog) okruženja servisa. + /// + protected string UriDev { 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 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 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 e133100..85dd67f 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,15 @@ 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 | ✅ | ✅ | ❌ | +| 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 | ✅ | ✅ | ❌ | +| Evidentiranje uplate | ✅ | ✅ | ❌* | +| Odbijanje računa | ✅ | ✅ | ❌* | + +\* Fina nema pola ovih api callova ili su na nekom drugom endpointu treba vidit ## Instalacija @@ -80,6 +82,39 @@ var posrednik = new EPoslovanje }; ``` +### Primjer inicijalizacije Fina posrednika: + +```csharp +using MAES.Fiskal2.Posrednici; + +var posrednik = new Fina +{ + IsDev = true, + OIB = "...", + Certificate = ... +}; +``` + +### Primjer korištenja posrednika + +```csharp +// dohvat računa u razdoblju zadnjih mj. dana +var racuni = posrednik.UlazniListAsync(DateTime.Now.AddMonths(-1), DateTime.Now); + +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(); +``` + +> 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 From 38967a8d7ad216312b3c8dce6d40c17c1ed7360b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Tue, 26 May 2026 23:27:17 +0200 Subject: [PATCH 05/10] dignut iposrednik dodana abstraktna klasa posrednik koja ima enpointadress rjesen na sebi --- MAES.Fiskal2.Tests/SuperTests.cs | 5 +- MAES.Fiskal2/IPosrednik.cs | 90 -------------------------- MAES.Fiskal2/Posrednici/EPoslovanje.cs | 43 ++++++------ MAES.Fiskal2/Posrednici/Fina.cs | 28 ++------ MAES.Fiskal2/Posrednici/Super.cs | 39 +++++------ MAES.Fiskal2/Posrednik.cs | 9 ++- 6 files changed, 58 insertions(+), 156 deletions(-) delete mode 100644 MAES.Fiskal2/IPosrednik.cs diff --git a/MAES.Fiskal2.Tests/SuperTests.cs b/MAES.Fiskal2.Tests/SuperTests.cs index e3522b0..42a5296 100644 --- a/MAES.Fiskal2.Tests/SuperTests.cs +++ b/MAES.Fiskal2.Tests/SuperTests.cs @@ -13,5 +13,8 @@ public class SuperTests }; [Fact] - public async Task SendInvoiceUBL() => await super.EvidentirajUBLAsync(File.ReadAllText("ubl.xml")); + public async Task SendInvoiceUBL() + { + await super.EvidentirajUBLAsync(File.ReadAllText("ubl.xml")); + } } \ No newline at end of file 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/Posrednici/EPoslovanje.cs b/MAES.Fiskal2/Posrednici/EPoslovanje.cs index 27ae26a..4c87059 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")); @@ -100,19 +101,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 +138,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 +178,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 +187,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 +196,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 732cfed..7f789fa 100644 --- a/MAES.Fiskal2/Posrednici/Fina.cs +++ b/MAES.Fiskal2/Posrednici/Fina.cs @@ -5,7 +5,7 @@ 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 : Posrednik { @@ -21,7 +21,7 @@ public class Fina : Posrednik public X509Certificate2? Certificate { get; set; } /// - /// Inicijalizira novi primjerak FINA posrednika s unaprijed definiranim URI postavkama za produkcijsko i razvojno okruženje. + /// Inicijalizira novog FINA posrednika s definiranim URI postavkama za produkcijsko i razvojno okruženje. /// public Fina() { @@ -84,28 +84,8 @@ public override async Task EvidentirajUBLAsync(string ubl, CancellationToken tok /// Iznos uplate. /// Način plaćanja. /// Cancellation token. - public override async Task EvidentirajUplatuAsync(string id, DateTime date, double amount, NacinPlacanja paymentMethod, CancellationToken token = default) - { - var msg = new SendB2BOutgoingInvoiceReportingMsg - { - HeaderSupplier = Header(), - Data = new() - { - B2BOutgoingInvoiceEnvelope = new() - { - SupplierInvoiceID = id, - //TODO: wtf je ovo - } - } - }; - - using var client = CreateClient(); - - var res = await client.sendB2BOutgoingInvoiceReportingAsync(msg); - - if (res.SendB2BOutgoingInvoiceReportingAckMsg.MessageAck.AckStatus != AckStatusType.ACCEPTED) - throw new Exception(res.SendB2BOutgoingInvoiceReportingAckMsg.MessageAck.AckStatusText); - } + 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. diff --git a/MAES.Fiskal2/Posrednici/Super.cs b/MAES.Fiskal2/Posrednici/Super.cs index 1b33a9f..4c94018 100644 --- a/MAES.Fiskal2/Posrednici/Super.cs +++ b/MAES.Fiskal2/Posrednici/Super.cs @@ -8,16 +8,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 +27,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 +84,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 +101,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 +113,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 +142,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 +160,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 +181,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 +209,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 +223,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 +238,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 index 20ba3db..c5d8ae7 100644 --- a/MAES.Fiskal2/Posrednik.cs +++ b/MAES.Fiskal2/Posrednik.cs @@ -1,10 +1,17 @@ +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. /// -public abstract class Posrednik : IPosrednik +[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. From 56adde13ed7fdcdfaa0b360220cb5637309c3b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Wed, 27 May 2026 00:30:37 +0200 Subject: [PATCH 06/10] promjenjeni testovi --- MAES.Fiskal2.Tests/Fiskal2Tests.cs | 78 ++++++++++++++++++++++++++++++ MAES.Fiskal2.Tests/SuperTests.cs | 20 -------- 2 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 MAES.Fiskal2.Tests/Fiskal2Tests.cs delete mode 100644 MAES.Fiskal2.Tests/SuperTests.cs diff --git a/MAES.Fiskal2.Tests/Fiskal2Tests.cs b/MAES.Fiskal2.Tests/Fiskal2Tests.cs new file mode 100644 index 0000000..a67643e --- /dev/null +++ b/MAES.Fiskal2.Tests/Fiskal2Tests.cs @@ -0,0 +1,78 @@ +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 = LoadCertificateFromStore(Environment.GetEnvironmentVariable("FINA_CERT_THUMBPRINT") ?? throw new InvalidOperationException("FINA_CERT_THUMBPRINT environment variable is not set.")), + IsDev = true + } + ]; + + [Fact] + public async Task SendInvoiceUBL() + { + var ubl = File.ReadAllText("ubl.xml"); + + foreach (var posrednik in posrednici) + { + await posrednik.EvidentirajUBLAsync(ubl); + } + } + + [Fact] + public async Task NoFinaTests() + { + foreach (var posrednik in posrednici.Where(p => p is not Fina)) + { + var izlazni = await posrednik.IzlazniListAsync(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow); + Assert.NotNull(izlazni); + + var first = izlazni.FirstOrDefault(); + if(first != null) + { + var pdf = await posrednik.IzlazniPdfAsync(first.Id); + Assert.NotNull(pdf); + + var ubl = await posrednik.IzlazniUBLAsync(first.Id); + Assert.NotNull(ubl); + + 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) + { + var pdf = await posrednik.UlazniPdfAsync(firstUlazni.Id); + Assert.NotNull(pdf); + + var ubl = await posrednik.UlazniUBLAsync(firstUlazni.Id); + Assert.NotNull(ubl); + + 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 42a5296..0000000 --- a/MAES.Fiskal2.Tests/SuperTests.cs +++ /dev/null @@ -1,20 +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 From 0f06a8019b44ed4348986fccaf104b87f01f6fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Wed, 27 May 2026 01:58:22 +0200 Subject: [PATCH 07/10] scaffoldan mer --- MAES.Fiskal2/Posrednici/EPoslovanje.cs | 16 ++- MAES.Fiskal2/Posrednici/MER.cs | 188 +++++++++++++++++++++++++ README.md | 20 +-- 3 files changed, 208 insertions(+), 16 deletions(-) create mode 100644 MAES.Fiskal2/Posrednici/MER.cs diff --git a/MAES.Fiskal2/Posrednici/EPoslovanje.cs b/MAES.Fiskal2/Posrednici/EPoslovanje.cs index 4c87059..0340c6f 100644 --- a/MAES.Fiskal2/Posrednici/EPoslovanje.cs +++ b/MAES.Fiskal2/Posrednici/EPoslovanje.cs @@ -49,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(); diff --git a/MAES.Fiskal2/Posrednici/MER.cs b/MAES.Fiskal2/Posrednici/MER.cs new file mode 100644 index 0000000..0ea1540 --- /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/apis/v2/"; + UriDev = "https://demo.moj-eracun.hr/apis/v2/"; + } + + 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/README.md b/README.md index 85dd67f..e15a71f 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,20 @@ 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` | +|---|:---:|:---:|:---:|:---:| +| 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 Instalirajte paket iz NuGeta: From 5f674875faf2da5fb0603260833d848470d40435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Wed, 27 May 2026 01:59:41 +0200 Subject: [PATCH 08/10] dodan mer u test pool --- MAES.Fiskal2.Tests/Fiskal2Tests.cs | 7 +++++++ MAES.Fiskal2/Posrednici/MER.cs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/MAES.Fiskal2.Tests/Fiskal2Tests.cs b/MAES.Fiskal2.Tests/Fiskal2Tests.cs index a67643e..2b63a02 100644 --- a/MAES.Fiskal2.Tests/Fiskal2Tests.cs +++ b/MAES.Fiskal2.Tests/Fiskal2Tests.cs @@ -25,6 +25,13 @@ public class SuperTests OIB = Environment.GetEnvironmentVariable("FINA_OIB") ?? throw new InvalidOperationException("FINA_OIB environment variable is not set."), //Certificate = LoadCertificateFromStore(Environment.GetEnvironmentVariable("FINA_CERT_THUMBPRINT") ?? throw new InvalidOperationException("FINA_CERT_THUMBPRINT environment variable is not set.")), 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 } ]; diff --git a/MAES.Fiskal2/Posrednici/MER.cs b/MAES.Fiskal2/Posrednici/MER.cs index 0ea1540..7d53a9e 100644 --- a/MAES.Fiskal2/Posrednici/MER.cs +++ b/MAES.Fiskal2/Posrednici/MER.cs @@ -31,8 +31,8 @@ public class MER : Posrednik /// public MER() { - UriProd = "https://www.moj-eracun.hr/apis/v2/"; - UriDev = "https://demo.moj-eracun.hr/apis/v2/"; + UriProd = "https://www.moj-eracun.hr"; + UriDev = "https://demo.moj-eracun.hr"; } async Task sendRequest(HttpMethod method, string url, object? body, CancellationToken token) From 1d535d3861f60d4d623396a68379c2a230326252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Wed, 27 May 2026 15:18:49 +0200 Subject: [PATCH 09/10] privateani ovi uriji koe ne treba koristit,ispravljen readme i jos masu toga --- MAES.Fiskal2.Tests/Fiskal2Tests.cs | 33 ++--- MAES.Fiskal2/Posrednici/Parra.cs | 203 +++++++++++++++++++++++++++++ MAES.Fiskal2/Posrednik.cs | 34 +++-- README.md | 62 +++++---- 4 files changed, 271 insertions(+), 61 deletions(-) create mode 100644 MAES.Fiskal2/Posrednici/Parra.cs diff --git a/MAES.Fiskal2.Tests/Fiskal2Tests.cs b/MAES.Fiskal2.Tests/Fiskal2Tests.cs index 2b63a02..4e462db 100644 --- a/MAES.Fiskal2.Tests/Fiskal2Tests.cs +++ b/MAES.Fiskal2.Tests/Fiskal2Tests.cs @@ -37,31 +37,19 @@ public class SuperTests [Fact] public async Task SendInvoiceUBL() - { - var ubl = File.ReadAllText("ubl.xml"); - - foreach (var posrednik in posrednici) - { - await posrednik.EvidentirajUBLAsync(ubl); - } - } - - [Fact] - public async Task NoFinaTests() { 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) { - var pdf = await posrednik.IzlazniPdfAsync(first.Id); - Assert.NotNull(pdf); - - var ubl = await posrednik.IzlazniUBLAsync(first.Id); - Assert.NotNull(ubl); + Assert.NotNull(await posrednik.IzlazniPdfAsync(first.Id)); + Assert.NotNull(await posrednik.IzlazniUBLAsync(first.Id)); await posrednik.EvidentirajUplatuAsync(first.Id, DateTime.UtcNow, 100, NacinPlacanja.TransakcijskiRaCun); } @@ -72,14 +60,17 @@ public async Task NoFinaTests() var firstUlazni = ulazni.FirstOrDefault(); if(firstUlazni != null) { - var pdf = await posrednik.UlazniPdfAsync(firstUlazni.Id); - Assert.NotNull(pdf); - - var ubl = await posrednik.UlazniUBLAsync(firstUlazni.Id); - Assert.NotNull(ubl); + Assert.NotNull(await posrednik.UlazniPdfAsync(firstUlazni.Id)); + Assert.NotNull(await posrednik.UlazniUBLAsync(firstUlazni.Id)); await posrednik.OdbijRacunAsync(firstUlazni.Id, RazlogOdbijanja.NeusklađenostKojaNeUtjeceNaObracunPoreza, "Nedostaje OIB"); } } } + + [Fact] + public async Task NoFinaTests() + { + + } } \ 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/Posrednik.cs b/MAES.Fiskal2/Posrednik.cs index c5d8ae7..730d3b7 100644 --- a/MAES.Fiskal2/Posrednik.cs +++ b/MAES.Fiskal2/Posrednik.cs @@ -22,12 +22,12 @@ public abstract class Posrednik /// /// Produkcijski URI servisa. /// - protected string UriProd { get; set; } = ""; + protected string UriProd { private get; set; } = ""; /// /// URI razvojnog (testnog) okruženja servisa. /// - protected string UriDev { get; set; } = ""; + protected string UriDev { private get; set; } = ""; /// /// Aktivni URI servisa ovisno o odabranom okruženju. @@ -65,11 +65,16 @@ public virtual Task EvidentirajUplatuAsync( /// 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(); + 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. @@ -114,11 +119,16 @@ public virtual Task OdbijRacunAsync( /// 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(); + 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. diff --git a/README.md b/README.md index e15a71f..8a5f1ec 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,15 @@ Modeli `UlazniERacun` i `IzlazniERacun` predstavljaju minimalne informacije o ra U `Posrednici/` direktoriju nalaze se konkretne implementacije -| Značajka / posrednik | `Super` | `EPoslovanje` | `Fina` | `Moj eRačun` | -|---|:---:|:---:|:---:|:---:| -| 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 @@ -56,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, @@ -68,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, @@ -82,19 +76,23 @@ var posrednik = new EPoslovanje Username = "...", Password = "..." }; -``` - -### Primjer inicijalizacije Fina posrednika: - -```csharp -using MAES.Fiskal2.Posrednici; +// 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 @@ -112,7 +110,7 @@ if(racun != null) } // evidentiranje računa -posrednik.EvidentirajUBLAsync(); +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... @@ -121,13 +119,17 @@ posrednik.EvidentirajUBLAsync(); > 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 @@ -141,6 +143,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 @@ -155,11 +161,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 From 6bbb091602808c35208cc3456bbb9cc9f47c67a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roko=20Tomovi=C4=87?= Date: Wed, 27 May 2026 15:36:57 +0200 Subject: [PATCH 10/10] zakomentirani testovi za sada osim super --- MAES.Fiskal2.Tests/Fiskal2Tests.cs | 49 ++++++++++++++---------------- MAES.Fiskal2/Posrednici/Super.cs | 1 - README.md | 3 +- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/MAES.Fiskal2.Tests/Fiskal2Tests.cs b/MAES.Fiskal2.Tests/Fiskal2Tests.cs index 4e462db..61af6ca 100644 --- a/MAES.Fiskal2.Tests/Fiskal2Tests.cs +++ b/MAES.Fiskal2.Tests/Fiskal2Tests.cs @@ -1,4 +1,5 @@ -using MAES.Fiskal2.Posrednici; +using System.Security.Cryptography.X509Certificates; +using MAES.Fiskal2.Posrednici; namespace MAES.Fiskal2.Tests; @@ -13,26 +14,26 @@ public class SuperTests 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 = LoadCertificateFromStore(Environment.GetEnvironmentVariable("FINA_CERT_THUMBPRINT") ?? throw new InvalidOperationException("FINA_CERT_THUMBPRINT environment variable is not set.")), - 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 - } + // 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] @@ -67,10 +68,4 @@ public async Task SendInvoiceUBL() } } } - - [Fact] - public async Task NoFinaTests() - { - - } } \ No newline at end of file diff --git a/MAES.Fiskal2/Posrednici/Super.cs b/MAES.Fiskal2/Posrednici/Super.cs index 4c94018..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; diff --git a/README.md b/README.md index 8a5f1ec..f82bee2 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,9 @@ var posrednik = new MER ### Primjer korištenja posrednika ```csharp -// dohvat računa u razdoblju zadnjih mj. dana +// 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)