Import dokumentów z plików XML część I
Transkrypt
Import dokumentów z plików XML część I
_________________________________________________________________________________________ Import dokumentów z plików XML część I (wersja 1.0) Soneta Sp z o.o. ul. Wadowicka 8a, wejście B 31-415 Kraków tel./fax +48 (12) 261 36 41 http://www.enova.pl e-mail: [email protected] 1 Spis treści 1 Wstęp ............................................................................................................................................................ 3 2 Eksport i import danych z plików XML ............................................................................................................ 3 3 Ogólna struktura plików importu ................................................................................................................... 4 4 5 3.1 Atrybut business..................................................................................................................................... 4 3.2 Atrybuty guid i id .................................................................................................................................... 5 Import danych słownikowych ......................................................................................................................... 5 4.1 Identyfikacja kontrahenta w bazie danych .............................................................................................. 5 4.2 Identyfikacja kontrahenta na dokumencie .............................................................................................. 6 4.2.1 Identyfikacja po GUID ..................................................................................................................... 6 4.2.2 Identyfikacja po polu unikalnym ..................................................................................................... 7 4.2.3 Wewnętrzny identyfikator .............................................................................................................. 7 Importy podlist .............................................................................................................................................. 8 5.1 Pozycje dokumentu handlowego ............................................................................................................ 8 5.2 Płatności................................................................................................................................................. 8 6 Najprostszy plik importu ................................................................................................................................ 9 7 Podsumowanie i kontynuacja....................................................................................................................... 11 2 1 Wstęp Często pojawiają się pytania o możliwośd importu danych – w szczególności faktur czy innych dokumentów handlowych – do enova. System enova dostarcza kilku mechanizmów importu danych – np. importy z arkuszy Microsoft Excel, czy kilka formatów importu danych do ewidencji dokumentów (w księgowości). W niniejszym dokumencie skupimy się nad importem danych z wykorzystaniem plików XML. Ma on na celu przybliżenie zasad budowy plików XML służących do importu danych do systemu enova. Odpowiednio wygenerowany plik XML może służyd np. do importu danych do systemu enova z zewnętrznych programów. 2 Eksport i import danych z plików XML W systemie istnieje funkcja eksportu danych do plików XML dostępna z menu Plik\Eksportuj zapisy. Funkcja ta jest dostępna na większości list i odnosi się do eksportu danych aktualnie wyświetlonych (zaznaczonych) na liście. Kilka słów wyjaśnienia, dlaczego na niektórych listach ta opcja nie jest dostępna – do pliku XML można wyeksportowad jedynie kompletne z logicznego punktu widzenia dane. Przykładowo – dokument handlowy (np. faktura) łącznie z pozycjami stanowi kompletną paczkę danych. Z drugiej strony, jeżeli otworzymy listę Handel\Dane analityczne\Pozycje – to lista ta zawiera zestawienie pozycji dokumentów handlowych. Pojedyncza pozycja nie jest kompletną paczką danych – pozycja bez nagłówka dokumentu nie może istnied. Dlatego w tym miejscu eksport danych do pliku XML nie jest dostępny. Używając określenia bardziej technicznego, możliwy jest import tylko zapisów „guidowanych”, czyli posiadających własny GUID. Funkcja „lustrzana” do eksportu dokumentów jest dostępna z menu Plik\Importuj zapisy\Z pliku XML. Funkcja ta pozwala na zaimportowanie danych z uprzednio przygotowanego pliku XML. W odróżnieniu od eksportu, który zapisuje do pliku dokumenty z bieżącej listy, import działa bezkontekstowo – tzn. niezależnie od tego na której liście zostanie uruchomiony, importuje wszystkie dane zawarte we wskazanym pliku XML. 3 W przypadku eksportu dokumentów handlowych do pliku XML mamy dostępną jeszcze jedną, specjalizowaną funkcję – dostępną z menu Czynności\Narzędziowe\Eksport dokumentu\do pliku. Funkcja dostępna jest na liście dokumentów handlowych (lub na formularzu dokumentu handlowego) i tworzy plik XML, który ma nieco inną strukturę od tego, który jest tworzony z funkcji Plik\Eksportuj zapisy, ale może byd importowany tą samą funkcją importu. Podstawowa różnica w strukturze plików generowanych tymi dwoma metodami zostanie omówiona w następnym punkcie. 3 Ogólna struktura plików importu Zobaczmy na układ pliku wygenerowanego funkcją Plik\Eksportuj zapisy (jest to fragment pliku zawierającego dokument handlowy) <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business"> <DokumentHandlowy id="DokumentHandlowy_14" guid="afd216af-1d07-4fc6-a6c2c8596e60fea9"> <Kategoria>Sprzedaż</Kategoria> <Stan>Zatwierdzony</Stan> <Potwierdzenie>Niepotwierdzony</Potwierdzenie> <Definicja>00000000-0011-0002-0001-000000000000</Definicja> <Magazyn>00000000-0011-0004-0001-000000000000</Magazyn> [...] </DokumentHandlowy> </session> Podstawowa zasada jest taka, że – oprócz znacznika XML na początku pliku – całośd danych umieszczona jest w tagu session, a dalej znajdują się tagi zawierające poszczególne zapisy. Nazwa tagu DokumentHandlowy odpowiada w tym wypadku typowi importowanych danych, natomiast w ramach dokumentu znajdują się tagi zawierające poszczególne pola z wartościami (Kategoria, Stan itd. są to pola dokumentu). 3.1 Atrybut business Jeżeli popatrzymy na fragment pliku wygenerowanego za pomocą funkcji Czynności\Narzędziowe\Eksport dokumentu\do pliku to wygląda on tak: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy guid="afd216af-1d07-4fc6-a6c2-c8596e60fea9"> <Definicja where="Symbol=FV" /> <Magazyn where="Symbol=F" /> <Data>2011-05-04</Data> [...] </DokumentHandlowy> </session> Co do ogólnej struktury to wygląda bardzo podobnie do poprzedniego (tagi session, DokumentHandlowy oraz tagi odpowiadające wartościom pól w dokumencie). Proszę natomiast zwrócid uwagę na pozornie drobną różnicę – a mianowicie na atrybut business="true" w tagu session. Atrybut ten ma kolosalne znaczenie dla funkcji importu danych z pliku XML: Jeżeli atrybut business ma wartośd true, wówczas import z pliku XML przebiega z wykorzystaniem logiki biznesowej programu – czyli w analogiczny sposób, jakby wartości kolejnych pól były ustawiane np. na 4 poziomie interfejsu użytkownika (na formularzu dokumentu). Oznacza to w szczególności wykonanie wszelkich obliczeo i weryfikacji podczas dodawania zapisu. Ponadto wszystkie pola które nie zostaną ustawione (czyli te, których nie będzie w pliku XML) zostaną zainicjalizowane tak, jak przy „normalnym” dodawaniu dokumentu. Jeżeli atrybut business ma wartośd false (albo nie jest ustawiony) wówczas kopiowanie danych odbywa się z pominięciem logiki biznesowej – w uproszczeniu można powiedzied, że import odbywa się niejako na poziomie danych zapisywanych do bazy. Oznacza to m.in., że dane nie są weryfikowane pod względem poprawności, żadne dane nie będą zainicjalizowane. Z powyższego wynika, że jeżeli chcemy zewnętrznymi narzędziami przygotowad plik XML do importu, wówczas koniecznie należy stosowad atrybut business="true". Bezpieczne tworzenie plików XML bez tego atrybutu jest możliwe tylko wewnętrznymi mechanizmami systemu enova – bo system ma pełną informację o dokumencie i jest w stanie wygenerowad komplet spójnych danych o eksportowanym zapisie. 3.2 Atrybuty guid i id W obu przypadkach tag DokumentHandlowy posiada atrybut guid. Atrybut ten odpowiada właściwości (polu) GUID dokumentu i jest jednoznacznym identyfikatorem tego dokumentu. W przypadku importu zapisów z pliku program zawsze zweryfikuje czy istnieje już zapis (w tym wypadku dokument handlowy) o podanym identyfikatorze GUID, i jeśli tak, to istniejący zapis zostanie nadpisany. W przeciwnym wypadku zostanie dodany nowy zapis. Atrybut guid może nie byd ustawiony w pliku XML – w takim wypadku podczas importu zawsze zostanie dodany nowy zapis i zostanie mu nadany nowy identyfikator GUID (tak, jak podczas „normalnego” dodawania dokumenty w systemie enova). Inaczej jest z atrybutem id. Jest to identyfikator wewnętrzny w ramach pliku XML. Nie ma on znaczenia dla dodawania zapisu do systemu enova, natomiast może mied znaczenie dla powiązania różnych zapisów znajdujących się w pliku XML – będzie o tym dalej mowa w punkcie mówiącym o imporcie danych kontrahentów. 4 Import danych słownikowych Jeden plik XML może zawierad wiele danych - może zarówno zawierad wiele dokumentów do zaimportowania, jak i dane różnego rodzaju. Dzięki temu w jednym pliku razem z dokumentem handlowym możemy umieścid np. dane o kontrahencie czy towarach. 4.1 Identyfikacja kontrahenta w bazie danych Poniżej plik zawierający podstawowe dane kontrahenta: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <Kontrahent id="kontrahent_2" key="Kod=Zefir" guid="ba66f548-1660-11d7-9ab0000795c951c8"> <Kod>Zefir</Kod> <Nazwa>ZEFIR J.Nowak i E.Nowak</Nazwa> </Kontrahent> </session> Ponieważ dla kontrahenta wymaganymi danymi są jedynie kod i nazwa, dla uproszczenia plik został ograniczony tylko do tych dwóch wymaganych tagów. Dokładniej omówimy znaczenie atrybutów id, key i guid oraz ich znaczenia do powiązania zapisu z zapisem w bazie danych i z innymi zapisami w pliku XML. 5 Jak już wcześniej wspomniano guid jest jednoznacznym identyfikatorem zapisu w bazie danych. Jeżeli atrybut guid jest wypełniony i zostanie znaleziony w bazie kontrahent o takim GUID, to jego dane zostaną podczas importu zaktualizowane. Jeżeli kontrahent o danym GUID nie zostanie znaleziony, wówczas zostanie dodana nowa kartoteka. Zastanówmy się, co się stanie, jeżeli w pliku XML nie określimy żadnego identyfikatora dla kontrahenta i spróbujemy zaimportowad dane: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <Kontrahent> <Kod>Zefir</Kod> <Nazwa>ZEFIR J.Nowak i E.Nowak</Nazwa> </Kontrahent> </session> Program w tym wypadku doda nowego kontrahenta, nada mu w enova nowy GUID. Co się jednak stanie jeśli spróbujemy wykonad import z tego pliku po raz drugi (lub jeśli kontrahent Zefir już wcześniej istniał w bazie). Program nie znajdzie kontrahenta po identyfikatorze GUID (bo takiego identyfikatora nie ma), spróbuje dodad nowego kontrahenta i otrzyma błąd duplikacji kodu kontrahenta. Aby z jednej strony nie wymuszad posługiwania się identyfikatorami GUID (co jest niewygodne, a czasami – przy przesyłaniu danych pomiędzy różnymi bazami danych – wręcz niemożliwe), wprowadzony został atrybut key, który umożliwia zidentyfikowanie zapisu po polu unikalnym innym niż GUID: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <Kontrahent key="Kod=Zefir" > <Kod>Zefir</Kod> <Nazwa>ZEFIR J.Nowak i E.Nowak</Nazwa> </Kontrahent> </session> Taki zapis oznacza, że program spróbuje znaleźd kontrahenta o kodzie Zefir, i jeśli go znajdzie to zaktualizuje jego dane, a jeśli nie znajdzie – założy nową kartotekę. 4.2 Identyfikacja kontrahenta na dokumencie Jeżeli przyjrzymy się plikowi zawierającemu wyeksportowany dokument handlowy, wówczas znajdziemy w nim m.in. tag Kontrahent, który wskazuje na kontrahenta, którego należy wstawid na dokumencie. Kontrahent na dokumencie może byd zidentyfikowany na 3 sposoby: 4.2.1 Identyfikacja po GUID Jako wartośd tagu Kontrahent podstawiamy po prostu GUID kontrahenta. Aby zastosowad taką metodę konieczna jest znajomośd identyfikatorów GUID – a jeśli mówimy o eksporcie/imporcie pomiędzy różnymi bazami danych (czy wręcz różnymi programami) to często taka synchronizacja GUID-ów jest trudna do zapewnienia. Warto zwrócid uwagę, że w takim przypadku dane kontrahenta nie muszą byd zapisane w pliku XML – ważne jest, żeby w bazie danych do której importujemy istniał kontrahent o wskazanym GUID. Oczywiście jeżeli w pliku oprócz dokumentu handlowego znajdzie się również tag z danymi kontrahenta, wówczas mamy pewnośd, że w przypadku braku kontrahenta o takim GUID zostanie on zaimportowany. 6 <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy > <Kontrahent> ba66f548-1660-11d7-9ab0-000795c951c8</Kontrahent> [...] </DokumentHandlowy> </session> Proszę zwrócid uwagę, że w pierwszym przykładzie podanym na początku w analogiczny sposób było wykonane odwołanie do magazynu czy definicji dokumentu: <Definicja>00000000-0011-0002-0001-000000000000</Definicja> <Magazyn>00000000-0011-0004-0001-000000000000</Magazyn> 4.2.2 Identyfikacja po polu unikalnym Podobnie, jak identyfikowaliśmy kontrahenta w bazie danych za pomocą atrybutu key, na dokumencie możemy go zidentyfikowad po polu unikalnym wykorzystując atrybut where. Ponieważ dla kontrahenta polem unikalnym jest kod, więc w atrybucie where użyjemy odwołania do kodu kontrahenta. <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy > <Kontrahent where="Kod=Zefir" /> [...] </DokumentHandlowy> </session> Podobnie jak w poprzednim przykładzie dane kontrahenta nie muszą byd umieszczone w pliku XML – ważne, żeby w bazie znajdował się kontrahent o podanym kodzie. Proszę zwrócid uwagę, że w drugim przykładzie podanym na początku tego dokumentu w analogiczny sposób było wykonane odwołanie do magazynu czy definicji dokumentu: <Definicja where="Symbol=FV" /> <Magazyn where="Symbol=F" /> 4.2.3 Wewnętrzny identyfikator Trzecim sposobem jest wykorzystanie wewnętrznego identyfikatora – atrybutu id. W tym wypadku dane kontrahenta muszą znajdowad się w pliku XML, kontrahent musi posiadad nadany atrybut id, i poprzez ten atrybut odwołujemy się do jego kartoteki, np.: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <Kontrahent id="kontrahent_2" key="Kod=Zefir" > <Kod>Zefir</Kod> <Nazwa>ZEFIR J.Nowak i E.Nowak</Nazwa> </Kontrahent> <DokumentHandlowy > <Kontrahent> kontrahent_2</Kontrahent> [...] </DokumentHandlowy> </session> 7 W tym wypadku kontrahentowi nadaliśmy wewnętrzny identyfikator kontrahent_2. Wartośd tego identyfikatora może mied dowolną wartośd alfanumeryczną i nie jest nigdzie zapisywana w bazie danych – obowiązuje wyłącznie „wewnątrz” pliku XML. Do tak nadanego identyfikatora możemy odwoład się ustalając kontrahenta na dokumencie handlowym. 5 Importy podlist 5.1 Pozycje dokumentu handlowego Dokument handlowy zawiera listę pozycji – w odróżnieniu od danych wcześniej omawianych w tym wypadku musimy zapewnid możliwośd zapisania nie jednej wartości (jak Kontrahent, Magazyn itp.), ale wielu – dla każdej pozycji trzeba określid towar, ilośd, cenę itp. <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy guid="afd216af-1d07-4fc6-a6c2-c8596e60fea9"> <Definicja where="Symbol=FV" /> <Magazyn where="Symbol=F" /> <Data>2011-05-04</Data> <Kontrahent where="Kod=Zefir" /> <Pozycje> <Pozycja> <Towar where="Kod=NAM_HOME1" /> <Ilosc>1 szt</Ilosc> <Cena>72.00 PLN</Cena> </Pozycja> <Pozycja> <Towar where="Kod=SPIWOR" /> <Ilosc>1 szt</Ilosc> <Cena>31.50 PLN</Cena> </Pozycja> </Pozycje> </DokumentHandlowy> </session> W tym wypadku mamy tag Pozycje, który rozpoczyna listę w ramach której dla każdej pozycji jest oddzielny tag Pozycja. W podanym przykładzie wszystkie dane relacyjne (magazyn, kontrahent, towary) są identyfikowane za pomocą atrybutu where. 5.2 Płatności W przypadku płatności sytuacja wygląda podobnie jak w przypadku pozycji. Są jednak dwie istotne różnice Po pierwsze płatnośd w systemie może byd typu należnośd lub zobowiązanie. Oczywiście jeśli mówimy o fakturze sprzedaży, to wiemy, że chodzi nam o należnośd – ale z punktu widzenia konstrukcji pliku XML musi to byd jawnie zadeklarowane – stąd atrybut class w tagu Platnosc. Druga sprawa dotyczy edycji płatności. Zastanówmy się, jak działa program podczas edycji dokumentu handlowego (na formularzu) – w szczególności podczas dodawania pozycji i płatności na dokument. Jeżeli nie edytujemy ręcznie płatności, to za każdym razem gdy zmieniamy pozycje na dokumencie (np. dodajemy nową pozycję) program automatycznie zmienia wartośd płatności. W tym wypadku płatnośd na dokumencie jest jedna i automatycznie jej wartośd dostosowuje się do wartości dokumentu. Jeżeli natomiast dokonamy zmian na 8 zakładce płatności – np. „rozbijemy” płatnośd na dwie raty – to wówczas program przestaje dostosowywad wartośd płatności do wartości dokumentu i osoba edytująca płatności musi zadbad o to, żeby ich suma była zgodna z dokumentem. Jeżeli więc podczas importu najpierw dodamy pozycje do dokumentu, to automatycznie program utworzy płatnośd na dokumencie. I jeśli wtedy dodatkowo zaimportowane zostaną płatności z pliku XML, to spowoduje niezgodnośd wartości dokumentu z płatnościami (płatności będą zdublowane). Jeżeli w pliku XML chcemy umieścid płatności (np. informację o rozbiciu na raty), wówczas musimy najpierw zaimportowad te płatności a potem pozycje dokumentu. Aby zachowad taką kolejnośd importowania danych, kolejnośd tagów w pliku XML musi byd z nią zgodna (a więc – najpierw płatności, potem pozycje): <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy> <Definicja where="Symbol=FV" /> <Magazyn where="Symbol=F" /> <Data>2011-05-04</Data> <Numer>FV/000001/11</Numer> <Kontrahent where="Kod=Zefir" /> <Platnosci> <Platnosc class="Soneta.Kasa.Naleznosc,Soneta.Kasa"> <SposobZaplaty where="Nazwa=Przelew" /> <Kwota>100.00 PLN</Kwota> <TerminDni>7</TerminDni> </Platnosc> <Platnosc class="Soneta.Kasa.Naleznosc,Soneta.Kasa"> <SposobZaplaty where="Nazwa=Gotówka" /> <Kwota>27.31 PLN</Kwota> <TerminDni>0</TerminDni> </Platnosc> </Platnosci> <Pozycje> [...] </Pozycje> </DokumentHandlowy> </session> 6 Najprostszy plik importu Bazując na dotychczasowej wiedzy o sposobie inicjalizowania danych oraz identyfikacji danych relacyjnych spróbujmy utworzyd najprostszy możliwy plik, z którego można zaimportowad kompletny dokument faktury sprzedaży. Plik będzie utworzony dla bazy demo – a więc zakłada w bazie istnienie określonych kartotek kontrahenta i towaru: <?xml version="1.0" encoding="Unicode" ?> <session xmlns="http://www.soneta.pl/schema/business" business="true"> <DokumentHandlowy> <Definicja where="Symbol=FV" /> <Magazyn where="Symbol=F" /> <Kontrahent where="Kod=Zefir" /> <Pozycje> 9 <Pozycja> <Towar where="Kod=NAM_HOME1" /> </Pozycja> </Pozycje> </DokumentHandlowy> </session> Proszę zwrócid uwagę, że w pliku nie ma np. daty – zainicjalizowana zostanie data bieżąca. Dla pozycji podany jest wyłącznie towar – ilośd, cena i rabat zostaną zainicjalizowane domyślnie (tak, jakbyśmy dodawali nową pozycję do faktury z poziomu formularza). Nie ma również płatności – zostanie więc utworzona jedna płatnośd ze sposobem i terminem płatności domyślnym dla wskazanego kontrahenta. Taki uproszczony plik może stad się bazą do dodawania kolejnych informacji do importu – np. chcąc w pliku umieścid datę dokumentu (żeby został utworzony ze wskazaną datą a nie domyślnie z datą bieżącą) – należy dodad tag Data. Utworzone w ten sposób pliki XML mogą byd wykorzystywane np. do importu danych z zewnętrznego oprogramowania – omówione tu zasady można potraktowad jako ogólne zasady tworzenia plików wymiany danych (nie tylko dla dokumentów handlowych). Omawiane przykłady dotyczą bardzo prostych struktur danych – są to w większości pliki „minimalistyczne”. Rozbudowę tych struktur można uzyskad przez dodawanie kolejnych tagów zawierających wartości innych pól dokumentu. Warto zwrócid uwagę, że ponieważ nazwy tagów w pliku XML odpowiadają nazwom właściwości (property, albo mówiąc w uproszczeniu – nazwom pól na dokumencie), dla zidentyfikowania jakich nazw tagów można używad warto posłużyd się pomocniczo organizatorem listy: Inne podejście do tworzenia własnych plików XML polega na wyeksportowaniu z enova pełnych danych o interesującym nas zapisie i wzorowanie się na tak przygotowanym pliku. Należy jednak pamiętad, że funkcja Plik\Eksport danych tworzy pliki w trybie niebiznesowym (atrybut business="false" bądź nieustawiony), co oznacza, że struktura pliku będzie nieco inna od tej, która nas interesuje (w trybie biznesowym). 10 7 Podsumowanie i kontynuacja Przedstawiony dokument miał na celu zapoznanie z podstawowymi zasadami budowy plików XML wykorzystywanych do importu danych do systemu enova. Wszystkie omawiane przykłady dotyczyły importu dokumentu handlowego, ale ogólne zasady budowy plików XML są uniwersalne dla całego systemu enova. W kolejnym miesiącu w ramach kontynuowania tematu zostaną omówione: Import cech Import innych danych powiązanych (np. zapłaty, zaliczki) Uruchamianie importu z poziomu zewnętrznych dodatków 11