{"id":9243,"date":"2024-02-23T08:50:12","date_gmt":"2024-02-23T07:50:12","guid":{"rendered":"https:\/\/pomoc.comarch.pl\/cee\/640\/?post_type=ht_kb&#038;p=9243"},"modified":"2025-05-14T12:25:10","modified_gmt":"2025-05-14T10:25:10","slug":"weryfikacja-podwojnych-adresow","status":"publish","type":"ht_kb","link":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/weryfikacja-podwojnych-adresow\/","title":{"rendered":"Weryfikacja zduplikowanych adres\u00f3w"},"content":{"rendered":"<h3 id=\"wprowadzenie\" >Wprowadzenie<\/h3>\n<p>W systemie adresy s\u0105 zapisywane w osobnej jednostce. Dzi\u0119ki temu mo\u017cliwe jest rozszerzanie atrybut\u00f3w typu <em>String<\/em> dost\u0119pnych w standardowym systemie i dodawanie nowych. Dodatkowo obs\u0142ugiwane s\u0105 kontrole duplikat\u00f3w i kontrole list wyklucze\u0144.<\/p>\n<p>W artykule wyja\u015bniono technicznie niezb\u0119dne atrybuty jednostki, om\u00f3wiono podstawowe klasy pomocnicze oraz spos\u00f3b, w jaki mo\u017cna przeprowadzi\u0107 kontrol\u0119 duplikat\u00f3w.<\/p>\n<h3 id=\"grupa-docelowa\" >Grupa docelowa<\/h3>\n<ul>\n<li>programi\u015bci<\/li>\n<\/ul>\n<h3 id=\"interfejs-programistyczny\" >Interfejs programistyczny<\/h3>\n<h4 id=\"model-danych\" >Model danych<\/h4>\n<p class=\"\" data-start=\"0\" data-end=\"234\">Adresy s\u0105 przechowywane w jednostce <em>com.cisag.app.general.obj.AddressData.<\/em> Atrybuty tej jednostki mo\u017cna podzieli\u0107 na dane u\u017cytkowe, takie jak ulica i miejscowo\u015b\u0107, oraz atrybuty wynikaj\u0105ce z wymog\u00f3w technicznych.<\/p>\n<p class=\"\" data-start=\"236\" data-end=\"270\">Technicznie niezb\u0119dne atrybuty to:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"border-style: outset;\">Atrybut<\/th>\n<th style=\"border-style: outset;\">Opis<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border-style: outset;\">guid<\/td>\n<td style=\"border-style: outset;\">Klucz g\u0142\u00f3wny.<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">hashCode<\/td>\n<td style=\"border-style: outset;\">Warto\u015b\u0107 liczbow\u0105 (hash), wyznaczona na podstawie danych u\u017cytkowych, do identyfikacji adresu. Cz\u0119\u015b\u0107 unikalnego klucza w procedurze HashCode (byPrevious).<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">previous<\/td>\n<td style=\"border-style: outset;\">Odwo\u0142anie do poprzedniej instancji o tym samym hashu. Cz\u0119\u015b\u0107 unikalnego klucza w procedurze HashCode (byPrevious).<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">next<\/td>\n<td style=\"border-style: outset;\">Odwo\u0142anie do nast\u0119pnej instancji o tym samym hashu<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">code<\/td>\n<td style=\"border-style: outset;\">Cz\u0119\u015b\u0107 klucza merytorycznego (byCode)<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">keyExtension<\/td>\n<td style=\"border-style: outset;\">Cz\u0119\u015b\u0107 klucza merytorycznego (byCode)<\/td>\n<\/tr>\n<tr>\n<td style=\"border-style: outset;\">backup<\/td>\n<td style=\"border-style: outset;\">Flaga rozr\u00f3\u017cniaj\u0105ca oryginalne adresy od kopii adres\u00f3w na potrzeby dokument\u00f3w<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Procedura HashCode u\u017cywana dla adres\u00f3w wyst\u0119puje r\u00f3wnie\u017c w innych miejscach w systemie i zapobiega tworzeniu identycznych rekord\u00f3w danych dla struktur danych bez merytorycznego klucza. Podczas zapisywania adresu, numer jest obliczany na podstawie danych u\u017cytkownika przy u\u017cyciu funkcji hash. Funkcja hash powinna unika\u0107 konfliktu warto\u015bci hash jesli tylko to jest mo\u017cliwe, aby zapewni\u0107 wysok\u0105 wydajno\u015b\u0107 procesu. Poniewa\u017c mimo to mog\u0105 istnie\u0107 inne adresy, dla kt\u00f3rych obliczono ten sam numer, najpierw podejmowana jest pr\u00f3ba za\u0142adowania takiego adresu przy u\u017cyciu unikalnego klucza (byPrevious: hashCode=? + previous=Guid.ZEROGUID). Je\u015bli adres z tym kluczem zostanie znaleziony, a jego zawarto\u015b\u0107 nie b\u0119dzie zgodna z zawarto\u015bci\u0105 adresu, kt\u00f3ry ma zosta\u0107 zapisany, wyszukiwany i sprawdzany jest nast\u0119pny adres, przy czym klucz g\u0142\u00f3wny wcze\u015bniej znalezionego adresu jest u\u017cywany jako poprzedni. Je\u015bli zostanie znaleziony ca\u0142kowicie identyczny adres, nie jest konieczne zapisywanie adresu; klucz g\u0142\u00f3wny istniej\u0105cego adresu jest u\u017cywany jako odniesienie. Je\u015bli nie znaleziono identycznego adresu, klucz g\u0142\u00f3wny ostatniego znalezionego adresu jest wprowadzany z t\u0105 sam\u0105 warto\u015bci\u0105 hash w poprzednim atrybucie nowego adresu i jest on zapisywany.<\/p>\n<p>W standardowym systemie adresy nie s\u0105 identyfikowane za pomoc\u0105 unikalnego kodu. Powinno by\u0107 jednak mo\u017cliwe zarz\u0105dzanie adresami za pomoc\u0105 merytorycznego klucza w ramach adaptacji (dostosowania). Wymagany do tego model danych jest dost\u0119pny w standardowym systemie i sk\u0142ada si\u0119 z dw\u00f3ch atrybut\u00f3w <em>code<\/em> i <em>keyExtension<\/em>, a tak\u017ce klucza biznesowego <em>byCode<\/em> (sk\u0142ada si\u0119 z code + keyExtension). Dla instancji <em>AddressData<\/em> utworzonych w systemie standardowym atrybut <em>code<\/em> zawiera pusty ci\u0105g znak\u00f3w. Aby jednak zapewni\u0107 unikalno\u015b\u0107 klucza <em>byCode<\/em>, klucz g\u0142\u00f3wny jest wprowadzany w atrybucie <em>keyExtension<\/em>. Oznacza to, \u017ce klucz jest unikalny, ale nie ma znaczenia dla standardu, poniewa\u017c jego zawarto\u015b\u0107 jest r\u00f3wnowa\u017cna kluczowi g\u0142\u00f3wnemu. Aby klucz m\u00f3g\u0142 by\u0107 u\u017cywany jako cz\u0119\u015b\u0107 adaptacji, atrybut keyExtension musi by\u0107 wype\u0142niony Guid.ZEROGUID i nale\u017cy okre\u015bli\u0107 unikalny kod do identyfikacji. W takim przypadku klucz <em>byPrevious<\/em> u\u017cywany w procedurze <em>hashCode<\/em> nie mo\u017ce by\u0107 ju\u017c stosowany. Atrybut <em>hashCode<\/em> musi zawiera\u0107 warto\u015bci\u0105 0, a atrybut <em>previous<\/em> musi posiada\u0107 warto\u015b\u0107 klucza g\u0142\u00f3wnego.<\/p>\n<p>Je\u015bli adresy s\u0105 identyfikowane za pomoc\u0105 unikalnego kodu, s\u0142u\u017cy to przede wszystkim do zarz\u0105dzania nimi lub ich zmiany. Zmiana adres\u00f3w nie mo\u017ce jednak prowadzi\u0107 do sytuacji, w kt\u00f3rej przy ponownym wydruku dokument\u00f3w, takich jak faktury sprzeda\u017cowe, zostanie wydrukowany inny adres ni\u017c w momencie generowania dokumentu. Dlatego u\u017cywanie modyfikowalnych adres\u00f3w w dokumentach nie jest dozwolone. Modyfikowalny adres musi najpierw zosta\u0107 przekszta\u0142cony w adres bez kodu i zapisany przy u\u017cyciu procedury <em>HashCode <\/em>(Snapshot). Tak powsta\u0142y niezmienny adres mo\u017ce by\u0107 u\u017cywany na dokumencie. W wyniku tego procesu powstaje zamierzony duplikat oryginalnego adresu. Aby u\u0142atwi\u0107 jego wykluczenie w ramach kontroli duplikat\u00f3w, flaga <em>backup <\/em>zostaje ustawiona na <em>true<\/em>.<\/p>\n<h4 id=\"klasy-pomocnicze\" >Klasy pomocnicze<\/h4>\n<article class=\"text-token-text-primary w-full\" dir=\"auto\" data-testid=\"conversation-turn-104\" data-scroll-anchor=\"true\">\n<div class=\"text-base my-auto mx-auto py-5 [--thread-content-margin:--spacing(4)] @[37rem]:[--thread-content-margin:--spacing(6)] @[72rem]:[--thread-content-margin:--spacing(16)] px-(--thread-content-margin)\">\n<div class=\"[--thread-content-max-width:32rem] @[34rem]:[--thread-content-max-width:40rem] @[64rem]:[--thread-content-max-width:48rem] mx-auto flex max-w-(--thread-content-max-width) flex-1 text-base gap-4 md:gap-5 lg:gap-6 group\/turn-messages focus-visible:outline-hidden\" tabindex=\"-1\">\n<div class=\"group\/conversation-turn relative flex w-full min-w-0 flex-col agent-turn\">\n<div class=\"relative flex-col gap-1 md:gap-3\">\n<div class=\"flex max-w-full flex-col grow\">\n<div class=\"min-h-8 text-message relative flex w-full flex-col items-end gap-2 text-start break-words whitespace-normal [.text-message+&amp;]:mt-5\" dir=\"auto\" data-message-author-role=\"assistant\" data-message-id=\"25921159-353e-4b34-a3d6-436e273624bf\" data-message-model-slug=\"gpt-4o\">\n<div class=\"flex w-full flex-col gap-1 empty:hidden first:pt-[3px]\">\n<div class=\"markdown prose dark:prose-invert w-full break-words light\">\n<p class=\"\" data-start=\"0\" data-end=\"77\">Do wykorzystania adres\u00f3w dost\u0119pne s\u0105 nast\u0119puj\u0105ce klasy pomocnicze:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/article>\n<div class=\"pointer-events-none h-px w-px\" aria-hidden=\"true\" data-edge=\"true\">\n<table style=\"width: 100%; height: 278px;\">\n<thead>\n<tr style=\"height: 23px;\">\n<th style=\"width: 50.2381%; border-style: outset; height: 23px;\">Klasa<\/th>\n<th style=\"width: 48.8095%; border-style: outset; height: 23px;\">Opis<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"height: 70px;\">\n<td style=\"width: 50.2381%; height: 70px; border-style: outset;\">com.cisag.app.general.log.HashCodeLogic<\/td>\n<td style=\"width: 48.8095%; height: 70px; border-style: outset;\">Realizuje procedur\u0119 HashCode i oferuje wsparcie dla migracji danych podczas zmiany funkcji hashuj\u0105cej.<\/td>\n<\/tr>\n<tr style=\"height: 46px;\">\n<td style=\"width: 50.2381%; height: 46px; border-style: outset;\">com.cisag.app.general.log.AddressDataAdapter<\/td>\n<td style=\"width: 48.8095%; height: 46px; border-style: outset;\">Udost\u0119pnia funkcj\u0119 hashuj\u0105c\u0105 niezb\u0119dn\u0105 do procedury HashCode.<\/td>\n<\/tr>\n<tr style=\"height: 116px;\">\n<td style=\"width: 50.2381%; height: 116px; border-style: outset;\">com.cisag.app.general.log.AddressDataValidation<\/td>\n<td style=\"width: 48.8095%; height: 116px; border-style: outset;\">S\u0142u\u017cy do sprawdzania poprawno\u015bci adresu. <section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Jednostka <em>AddressData <\/em>nie zawiera nazw, dlatego wywo\u0142ywanie kontroli duplikat\u00f3w bezpo\u015brednio z tej klasy zazwyczaj nie jest celowe.<\/div><\/section><\/td>\n<\/tr>\n<tr style=\"height: 23px;\">\n<td style=\"width: 50.2381%; height: 23px; border-style: outset;\">com.cisag.app.general.gui.AddressDataField<\/td>\n<td style=\"width: 48.8095%; height: 23px; border-style: outset;\">S\u0142u\u017cy do wprowadzania i wy\u015bwietlania adres\u00f3w.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Adres musi by\u0107 zawsze zapisany przy u\u017cyciu klasy HashCodeLogic:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">AddressDataAdapter adapter = AddressDataAdapter.getInstance();\n\nbyte[] guid = HashCodeLogic.getInstance().save(myAddress, adapter);\n\nmyBO.setAddress(guid);<\/pre>\n<section class=\"document-alert-box warning\"><div class=\"document-alert-title\">Uwaga<\/div><div class=\"document-alert-content\">Zmiana i zapisywanie danych u\u017cytkownika AddressData bezpo\u015brednio bez u\u017cycia klasy <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">HashCodeLogic <\/code>regularnie prowadzi do nieodwracalnego uszkodzenia danych!<\/div><\/section>\n<h3 id=\"sprawdzanie-duplikatow\" >Sprawdzanie duplikat\u00f3w<\/h3>\n<h4 id=\"uwagi-ogolne\" >Uwagi og\u00f3lne<\/h4>\n<p class=\"\" data-start=\"0\" data-end=\"237\">W kolejnych rozdzia\u0142ach opisano mo\u017cliwo\u015bci rozszerzenia o kontrole, takie jak sprawdzanie duplikat\u00f3w, sprawdzanie na li\u015bcie wyklucze\u0144 lub weryfikacja wyst\u0105pienia za po\u015brednictwem zewn\u0119trznych dostawc\u00f3w (np. poczta) w ramach dostosowa\u0144.<\/p>\n<p class=\"\" data-start=\"239\" data-end=\"711\">Zazwyczaj opisane kontrole nie s\u0105 wymagane ani po\u017c\u0105dane dla wszystkich adres\u00f3w w systemie. Przyk\u0142adowo, je\u015bli w aplikacji <em>Banki<\/em> zostanie przypisany adres, to ten sam adres powinien m\u00f3c zosta\u0107 przypisany tak\u017ce do partnera, je\u015bli oddzia\u0142 banku ma by\u0107 traktowany jako np. klient, kontakt. Ponadto kontrola duplikat\u00f3w lub sprawdzanie listy wyklucze\u0144 przy wprowadzaniu danych oddzia\u0142u banku prawdopodobnie nie jest po\u017c\u0105dane.<\/p>\n<p class=\"\" data-start=\"713\" data-end=\"845\">Przed dostosowaniem nale\u017cy zdefiniowa\u0107, w kt\u00f3rych aplikacjach kontrola ma si\u0119 odbywa\u0107 i jakie duplikaty s\u0105 niepo\u017c\u0105dane.<\/p>\n<p class=\"\" data-start=\"847\" data-end=\"1193\">W kolejnych rozdzia\u0142ach przedstawiono kontrole podczas wprowadzania nowego partnera oraz podczas wprowadzania adresu dla pseudopartnera w zam\u00f3wieniu sprzeda\u017cy. Zamiast bezpo\u015bredniego sprawdzenia w ramach og\u00f3lnych kontroli, weryfikacja istnienia mo\u017ce zosta\u0107 przeprowadzona tak\u017ce w p\u00f3\u017aniejszym terminie dla wielu nowych adres\u00f3w jednocze\u015bnie.<\/p>\n<p class=\"\" data-start=\"1195\" data-end=\"1383\">Dla obiektu biznesowego <em>com.cisag.app.general.obj.AddressData<\/em> czas utworzenia jest rejestrowany w cz\u0119\u015bci <em>updateInfo<\/em>, co pozwala na \u0142atwe ograniczenie sprawdzania do nowych adres\u00f3w.<\/p>\n<h4 id=\"dodawanie-nowego-partnera\" >Dodawanie nowego partnera<\/h4>\n<p>Po wprowadzeniu nowego partnera adres jest sprawdzany w klasie <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">com.cisag.app.general.partner.log.PartnerBaseValidation<\/code>. Klas\u0119 t\u0119 nale\u017cy r\u00f3wnie\u017c dostosowa\u0107, je\u015bli opr\u00f3cz standardowych kontroli ma zosta\u0107 przeprowadzona kontrola duplikat\u00f3w lub podobna. Metoda <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">validateCreate(PartnerBaseData)<\/code>powinna zosta\u0107 rozszerzona tak, aby kontrola by\u0142a przeprowadzana dla wszystkich &#8222;prawdziwych&#8221; partner\u00f3w, tj. pseudo partnerzy i szablony partner\u00f3w nie s\u0105 sprawdzane:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">PartnerBaseData base = ...\n\nPartnerValidation pv = PartnerValidation.getInstance();\n\nboolean pseudo = pv.isPseudoPartner(base.getPartnerObject());\n\nboolean template = base.getPartnerEntity().isTemplateMode();\n\nif (!pseudo &amp;&amp; !template) {\n\n...\n\n}<\/pre>\n<p>Nazwa regularnie wymagana do sprawdzania duplikat\u00f3w jest okre\u015blana na podstawie osoby lub organizacji w zale\u017cno\u015bci od typu:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Partner partner = base.getPartnerObject();\n\nif (partner.isHuman()) {\n\nPersonMutable person = partner.getMutablePerson();\n\nString name = person.getSurname();\n\n...\n\n} else {\n\nOrganisizationalUnitMutable ou =\n\npartner.getMutableOrganisationalUnit();\n\nString[] names = ou.getName();\n\n...\n\n}<\/pre>\n<p>Je\u015bli wy\u0142\u0105cznie dok\u0142adnie takie same adresy maj\u0105 by\u0107 rozpoznawane jako duplikaty, mo\u017cna u\u017cy\u0107 warto\u015bci hash wyznaczonej w standardzie do zaw\u0119\u017cenia zakresu adres\u00f3w do sprawdzenia. W przeciwnym razie zaleca si\u0119 wprowadzenie nowego atrybutu do wst\u0119pnej selekcji i odpowiednie indeksowanie podobnych adres\u00f3w za pomoc\u0105 odpowiedniego algorytmu.<\/p>\n<p>Poni\u017csza metoda okre\u015bla klucz g\u0142\u00f3wny dok\u0142adnie takiego samego adresu jako przyk\u0142ad. Zwr\u00f3con\u0105 warto\u015b\u0107 mo\u017cna nast\u0119pnie wykorzysta\u0107 m.in. do okre\u015blenia partner\u00f3w, do kt\u00f3rych przypisany jest potencjalnie ju\u017c istniej\u0105cy adres. Je\u015bli nazwa partnera do sprawdzenia pasuje do nazwy jednego z partner\u00f3w okre\u015blonych w ten spos\u00f3b, jest to duplikat.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">private byte[] findDuplicateCopy(AddressData address) {\n\nAddressDataAdapter adapter = AddressDataAdapter.getInstance();\n\nint hash = adapter.hashCode(data.getAddressData());\n\nbyte[] previous = Guid.ZEROGUID;\n\nwhile(true) {\n\nAddressData temp = (AddressData)\n\nom.getObject(AddressData.buildByPreviousKey(hash, previous));\n\nif (temp == null) return null;\n\nif (!temp.isBackup() &amp;&amp; equals(address, temp))\n\nreturn temp.getGuid();\n\nprevious = temp.getGuid();\n\n}\n\n}<\/pre>\n<p class=\"\" data-start=\"70\" data-end=\"440\">Nale\u017cy za\u0142o\u017cy\u0107, \u017ce funkcja hashuj\u0105ca rzadko wyznacza t\u0119 sam\u0105 warto\u015b\u0107 hash dla r\u00f3\u017cnych adres\u00f3w, co oznacza, \u017ce konflikty powinny wyst\u0119powa\u0107 sporadycznie. Dlatego zaleca si\u0119 \u0142adowanie adres\u00f3w pojedynczo za pomoc\u0105 unikalnego klucza <em>byPrevious<\/em>, zamiast u\u017cywania <em>CisObjectIterator <\/em>do jednoczesnego pobierania wszystkich adres\u00f3w o tym samym hashu.<\/p>\n<p class=\"\" data-start=\"442\" data-end=\"719\">Do por\u00f3wnywania adres\u00f3w nie mo\u017cna u\u017cywa\u0107 metody <em>contentEquals <\/em>z klasy <em>AddressData<\/em>, poniewa\u017c metoda ta por\u00f3wnuje r\u00f3wnie\u017c atrybuty techniczne, takie jak <em>hashCode<\/em>, <em>previous <\/em>itp. Zamiast tego por\u00f3wnanie danych u\u017cytkowych musi zosta\u0107 zaprogramowane w spos\u00f3b jawny.<\/p>\n<h4 id=\"pseudopartnerzy-na-zamowieniu-sprzedazy\" >Pseudopartnerzy na zam\u00f3wieniu sprzeda\u017cy<\/h4>\n<p>Kontrola duplikat\u00f3w dla pseudopartner\u00f3w na zam\u00f3wieniu sprzeda\u017cy powinna zapewni\u0107, \u017ce klient nie jest ju\u017c zarejestrowany jako &#8222;normalny&#8221; partner. Oznacza to, \u017ce nie mo\u017ce istnie\u0107 \u017caden partner, kt\u00f3rego nazwa i adres pasuj\u0105 do danych wprowadzonych na zam\u00f3wieniu.<\/p>\n<p>Domy\u015blnie adres klienta jest sprawdzany w klasie <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">com.cisag.app.sales.order.log.OrderHeaderValidation<\/code>. Metod\u0119 <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">validateCustomerData(Data)<\/code>mo\u017cna odpowiednio rozszerzy\u0107, dzi\u0119ki czemu sprawdzanie musi by\u0107 przeprowadzane tylko wtedy, gdy jest to pseudopartner:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Data header = ...\n\nPartner partner = header.getCustomer().retrievePartner();\n\nboolean pseudo =\n\nPartnerValidation.getInstance().isPseudoPartner(partner);<\/pre>\n<p>Nazwa wymagana do sprawdzenia jest zawarta w obiekcie <em>OrderCustomerDataInfo<\/em> (r\u00f3wnie\u017c obiekt biznesowy, kt\u00f3ry jest zarz\u0105dzany za pomoc\u0105 metody <em>HashCode<\/em>), a sam adres jest dost\u0119pny za po\u015brednictwem metody <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">getCustomerAddressData()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">String name = header.getCustomerData().getName();\n\nAddressData address = header.getCustomerAddressData();<\/pre>\n<p>Poniewa\u017c kontrola musi by\u0107 przeprowadzana tylko wtedy, gdy dane s\u0105 zmieniane, zaleca si\u0119 por\u00f3wnanie z danymi, kt\u00f3re s\u0105 ju\u017c w systemie. Dost\u0119p do nich mo\u017cna uzyska\u0107 za pomoc\u0105 funkcji <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">getPersistentCustomerData<\/code> lub <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">getPersistentCustomerAddressData().<\/code><\/p>\n<p>Podobnie jak w przypadku wprowadzania nowego partnera, duplikaty mo\u017cna okre\u015bli\u0107, najpierw identyfikuj\u0105c identyczne lub podobne adresy, a nast\u0119pnie por\u00f3wnuj\u0105c nazwy powi\u0105zanych partner\u00f3w.<\/p>\n<p>Adresy odbiorc\u00f3w dostaw i odbiorc\u00f3w faktur mog\u0105 by\u0107 sprawdzane w ten sam spos\u00f3b poprzez rozszerzenie metod <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">validateDeliveryCustomerData<\/code>\u00a0i <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">validateInvoiceCustomerData<\/code>.<\/p>\n","protected":false},"author":27,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"class_list":["post-9243","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-interfejsy-do-systemow-zarzadzania-przedsiebiorstwem"],"_links":{"self":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb"}],"about":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/comments?post=9243"}],"version-history":[{"count":4,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9243\/revisions"}],"predecessor-version":[{"id":30402,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9243\/revisions\/30402"}],"wp:attachment":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/media?parent=9243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}