710 Nexar API (Octopart) » Historie » Version 1
[X] Philipp Wolak, 17.07.2023 12:37
1 | 1 | [X] Philipp Wolak | h1. 710 Nexar API (Octopart) |
---|---|---|---|
2 | |||
3 | h2. Voraussetzungen: |
||
4 | |||
5 | # Erstellung eines Login's unter https://portal.nexar.com/ |
||
6 | # Anlage einer Application unter https://portal.nexar.com/applications/ {{collapse(Aufklappen) |
||
7 | !clipboard-202307171146-bhcrl.png! |
||
8 | }} |
||
9 | # Eintragung von Client-ID und Client-Secret in den dynamischen Einstellungen in Prodat {{collapse(Aufklappen) |
||
10 | !clipboard-202307171150-g4qoe.png! |
||
11 | }} |
||
12 | |||
13 | h2. Implementierte Funktionen |
||
14 | |||
15 | * Artikelinformationen in Stammdaten übernehmen |
||
16 | * Preise ale Lieferantenanfrage übernehmen |
||
17 | |||
18 | h2. Technische Dokumentation |
||
19 | |||
20 | * Das Datenmodell der Nexar API: https://api.nexar.com/ui/voyager |
||
21 | |||
22 | * Für die Abfrage der API wird folgendes benötigt: |
||
23 | ** ein Token ... Dieser wird bei jeder Anfrage aus der Client-ID und dem Client-Secret erstellt. |
||
24 | Dies macht die Funktion @get_token()@ in @nexarClient.py@ |
||
25 | ** eine Abfrage-Query ... Beispiele für Abfragen sind hier zu finden: https://support.nexar.com/support/solutions/articles/101000472564-query-templates |
||
26 | ** (optional Variablen ... Diese werden in der Abfrage-Query eingefügt, z.B. MPN) |
||
27 | * Die API wird mit der Python-Funktion @results = nexar.get_query(query, variables)@ abgefragt |
||
28 | |||
29 | h1. Integration in Prodat |
||
30 | |||
31 | * {{collapse(Tabellenstruktur) |
||
32 | In der Tabelle @nexar_api_call@ lässt sich die Abfrage-Query je Prodat-Form definieren |
||
33 | <pre><code class="sql"> |
||
34 | CREATE TABLE nexar_api_call ( |
||
35 | nex_id SERIAL PRIMARY KEY, |
||
36 | nex_api text NOT NULL, -- Nexar Anfrage-Query |
||
37 | nex_ownerform VARCHAR(100) -- Prodat Form |
||
38 | ); |
||
39 | </code></pre> |
||
40 | |||
41 | In der Tabelle @nexar_mapping@ lässt sich definieren welche Werte aus den erhaltenen Daten wo gespeichert werden sollen |
||
42 | <pre><code class="sql"> |
||
43 | CREATE TABLE nexar_mapping ( |
||
44 | nexm_id SERIAL PRIMARY KEY, |
||
45 | nexm_json_psth VARCHAR(250) NOT NULL, -- Nexar Attribut |
||
46 | nexm_table regclass NOT NULL, -- Zieltabelle Prodat |
||
47 | nexm_column VARCHAR(100) NOT NULL -- Zielfeld Prodat |
||
48 | ); |
||
49 | </code></pre> |
||
50 | Bsp: |
||
51 | !clipboard-202307171217-esdg5.png! |
||
52 | |||
53 | In der Tabelle @link_import@ werden die Informationen zu einer durchgeführten Abfrage gespeichert. |
||
54 | <pre><code class="sql"> |
||
55 | CREATE TABLE link_import ( |
||
56 | li_id SERIAL PRIMARY KEY, |
||
57 | li_connector varchar(20) NOT NULL, -- Anbindung (z.B. Nexar) |
||
58 | li_ownerform varchar(100), -- Prodat Form |
||
59 | li_ownerform_var json, -- Prodat Variablen |
||
60 | li_api_call text NOT NULL, -- Anfrage-Query |
||
61 | li_api_call_var json, -- zusätzliche Variablen |
||
62 | li_result json NOT NULL -- Ergebnis |
||
63 | ); |
||
64 | </code></pre> |
||
65 | }} |
||
66 | * Funktionen |
||
67 | ** Die Funktion @connector_import_json@ ruft für eine durchgeführte Abfrage die passende Import-Funktion auf (aktuell nur auf Nexar beschränkt) |
||
68 | {{collapse(SQL) |
||
69 | <pre><code class="sql"> |
||
70 | CREATE OR REPLACE FUNCTION connector_import_json( |
||
71 | IN _li_id integer |
||
72 | ) |
||
73 | RETURNS VOID AS $$ |
||
74 | DECLARE |
||
75 | _r record; |
||
76 | _ak_nr varchar; |
||
77 | BEGIN |
||
78 | |||
79 | SELECT * |
||
80 | INTO _r |
||
81 | FROM link_import |
||
82 | WHERE li_id = _li_id; |
||
83 | |||
84 | -- Nexar |
||
85 | IF _r.li_connector = 'Nexar' THEN |
||
86 | |||
87 | -- Artikelnummer aus den Variablen holen |
||
88 | _ak_nr = _r.li_ownerform_var->>'ak_nr'; |
||
89 | |||
90 | -- JSON importieren |
||
91 | PERFORM nexar_import_json(_r.li_result, _ak_nr); |
||
92 | |||
93 | END IF; |
||
94 | |||
95 | END $$ LANGUAGE plpgsql; |
||
96 | </code></pre> |
||
97 | }} |
||
98 | ** Die Funktionen @get_dynamic_json_path@ ermitteln anhand eines JSON-Paths das passende Element |
||
99 | {{collapse(SQL) |
||
100 | <pre><code class="sql"> |
||
101 | CREATE OR REPLACE FUNCTION get_dynamic_json_path(json_data jsonb, path_parts varchar) |
||
102 | RETURNS jsonb AS $$ |
||
103 | DECLARE |
||
104 | path jsonb; |
||
105 | current_part text; |
||
106 | BEGIN |
||
107 | path := json_data; |
||
108 | current_part := path_parts; |
||
109 | |||
110 | IF current_part ~ '^\\d+$' THEN |
||
111 | -- JSON-Array-Element |
||
112 | path := path -> current_part::int; |
||
113 | ELSEIF current_part LIKE '$%' THEN |
||
114 | -- JSON-Path-Query |
||
115 | path := jsonb_path_query(path,current_part::JSONPATH); |
||
116 | ELSE |
||
117 | -- JSON-Objekt-Eigenschaft |
||
118 | path := path -> current_part; |
||
119 | END IF; |
||
120 | |||
121 | |||
122 | RETURN path; |
||
123 | END; |
||
124 | $$ LANGUAGE plpgsql; |
||
125 | |||
126 | |||
127 | CREATE OR REPLACE FUNCTION get_dynamic_json_path(json_data jsonb, path_parts varchar[]) |
||
128 | RETURNS jsonb AS $$ |
||
129 | DECLARE |
||
130 | path jsonb; |
||
131 | current_part text; |
||
132 | BEGIN |
||
133 | path := json_data; |
||
134 | |||
135 | FOREACH current_part IN ARRAY path_parts |
||
136 | LOOP |
||
137 | IF current_part ~ '^\\d+$' THEN |
||
138 | -- JSON-Array-Element |
||
139 | path := path -> current_part::int; |
||
140 | ELSEIF current_part LIKE '$%' THEN |
||
141 | -- JSON-Path-Query |
||
142 | path := jsonb_path_query(path,current_part::JSONPATH); |
||
143 | ELSE |
||
144 | -- JSON-Objekt-Eigenschaft |
||
145 | path := path -> current_part; |
||
146 | END IF; |
||
147 | END LOOP; |
||
148 | |||
149 | RETURN path; |
||
150 | END; |
||
151 | $$ LANGUAGE plpgsql; |
||
152 | </code></pre> |
||
153 | }} |
||
154 | ** Die Funktion @nexar_import_json@ schreibt die Werte der Nexar API in die Prodat Datenbank |
||
155 | {{collapse(SQL) |
||
156 | <pre><code class="sql"> |
||
157 | CREATE OR REPLACE FUNCTION nexar_import_json( |
||
158 | IN _results json, |
||
159 | IN _ak_nr varchar, |
||
160 | IN _write_to_art boolean DEFAULT true, |
||
161 | IN _write_to_epreis boolean DEFAULT true |
||
162 | ) |
||
163 | RETURNS VOID AS $$ |
||
164 | DECLARE |
||
165 | _seller varchar; |
||
166 | _seller_path varchar; |
||
167 | _inventory varchar; |
||
168 | _inventory_path varchar; |
||
169 | _r record; |
||
170 | _value varchar; |
||
171 | _query varchar; |
||
172 | BEGIN |
||
173 | |||
174 | -- Artikeldaten übernehmen |
||
175 | IF _write_to_art THEN |
||
176 | |||
177 | -- alle definierten Felder durchlaufen und Werte schreiben |
||
178 | FOR _r IN ( |
||
179 | SELECT nexm_json_path AS path, |
||
180 | nexar_mapping.* |
||
181 | FROM nexar_mapping |
||
182 | WHERE nexm_table = 'art'::regclass |
||
183 | ) |
||
184 | LOOP |
||
185 | |||
186 | -- Wert für Feld aus JSON gemäß Setting-Tabelle ermitteln |
||
187 | SELECT get_dynamic_json_path(_results::jsonb, _r.nexm_json_path) |
||
188 | INTO _value; |
||
189 | |||
190 | continue when _value is null OR _value = 'null'; |
||
191 | |||
192 | -- Update Statement zusammenbauen und ausführen |
||
193 | _query := 'UPDATE ' || _r.nexm_table::varchar || ' SET ' || _r.nexm_column::varchar || ' = ''' || _value || ''' WHERE ak_nr = ''' || _ak_nr || ''''; |
||
194 | EXECUTE _query; |
||
195 | |||
196 | END LOOP; |
||
197 | |||
198 | END IF; |
||
199 | |||
200 | -- Lieferantenpreise übernehmen |
||
201 | IF _write_to_epreis THEN |
||
202 | |||
203 | -- alle definierten Felder durchlaufen und Werte schreiben |
||
204 | FOR _r IN ( |
||
205 | SELECT nexm_json_path AS path, |
||
206 | nexar_mapping.* |
||
207 | FROM nexar_mapping |
||
208 | WHERE nexm_table = 'epreis'::regclass |
||
209 | ) |
||
210 | LOOP |
||
211 | |||
212 | /* |
||
213 | ToDo: |
||
214 | 1. Lieferanten aus Adressstamm mit Nexar ID holen |
||
215 | 2. Loop über alle relevanten Lieferanten (evt. sinnvoll einschränken?) |
||
216 | 2.1 passenden Eintrag in JSON zum Lieferant finden |
||
217 | 2.2 INSERT/UPDATE Statement zusammenbauen und ausführen |
||
218 | */ |
||
219 | |||
220 | END LOOP; |
||
221 | |||
222 | END IF; |
||
223 | |||
224 | |||
225 | |||
226 | END $$ LANGUAGE plpgsql; |
||
227 | </code></pre> |
||
228 | }} |
||
229 | * Aufrufen lässt sich die Anbindung über den Zauberstab |