Zobrazují se příspěvky se štítkemXML. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemXML. Zobrazit všechny příspěvky

neděle 19. srpna 2018

Chyba při XSLT transformaci vstupních dat pro import do pohody

Pokud Vám pohoda tvrdí, že je element prázdný tak má pravdu, i když to tak na první pohled nemusí vypadat.
Pokud při Importu dat používáte transformační šablonu a transformujete vstupní data, zkontrolujte si vstupní soubor jestli náhodou Pohodě nedáváte již jednou transformovaná dat. Protože transformace v takovém případě se už nejspíš nemá na co chytit (root vstupního souboru dat) a transformace vrátí prázdný dataPack.

Obálku dokumentu se nepodarilo overit podle schématu.
Reason: Element '{http://www.stormware.cz/schema/version_2/data.xsd}dataPack' cannot be empty according to the DTD/Schema.
Line: 2, Pos.: 645,
SrcText: <dat:dataPack id="Update" ico="49761540" application="POHODA-ZASOBY-UPDATE" version="2.0" note="Aktualizace skladových zásob" xmlns:dat="http://www.stormware.cz/schema/version_2/data.xsd" xmlns:stk="http://www.stormware.cz/schema/version_2/stock.xsd" xmlns:typ="http://www.stormware.cz/schema/version_2/type.xsd" xmlns:ftr="http://www.stormware.cz/schema/version_2/filter.xsd" ></dat:dataPack>,
Error code: -1072898031 

středa 27. června 2018

Import obrázků do ERP Pohoda pomocí XSLT a XML


Pro použití obrázku ve skladových zásobách je potřeba nastavit firemní složku.
To je možné nastavit v [Nastavení] / [Globální nastavení] / [dokumenty] 
zaškertnutím pole  Používat složku dokumentl firmy [x]
a vyplněním názvu adresáře
Složka dokumentů firmy [frmaDta_______]

Obrázky pak budou uloženy v podadresáři Obrázky (složku obrázky si vytváří Pohoda sama)
např: C:\ProgramData\STORMWARE\POHODA01\Dokumenty\frmaDta\Obrázky
Cesta k obrázku je v DB uložena v tabulce SkRefObraz
Z obrázku se ukládají pouze jejich názvy (neukládá se kompletní cesta)


Zdroj:
http://morg.nl/2012/02/get-file-extention-in-xslt/


sobota 23. června 2018

Raiffaisen Bank XML

Pokud nemáte podnikatelský účet, tak máte možnost exportovat bankovní výpisi u Raiffaisen Bank pouze do PDF nebo XML. XML soubor, ale nelze načíst do ekonomického systému jako je např. Money S3 nebo Stormware Pohoda.
Raiffaisen bank tímto nutí majitele účtů aby platili za možnost integrace s ERP systémy cca 150,-Kč / mes za podnikatelský účet. 
Řešením je transformace XML souboru do formátu ABO, který umí načíst asi každý účetní systém. Bohužel ke XML formátu Raifka neposkytuje dokumentaci. Tak nezbývá nic jiného než si na význam jednotlivých informací ve výpise přijít sám. Aby jste nemuseli absoluovat stejný výzkum jako já, tak tady uvádím výsledek mého zkoumání.

Struktura souboru

<?xml version='1.0' encoding='ISO-8859-1'?>
<OFX>
<STMTRS>
<BANKACCTFROM>
<BANKID>5500</BANKID>
<ACCTID>000000 1578954234</ACCTID>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>31.03.2015</DTSTART>
<DTEND>30.04.2015</DTEND>
<BALOPEN>15.65</BALOPEN>
<BALCLOSE>112.8</BALCLOSE>
...
<STMTTRN>
<TRNTYPE>CREDIT</TRNTYPE>
<DTPOSTED>20140330</DTPOSTED>
<DTAVAIL>20140330</DTAVAIL>
<TRNAMT>49980</TRNAMT>
<TRNSPSYM>0000000000</TRNSPSYM>
<TRNVASYM>0143459756</TRNVASYM>
<TRNCOSYM>0000000308</TRNCOSYM>
<NAME>P&#345;&#237;choz&#237; platba</NAME>
<BANKACCTO>
<BANKID>0100</BANKID>
<ACCTID>9446534895</ACCTID>
<ACCTKEY>000000</ACCTKEY>
</BANKACCTO>
<MEMO/>
<CURRENCY>CZK</CURRENCY>
</STMTTRN>
...
</BANKTRANLIST>
</STMTRS>
</OFX>

Popis hlavičky souboru

BANKID = kód banky
ACCTID = číslo účtu včetně předčíslí oddělené mezerou

Popis Bonkovního výpisu

DTSTART = Datum začátku výpisu ve forátu 28.01.2013
DTEND  = Datum začátku výpisu ve forátu 31.02.2013
BALOPEN = počáteční stav účtu ve formátu 170.95
BALCLOSE = konečný stav účtu ve formátu 268.79

Popis položek výpisu

DTPOSTED = Den účtování (dříve) (20130230 = 30.02.2013)
DTAVAIL = Den valuty (později ) (20130230 = 30.02.2013)

TRNAMT = Objem transakce * 1/100 (216 = 2,16)
CURRENCY = Měna transakce - nevypovídá o tom jestli se jedná o zahraniční nebo tuzemskou platbu a zda kód banky a bankovní účet obsahuje IBAN a BIC nebo numerické číslo tuzemského účtu

TRNSPSYM = Specifický symbol (nepovinný)
TRNVASYM = Variabilní symbol (nepovinný)
TRNCOSYM = Constantní symbol (nepovinný)
TRNTYPE = DEBIT / CREDIT

ACCTKEY = Předčíslí bankovního účtu (nepovinný)
ACCTID = Číslo bankovního účtu nebo IBAN (nepovinný)
BANKID = Kód banky nebo BIC (nepovinný)

MEMO = Detail transakce (nepovinný)
<MEMO>DA&#327; Z &#218;ROK&#366;</MEMO>
NAME = Typ transakce
<NAME>Provoz &#250;&#269;tu</NAME>
<NAME>P&#345;&#237;choz&#237; platba</NAME>
<NAME>Odchoz&#237; platba</NAME>

Platba kartou

Nemá nastaveny symboly ani informace o protiúčtu<TRNSPSYM/>
<TRNVASYM/>
<TRNCOSYM/>
<NAME>Platba PK u obchodn&#237;ka</NAME>
<BANKACCTO>
<BANKID/>
<ACCTID/>
<ACCTKEY/>
</BANKACCTO>

BIC

ISO 9362

Např. 
Fio banka - FIOZSKBA
mBank - BREXSKBX

SWIFT

https://cs.wikipedia.org/wiki/SWIFT

Závěrem

Pokud Vám tento článek v něčem pomohl, budu rád pokud mi to napíšete do komentáře. Pokud najdete nějakou chybu nebo máte připomínku tak mi napište a já článek opravím aby se se stejnou chybou nemuseli mordovat ostatní co si ho přečtou. 

pátek 25. srpna 2017

XSLT Nahrazení desetinné čárky za tečku

Je potřeba vytvořit XSLT šablonu aby bylo možné ze zdrojového feedu importovat stavy skladů do ERP Stormware Pohoda. Protože ale zdrojová data obsahují hodnotu s desetinnou čárkou namísto tečky, je potřeba ji nejprve nahradit. A až potom může být vložena sloupce VPrDPC, který je typu desetinné číslo.

<xsl:value-of select="translate(PRICE,',','.')" />

Zdroj:
https://stackoverflow.com/questions/11716358/replacing-characters-in-xslt-1-0
https://www.w3schools.com/xml/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog_if

pondělí 31. července 2017

Chyba při serializaci objektu pomocí XmlSerializer do existujícího souboru

<?xml version="1.0"?>
<RobotSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ComPortName>COM9</ComPortName>
  <BaudRate>9600</BaudRate>
  <AutoConnect>false</AutoConnect>
  <Velocity>100</Velocity>
  <MoveDuration>250</MoveDuration>
  <TurningDuration>250</TurningDuration>
  <QueueSize>6</QueueSize>
</RobotSettings>>ngDuration></RobotSettings>
Vyserializováním objektu do již existujícího souboru může dojít k chybě, která za "příznivých podmínek" tj. pokud výsledný text je delší než předchozí (a kompletně přepíše starou verzi), nemusí projevit.
Pokud je ale text kratší a vy použijete špatný FileMode - tak přepíše jen začátek a konec ponechá. Jak je vidět v příkladu. A to vede k nevalidnímu XML a chybě parsování a deserializace objektu.

using (FileStream myFileStream = new FileStream(FileName, FileMode.OpenOrCreate))
using (FileStream myFileStream = new FileStream(FileName, FileMode.CreateNew)) ->  již existuje.

středa 2. března 2016

XML serializace a atributy

Serializace třídy do XML
Zdroj:
https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

XmlIgnore
[XmlIgnore]
public int PropertyName{get; set;}

XmlRoot
[XmlRoot("korenovy_tag")]
public class XmlRootElement {get; set;}
<korenovy_tag>
...
</korenovy_tag>

XmlText
Zdroj:
http://stackoverflow.com/questions/3638113/using-xml-class-attributes-how-to-represent-an-xml-tag-with-both-inner-text-and
[XmlText()]
public string Text {get; set;}
<tag>text</tag>
Poznámka: Pokud nemá property setter tak se hodnota do XML při serializaci nezapíše.

XmlAttribute
Zdroj:
http://stackoverflow.com/questions/3638113/using-xml-class-attributes-how-to-represent-an-xml-tag-with-both-inner-text-and
[XmlAttribute("skutecny_nazev_tagu")]
public string NazevProperty {get; set;}
<tag skutecny_nazev_tagu="hodnota">

XmlElement
[XmlElement("skutecny_nazev_tagu")]
public int Value {get; set;}
<skutecny_nazev_tagu>1</skutecny_nazev_tagu>

XmlArray a XmlArrayItem
[XmlArray("collection_name")]
[XmlArrayItem("collection_item_name")]
public List<ItemType> Items { get; set; }
<colection_name>
<collection_item_name Id="1" />
<collection_item_name Id="2"/>
....
</colection_name>

Vynechat prázdné hodnoty
Zdroj:
http://stackoverflow.com/questions/5818513/xml-serialization-hide-null-values
Property s názvem ShouldSerialize{PropertyName} kde PropertyName je název property která by se měla nebo neměla serializovat.

public bool ShouldSerializeMyNullableInt() 
{
  return MyNullableInt.HasValue;
}
nebo
{PropertyName}Specified

Serializace bez Namespace
Zdroje:
http://stackoverflow.com/questions/8061106/xml-serialization-remove-namespace

var xns = new XmlSerializerNamespaces();
var serializer = new XmlSerializer(users.GetType());
xns.Add(string.Empty, string.Empty);
//...
serializer.Serialize(stream, users, xns);



neděle 19. dubna 2015

Import do Pohody

Chyby

Velikost písmen
Obálku dokumentu se nepodařilo ověřit podle schématu.
Reason: The element 'dat:DataPackItem' is used but not declared in the DTD/Schema.
Pohoda totiž používá pro názvy elementů na začátku malá písmena.

Chybí prefix
dataPack namísto dat:dataPack
pokud Vám chybí prefixy, musíte při serializaci předat serializerů seznam namespace a jejich prefixů.

Chybí povinný atribut
Obálku dokumentu se nepodařilo ověřit podle schématu.
Reason: Required attribute 'application' is missing.

Hodnota atributu application se zobrazuje v seznamu XML Log, stejně tak jako název PC ze kterého byl import proveden, uživatelské jméno přihlášeného uživatel do účetnictví a číslo (ID) dataPacku

Chyba: Tento balíček není určen pro tuto jednotku.
Snažíte se importovat soubor který obsahuje rozdílné IČO od IČa vyplněném v účetní jednotce

dat:DataPackItem nesmí být prázdný
Obálku dokumentu se nepodařilo ověřit podle schématu.
Reason: Element cannot be empty according to the DTD/Schema.

Probíhá zpracování ...Zpracování bylo dokončeno.Výsledek: Ok
Odpověď uložena v: C:\Pohoda_Import\Response\FV4.xmlVýsledek importu položek:
ID: CM001: Ok
Minimální importovatelný datapack faktury
<?xml version="1.0" encoding="windows-1250"?><dat:dataPack id="FV20150001" ico="12345678" version="2.0" application="OdvezTo.Eu"note="Faktura byla exportována ze systému OdvezTo.Eu"xmlns:inv="http://www.stormware.cz/schema/version_2/invoice.xsd" xmlns:typ="http://www.stormware.cz/schema/version_2/type.xsd" xmlns:dat="http://www.stormware.cz/schema/version_2/data.xsd"><dat:dataPackItem id="CM001" version="2.0"><inv:invoice version="2.0"><inv:invoiceHeader><inv:invoiceType>issuedInvoice</inv:invoiceType><inv:date>2014-10-14</inv:date></inv:invoiceHeader></inv:invoice></dat:dataPackItem></dat:dataPack> 

Závažnou chybou je také nesprávná znaková sada (CodePage) datového souboru.
Pokud máte XML například v UTF-8 (výchozí znaková sada .NET) a pokusíte se ho naimportovat
a v hlavičce XML máte uvedeno <?xml version="1.0" encoding="windows-1250"?>
Vrátí vám Pohoda nic neříkající chybovou hlášku:

Probíhá zpracování ...Zpracování bylo dokončeno.Výsledek: Error Odpověď uložena v: C:\Users\zbynek.sulc\Downloads\Response\FVObj20150005 (2).xmlObálku dokumentu se nepodařilo ověřit podle schématu. 


Validace podle schmatu
Pokud máte chybu ve struktuře XML dokumentu neprojde validací a nezbyde Vám nic jiného než soubor otevřít a chybu najít ručně. Jste si jisti že máte všechno správně a stejně aplikace hlásí chybu? K této chyba může dojít i proto, že máte rozdílné znakové sady. v XML sice uvádíte windows-1250, ale do souboru jste ho zapsali jako UTF-8 což je defaultní znaková sada .NET Frameworku.


Probíhá zpracování ...



Zpracování bylo dokončeno.

Výsledek: Ok 

Odpověď uložena v: C:\Users\zbynek.sulc\Downloads\Response\FVObj20150005 (3).xml



Výsledek importu položek: 
ID: Usr01 (001): Error 'Element content is invalid according to the DTD/Schema.Nepodařila se validace dokumentu podle schématu.'

Tuto chybu napříkald obdržíte pokud si nevšimnete že inv:homeCurrency v 
inv:invoiceSummary a v části inv:invoiceItem mají různý typ a tudíž i atributy.

v summary je to typ:typeCurrencyHome 
v Items pak typ:typeCurrencyHomeItem

Aby Vás udrželi vývojáři ze Stormware v bdělém stavu a zvíšili Vám hladinu adrenalinu tak tuto nekonzistenci opakují i na Adrese
addressType a myAddress


Další záludností je délka textu DTD Schema říká že:
<xsd:element name="text" type="typ:string90" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Text položky.</xsd:documentation>
</xsd:annotation>
</xsd:element>
Takže
<xsd:simpleType name="string90">
<xsd:annotation>
<xsd:documentation>Řetězec o délce 90 znaků.</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="90"/>
</xsd:restriction>
</xsd:simpleType>


Pokud máte nějaké otázky klidně je napište do komentáře nebo na můj e-mail.
Instalačku Pohody můžete bez registrace stáhnout z adresy http://www.stormware.cz/pohoda/start.aspx

Generování .NET tříd podle XSD schematu XML souboru

Určitě jste někdy parsovali cizí XML.Možná Vás bude zajímat jak to zvládnout co nejrychleji.
Pokud máte jednoduché XML a chcete ho deserializovat do objektu musíte si tyto objekdy nejdříve nachystat. To bývá docela makačka, ale na každou makačku většinou existuje nějaká lopata.

V našem případě použijeme nástroj XSD, který je součástí Visual Studia a najdeme ho například v adresáři c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\x64\

Pokud tomuto programu předhodíte nějaké XSD tak Vám k němu vygenerovat jednotlivé třídy.
Pokud nemáte XSD můžete si ho nechat vygenerovat podle XML. V dalším kroku potom z XSD necháme vygenerovat třídy.

"c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\xsd.exe" Data.xml

"c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\xsd.exe" Data.xsd /c /n:Bt.Transform.Data


Pokud XML má více namespace a XSD šablon, můžeme je předat v řadě za sebou v příkazové řádce a nebo pomocí XML souboru [2].

Pojmenování výstupního soubboru 
Použijete-li více xsd šablon tak aplikace vygeneruje soubor který se bude jmenovat podle všech použitých schemat. Použijete li jich opravdu hodně, tak aplikace skončí chybou ve smyslu, že název soubboru je příliš dlouhý. Naštěstí má v sobě aplikace xsd.exe chybu [3], která přeruší skládání jmen souborů za sebe a začne znovu. Což znamená že když použijete v cestě k souboru ".\" a umístíte ho na konec příkazové řádky nebo jako poslední Schema element v XML, bude se výstupní soubor jmenovat podle něj.

S touto pomocí budete generovat XML faktury do vašeho oblíbeného účetnictví během jednoho dne a né za 14 dní.
Stejně dobrou službu vám udělá při synchronizaci kurzovních lístků, nabídek realitních kanceláří, autobazarů nebo zboží v e-shopech.

Pokud máte nějaké otázky klidně je napište do komentáře nebo na můj e-mail.

Zdroj:
  1. http://blogs.msdn.com/b/yojoshi/archive/2011/05/14/xml-serialization-and-deserialization-entity-classes-with-xsd-exe.aspx
  2. http://stackoverflow.com/questions/1140495/multiple-xsd-schema-files-to-c-sharp-classes
  3. https://social.msdn.microsoft.com/Forums/en-US/8ab41df8-69d4-44e4-8795-436088f230e2/xsdexe-path-is-too-long-after-being-fully-qualified?forum=xmlandnetfx
  4. https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

středa 11. března 2015

Xml Unit

Pokud jste někdy psali testy na XML určitě jste přišli na to že testování pomocí
 Assert.AreEqual(expectedInvoice, xmlString);
Není moc dobrý nápad, protože při každé změně se vám testy rozbijí.

XML Unit se perfektně hodí na testování vygenerovaného XML protože umožňuje testovanou hodnotu vyhledávat pomocí XPath.

Install-Package XmlUnit.Xunit

Příklad:
using System;
using Bt.Stormware.Entity;
using System.Text;
using System.Diagnostics;
using NUnit.Framework;
using System.Xml;
using XmlUnit.Xunit;


 [Test]
        public void XmlTest()
        {
            var xmlString = "<body><a href="https://www.blogger.com/null">Karel</a><input ext="" type="\" /><textarea rows="\">Jan</textarea></body>";

            XmlAssertion.AssertXmlValid(xmlString);
            XmlAssertion.AssertXPathEvaluatesTo("/body/a[text()]", xmlString, "Karel");
            XmlAssertion.AssertXPathEvaluatesTo("/body/a", xmlString, "Karel");

            
            XmlAssertion.AssertXPathExists("/body/input[@type='Text']", xmlString);
            XmlAssertion.AssertXPathEvaluatesTo("/body/textarea[@rows='3']", xmlString, "Jan");
            XmlAssertion.AssertXPathEvaluatesTo("/body/textarea[@rows]", xmlString, "Jan");

        }