Projekt

Allgemein

Profil

710 Nexar API (Octopart) » Historie » Version 2

[X] Philipp Wolak, 17.07.2023 16:51

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 2 [X] Philipp Wolak
*** Funktion @nexar_import_epreisstaffel@ schreibt Preisstaffeln in Prodat Datenbank
230
{{collapse(SQL)
231
<pre><code class="sql">
232
CREATE OR REPLACE FUNCTION nexar_import_epreisstaffel(
233
      IN _prices          jsonb,
234
      IN _est_e_id        integer  DEFAULT null,
235
	  IN _est_aart_id     integer  DEFAULT null,
236
	  IN _est_aang_id     integer  DEFAULT null
237
    )
238
	RETURNS VOID AS $$
239
	DECLARE
240
	  _r            record;
241
	  _element      record;
242
	  _query_insert varchar;
243
	  _query_fields varchar;
244
	  _value        varchar;
245
	BEGIN
246
	
247
	  IF _est_e_id is null and _est_aart_id is null and _est_aang_id is null THEN
248
	    RAISE EXCEPTION 'Staffelpreise können nicht ohne Bezug angelegt werden';
249
	  END IF;
250
	  
251
	  -- Alte Staffel löschen
252
	  EXECUTE 'DELETE FROM epreisstaffel WHERE ' || coalesce(_est_e_id::varchar,'null') || ' = est_e_id OR ' || coalesce(_est_aart_id::varchar,'null') || ' = est_aart_id OR ' || coalesce(_est_aang_id::varchar,'null') || ' = est_aang_id';
253
	  
254
	  FOR _element IN
255
        SELECT jsonb_array_elements FROM jsonb_array_elements(_prices)
256
      LOOP
257
	  
258
	    _query_insert := 'INSERT INTO epreisstaffel (est_e_id, est_aart_id, est_aang_id, est_ep, est_mengevon) VALUES (' || coalesce(_est_e_id::varchar,'null') || ', ' || coalesce(_est_aart_id::varchar,'null') || ', ' || coalesce(_est_aang_id::varchar,'null');
259
	    _query_fields := '';
260
	
261
	    -- alle definierten Felder durchlaufen und Werte schreiben
262
	    FOR _r IN (
263
          SELECT nexm_json_path AS path,
264
	             nexar_mapping.*
265
            FROM nexar_mapping
266
           WHERE nexm_table = 'epreisstaffel'::regclass
267
		   ORDER BY nexm_column = 'est_ep'       desc,
268
		            nexm_column = 'est_mengevon' desc
269
          )
270
        LOOP
271
272
	      -- Wert für Feld aus JSON gemäß Setting-Tabelle ermitteln
273
		  SELECT get_dynamic_json_path(_element.jsonb_array_elements, _r.nexm_json_path)
274
	        INTO _value;
275
276
		  IF _value is null THEN
277
		    _value := 'null';
278
	      END IF;
279
	
280
	      -- Update Statement zusammenbauen und ausführen
281
		  _query_fields := _query_fields || ', ' || _value;
282
	 
283
	    END LOOP;
284
	  
285
	    -- Staffel schreiben
286
	    EXECUTE _query_insert || _query_fields || ')';
287
	  
288
	  END LOOP;
289
290
    END $$ LANGUAGE plpgsql;
291
</code></pre>
292
}}
293 1 [X] Philipp Wolak
* Aufrufen lässt sich die Anbindung über den Zauberstab