att
This commit is contained in:
@@ -6,10 +6,16 @@ function defineStructure() {
|
||||
addColumn("sku");
|
||||
addColumn("brand");
|
||||
addColumn("ncmId");
|
||||
addColumn("categoria");
|
||||
}
|
||||
|
||||
function onSync(lastSyncDate) {}
|
||||
|
||||
var GB_TOKEN_URL = "https://api.grupoboticario.com.br/global/v2/jwt-token/token";
|
||||
var GB_STRATEGICS_URL = "https://api.grupoboticario.com.br/global/v1/franchising/gb-stores-data/product/classification/strategics";
|
||||
var DEFAULT_GB_CLIENT_ID = "88ymKwAUNfu06sD85i0RiokCxWGSkFBkx9ytgI5y1ZKxX3OQ";
|
||||
var DEFAULT_GB_CLIENT_SECRET = "YDFz43qAzL6ApNIKVCxu3dAmS9GWOqJbcc2aPnFDkmEaBXexSpsHGfcItg56i2dE";
|
||||
|
||||
function createDataset(fields, constraints, sortFields) {
|
||||
var dataset = DatasetBuilder.newDataset();
|
||||
dataset.addColumn("Code");
|
||||
@@ -19,6 +25,7 @@ function createDataset(fields, constraints, sortFields) {
|
||||
dataset.addColumn("sku");
|
||||
dataset.addColumn("brand");
|
||||
dataset.addColumn("ncmId");
|
||||
dataset.addColumn("categoria");
|
||||
|
||||
try {
|
||||
var filtro = parseConstraints(constraints);
|
||||
@@ -62,6 +69,8 @@ function createDataset(fields, constraints, sortFields) {
|
||||
|
||||
var searchNorm = normalize(filtro.search);
|
||||
var maxRows = filtro.maxRows;
|
||||
var categoryMap = null;
|
||||
var categoryDiag = "";
|
||||
|
||||
for (var i = 0; i < itens.length; i++) {
|
||||
var item = itens[i] || {};
|
||||
@@ -77,7 +86,17 @@ function createDataset(fields, constraints, sortFields) {
|
||||
var desc = trim(item.description);
|
||||
var codigoDescricao = code + " - " + desc;
|
||||
var brand = trim(item.brand);
|
||||
var blob = normalize([code, desc, brand, trim(item.id)].join(" "));
|
||||
var categoria = trim(item.strategicDescription || item.strategic_description || item.categoria);
|
||||
if (!categoria) {
|
||||
if (categoryMap == null) {
|
||||
var categorization = loadStrategicCategoryMap(constraints, 30000);
|
||||
categoryMap = categorization.map || {};
|
||||
categoryDiag = categorization.diag || "";
|
||||
}
|
||||
var strategicId = resolveStrategicId(item, code);
|
||||
categoria = resolveCategory(categoryMap, strategicId);
|
||||
}
|
||||
var blob = normalize([code, desc, brand, trim(item.id), categoria].join(" "));
|
||||
|
||||
if (searchNorm && searchNorm.length >= 2 && blob.indexOf(searchNorm) === -1) {
|
||||
continue;
|
||||
@@ -90,7 +109,8 @@ function createDataset(fields, constraints, sortFields) {
|
||||
desc,
|
||||
code,
|
||||
brand,
|
||||
trim(item.ncmId)
|
||||
trim(item.ncmId),
|
||||
categoria
|
||||
]);
|
||||
|
||||
if (dataset.rowsCount >= maxRows) {
|
||||
@@ -99,7 +119,8 @@ function createDataset(fields, constraints, sortFields) {
|
||||
}
|
||||
|
||||
if (dataset.rowsCount === 0) {
|
||||
addDiagRow(dataset, "Sem produtos apos filtros (busca: " + filtro.search + ")");
|
||||
var suffix = categoryDiag ? " | Categoria: " + categoryDiag : "";
|
||||
addDiagRow(dataset, "Sem produtos apos filtros (busca: " + filtro.search + ")" + suffix);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
@@ -126,9 +147,10 @@ function parseConstraints(constraints) {
|
||||
if (!c || !c.fieldName) continue;
|
||||
|
||||
var name = String(c.fieldName);
|
||||
var lowerName = name.toLowerCase();
|
||||
var value = cleanSearchValue(c.initialValue);
|
||||
|
||||
if (name === "sqlLimit") {
|
||||
if (lowerName === "sqllimit") {
|
||||
var n = parseInt(value, 10);
|
||||
if (!isNaN(n) && n > 0 && n <= 1000) {
|
||||
out.maxRows = n;
|
||||
@@ -138,9 +160,13 @@ function parseConstraints(constraints) {
|
||||
|
||||
if (
|
||||
value &&
|
||||
name !== "metadata#id" &&
|
||||
name !== "metadata#active" &&
|
||||
name !== "sqlLimit"
|
||||
lowerName !== "metadata#id" &&
|
||||
lowerName !== "metadata#active" &&
|
||||
lowerName !== "sqllimit" &&
|
||||
lowerName !== "gbclientid" &&
|
||||
lowerName !== "gbclientsecret" &&
|
||||
lowerName !== "clientid" &&
|
||||
lowerName !== "clientsecret"
|
||||
) {
|
||||
if (!out.search || value.length > out.search.length) {
|
||||
out.search = value;
|
||||
@@ -209,6 +235,205 @@ function extractItems(obj) {
|
||||
return [];
|
||||
}
|
||||
|
||||
function getConstraintValue(constraints, fieldName) {
|
||||
if (!constraints || !fieldName) return "";
|
||||
var target = String(fieldName).toLowerCase();
|
||||
for (var i = 0; i < constraints.length; i++) {
|
||||
var c = constraints[i];
|
||||
if (!c || !c.fieldName) continue;
|
||||
if (String(c.fieldName).toLowerCase() === target) {
|
||||
return c.initialValue;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function resolveGbCredentials(constraints) {
|
||||
var clientId = trim(getConstraintValue(constraints, "gbClientId"));
|
||||
if (!clientId) clientId = trim(getConstraintValue(constraints, "clientId"));
|
||||
if (!clientId) {
|
||||
try { clientId = trim(java.lang.System.getenv("GB_CLIENT_ID")); } catch (e1) {}
|
||||
}
|
||||
if (!clientId) clientId = DEFAULT_GB_CLIENT_ID;
|
||||
|
||||
var clientSecret = trim(getConstraintValue(constraints, "gbClientSecret"));
|
||||
if (!clientSecret) clientSecret = trim(getConstraintValue(constraints, "clientSecret"));
|
||||
if (!clientSecret) {
|
||||
try { clientSecret = trim(java.lang.System.getenv("GB_CLIENT_SECRET")); } catch (e2) {}
|
||||
}
|
||||
if (!clientSecret) clientSecret = DEFAULT_GB_CLIENT_SECRET;
|
||||
|
||||
return {
|
||||
clientId: clientId,
|
||||
clientSecret: clientSecret
|
||||
};
|
||||
}
|
||||
|
||||
function loadStrategicCategoryMap(constraints, timeoutMs) {
|
||||
var out = { map: {}, diag: "" };
|
||||
|
||||
var creds = resolveGbCredentials(constraints);
|
||||
if (!creds.clientId || !creds.clientSecret) {
|
||||
out.diag = "credenciais ausentes";
|
||||
return out;
|
||||
}
|
||||
|
||||
var tokenResp = requestGbToken(creds, timeoutMs || 30000);
|
||||
if (!tokenResp.token) {
|
||||
out.diag = tokenResp.diag || "falha ao obter token";
|
||||
return out;
|
||||
}
|
||||
|
||||
var strategicsResp = requestStrategics(tokenResp.token, timeoutMs || 30000);
|
||||
var strategics = strategicsResp.items || [];
|
||||
if (!strategics.length) {
|
||||
out.diag = strategicsResp.diag || "sem classificacoes";
|
||||
return out;
|
||||
}
|
||||
|
||||
for (var i = 0; i < strategics.length; i++) {
|
||||
var item = strategics[i] || {};
|
||||
var id = trim(item.strategicId || item.strategicID || item.id || item.code);
|
||||
var descricao = trim(item.description || item.descricao || item.category || item.name);
|
||||
if (!id || !descricao) continue;
|
||||
out.map[id] = descricao;
|
||||
}
|
||||
|
||||
if (!hasOwnKeys(out.map)) {
|
||||
out.diag = "classificacoes sem strategicId/description";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function requestGbToken(creds, timeoutMs) {
|
||||
var timeout = timeoutMs || 30000;
|
||||
var body = "client_id=" + urlEncode(creds.clientId) +
|
||||
"&client_secret=" + urlEncode(creds.clientSecret);
|
||||
|
||||
var attempts = [
|
||||
{
|
||||
name: "post-query-body",
|
||||
method: "POST",
|
||||
url: GB_TOKEN_URL + "?grant_type=client_credentials",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: body
|
||||
}
|
||||
];
|
||||
|
||||
var trace = [];
|
||||
for (var i = 0; i < attempts.length; i++) {
|
||||
var attempt = attempts[i];
|
||||
var resp = httpRequest(attempt.url, attempt.method, attempt.headers, attempt.body, timeout);
|
||||
trace.push(attempt.name + ":" + trim(resp.status));
|
||||
var parsed = normalizeApiBody(resp.body);
|
||||
var token = trim(parsed && (parsed.access_token || parsed.accessToken || parsed.token));
|
||||
if (token) {
|
||||
return { token: token, diag: "token ok (" + attempt.name + ")" };
|
||||
}
|
||||
}
|
||||
|
||||
return { token: "", diag: "token falhou [" + trace.join(" | ") + "]" };
|
||||
}
|
||||
|
||||
function requestStrategics(accessToken, timeoutMs) {
|
||||
var resp = httpRequest(
|
||||
GB_STRATEGICS_URL,
|
||||
"GET",
|
||||
{
|
||||
"Accept": "application/json",
|
||||
"Authorization": "Bearer " + trim(accessToken)
|
||||
},
|
||||
"",
|
||||
timeoutMs || 30000
|
||||
);
|
||||
|
||||
var parsed = normalizeApiBody(resp.body);
|
||||
var items = extractItems(parsed);
|
||||
if ((!items || !items.length) && parsed && parsed.items instanceof Array) {
|
||||
items = parsed.items;
|
||||
}
|
||||
if ((!items || !items.length) && parsed && parsed.strategics instanceof Array) {
|
||||
items = parsed.strategics;
|
||||
}
|
||||
|
||||
if (!items || !items.length) {
|
||||
return { items: [], diag: "strategics HTTP " + trim(resp.status) };
|
||||
}
|
||||
|
||||
return { items: items, diag: "ok" };
|
||||
}
|
||||
|
||||
function resolveStrategicId(item, fallbackCode) {
|
||||
var candidates = [
|
||||
item && item.strategicId,
|
||||
item && item.strategicID,
|
||||
item && item.classificationStrategicId,
|
||||
item && item.productStrategicId,
|
||||
item && item.estrategicId,
|
||||
item && item.strategyId,
|
||||
item && item.code,
|
||||
fallbackCode
|
||||
];
|
||||
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var value = trim(candidates[i]);
|
||||
if (value) return value;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function resolveCategory(map, strategicId) {
|
||||
var id = trim(strategicId);
|
||||
if (!id || !map) return "";
|
||||
|
||||
if (map.hasOwnProperty(id)) {
|
||||
return trim(map[id]);
|
||||
}
|
||||
|
||||
var asInt = parseInt(id, 10);
|
||||
if (!isNaN(asInt)) {
|
||||
var normalized = String(asInt);
|
||||
if (map.hasOwnProperty(normalized)) {
|
||||
return trim(map[normalized]);
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function normalizeApiBody(text) {
|
||||
var obj = parseJsonSafe(text);
|
||||
if (!obj) return null;
|
||||
|
||||
if (obj.content && typeof obj.content === "string") {
|
||||
var parsedContent = parseJsonSafe(obj.content);
|
||||
if (parsedContent) return parsedContent;
|
||||
}
|
||||
|
||||
if (obj.result && typeof obj.result === "string") {
|
||||
var parsedResult = parseJsonSafe(obj.result);
|
||||
if (parsedResult) return parsedResult;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function hasOwnKeys(obj) {
|
||||
for (var k in obj) {
|
||||
if (obj.hasOwnProperty(k)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function urlEncode(value) {
|
||||
return String(java.net.URLEncoder.encode(String(value || ""), "UTF-8"));
|
||||
}
|
||||
|
||||
function addDiagRow(dataset, msg) {
|
||||
dataset.addRow([
|
||||
"DEBUG",
|
||||
@@ -223,23 +448,53 @@ function addDiagRow(dataset, msg) {
|
||||
}
|
||||
|
||||
function fetchDirect(url, timeoutMs) {
|
||||
return httpRequest(
|
||||
url,
|
||||
"GET",
|
||||
{ "Accept": "application/json" },
|
||||
"",
|
||||
timeoutMs || 30000
|
||||
);
|
||||
}
|
||||
|
||||
function httpRequest(url, method, headers, body, timeoutMs) {
|
||||
var conn = null;
|
||||
var reader = null;
|
||||
var writer = null;
|
||||
try {
|
||||
var URL = java.net.URL;
|
||||
var HttpURLConnection = java.net.HttpURLConnection;
|
||||
var InputStreamReader = java.io.InputStreamReader;
|
||||
var BufferedReader = java.io.BufferedReader;
|
||||
var OutputStreamWriter = java.io.OutputStreamWriter;
|
||||
var StringBuilder = java.lang.StringBuilder;
|
||||
|
||||
conn = new URL(url).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(timeoutMs || 30000);
|
||||
conn.setReadTimeout(timeoutMs || 30000);
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
var httpMethod = String(method || "GET").toUpperCase();
|
||||
var timeout = timeoutMs || 30000;
|
||||
var payload = body == null ? "" : String(body);
|
||||
|
||||
var status = conn.getResponseCode();
|
||||
var stream = (status >= 200 && status < 300) ? conn.getInputStream() : conn.getErrorStream();
|
||||
conn = new URL(url).openConnection();
|
||||
conn.setRequestMethod(httpMethod);
|
||||
conn.setConnectTimeout(timeout);
|
||||
conn.setReadTimeout(timeout);
|
||||
|
||||
if (headers) {
|
||||
for (var h in headers) {
|
||||
if (!headers.hasOwnProperty(h)) continue;
|
||||
if (headers[h] == null || headers[h] === "") continue;
|
||||
conn.setRequestProperty(String(h), String(headers[h]));
|
||||
}
|
||||
}
|
||||
|
||||
if (payload && (httpMethod === "POST" || httpMethod === "PUT" || httpMethod === "PATCH")) {
|
||||
conn.setDoOutput(true);
|
||||
writer = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
|
||||
writer.write(payload);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
var statusCode = conn.getResponseCode();
|
||||
var status = String(statusCode);
|
||||
var stream = (statusCode >= 200 && statusCode < 300) ? conn.getInputStream() : conn.getErrorStream();
|
||||
if (stream == null) {
|
||||
return { status: status, body: "" };
|
||||
}
|
||||
@@ -251,14 +506,12 @@ function fetchDirect(url, timeoutMs) {
|
||||
sb.append(line);
|
||||
}
|
||||
|
||||
return {
|
||||
status: status,
|
||||
body: String(sb.toString())
|
||||
};
|
||||
return { status: status, body: String(sb.toString()) };
|
||||
} catch (e) {
|
||||
return { status: 0, body: "" };
|
||||
return { status: "", body: "" };
|
||||
} finally {
|
||||
try { if (reader) reader.close(); } catch (e1) {}
|
||||
try { if (conn) conn.disconnect(); } catch (e2) {}
|
||||
try { if (writer) writer.close(); } catch (e1) {}
|
||||
try { if (reader) reader.close(); } catch (e2) {}
|
||||
try { if (conn) conn.disconnect(); } catch (e3) {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user