/// <summary> /// Saves the given invoice to the given stream. /// Make sure that the stream is open and writeable. Otherwise, an IllegalStreamException will be thron. /// </summary> /// <param name="descriptor"></param> /// <param name="stream"></param> public override void Save(InvoiceDescriptor descriptor, Stream stream) { if (!stream.CanWrite || !stream.CanSeek) { throw new IllegalStreamException("Cannot write to stream"); } // write data long streamPosition = stream.Position; this.Descriptor = descriptor; this.Writer = new ProfileAwareXmlTextWriter(stream, Encoding.UTF8, descriptor.Profile); Writer.Formatting = Formatting.Indented; Writer.WriteStartDocument(); #region Kopfbereich Writer.WriteStartElement("rsm:CrossIndustryInvoice"); Writer.WriteAttributeString("xmlns", "a", null, "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"); Writer.WriteAttributeString("xmlns", "rsm", null, "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"); Writer.WriteAttributeString("xmlns", "qdt", null, "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"); Writer.WriteAttributeString("xmlns", "ram", null, "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"); Writer.WriteAttributeString("xmlns", "xs", null, "http://www.w3.org/2001/XMLSchema"); Writer.WriteAttributeString("xmlns", "udt", null, "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"); #endregion #region SpecifiedExchangedDocumentContext Writer.WriteStartElement("rsm:ExchangedDocumentContext"); Writer.WriteStartElement("ram:TestIndicator"); Writer.WriteElementString("udt:Indicator", this.Descriptor.IsTest ? "true" : "false"); Writer.WriteEndElement(); // !ram:TestIndicator Writer.WriteStartElement("ram:GuidelineSpecifiedDocumentContextParameter"); Writer.WriteElementString("ram:ID", this.Descriptor.Profile.EnumToString(ZUGFeRDVersion.Version20)); Writer.WriteEndElement(); // !ram:GuidelineSpecifiedDocumentContextParameter Writer.WriteEndElement(); // !rsm:ExchangedDocumentContext Writer.WriteStartElement("rsm:ExchangedDocument"); Writer.WriteElementString("ram:ID", this.Descriptor.InvoiceNo); Writer.WriteElementString("ram:Name", _translateInvoiceType(this.Descriptor.Type)); Writer.WriteElementString("ram:TypeCode", String.Format("{0}", _encodeInvoiceType(this.Descriptor.Type))); if (this.Descriptor.InvoiceDate.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.InvoiceDate.Value)); Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime } _writeNotes(Writer, this.Descriptor.Notes); Writer.WriteEndElement(); // !rsm:ExchangedDocument #endregion /* * @todo continue here to adopt v2 tag names */ #region SpecifiedSupplyChainTradeTransaction Writer.WriteStartElement("rsm:SupplyChainTradeTransaction"); foreach (TradeLineItem tradeLineItem in this.Descriptor.TradeLineItems) { Writer.WriteStartElement("ram:IncludedSupplyChainTradeLineItem"); if (tradeLineItem.AssociatedDocument != null) { Writer.WriteStartElement("ram:AssociatedDocumentLineDocument"); if (!String.IsNullOrEmpty(tradeLineItem.AssociatedDocument.LineID)) { Writer.WriteElementString("ram:LineID", tradeLineItem.AssociatedDocument.LineID); } _writeNotes(Writer, tradeLineItem.AssociatedDocument.Notes); Writer.WriteEndElement(); // ram:AssociatedDocumentLineDocument } // handelt es sich um einen Kommentar? if ((tradeLineItem.AssociatedDocument?.Notes.Count > 0) && (tradeLineItem.BilledQuantity == 0) && (String.IsNullOrEmpty(tradeLineItem.Description))) { Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem continue; } Writer.WriteStartElement("ram:SpecifiedTradeProduct"); if ((tradeLineItem.GlobalID != null) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.SchemeID) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.ID)) { _writeElementWithAttribute(Writer, "ram:GlobalID", "schemeID", tradeLineItem.GlobalID.SchemeID, tradeLineItem.GlobalID.ID); } _writeOptionalElementString(Writer, "ram:SellerAssignedID", tradeLineItem.SellerAssignedID); _writeOptionalElementString(Writer, "ram:BuyerAssignedID", tradeLineItem.BuyerAssignedID); _writeOptionalElementString(Writer, "ram:Name", tradeLineItem.Name); _writeOptionalElementString(Writer, "ram:Description", tradeLineItem.Description); Writer.WriteEndElement(); // !ram:SpecifiedTradeProduct Writer.WriteStartElement("ram:SpecifiedLineTradeAgreement", Profile.Basic | Profile.Comfort | Profile.Extended); if (tradeLineItem.BuyerOrderReferencedDocument != null) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument", Profile.Comfort | Profile.Extended | Profile.XRechnung1 | Profile.XRechnung); #region IssuerAssignedID //Bestellnummer if (!String.IsNullOrEmpty(tradeLineItem.BuyerOrderReferencedDocument.ID)) { Writer.WriteElementString("ram:IssuerAssignedID", tradeLineItem.BuyerOrderReferencedDocument.ID); } #endregion #region LineID //Referenz zur Bestellposition //ToDo: fehlt ganz #endregion #region IssueDateTime if (tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteStartElement("qdt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.Value)); Writer.WriteEndElement(); // !qdt:DateTimeString Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } #endregion Writer.WriteEndElement(); // !ram:BuyerOrderReferencedDocument } if (tradeLineItem.ContractReferencedDocument != null) { Writer.WriteStartElement("ram:InvoiceReferencedDocument"); if (tradeLineItem.ContractReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.ContractReferencedDocument.IssueDateTime.Value, true)); Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.ContractReferencedDocument.ID)) { Writer.WriteElementString("ram:IssuerAssignedID", tradeLineItem.ContractReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:InvoiceReferencedDocument } if (tradeLineItem.AdditionalReferencedDocuments != null) { foreach (AdditionalReferencedDocument document in tradeLineItem.AdditionalReferencedDocuments) { Writer.WriteStartElement("ram:AdditionalReferencedDocument"); if (document.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteValue(_formatDate(document.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } Writer.WriteElementString("ram:LineID", String.Format("{0}", tradeLineItem.AssociatedDocument?.LineID)); if (!String.IsNullOrEmpty(document.ID)) { Writer.WriteElementString("ram:IssuerAssignedID", document.ID); } Writer.WriteElementString("ram:ReferenceTypeCode", document.ReferenceTypeCode.EnumToString()); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } // !foreach(document) } Writer.WriteStartElement("ram:GrossPriceProductTradePrice"); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.GrossUnitPrice, 4); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 4)); } foreach (TradeAllowanceCharge tradeAllowanceCharge in tradeLineItem.TradeAllowanceCharges) { Writer.WriteStartElement("ram:AppliedTradeAllowanceCharge"); Writer.WriteStartElement("ram:ChargeIndicator"); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator Writer.WriteStartElement("ram:BasisAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount, 4)); Writer.WriteEndElement(); Writer.WriteStartElement("ram:ActualAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount, 4)); Writer.WriteEndElement(); _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason); Writer.WriteEndElement(); // !AppliedTradeAllowanceCharge } Writer.WriteEndElement(); // ram:GrossPriceProductTradePrice Writer.WriteStartElement("ram:NetPriceProductTradePrice"); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.NetUnitPrice, 4); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 4)); } Writer.WriteEndElement(); // ram:NetPriceProductTradePrice Writer.WriteEndElement(); // !ram:SpecifiedLineTradeAgreement if (Descriptor.Profile != Profile.Basic) { Writer.WriteStartElement("ram:SpecifiedLineTradeDelivery"); _writeElementWithAttribute(Writer, "ram:BilledQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.BilledQuantity, 4)); if (tradeLineItem.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.DeliveryNoteReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.DeliveryNoteReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:DeliveryNoteReferencedDocument } if (tradeLineItem.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(tradeLineItem.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } Writer.WriteEndElement(); // !ram:SpecifiedLineTradeDelivery } else { Writer.WriteStartElement("ram:SpecifiedLineTradeDelivery"); _writeElementWithAttribute(Writer, "ram:BilledQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.BilledQuantity, 4)); Writer.WriteEndElement(); // !ram:SpecifiedLineTradeDelivery } Writer.WriteStartElement("ram:SpecifiedLineTradeSettlement"); Writer.WriteStartElement("ram:ApplicableTradeTax", Profile.Basic | Profile.Comfort | Profile.Extended); Writer.WriteElementString("ram:TypeCode", tradeLineItem.TaxType.EnumToString()); Writer.WriteElementString("ram:CategoryCode", tradeLineItem.TaxCategoryCode.EnumToString()); Writer.WriteElementString("ram:RateApplicablePercent", _formatDecimal(tradeLineItem.TaxPercent)); Writer.WriteEndElement(); // !ram:ApplicableTradeTax if (Descriptor.BillingPeriodStart.HasValue || Descriptor.BillingPeriodEnd.HasValue) { Writer.WriteStartElement("ram:BillingSpecifiedPeriod", Profile.BasicWL | Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung1 | Profile.XRechnung); if (Descriptor.BillingPeriodStart.HasValue) { Writer.WriteStartElement("ram:StartDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.BillingPeriodStart.Value)); Writer.WriteEndElement(); // !StartDateTime } if (Descriptor.BillingPeriodEnd.HasValue) { Writer.WriteStartElement("ram:EndDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.BillingPeriodEnd.Value)); Writer.WriteEndElement(); // !EndDateTime } Writer.WriteEndElement(); // !BillingSpecifiedPeriod } Writer.WriteStartElement("ram:SpecifiedTradeSettlementLineMonetarySummation"); decimal _total = 0m; if (tradeLineItem.LineTotalAmount.HasValue) { _total = tradeLineItem.LineTotalAmount.Value; } else if (tradeLineItem.NetUnitPrice.HasValue) { _total = tradeLineItem.NetUnitPrice.Value * tradeLineItem.BilledQuantity; } _writeElementWithAttribute(Writer, "ram:LineTotalAmount", "currencyID", this.Descriptor.Currency.EnumToString(), _formatDecimal(_total)); Writer.WriteEndElement(); // ram:SpecifiedTradeSettlementLineMonetarySummation Writer.WriteEndElement(); // !ram:SpecifiedLineTradeSettlement Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem } // !foreach(tradeLineItem) Writer.WriteStartElement("ram:ApplicableHeaderTradeAgreement"); if (!String.IsNullOrEmpty(this.Descriptor.ReferenceOrderNo)) { Writer.WriteElementString("ram:BuyerReference", this.Descriptor.ReferenceOrderNo); } _writeOptionalParty(Writer, "ram:SellerTradeParty", this.Descriptor.Seller, this.Descriptor.SellerContact, TaxRegistrations: this.Descriptor.SellerTaxRegistration); _writeOptionalParty(Writer, "ram:BuyerTradeParty", this.Descriptor.Buyer, this.Descriptor.BuyerContact, TaxRegistrations: this.Descriptor.BuyerTaxRegistration); if (!String.IsNullOrEmpty(this.Descriptor.OrderNo)) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument"); Writer.WriteElementString("ram:IssuerAssignedID", this.Descriptor.OrderNo); if (this.Descriptor.OrderDate.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteStartElement("qdt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.OrderDate.Value)); Writer.WriteEndElement(); // !qdt:DateTimeString Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } Writer.WriteEndElement(); // !BuyerOrderReferencedDocument } if (this.Descriptor.AdditionalReferencedDocuments != null) { foreach (AdditionalReferencedDocument document in this.Descriptor.AdditionalReferencedDocuments) { Writer.WriteStartElement("ram:AdditionalReferencedDocument"); if (document.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteValue(_formatDate(document.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !FormattedIssueDateTime } if (document.ReferenceTypeCode != ReferenceTypeCodes.Unknown) { Writer.WriteElementString("ram:TypeCode", document.ReferenceTypeCode.EnumToString()); } Writer.WriteElementString("ram:ID", document.ID); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } // !foreach(document) } Writer.WriteEndElement(); // !ApplicableHeaderTradeAgreement Writer.WriteStartElement("ram:ApplicableHeaderTradeDelivery"); // Pflichteintrag if (Descriptor.Profile == Profile.Extended) { _writeOptionalParty(Writer, "ram:ShipToTradeParty", this.Descriptor.ShipTo); _writeOptionalParty(Writer, "ram:ShipFromTradeParty", this.Descriptor.ShipFrom); } if (this.Descriptor.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } if (this.Descriptor.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteValue(_formatDate(this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !IssueDateTime } Writer.WriteElementString("ram:IssuerAssignedID", this.Descriptor.DeliveryNoteReferencedDocument.ID); Writer.WriteEndElement(); // !DeliveryNoteReferencedDocument } Writer.WriteEndElement(); // !ApplicableHeaderTradeDelivery Writer.WriteStartElement("ram:ApplicableHeaderTradeSettlement"); // order of sub-elements of ApplicableHeaderTradeSettlement: // 1. CreditorReferenceID (optional) // 2. PaymentReference (optional) // 3. TaxCurrencyCode (optional) // 4. InvoiceCurrencyCode (optional) // 5. InvoiceIssuerReference (optional) // 6. InvoicerTradeParty (optional) // 7. InvoiceeTradeParty (optional) // 8. PayeeTradeParty (optional) // 9. TaxApplicableTradeCurrencyExchange (optional) // 10. SpecifiedTradeSettlementPaymentMeans (optional) // 11. ApplicableTradeTax (optional) // 12. BillingSpecifiedPeriod (optional) // 13. SpecifiedTradeAllowanceCharge (optional) // 14. SpecifiedLogisticsServiceCharge (optional) // 15. SpecifiedTradePaymentTerms (optional) // 16. SpecifiedTradeSettlementHeaderMonetarySummation // 17. InvoiceReferencedDocument (optional) // 18. ReceivableSpecifiedTradeAccountingAccount (optional) // 19. SpecifiedAdvancePayment (optional) // 2. PaymentReference (optional) if (!String.IsNullOrEmpty(this.Descriptor.PaymentReference)) { _writeOptionalElementString(Writer, "ram:PaymentReference", this.Descriptor.PaymentReference); } // 4. InvoiceCurrencyCode (optional) Writer.WriteElementString("ram:InvoiceCurrencyCode", this.Descriptor.Currency.EnumToString()); // 7. InvoiceeTradeParty (optional) if (Descriptor.Profile == Profile.Extended) { _writeOptionalParty(Writer, "ram:InvoiceeTradeParty", this.Descriptor.Invoicee); } // 8. PayeeTradeParty (optional) if (Descriptor.Profile != Profile.Minimum) { _writeOptionalParty(Writer, "ram:PayeeTradeParty", this.Descriptor.Payee); } // 10. SpecifiedTradeSettlementPaymentMeans (optional) if (this.Descriptor.CreditorBankAccounts.Count == 0 && this.Descriptor.DebitorBankAccounts.Count == 0) { if (this.Descriptor.PaymentMeans != null) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } else { foreach (BankAccount account in this.Descriptor.CreditorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayeePartyCreditorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.Name)) { Writer.WriteElementString("ram:AccountName", account.Name); } if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayeePartyCreditorFinancialAccount Writer.WriteStartElement("ram:PayeeSpecifiedCreditorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } Writer.WriteEndElement(); // !PayeeSpecifiedCreditorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } foreach (BankAccount account in this.Descriptor.DebitorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayerPartyDebtorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayerPartyDebtorFinancialAccount Writer.WriteStartElement("ram:PayerSpecifiedDebtorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } if (!String.IsNullOrEmpty(account.BankName)) { Writer.WriteElementString("ram:Name", account.BankName); } Writer.WriteEndElement(); // !PayerSpecifiedDebtorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } /* * @todo add writer for this: * <SpecifiedTradeSettlementPaymentMeans> * <TypeCode>42</TypeCode> * <Information>Überweisung</Information> * <PayeePartyCreditorFinancialAccount> * <IBANID>DE08700901001234567890</IBANID> * <ProprietaryID>1234567890</ProprietaryID> * </PayeePartyCreditorFinancialAccount> * <PayeeSpecifiedCreditorFinancialInstitution> * <BICID>GENODEF1M04</BICID> * <GermanBankleitzahlID>70090100</GermanBankleitzahlID> * <Name>Hausbank München</Name> * </PayeeSpecifiedCreditorFinancialInstitution> * </SpecifiedTradeSettlementPaymentMeans> */ // 11. ApplicableTradeTax (optional) _writeOptionalTaxes(Writer); // 13. SpecifiedTradeAllowanceCharge (optional) if ((this.Descriptor.TradeAllowanceCharges != null) && (this.Descriptor.TradeAllowanceCharges.Count > 0)) { foreach (TradeAllowanceCharge tradeAllowanceCharge in this.Descriptor.TradeAllowanceCharges) { Writer.WriteStartElement("ram:SpecifiedTradeAllowanceCharge"); Writer.WriteStartElement("ram:ChargeIndicator"); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator Writer.WriteStartElement("ram:BasisAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount)); Writer.WriteEndElement(); Writer.WriteStartElement("ram:ActualAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount)); Writer.WriteEndElement(); _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason); if (tradeAllowanceCharge.Tax != null) { Writer.WriteStartElement("ram:CategoryTradeTax"); Writer.WriteElementString("ram:TypeCode", tradeAllowanceCharge.Tax.TypeCode.EnumToString()); if (tradeAllowanceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", tradeAllowanceCharge.Tax.CategoryCode?.EnumToString()); } Writer.WriteElementString("ram:RateApplicablePercent", _formatDecimal(tradeAllowanceCharge.Tax.Percent)); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } // 14. SpecifiedLogisticsServiceCharge (optional) if ((this.Descriptor.ServiceCharges != null) && (this.Descriptor.ServiceCharges.Count > 0)) { foreach (ServiceCharge serviceCharge in this.Descriptor.ServiceCharges) { Writer.WriteStartElement("ram:SpecifiedLogisticsServiceCharge"); if (!String.IsNullOrEmpty(serviceCharge.Description)) { Writer.WriteElementString("ram:Description", serviceCharge.Description); } Writer.WriteElementString("ram:AppliedAmount", _formatDecimal(serviceCharge.Amount)); if (serviceCharge.Tax != null) { Writer.WriteStartElement("ram:AppliedTradeTax"); Writer.WriteElementString("ram:TypeCode", serviceCharge.Tax.TypeCode.EnumToString()); if (serviceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", serviceCharge.Tax.CategoryCode?.EnumToString()); } Writer.WriteElementString("ram:RateApplicablePercent", _formatDecimal(serviceCharge.Tax.Percent)); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } // 15. SpecifiedTradePaymentTerms (optional) if (this.Descriptor.PaymentTerms != null) { Writer.WriteStartElement("ram:SpecifiedTradePaymentTerms"); _writeOptionalElementString(Writer, "ram:Description", this.Descriptor.PaymentTerms.Description); if (this.Descriptor.PaymentTerms.DueDate.HasValue) { Writer.WriteStartElement("ram:DueDateDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.PaymentTerms.DueDate.Value)); Writer.WriteEndElement(); // !ram:DueDateDateTime } Writer.WriteEndElement(); } // 16. SpecifiedTradeSettlementHeaderMonetarySummation Writer.WriteStartElement("ram:SpecifiedTradeSettlementHeaderMonetarySummation"); _writeOptionalAmount(Writer, "ram:LineTotalAmount", this.Descriptor.LineTotalAmount); _writeOptionalAmount(Writer, "ram:ChargeTotalAmount", this.Descriptor.ChargeTotalAmount); _writeOptionalAmount(Writer, "ram:AllowanceTotalAmount", this.Descriptor.AllowanceTotalAmount); _writeOptionalAmount(Writer, "ram:TaxBasisTotalAmount", this.Descriptor.TaxBasisAmount); _writeOptionalAmount(Writer, "ram:TaxTotalAmount", this.Descriptor.TaxTotalAmount); _writeOptionalAmount(Writer, "ram:RoundingAmount", this.Descriptor.RoundingAmount, profile: Profile.Comfort | Profile.Extended); // RoundingAmount //Rundungsbetrag _writeOptionalAmount(Writer, "ram:GrandTotalAmount", this.Descriptor.GrandTotalAmount); if (this.Descriptor.TotalPrepaidAmount.HasValue) { _writeOptionalAmount(Writer, "ram:TotalPrepaidAmount", this.Descriptor.TotalPrepaidAmount.Value); } _writeOptionalAmount(Writer, "ram:DuePayableAmount", this.Descriptor.DuePayableAmount); Writer.WriteEndElement(); // !ram:SpecifiedTradeSettlementHeaderMonetarySummation #region InvoiceReferencedDocument // 17. InvoiceReferencedDocument (optional) if (this.Descriptor.InvoiceReferencedDocument != null) { Writer.WriteStartElement("ram:InvoiceReferencedDocument"); _writeOptionalElementString(Writer, "ram:IssuerAssignedID", this.Descriptor.InvoiceReferencedDocument.ID); if (this.Descriptor.InvoiceReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); _writeElementWithAttribute(Writer, "qdt:DateTimeString", "format", "102", _formatDate(this.Descriptor.InvoiceReferencedDocument.IssueDateTime.Value)); Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } Writer.WriteEndElement(); // !ram:InvoiceReferencedDocument } #endregion Writer.WriteEndElement(); // !ram:ApplicableHeaderTradeSettlement Writer.WriteEndElement(); // !ram:SupplyChainTradeTransaction #endregion Writer.WriteEndElement(); // !ram:Invoice Writer.WriteEndDocument(); Writer.Flush(); stream.Seek(streamPosition, SeekOrigin.Begin); } // !Save()
/// <summary> /// Saves the given invoice to the given stream. /// Make sure that the stream is open and writeable. Otherwise, an IllegalStreamException will be thron. /// </summary> /// <param name="descriptor"></param> /// <param name="stream"></param> public override void Save(InvoiceDescriptor descriptor, Stream stream) { if (!stream.CanWrite || !stream.CanSeek) { throw new IllegalStreamException("Cannot write to stream"); } // validate data if ((descriptor.Profile == Profile.BasicWL) || (descriptor.Profile == Profile.Minimum)) { throw new UnsupportedException("Invalid profile used for ZUGFeRD 1.x invoice."); } // write data long streamPosition = stream.Position; this.Descriptor = descriptor; this.Writer = new ProfileAwareXmlTextWriter(stream, Encoding.UTF8, descriptor.Profile); Writer.Formatting = Formatting.Indented; Writer.WriteStartDocument(); #region Kopfbereich Writer.WriteStartElement("rsm:CrossIndustryDocument"); Writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); Writer.WriteAttributeString("xmlns", "rsm", null, "urn:ferd:CrossIndustryDocument:invoice:1p0"); Writer.WriteAttributeString("xmlns", "ram", null, "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12"); Writer.WriteAttributeString("xmlns", "udt", null, "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15"); #endregion #region SpecifiedExchangedDocumentContext Writer.WriteStartElement("rsm:SpecifiedExchangedDocumentContext"); Writer.WriteStartElement("ram:TestIndicator"); Writer.WriteElementString("udt:Indicator", this.Descriptor.IsTest ? "true" : "false"); Writer.WriteEndElement(); // !ram:TestIndicator Writer.WriteStartElement("ram:GuidelineSpecifiedDocumentContextParameter"); Writer.WriteElementString("ram:ID", this.Descriptor.Profile.EnumToString(ZUGFeRDVersion.Version1)); Writer.WriteEndElement(); // !ram:GuidelineSpecifiedDocumentContextParameter Writer.WriteEndElement(); // !rsm:SpecifiedExchangedDocumentContext Writer.WriteStartElement("rsm:HeaderExchangedDocument"); Writer.WriteElementString("ram:ID", this.Descriptor.InvoiceNo); Writer.WriteElementString("ram:Name", _translateInvoiceType(this.Descriptor.Type)); Writer.WriteElementString("ram:TypeCode", String.Format("{0}", _encodeInvoiceType(this.Descriptor.Type))); if (this.Descriptor.InvoiceDate.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.InvoiceDate.Value)); Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime } _writeNotes(Writer, this.Descriptor.Notes); Writer.WriteEndElement(); // !rsm:HeaderExchangedDocument #endregion #region SpecifiedSupplyChainTradeTransaction Writer.WriteStartElement("rsm:SpecifiedSupplyChainTradeTransaction"); Writer.WriteStartElement("ram:ApplicableSupplyChainTradeAgreement"); if (!String.IsNullOrEmpty(this.Descriptor.ReferenceOrderNo)) { Writer.WriteElementString("ram:BuyerReference", this.Descriptor.ReferenceOrderNo); } _writeOptionalParty(Writer, "ram:SellerTradeParty", this.Descriptor.Seller, this.Descriptor.SellerContact, TaxRegistrations: this.Descriptor.SellerTaxRegistration); _writeOptionalParty(Writer, "ram:BuyerTradeParty", this.Descriptor.Buyer, this.Descriptor.BuyerContact, TaxRegistrations: this.Descriptor.BuyerTaxRegistration); if (!String.IsNullOrEmpty(this.Descriptor.OrderNo)) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument"); if (this.Descriptor.OrderDate.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); //Writer.WriteStartElement("udt:DateTimeString"); //Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.OrderDate.Value, false)); //Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime() } Writer.WriteElementString("ram:ID", this.Descriptor.OrderNo); Writer.WriteEndElement(); // !BuyerOrderReferencedDocument } if (this.Descriptor.AdditionalReferencedDocuments != null) { foreach (AdditionalReferencedDocument document in this.Descriptor.AdditionalReferencedDocuments) { Writer.WriteStartElement("ram:AdditionalReferencedDocument"); if (document.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); //Writer.WriteStartElement("udt:DateTimeString"); //Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(document.IssueDateTime.Value, false)); //Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime() } if (document.ReferenceTypeCode != ReferenceTypeCodes.Unknown) { Writer.WriteElementString("ram:TypeCode", document.ReferenceTypeCode.EnumToString()); } Writer.WriteElementString("ram:ID", document.ID); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } // !foreach(document) } Writer.WriteEndElement(); // !ApplicableSupplyChainTradeAgreement Writer.WriteStartElement("ram:ApplicableSupplyChainTradeDelivery"); // Pflichteintrag if (Descriptor.Profile == Profile.Extended) { _writeOptionalParty(Writer, "ram:ShipToTradeParty", this.Descriptor.ShipTo); _writeOptionalParty(Writer, "ram:ShipFromTradeParty", this.Descriptor.ShipFrom); } if (this.Descriptor.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } if (this.Descriptor.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !IssueDateTime } Writer.WriteElementString("ram:ID", this.Descriptor.DeliveryNoteReferencedDocument.ID); Writer.WriteEndElement(); // !DeliveryNoteReferencedDocument } Writer.WriteEndElement(); // !ApplicableSupplyChainTradeDelivery Writer.WriteStartElement("ram:ApplicableSupplyChainTradeSettlement"); if (Descriptor.Profile != Profile.Basic) { _writeOptionalParty(Writer, "ram:InvoiceeTradeParty", this.Descriptor.Invoicee); } if (Descriptor.Profile == Profile.Extended) { _writeOptionalParty(Writer, "ram:PayeeTradeParty", this.Descriptor.Payee); } if (!String.IsNullOrEmpty(this.Descriptor.PaymentReference)) { _writeOptionalElementString(Writer, "ram:PaymentReference", this.Descriptor.PaymentReference); } Writer.WriteElementString("ram:InvoiceCurrencyCode", this.Descriptor.Currency.EnumToString()); if (this.Descriptor.CreditorBankAccounts.Count == 0 && this.Descriptor.DebitorBankAccounts.Count == 0) { if (this.Descriptor.PaymentMeans != null) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } else { foreach (BankAccount account in this.Descriptor.CreditorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayeePartyCreditorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.Name)) { Writer.WriteElementString("ram:AccountName", account.Name); } if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayeePartyCreditorFinancialAccount Writer.WriteStartElement("ram:PayeeSpecifiedCreditorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } if (!String.IsNullOrEmpty(account.BankName)) { Writer.WriteElementString("ram:Name", account.BankName); } Writer.WriteEndElement(); // !PayeeSpecifiedCreditorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } foreach (BankAccount account in this.Descriptor.DebitorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayerPartyDebtorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayerPartyDebtorFinancialAccount Writer.WriteStartElement("ram:PayerSpecifiedDebtorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } if (!String.IsNullOrEmpty(account.BankName)) { Writer.WriteElementString("ram:Name", account.BankName); } Writer.WriteEndElement(); // !PayerSpecifiedDebtorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } _writeOptionalTaxes(Writer); if ((this.Descriptor.TradeAllowanceCharges != null) && (this.Descriptor.TradeAllowanceCharges.Count > 0)) { foreach (TradeAllowanceCharge tradeAllowanceCharge in this.Descriptor.TradeAllowanceCharges) { Writer.WriteStartElement("ram:SpecifiedTradeAllowanceCharge"); Writer.WriteStartElement("ram:ChargeIndicator", Profile.Comfort | Profile.Extended); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator Writer.WriteStartElement("ram:BasisAmount", Profile.Extended); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount)); Writer.WriteEndElement(); Writer.WriteStartElement("ram:ActualAmount", Profile.Comfort | Profile.Extended); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount, 2)); Writer.WriteEndElement(); _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason, Profile.Comfort | Profile.Extended); if (tradeAllowanceCharge.Tax != null) { Writer.WriteStartElement("ram:CategoryTradeTax"); Writer.WriteElementString("ram:TypeCode", tradeAllowanceCharge.Tax.TypeCode.EnumToString(), Profile.Comfort | Profile.Extended); if (tradeAllowanceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", tradeAllowanceCharge.Tax.CategoryCode?.EnumToString(), Profile.Comfort | Profile.Extended); } Writer.WriteElementString("ram:ApplicablePercent", _formatDecimal(tradeAllowanceCharge.Tax.Percent), Profile.Comfort | Profile.Extended); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } if ((this.Descriptor.ServiceCharges != null) && (this.Descriptor.ServiceCharges.Count > 0)) { foreach (ServiceCharge serviceCharge in this.Descriptor.ServiceCharges) { Writer.WriteStartElement("ram:SpecifiedLogisticsServiceCharge"); if (!String.IsNullOrEmpty(serviceCharge.Description)) { Writer.WriteElementString("ram:Description", serviceCharge.Description, Profile.Comfort | Profile.Extended); } Writer.WriteElementString("ram:AppliedAmount", _formatDecimal(serviceCharge.Amount), Profile.Comfort | Profile.Extended); if (serviceCharge.Tax != null) { Writer.WriteStartElement("ram:AppliedTradeTax"); Writer.WriteElementString("ram:TypeCode", serviceCharge.Tax.TypeCode.EnumToString(), Profile.Comfort | Profile.Extended); if (serviceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", serviceCharge.Tax.CategoryCode?.EnumToString(), Profile.Comfort | Profile.Extended); } Writer.WriteElementString("ram:ApplicablePercent", _formatDecimal(serviceCharge.Tax.Percent), Profile.Comfort | Profile.Extended); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } if (this.Descriptor.PaymentTerms != null) { Writer.WriteStartElement("ram:SpecifiedTradePaymentTerms"); _writeOptionalElementString(Writer, "ram:Description", this.Descriptor.PaymentTerms.Description); if (this.Descriptor.PaymentTerms.DueDate.HasValue) { Writer.WriteStartElement("ram:DueDateDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.PaymentTerms.DueDate.Value)); Writer.WriteEndElement(); // !ram:DueDateDateTime } Writer.WriteEndElement(); } Writer.WriteStartElement("ram:SpecifiedTradeSettlementMonetarySummation"); _writeOptionalAmount(Writer, "ram:LineTotalAmount", this.Descriptor.LineTotalAmount); _writeOptionalAmount(Writer, "ram:ChargeTotalAmount", this.Descriptor.ChargeTotalAmount); _writeOptionalAmount(Writer, "ram:AllowanceTotalAmount", this.Descriptor.AllowanceTotalAmount); _writeOptionalAmount(Writer, "ram:TaxBasisTotalAmount", this.Descriptor.TaxBasisAmount); _writeOptionalAmount(Writer, "ram:TaxTotalAmount", this.Descriptor.TaxTotalAmount); _writeOptionalAmount(Writer, "ram:GrandTotalAmount", this.Descriptor.GrandTotalAmount); _writeOptionalAmount(Writer, "ram:TotalPrepaidAmount", this.Descriptor.TotalPrepaidAmount); _writeOptionalAmount(Writer, "ram:DuePayableAmount", this.Descriptor.DuePayableAmount); Writer.WriteEndElement(); // !ram:SpecifiedTradeSettlementMonetarySummation Writer.WriteEndElement(); // !ram:ApplicableSupplyChainTradeSettlement foreach (TradeLineItem tradeLineItem in this.Descriptor.TradeLineItems) { Writer.WriteStartElement("ram:IncludedSupplyChainTradeLineItem"); if (tradeLineItem.AssociatedDocument != null) { Writer.WriteStartElement("ram:AssociatedDocumentLineDocument"); if (!String.IsNullOrEmpty(tradeLineItem.AssociatedDocument.LineID)) { Writer.WriteElementString("ram:LineID", tradeLineItem.AssociatedDocument.LineID); } _writeNotes(Writer, tradeLineItem.AssociatedDocument.Notes); Writer.WriteEndElement(); // ram:AssociatedDocumentLineDocument } // handelt es sich um einen Kommentar? if ((tradeLineItem.AssociatedDocument?.Notes.Count > 0) && (tradeLineItem.BilledQuantity == 0) && (String.IsNullOrEmpty(tradeLineItem.Description))) { Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem continue; } if (Descriptor.Profile != Profile.Basic) { Writer.WriteStartElement("ram:SpecifiedSupplyChainTradeAgreement"); if (tradeLineItem.BuyerOrderReferencedDocument != null) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument"); if (tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.BuyerOrderReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.BuyerOrderReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:BuyerOrderReferencedDocument } if (tradeLineItem.ContractReferencedDocument != null) { Writer.WriteStartElement("ram:ContractReferencedDocument"); if (tradeLineItem.ContractReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.ContractReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.ContractReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.ContractReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:ContractReferencedDocument } if (tradeLineItem.AdditionalReferencedDocuments != null) { foreach (AdditionalReferencedDocument document in tradeLineItem.AdditionalReferencedDocuments) { Writer.WriteStartElement("ram:AdditionalReferencedDocument"); if (document.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(document.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } Writer.WriteElementString("ram:LineID", String.Format("{0}", tradeLineItem.AssociatedDocument?.LineID)); if (!String.IsNullOrEmpty(document.ID)) { Writer.WriteElementString("ram:ID", document.ID); } Writer.WriteElementString("ram:ReferenceTypeCode", document.ReferenceTypeCode.EnumToString()); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } } Writer.WriteStartElement("ram:GrossPriceProductTradePrice"); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.GrossUnitPrice, 4); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 4)); } foreach (TradeAllowanceCharge tradeAllowanceCharge in tradeLineItem.TradeAllowanceCharges) { Writer.WriteStartElement("ram:AppliedTradeAllowanceCharge"); Writer.WriteStartElement("ram:ChargeIndicator", Profile.Comfort | Profile.Extended); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator Writer.WriteStartElement("ram:BasisAmount", Profile.Extended); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount, 4)); Writer.WriteEndElement(); Writer.WriteStartElement("ram:ActualAmount", Profile.Comfort | Profile.Extended); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount, 4)); Writer.WriteEndElement(); _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason, Profile.Comfort | Profile.Extended); Writer.WriteEndElement(); // !AppliedTradeAllowanceCharge } Writer.WriteEndElement(); // ram:GrossPriceProductTradePrice Writer.WriteStartElement("ram:NetPriceProductTradePrice"); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.NetUnitPrice, 4); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 4)); } Writer.WriteEndElement(); // ram:NetPriceProductTradePrice Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeAgreement } if (Descriptor.Profile != Profile.Basic) { Writer.WriteStartElement("ram:SpecifiedSupplyChainTradeDelivery"); _writeElementWithAttribute(Writer, "ram:BilledQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.BilledQuantity, 4)); if (tradeLineItem.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.DeliveryNoteReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.DeliveryNoteReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:DeliveryNoteReferencedDocument } if (tradeLineItem.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(tradeLineItem.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeDelivery } else { Writer.WriteStartElement("ram:SpecifiedSupplyChainTradeDelivery"); _writeElementWithAttribute(Writer, "ram:BilledQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.BilledQuantity, 4)); Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeDelivery } Writer.WriteStartElement("ram:SpecifiedSupplyChainTradeSettlement"); if (Descriptor.Profile != Profile.Basic) { Writer.WriteStartElement("ram:ApplicableTradeTax"); Writer.WriteElementString("ram:TypeCode", tradeLineItem.TaxType.EnumToString()); Writer.WriteElementString("ram:CategoryCode", tradeLineItem.TaxCategoryCode.EnumToString()); Writer.WriteElementString("ram:ApplicablePercent", _formatDecimal(tradeLineItem.TaxPercent)); Writer.WriteEndElement(); // !ram:ApplicableTradeTax } if (Descriptor.BillingPeriodStart.HasValue && Descriptor.BillingPeriodEnd.HasValue) { Writer.WriteStartElement("ram:BillingSpecifiedPeriod", Profile.BasicWL | Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung1 | Profile.XRechnung); Writer.WriteStartElement("ram:StartDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.BillingPeriodStart.Value)); Writer.WriteEndElement(); // !StartDateTime Writer.WriteStartElement("ram:EndDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.BillingPeriodEnd.Value)); Writer.WriteEndElement(); // !EndDateTime Writer.WriteEndElement(); // !BillingSpecifiedPeriod } Writer.WriteStartElement("ram:SpecifiedTradeSettlementMonetarySummation"); decimal _total = 0m; if (tradeLineItem.LineTotalAmount.HasValue) { _total = tradeLineItem.LineTotalAmount.Value; } else if (tradeLineItem.NetUnitPrice.HasValue) { _total = tradeLineItem.NetUnitPrice.Value * tradeLineItem.BilledQuantity; } _writeElementWithAttribute(Writer, "ram:LineTotalAmount", "currencyID", this.Descriptor.Currency.EnumToString(), _formatDecimal(_total)); Writer.WriteEndElement(); // ram:SpecifiedTradeSettlementMonetarySummation Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeSettlement Writer.WriteStartElement("ram:SpecifiedTradeProduct"); if ((tradeLineItem.GlobalID != null) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.SchemeID) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.ID)) { _writeElementWithAttribute(Writer, "ram:GlobalID", "schemeID", tradeLineItem.GlobalID.SchemeID, tradeLineItem.GlobalID.ID); } _writeOptionalElementString(Writer, "ram:SellerAssignedID", tradeLineItem.SellerAssignedID); _writeOptionalElementString(Writer, "ram:BuyerAssignedID", tradeLineItem.BuyerAssignedID); _writeOptionalElementString(Writer, "ram:Name", tradeLineItem.Name); _writeOptionalElementString(Writer, "ram:Description", tradeLineItem.Description); Writer.WriteEndElement(); // !ram:SpecifiedTradeProduct Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem } // !foreach(tradeLineItem) Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeTransaction #endregion Writer.WriteEndElement(); // !ram:Invoice Writer.WriteEndDocument(); Writer.Flush(); stream.Seek(streamPosition, SeekOrigin.Begin); } // !Save()
public override void Save(InvoiceDescriptor descriptor, Stream stream) { if (!stream.CanWrite || !stream.CanSeek) { throw new IllegalStreamException("Cannot write to stream"); } long streamPosition = stream.Position; this.Descriptor = descriptor; this.Writer = new ProfileAwareXmlTextWriter(stream, Encoding.UTF8, descriptor.Profile); Writer.Formatting = Formatting.Indented; Writer.WriteStartDocument(); #region Kopfbereich Writer.WriteStartElement("rsm:CrossIndustryInvoice"); Writer.WriteAttributeString("xmlns", "a", null, "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"); Writer.WriteAttributeString("xmlns", "rsm", null, "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"); Writer.WriteAttributeString("xmlns", "qdt", null, "urn:un:unece:uncefact:data:standard:QualifiedDataType:10"); Writer.WriteAttributeString("xmlns", "ram", null, "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"); Writer.WriteAttributeString("xmlns", "xs", null, "http://www.w3.org/2001/XMLSchema"); Writer.WriteAttributeString("xmlns", "udt", null, "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"); #endregion #region ExchangedDocumentContext //Prozesssteuerung Writer.WriteStartElement("rsm:ExchangedDocumentContext"); if (this.Descriptor.IsTest) { Writer.WriteStartElement("ram:TestIndicator"); Writer.WriteElementString("udt:Indicator", "true"); Writer.WriteEndElement(); // !ram:TestIndicator } Writer.WriteStartElement("ram:GuidelineSpecifiedDocumentContextParameter"); //Gruppierung der Anwendungsempfehlungsinformationen Writer.WriteElementString("ram:ID", this.Descriptor.Profile.EnumToString(ZUGFeRDVersion.Version21)); Writer.WriteEndElement(); // !ram:GuidelineSpecifiedDocumentContextParameter Writer.WriteEndElement(); // !rsm:ExchangedDocumentContext #endregion #region ExchangedDocument //Gruppierung der Eigenschaften, die das gesamte Dokument betreffen. Writer.WriteStartElement("rsm:ExchangedDocument"); Writer.WriteElementString("ram:ID", this.Descriptor.InvoiceNo); //Rechnungsnummer Writer.WriteElementString("ram:Name", _translateInvoiceType(this.Descriptor.Type), Profile.Extended); //Dokumentenart (Freitext) Writer.WriteElementString("ram:TypeCode", String.Format("{0}", _encodeInvoiceType(this.Descriptor.Type))); //Code für den Rechnungstyp //ToDo: LanguageID //Sprachkennzeichen //ToDo: IncludedNote //Freitext zur Rechnung if (this.Descriptor.InvoiceDate.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteStartElement("udt:DateTimeString"); //Rechnungsdatum Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.InvoiceDate.Value)); Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime } _writeNotes(Writer, this.Descriptor.Notes); Writer.WriteEndElement(); // !rsm:ExchangedDocument #endregion /** * @todo continue here to adopt v2 tag names */ #region SpecifiedSupplyChainTradeTransaction //Gruppierung der Informationen zum Geschäftsvorfall Writer.WriteStartElement("rsm:SupplyChainTradeTransaction"); #region IncludedSupplyChainTradeLineItem foreach (TradeLineItem tradeLineItem in this.Descriptor.TradeLineItems) { Writer.WriteStartElement("ram:IncludedSupplyChainTradeLineItem"); #region AssociatedDocumentLineDocument //Gruppierung von allgemeinen Positionsangaben if (tradeLineItem.AssociatedDocument != null) { Writer.WriteStartElement("ram:AssociatedDocumentLineDocument", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); if (tradeLineItem.AssociatedDocument.LineID.HasValue) { Writer.WriteElementString("ram:LineID", String.Format("{0}", tradeLineItem.AssociatedDocument.LineID)); } _writeNotes(Writer, tradeLineItem.AssociatedDocument.Notes); Writer.WriteEndElement(); // ram:AssociatedDocumentLineDocument(Basic|Comfort|Extended|XRechnung) } #endregion // handelt es sich um einen Kommentar? if ((tradeLineItem.AssociatedDocument?.Notes.Count > 0) && (tradeLineItem.BilledQuantity == 0) && (String.IsNullOrEmpty(tradeLineItem.Description))) { Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem continue; } #region SpecifiedTradeProduct //Eine Gruppe von betriebswirtschaftlichen Begriffen, die Informationen über die in Rechnung gestellten Waren und Dienstleistungen enthält Writer.WriteStartElement("ram:SpecifiedTradeProduct", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); if ((tradeLineItem.GlobalID != null) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.SchemeID) && !String.IsNullOrEmpty(tradeLineItem.GlobalID.ID)) { _writeElementWithAttribute(Writer, "ram:GlobalID", "schemeID", tradeLineItem.GlobalID.SchemeID, tradeLineItem.GlobalID.ID); } _writeOptionalElementString(Writer, "ram:SellerAssignedID", tradeLineItem.SellerAssignedID); _writeOptionalElementString(Writer, "ram:BuyerAssignedID", tradeLineItem.BuyerAssignedID); _writeOptionalElementString(Writer, "ram:Name", tradeLineItem.Name); _writeOptionalElementString(Writer, "ram:Description", tradeLineItem.Description); Writer.WriteEndElement(); // !ram:SpecifiedTradeProduct(Basic|Comfort|Extended|XRechnung) #endregion #region SpecifiedLineTradeAgreement (Basic, Comfort, Extended, XRechnung) //Eine Gruppe von betriebswirtschaftlichen Begriffen, die Informationen über den Preis für die in der betreffenden Rechnungsposition in Rechnung gestellten Waren und Dienstleistungen enthält if (new Profile[] { Profile.Basic, Profile.Comfort, Profile.Extended, Profile.XRechnung }.Contains(descriptor.Profile)) { Writer.WriteStartElement("ram:SpecifiedLineTradeAgreement", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); #region BuyerOrderReferencedDocument (Comfort, Extended, XRechnung) //Detailangaben zur zugehörigen Bestellung if (tradeLineItem.BuyerOrderReferencedDocument != null) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument", Profile.Comfort | Profile.Extended | Profile.XRechnung); #region IssuerAssignedID //Bestellnummer if (!String.IsNullOrEmpty(tradeLineItem.BuyerOrderReferencedDocument.ID)) { Writer.WriteElementString("ram:IssuerAssignedID", tradeLineItem.BuyerOrderReferencedDocument.ID); } #endregion #region LineID //Referenz zur Bestellposition //ToDo: fehlt ganz #endregion #region FormattedIssueDateTime if (tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:FormattedIssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.BuyerOrderReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:FormattedIssueDateTime } #endregion Writer.WriteEndElement(); // !ram:BuyerOrderReferencedDocument } #endregion #region ContractReferencedDocument //Detailangaben zum zugehörigen Vertrag if (tradeLineItem.ContractReferencedDocument != null) { Writer.WriteStartElement("ram:ContractReferencedDocument", Profile.Extended); if (tradeLineItem.ContractReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.ContractReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.ContractReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.ContractReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:ContractReferencedDocument(Extended) } #endregion #region AdditionalReferencedDocument (Extended) //Detailangaben zu einer zusätzlichen Dokumentenreferenz if ((tradeLineItem.AdditionalReferencedDocuments != null) && (tradeLineItem.AdditionalReferencedDocuments.Count > 0)) { foreach (AdditionalReferencedDocument doc in tradeLineItem.AdditionalReferencedDocuments) { Writer.WriteStartElement("ram:AdditionalReferencedDocument", Profile.Extended); if (doc.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(doc.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } Writer.WriteElementString("ram:LineID", String.Format("{0}", tradeLineItem.AssociatedDocument?.LineID)); if (!String.IsNullOrEmpty(doc.ID)) { Writer.WriteElementString("ram:ID", doc.ID); } Writer.WriteElementString("ram:ReferenceTypeCode", doc.ReferenceTypeCode.EnumToString()); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } } #endregion #region GrossPriceProductTradePrice (Comfort, Extended, XRechnung) Writer.WriteStartElement("ram:GrossPriceProductTradePrice", Profile.Comfort | Profile.Extended | Profile.XRechnung); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.GrossUnitPrice, 2); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 2)); } #region AppliedTradeAllowanceCharge foreach (TradeAllowanceCharge tradeAllowanceCharge in tradeLineItem.TradeAllowanceCharges) { Writer.WriteStartElement("ram:AppliedTradeAllowanceCharge"); #region ChargeIndicator Writer.WriteStartElement("ram:ChargeIndicator"); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator #endregion #region BasisAmount Writer.WriteStartElement("ram:BasisAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount, 2)); Writer.WriteEndElement(); #endregion #region ActualAmount Writer.WriteStartElement("ram:ActualAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount, 2)); Writer.WriteEndElement(); #endregion _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason); Writer.WriteEndElement(); // !AppliedTradeAllowanceCharge } Writer.WriteEndElement(); // ram:GrossPriceProductTradePrice(Comfort|Extended|XRechnung) #endregion #endregion // !GrossPriceProductTradePrice(Comfort|Extended|XRechnung) #region NetPriceProductTradePrice //Im Nettopreis sind alle Zu- und Abschläge enthalten, jedoch nicht die Umsatzsteuer. Writer.WriteStartElement("ram:NetPriceProductTradePrice", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); _writeOptionalAmount(Writer, "ram:ChargeAmount", tradeLineItem.NetUnitPrice, 2); if (tradeLineItem.UnitQuantity.HasValue) { _writeElementWithAttribute(Writer, "ram:BasisQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.UnitQuantity.Value, 2)); } Writer.WriteEndElement(); // ram:NetPriceProductTradePrice(Basic|Comfort|Extended|XRechnung) #endregion // !NetPriceProductTradePrice(Basic|Comfort|Extended|XRechnung) #region UltimateCustomerOrderReferencedDocument //ToDo: UltimateCustomerOrderReferencedDocument #endregion Writer.WriteEndElement(); // ram:SpecifiedLineTradeAgreement } #endregion #region SpecifiedLineTradeDelivery (Basic, Comfort, Extended) Writer.WriteStartElement("ram:SpecifiedLineTradeDelivery", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); _writeElementWithAttribute(Writer, "ram:BilledQuantity", "unitCode", tradeLineItem.UnitCode.EnumToString(), _formatDecimal(tradeLineItem.BilledQuantity, 2)); if (tradeLineItem.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(tradeLineItem.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !ram:IssueDateTime } if (!String.IsNullOrEmpty(tradeLineItem.DeliveryNoteReferencedDocument.ID)) { Writer.WriteElementString("ram:ID", tradeLineItem.DeliveryNoteReferencedDocument.ID); } Writer.WriteEndElement(); // !ram:DeliveryNoteReferencedDocument } if (tradeLineItem.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(tradeLineItem.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } Writer.WriteEndElement(); // !ram:SpecifiedLineTradeDelivery #endregion #region SpecifiedLineTradeSettlement Writer.WriteStartElement("ram:SpecifiedLineTradeSettlement"); //ToDo: Prüfen #region ApplicableTradeTax Writer.WriteStartElement("ram:ApplicableTradeTax", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); Writer.WriteElementString("ram:TypeCode", tradeLineItem.TaxType.EnumToString()); Writer.WriteElementString("ram:CategoryCode", tradeLineItem.TaxCategoryCode.EnumToString()); Writer.WriteElementString("ram:RateApplicablePercent", _formatDecimal(tradeLineItem.TaxPercent)); Writer.WriteEndElement(); // !ram:ApplicableTradeTax(Basic|Comfort|Extended|XRechnung) #endregion // !ApplicableTradeTax(Basic|Comfort|Extended|XRechnung) #region BillingSpecifiedPeriod (Comfort, Extended) //Eine Gruppe von betriebswirtschaftlichen Begriffen, die Informationen über den für die Rechnungsposition maßgeblichen Zeitraum enthält //ToDo: BillingSpecifiedPeriod für Comfort und Extended #endregion #region SpecifiedTradeAllowanceCharge //Abschläge auf Ebene der Rechnungsposition (Basic, Comfort, Extended) //ToDo: SpecifiedTradeAllowanceCharge für Basic, Comfort und Extended #endregion #region SpecifiedTradeSettlementLineMonetarySummation (Basic, Comfort, Extended) //Detailinformationen zu Positionssummen Writer.WriteStartElement("ram:SpecifiedTradeSettlementLineMonetarySummation"); decimal _total = 0m; if (tradeLineItem.LineTotalAmount.HasValue) { _total = tradeLineItem.LineTotalAmount.Value; } else { _total = tradeLineItem.NetUnitPrice * tradeLineItem.BilledQuantity; } Writer.WriteStartElement("ram:LineTotalAmount", Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); Writer.WriteAttributeString("currencyID", this.Descriptor.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(_total)); Writer.WriteEndElement(); // !ram:LineTotalAmount //ToDo: TotalAllowanceChargeAmount //Gesamtbetrag der Positionszu- und Abschläge Writer.WriteEndElement(); // ram:SpecifiedTradeSettlementMonetarySummation #endregion #region AdditionalReferencedDocument //Objektkennung auf Ebene der Rechnungsposition //ToDo: AdditionalReferencedDocument #endregion #region ReceivableSpecifiedTradeAccountingAccount //Detailinformationen zur Buchungsreferenz //ToDo: ReceivableSpecifiedTradeAccountingAccount #endregion Writer.WriteEndElement(); // !ram:SpecifiedLineTradeSettlement #endregion Writer.WriteEndElement(); // !ram:IncludedSupplyChainTradeLineItem } // !foreach(tradeLineItem) #endregion #region ApplicableHeaderTradeAgreement Writer.WriteStartElement("ram:ApplicableHeaderTradeAgreement");//CG if (!String.IsNullOrEmpty(this.Descriptor.ReferenceOrderNo)) { Writer.WriteElementString("ram:BuyerReference", this.Descriptor.ReferenceOrderNo); } #region SellerTradeParty _writeOptionalParty(Writer, "ram:SellerTradeParty", this.Descriptor.Seller, this.Descriptor.SellerContact, TaxRegistrations: this.Descriptor.SellerTaxRegistration); #endregion #region BuyerTradeParty _writeOptionalParty(Writer, "ram:BuyerTradeParty", this.Descriptor.Buyer, this.Descriptor.BuyerContact, TaxRegistrations: this.Descriptor.BuyerTaxRegistration); #endregion #region BuyerOrderReferencedDocument if (this.Descriptor.OrderDate.HasValue || ((this.Descriptor.OrderNo != null) && (this.Descriptor.OrderNo.Length > 0))) { Writer.WriteStartElement("ram:BuyerOrderReferencedDocument"); if (this.Descriptor.OrderDate.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); //Writer.WriteStartElement("udt:DateTimeString"); //Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.OrderDate.Value, false)); //Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime() } Writer.WriteElementString("ram:ID", this.Descriptor.OrderNo); Writer.WriteEndElement(); // !BuyerOrderReferencedDocument } #endregion #region AdditionalReferencedDocument if (this.Descriptor.AdditionalReferencedDocument != null) { Writer.WriteStartElement("ram:AdditionalReferencedDocument"); if (this.Descriptor.AdditionalReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); //Writer.WriteStartElement("udt:DateTimeString"); //Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.AdditionalReferencedDocument.IssueDateTime.Value, false)); //Writer.WriteEndElement(); // !udt:DateTimeString Writer.WriteEndElement(); // !IssueDateTime() } if (this.Descriptor.AdditionalReferencedDocument.ReferenceTypeCode != ReferenceTypeCodes.Unknown) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.AdditionalReferencedDocument.ReferenceTypeCode.EnumToString()); } Writer.WriteElementString("ram:ID", this.Descriptor.AdditionalReferencedDocument.ID); Writer.WriteEndElement(); // !ram:AdditionalReferencedDocument } #endregion Writer.WriteEndElement(); // !ApplicableHeaderTradeAgreement #endregion #region ApplicableHeaderTradeDelivery Writer.WriteStartElement("ram:ApplicableHeaderTradeDelivery"); // Pflichteintrag _writeOptionalParty(Writer, "ram:ShipToTradeParty", this.Descriptor.ShipTo, profile: Profile.Extended); //ToDo: UltimateShipToTradeParty _writeOptionalParty(Writer, "ram:ShipFromTradeParty", this.Descriptor.ShipFrom, profile: Profile.Extended); #region ActualDeliverySupplyChainEvent if (this.Descriptor.ActualDeliveryDate.HasValue) { Writer.WriteStartElement("ram:ActualDeliverySupplyChainEvent"); Writer.WriteStartElement("ram:OccurrenceDateTime"); Writer.WriteStartElement("udt:DateTimeString"); Writer.WriteAttributeString("format", "102"); Writer.WriteValue(_formatDate(this.Descriptor.ActualDeliveryDate.Value)); Writer.WriteEndElement(); // "udt:DateTimeString Writer.WriteEndElement(); // !OccurrenceDateTime() Writer.WriteEndElement(); // !ActualDeliverySupplyChainEvent } #endregion #region DeliveryNoteReferencedDocument if (this.Descriptor.DeliveryNoteReferencedDocument != null) { Writer.WriteStartElement("ram:DeliveryNoteReferencedDocument"); if (this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.HasValue) { Writer.WriteStartElement("ram:IssueDateTime"); Writer.WriteValue(_formatDate(this.Descriptor.DeliveryNoteReferencedDocument.IssueDateTime.Value, false)); Writer.WriteEndElement(); // !IssueDateTime } Writer.WriteElementString("ram:ID", this.Descriptor.DeliveryNoteReferencedDocument.ID); Writer.WriteEndElement(); // !DeliveryNoteReferencedDocument } #endregion Writer.WriteEndElement(); // !ApplicableHeaderTradeDelivery #endregion #region ApplicableHeaderTradeSettlement Writer.WriteStartElement("ram:ApplicableHeaderTradeSettlement"); if (Descriptor.Profile == Profile.Extended) { _writeOptionalParty(Writer, "ram:InvoiceeTradeParty", this.Descriptor.Invoicee); } if (Descriptor.Profile != Profile.Minimum) { _writeOptionalParty(Writer, "ram:PayeeTradeParty", this.Descriptor.Payee); } if (!String.IsNullOrEmpty(this.Descriptor.InvoiceNoAsReference)) { _writeOptionalElementString(Writer, "ram:PaymentReference", this.Descriptor.InvoiceNoAsReference); } Writer.WriteElementString("ram:InvoiceCurrencyCode", this.Descriptor.Currency.EnumToString()); #region SpecifiedTradeSettlementPaymentMeans (alle außer Minimum) if (this.Descriptor.CreditorBankAccounts.Count == 0 && this.Descriptor.DebitorBankAccounts.Count == 0) { if (this.Descriptor.PaymentMeans != null) { if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans", Profile.BasicWL | Profile.Basic | Profile.Comfort | Profile.Extended | Profile.XRechnung); Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } } else { foreach (BankAccount account in this.Descriptor.CreditorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayeePartyCreditorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.Name)) { Writer.WriteElementString("ram:AccountName", account.Name); } if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayeePartyCreditorFinancialAccount Writer.WriteStartElement("ram:PayeeSpecifiedCreditorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } if (!String.IsNullOrEmpty(account.BankName)) { Writer.WriteElementString("ram:Name", account.BankName); } Writer.WriteEndElement(); // !PayeeSpecifiedCreditorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } foreach (BankAccount account in this.Descriptor.DebitorBankAccounts) { Writer.WriteStartElement("ram:SpecifiedTradeSettlementPaymentMeans"); if ((this.Descriptor.PaymentMeans != null) && (this.Descriptor.PaymentMeans.TypeCode != PaymentMeansTypeCodes.Unknown)) { Writer.WriteElementString("ram:TypeCode", this.Descriptor.PaymentMeans.TypeCode.EnumToString()); Writer.WriteElementString("ram:Information", this.Descriptor.PaymentMeans.Information); if (!String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPACreditorIdentifier) && !String.IsNullOrEmpty(this.Descriptor.PaymentMeans.SEPAMandateReference)) { Writer.WriteStartElement("ram:ID"); Writer.WriteAttributeString("schemeAgencyID", this.Descriptor.PaymentMeans.SEPACreditorIdentifier); Writer.WriteValue(this.Descriptor.PaymentMeans.SEPAMandateReference); Writer.WriteEndElement(); // !ram:ID } } Writer.WriteStartElement("ram:PayerPartyDebtorFinancialAccount"); Writer.WriteElementString("ram:IBANID", account.IBAN); if (!String.IsNullOrEmpty(account.ID)) { Writer.WriteElementString("ram:ProprietaryID", account.ID); } Writer.WriteEndElement(); // !PayerPartyDebtorFinancialAccount Writer.WriteStartElement("ram:PayerSpecifiedDebtorFinancialInstitution"); Writer.WriteElementString("ram:BICID", account.BIC); if (!String.IsNullOrEmpty(account.Bankleitzahl)) { Writer.WriteElementString("ram:GermanBankleitzahlID", account.Bankleitzahl); } if (!String.IsNullOrEmpty(account.BankName)) { Writer.WriteElementString("ram:Name", account.BankName); } Writer.WriteEndElement(); // !PayerSpecifiedDebtorFinancialInstitution Writer.WriteEndElement(); // !SpecifiedTradeSettlementPaymentMeans } } #endregion #region ApplicableTradeTax _writeOptionalTaxes(Writer); #endregion if ((this.Descriptor.TradeAllowanceCharges != null) && (this.Descriptor.TradeAllowanceCharges.Count > 0)) { foreach (TradeAllowanceCharge tradeAllowanceCharge in this.Descriptor.TradeAllowanceCharges) { Writer.WriteStartElement("ram:SpecifiedTradeAllowanceCharge"); Writer.WriteStartElement("ram:ChargeIndicator"); Writer.WriteElementString("udt:Indicator", tradeAllowanceCharge.ChargeIndicator ? "true" : "false"); Writer.WriteEndElement(); // !ram:ChargeIndicator Writer.WriteStartElement("ram:BasisAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.BasisAmount)); Writer.WriteEndElement(); Writer.WriteStartElement("ram:ActualAmount"); Writer.WriteAttributeString("currencyID", tradeAllowanceCharge.Currency.EnumToString()); Writer.WriteValue(_formatDecimal(tradeAllowanceCharge.ActualAmount, 2)); Writer.WriteEndElement(); _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason); if (tradeAllowanceCharge.Tax != null) { Writer.WriteStartElement("ram:CategoryTradeTax"); Writer.WriteElementString("ram:TypeCode", tradeAllowanceCharge.Tax.TypeCode.EnumToString()); if (tradeAllowanceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", tradeAllowanceCharge.Tax.CategoryCode?.EnumToString()); } Writer.WriteElementString("ram:ApplicablePercent", _formatDecimal(tradeAllowanceCharge.Tax.Percent)); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } if ((this.Descriptor.ServiceCharges != null) && (this.Descriptor.ServiceCharges.Count > 0)) { foreach (ServiceCharge serviceCharge in this.Descriptor.ServiceCharges) { Writer.WriteStartElement("ram:SpecifiedLogisticsServiceCharge"); if (!String.IsNullOrEmpty(serviceCharge.Description)) { Writer.WriteElementString("ram:Description", serviceCharge.Description); } Writer.WriteElementString("ram:AppliedAmount", _formatDecimal(serviceCharge.Amount)); if (serviceCharge.Tax != null) { Writer.WriteStartElement("ram:AppliedTradeTax"); Writer.WriteElementString("ram:TypeCode", serviceCharge.Tax.TypeCode.EnumToString()); if (serviceCharge.Tax.CategoryCode.HasValue) { Writer.WriteElementString("ram:CategoryCode", serviceCharge.Tax.CategoryCode?.EnumToString()); } Writer.WriteElementString("ram:ApplicablePercent", _formatDecimal(serviceCharge.Tax.Percent)); Writer.WriteEndElement(); } Writer.WriteEndElement(); } } if (this.Descriptor.PaymentTerms != null) { Writer.WriteStartElement("ram:SpecifiedTradePaymentTerms"); _writeOptionalElementString(Writer, "ram:Description", this.Descriptor.PaymentTerms.Description); if (this.Descriptor.PaymentTerms.DueDate.HasValue) { Writer.WriteStartElement("ram:DueDateDateTime"); _writeElementWithAttribute(Writer, "udt:DateTimeString", "format", "102", _formatDate(this.Descriptor.PaymentTerms.DueDate.Value)); Writer.WriteEndElement(); // !ram:DueDateDateTime } Writer.WriteEndElement(); } #endregion #region SpecifiedTradeSettlementHeaderMonetarySummation //Gesamtsummen auf Dokumentenebene Writer.WriteStartElement("ram:SpecifiedTradeSettlementHeaderMonetarySummation"); _writeOptionalAmount(Writer, "ram:LineTotalAmount", this.Descriptor.LineTotalAmount); //Summe der Nettobeträge aller Rechnungspositionen _writeOptionalAmount(Writer, "ram:ChargeTotalAmount", this.Descriptor.ChargeTotalAmount); //Summe der Zuschläge auf Dokumentenebene _writeOptionalAmount(Writer, "ram:AllowanceTotalAmount", this.Descriptor.AllowanceTotalAmount); //Summe der Abschläge auf Dokumentenebene _writeOptionalAmount(Writer, "ram:TaxBasisTotalAmount", this.Descriptor.TaxBasisAmount, profile: Profile.Extended); //Rechnungsgesamtbetrag ohne Umsatzsteuer _writeOptionalAmount(Writer, "ram:TaxTotalAmount", this.Descriptor.TaxTotalAmount); //Gesamtbetrag der Rechnungsumsatzsteuer, Steuergesamtbetrag in Buchungswährung //ToDo: RoundingAmount //Rundungsbetrag _writeOptionalAmount(Writer, "ram:GrandTotalAmount", this.Descriptor.GrandTotalAmount); //Rechnungsgesamtbetrag einschließlich Umsatzsteuer _writeOptionalAmount(Writer, "ram:TotalPrepaidAmount", this.Descriptor.TotalPrepaidAmount); //Vorauszahlungsbetrag _writeOptionalAmount(Writer, "ram:DuePayableAmount", this.Descriptor.DuePayableAmount); //Fälliger Zahlungsbetrag Writer.WriteEndElement(); // !ram:SpecifiedTradeSettlementMonetarySummation #endregion Writer.WriteEndElement(); // !ram:ApplicableSupplyChainTradeSettlement Writer.WriteEndElement(); // !ram:SpecifiedSupplyChainTradeTransaction #endregion Writer.WriteEndElement(); // !ram:Invoice Writer.WriteEndDocument(); Writer.Flush(); stream.Seek(streamPosition, SeekOrigin.Begin); } // !Save()