diff --git a/Transferência Ginseng/.vscode/servers.json b/Transferência Ginseng/.vscode/servers.json index b3a4066..4a764ca 100644 --- a/Transferência Ginseng/.vscode/servers.json +++ b/Transferência Ginseng/.vscode/servers.json @@ -2,13 +2,13 @@ "version": "1.0.0", "configurations": [ { - "id": "1v6yi27yg82mmzgeg2todjqzi42g7", + "id": "5i6o3b75rrmmn0z5dbms6ldputs2v", "name": "teste", "host": "comerciode188007.fluig.cloudtotvs.com.br", "ssl": true, "port": 443, "username": "andrey.cunha", - "password": "eyJpdiI6Ijk2Mzg4MGUwODVkYTVkZmI0YjQ2ZTdmNmNlYTJlMGI2Iiwic2FsdCI6ImI0ODMzZTAyNDkxNWYzNGFkNDVkYjE5ZThkMGNlOTM3IiwidGV4dCI6IjY3NDBmZjM2MTE1YjhiODAyM2IzYjVjZDYyYzEwYWRiIn0=", + "password": "eyJpdiI6ImE1ZmNlY2U2NjVlMjFlMzJiM2U1NzFjM2RlNTU3NDQyIiwic2FsdCI6ImU5ZDQ5MWUzNjA5OWZmYmFlZjgxZTRmODFmM2M1ZDNlIiwidGV4dCI6IjRkYTIxY2E1Mjg0ZDkxNTkzZTk0MTliYTljZGQ1ZjUzIn0=", "userCode": "andrey.cunha", "confirmExporting": false, "hasBrowser": false, diff --git a/Transferência Ginseng/.vscode/settings.json b/Transferência Ginseng/.vscode/settings.json index 6def96a..aa86c45 100644 --- a/Transferência Ginseng/.vscode/settings.json +++ b/Transferência Ginseng/.vscode/settings.json @@ -1,3 +1,4 @@ { - "totvsLanguageServer.welcomePage": false + "totvsLanguageServer.welcomePage": false, + "totvsLanguageServer.editor.linter.includes": "C:\\25-04-14-P12-SMARTCLIENT_BUILD 20.3.2.12_WINDOWS_X64\\include" } \ No newline at end of file diff --git a/Transferência Ginseng/datasets/ds_LojasTransfteste.js b/Transferência Ginseng/datasets/ds_LojasTransf.js similarity index 98% rename from Transferência Ginseng/datasets/ds_LojasTransfteste.js rename to Transferência Ginseng/datasets/ds_LojasTransf.js index d6c4ad9..1273d55 100644 --- a/Transferência Ginseng/datasets/ds_LojasTransfteste.js +++ b/Transferência Ginseng/datasets/ds_LojasTransf.js @@ -18,7 +18,7 @@ function createDataset(fields, constraints, sortFields) { var clientService = fluigAPI.getAuthorizeClientService(); var data = { companyId: String(getValue("WKCompany") || "1"), - serviceCode: "GINSENG APITESTE", // ajuste para o codigo do servico cadastrado no Fluig + serviceCode: "GINSENG API", // ajuste para o codigo do servico cadastrado no Fluig endpoint: "/base_pdvs", method: "get", timeoutService: "60000", diff --git a/Transferência Ginseng/datasets/ds_fiscal_invoice_by_keys.js b/Transferência Ginseng/datasets/ds_fiscal_invoice_by_keys.js index ad4ffc2..259ac84 100644 --- a/Transferência Ginseng/datasets/ds_fiscal_invoice_by_keys.js +++ b/Transferência Ginseng/datasets/ds_fiscal_invoice_by_keys.js @@ -236,7 +236,7 @@ function invokeAuthorizedGet(clientService, endpoint, auth) { var data = { companyId: String(getValue("WKCompany") || "1"), - serviceCode: "GINSENG APITESTE", + serviceCode: "GinsengAPI2", endpoint: endpoint, method: "get", timeoutService: "30000", diff --git a/Transferência Ginseng/datasets/ds_rgb_products.js b/Transferência Ginseng/datasets/ds_rgb_products.js index 0fc0eb6..a9daf36 100644 --- a/Transferência Ginseng/datasets/ds_rgb_products.js +++ b/Transferência Ginseng/datasets/ds_rgb_products.js @@ -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) {} } } diff --git a/Transferência Ginseng/datasets/ds_rgb_products_v2.js b/Transferência Ginseng/datasets/ds_rgb_products_v2.js new file mode 100644 index 0000000..cf0783c --- /dev/null +++ b/Transferência Ginseng/datasets/ds_rgb_products_v2.js @@ -0,0 +1,517 @@ +function defineStructure() { + addColumn("Code"); + addColumn("Description"); + addColumn("codigoDescricao"); + addColumn("descricao"); + 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"); + dataset.addColumn("Description"); + dataset.addColumn("codigoDescricao"); + dataset.addColumn("descricao"); + dataset.addColumn("sku"); + dataset.addColumn("brand"); + dataset.addColumn("ncmId"); + dataset.addColumn("categoria"); + + try { + var filtro = parseConstraints(constraints); + var clientService = fluigAPI.getAuthorizeClientService(); + var data = { + companyId: String(getValue("WKCompany") || "1"), + serviceCode: "GINSENG APITESTE", + endpoint: "/dados_rgb_products", + method: "get", + timeoutService: "60000", + params: {} + }; + + var vo = clientService.invoke(JSON.stringify(data)); + var statusHttp = vo ? String(vo.getHttpStatusResult() || "") : ""; + var retorno = vo ? String(vo.getResult() || "") : ""; + + // Fallback: se o servico integrado estiver com endpoint/base incorreto, chama URL direta. + if (statusHttp !== "200" || !retorno) { + var direct = fetchDirect("https://api.grupoginseng.com.br/dados_rgb_products", 60000); + statusHttp = String(direct.status || statusHttp); + retorno = direct.body || retorno; + } + + if (!retorno) { + addDiagRow(dataset, "Sem retorno da API (HTTP " + statusHttp + ")"); + return dataset; + } + + var obj = parseJsonSafe(retorno); + if (!obj) { + addDiagRow(dataset, "Falha no JSON da API (HTTP " + statusHttp + ")"); + return dataset; + } + + var itens = extractItems(obj); + if (!itens || !itens.length) { + addDiagRow(dataset, "API sem itens (HTTP " + statusHttp + ")"); + return dataset; + } + + 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] || {}; + + if (item.discontinued === true) { + continue; + } + if (item.purchaseBlocked === true) { + continue; + } + + var code = trim(item.sku); + var desc = trim(item.description); + var codigoDescricao = code + " - " + desc; + var brand = trim(item.brand); + 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; + } + + dataset.addRow([ + code, + desc, + codigoDescricao, + desc, + code, + brand, + trim(item.ncmId), + categoria + ]); + + if (maxRows > 0 && dataset.rowsCount >= maxRows) { + break; + } + } + + if (dataset.rowsCount === 0) { + var suffix = categoryDiag ? " | Categoria: " + categoryDiag : ""; + addDiagRow(dataset, "Sem produtos apos filtros (busca: " + filtro.search + ")" + suffix); + } + + } catch (e) { + addDiagRow(dataset, "Erro ao consultar API: " + e); + } + + return dataset; +} + +function onMobileSync(user) {} + +function parseConstraints(constraints) { + var out = { + search: "", + maxRows: 0 + }; + + if (!constraints) { + return out; + } + + for (var i = 0; i < constraints.length; i++) { + var c = constraints[i]; + if (!c || !c.fieldName) continue; + + var name = String(c.fieldName); + var lowerName = name.toLowerCase(); + var value = cleanSearchValue(c.initialValue); + + if (lowerName === "sqllimit") { + var n = parseInt(trim(c.initialValue), 10); + if (!isNaN(n) && n > 0) { + out.maxRows = n; + } + continue; + } + + if ( + value && + 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; + } + } + } + + return out; +} + +function cleanSearchValue(v) { + var s = trim(v); + s = s.replace(/[%*_]/g, ""); + // Evita que flags comuns do Fluig virem termo de busca + if (s === "true" || s === "false" || s === "on" || s === "off" || s === "1") { + return ""; + } + return trim(s); +} + +function normalize(v) { + return trim(v).toLowerCase(); +} + +function trim(v) { + return String(v == null ? "" : v).trim(); +} + +function parseJsonSafe(text) { + try { + return JSON.parse(text); + } catch (e) { + return null; + } +} + +function extractItems(obj) { + if (!obj) return []; + if (obj instanceof Array) return obj; + if (obj.data && obj.data instanceof Array) return obj.data; + + if (obj.content) { + if (obj.content instanceof Array) return obj.content; + if (typeof obj.content === "string") { + var parsedContent = parseJsonSafe(obj.content); + if (parsedContent && parsedContent.data && parsedContent.data instanceof Array) { + return parsedContent.data; + } + if (parsedContent && parsedContent instanceof Array) { + return parsedContent; + } + } + if (obj.content.data && obj.content.data instanceof Array) return obj.content.data; + } + + if (obj.result) { + if (obj.result instanceof Array) return obj.result; + if (typeof obj.result === "string") { + var parsedResult = parseJsonSafe(obj.result); + if (parsedResult && parsedResult.data && parsedResult.data instanceof Array) { + return parsedResult.data; + } + } + } + + 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", + String(msg), + String(msg), + String(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 InputStreamReader = java.io.InputStreamReader; + var BufferedReader = java.io.BufferedReader; + var OutputStreamWriter = java.io.OutputStreamWriter; + var StringBuilder = java.lang.StringBuilder; + + var httpMethod = String(method || "GET").toUpperCase(); + var timeout = timeoutMs || 30000; + var payload = body == null ? "" : String(body); + + 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: "" }; + } + + reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + var sb = new StringBuilder(); + var line = null; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + + return { status: status, body: String(sb.toString()) }; + } catch (e) { + return { status: "", body: "" }; + } finally { + try { if (writer) writer.close(); } catch (e1) {} + try { if (reader) reader.close(); } catch (e2) {} + try { if (conn) conn.disconnect(); } catch (e3) {} + } +} diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/.metadata b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/.metadata index d744d9a..0a702dd 100644 Binary files a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/.metadata and b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/.metadata differ diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/events/validateForm.js b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/events/validateForm.js index c0f4550..f99f2af 100644 --- a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/events/validateForm.js +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/events/validateForm.js @@ -95,6 +95,10 @@ function validateForm(form) { message += getMessage("Data da entrega", 1, form); hasErros = true; } + if (String(form.getValue("nomerecebedor") || "").trim() == "") { + message += getMessage("Nome de quem recebeu a mercadoria", 1, form); + hasErros = true; + } break; case RECEBIMENTO: diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/excel.js b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/excel.js index e1d8155..893d865 100644 --- a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/excel.js +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/excel.js @@ -97,6 +97,7 @@ function processarArquivoExcel(file) { var codigo = getCellByAliases(item, ["codigoItem", "codigo", "codItem", "sku", "code", "item"]); var quantidade = getCellByAliases(item, ["quantidadeItem", "quantidade", "qtd", "qtde"]); var descricao = getCellByAliases(item, ["descricao", "description", "desc"]); + var categoria = getCellByAliases(item, ["categoria", "category"]); if (!codigo || !quantidade) { return; @@ -105,7 +106,8 @@ function processarArquivoExcel(file) { linhasValidas.push({ codigo: String(codigo).trim(), quantidade: String(quantidade).trim(), - descricao: String(descricao || "").trim() + descricao: String(descricao || "").trim(), + categoria: String(categoria || "").trim() }); }); @@ -141,6 +143,11 @@ function processarArquivoExcel(file) { if (descricaoFinal) { $("#codigoItem___" + idx).val(descricaoFinal); } + + var categoriaFinal = item.categoria || produtoInfo.categoria; + if (categoriaFinal) { + $("#categoriaItem___" + idx).val(categoriaFinal); + } }); if (typeof processarConferenciaNfe === "function") { @@ -192,16 +199,16 @@ function normalizeHeader(text) { function buscarProdutoPorCodigo(codigo) { try { if (typeof DatasetFactory === "undefined" || typeof ConstraintType === "undefined") { - return { descricao: "", id: "" }; + return { descricao: "", id: "", categoria: "" }; } var codigoTxt = String(codigo || "").trim(); - if (!codigoTxt) return { descricao: "", id: "" }; + if (!codigoTxt) return { descricao: "", id: "", categoria: "" }; var cCodigo = DatasetFactory.createConstraint("Code", codigoTxt, codigoTxt, ConstraintType.MUST); - var ds = DatasetFactory.getDataset("ds_rgb_products", null, [cCodigo], null); + var ds = DatasetFactory.getDataset("ds_rgb_products_v2", null, [cCodigo], null); if (!ds || !ds.values || !ds.values.length) { - return { descricao: "", id: "" }; + return { descricao: "", id: "", categoria: "" }; } for (var i = 0; i < ds.values.length; i++) { @@ -209,7 +216,8 @@ function buscarProdutoPorCodigo(codigo) { if (String(row.Code || "").trim() === codigoTxt) { return { descricao: String(row.descricao || row.Description || "").trim(), - id: String(row.id || "").trim() + id: String(row.id || "").trim(), + categoria: String(row.categoria || row.strategicDescription || "").trim() }; } } @@ -217,11 +225,12 @@ function buscarProdutoPorCodigo(codigo) { var first = ds.values[0] || {}; return { descricao: String(first.descricao || first.Description || "").trim(), - id: String(first.id || "").trim() + id: String(first.id || "").trim(), + categoria: String(first.categoria || first.strategicDescription || "").trim() }; } catch (e) { console.error("Erro ao buscar descricao por codigo:", e); - return { descricao: "", id: "" }; + return { descricao: "", id: "", categoria: "" }; } } diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/script.js b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/script.js index ece38a2..535fd70 100644 --- a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/script.js +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/script.js @@ -49,13 +49,15 @@ $(document).ready(function () { processarConferenciaNfe(); }); + var activity = String($("#activity").val() || ""); + applyTransferStatus(activity); + if ($("#formMode").val() == "VIEW") { showAndBlock(["all"]); $("#btnConsultarChaveNfe").prop("disabled", true).hide(); - updateConferenciaNfeVisibility($("#activity").val()); + updateConferenciaNfeVisibility(activity); } else { //show the right fields - var activity = $("#activity").val(); var requestDate = getCurrentDate(); if (String(activity) !== "6") { @@ -209,6 +211,40 @@ $(document).ready(function () { }); +function applyTransferStatus(activity) { + var current = String(activity || ""); + var pills = $("#transferStatus .status-pill"); + if (!pills.length) return; + + pills.removeClass("is-active is-done"); + + var activeOrder = -1; + pills.each(function () { + var pill = $(this); + var activities = String(pill.attr("data-activities") || "").split(","); + for (var i = 0; i < activities.length; i++) { + if ($.trim(activities[i]) === current) { + pill.addClass("is-active"); + var order = parseInt(pill.attr("data-order"), 10); + if (!isNaN(order)) { + activeOrder = order; + } + break; + } + } + }); + + if (activeOrder < 0) return; + + pills.each(function () { + var pill = $(this); + var order = parseInt(pill.attr("data-order"), 10); + if (!isNaN(order) && order < activeOrder) { + pill.addClass("is-done"); + } + }); +} + function resolveFormModeFallback() { var mode = ($("#formMode").val() || "").toUpperCase(); if (mode) return mode; @@ -353,30 +389,67 @@ function clearZoomField(fieldId) { $("#" + fieldId).val(""); } -var MOTORISTAS_GROUP_ID = "Motoristas"; -var motoristasEntregaCache = null; -var motoristasEntregaLoading = false; +var MOTORISTAS_GROUP_DEFAULT_ID = "Motoristas"; +var MOTORISTAS_GROUP_BY_UF = { + AL: "motoristaAL", + BA: "motoristaBA", + SE: "motoristaSE" +}; +var motoristasEntregaCacheByGroup = {}; +var motoristasEntregaLoadingByGroup = {}; +var motoristaEntregaGroupAtual = ""; + +function normalizeUfCode(value) { + return String(value || "").toUpperCase().replace(/[^A-Z]/g, "").substring(0, 2); +} + +function resolveMotoristasGroupIdByUf(uf) { + var ufCode = normalizeUfCode(uf); + if (!ufCode) { + return MOTORISTAS_GROUP_DEFAULT_ID; + } + if (MOTORISTAS_GROUP_BY_UF[ufCode]) { + return String(MOTORISTAS_GROUP_BY_UF[ufCode] || "").trim() || MOTORISTAS_GROUP_DEFAULT_ID; + } + // Convencao para facilitar novos estados sem precisar alterar o JS. + return "motorista" + ufCode; +} + +function getMotoristasEntregaQueryContext() { + var uf = normalizeUfCode($("#ufDestino").val()); + var groupId = resolveMotoristasGroupIdByUf(uf); + return { + uf: uf, + groupId: groupId, + cacheKey: groupId + }; +} function loadMotoristasEntregaSelect(forceReload) { var select = $("#motoristaEntregaSelecionado"); if (!select.length) return; - if (!forceReload && motoristasEntregaCache && motoristasEntregaCache.length) { - renderMotoristasEntregaOptions(motoristasEntregaCache); + var context = getMotoristasEntregaQueryContext(); + var cacheKey = context.cacheKey; + motoristaEntregaGroupAtual = context.groupId; + + if (!forceReload && Object.prototype.hasOwnProperty.call(motoristasEntregaCacheByGroup, cacheKey)) { + renderMotoristasEntregaOptions(motoristasEntregaCacheByGroup[cacheKey], context); return; } - if (motoristasEntregaLoading) return; + if (motoristasEntregaLoadingByGroup[cacheKey]) return; - motoristasEntregaLoading = true; + motoristasEntregaLoadingByGroup[cacheKey] = true; + select.prop("disabled", true); var requestPayload = { name: "ds_motoristas_grupo", fields: null, constraints: [{ _field: "GROUP_ID", - _initialValue: MOTORISTAS_GROUP_ID, - _finalValue: MOTORISTAS_GROUP_ID, + _initialValue: context.groupId, + _finalValue: context.groupId, _type: 1 }], order: null @@ -390,14 +463,22 @@ function loadMotoristasEntregaSelect(forceReload) { data: JSON.stringify(requestPayload) }).done(function (response) { var values = ((((response || {}).content || {}).values) || []); - motoristasEntregaCache = normalizeMotoristasEntregaRows(values); - renderMotoristasEntregaOptions(motoristasEntregaCache); + var rows = normalizeMotoristasEntregaRows(values); + motoristasEntregaCacheByGroup[cacheKey] = rows; + if (motoristaEntregaGroupAtual === context.groupId) { + renderMotoristasEntregaOptions(rows, context); + } }).fail(function (xhr) { - console.error("Falha ao carregar motoristas do dataset:", xhr); - motoristasEntregaCache = []; - renderMotoristasEntregaOptions([]); + console.error("Falha ao carregar motoristas do dataset (" + context.groupId + "):", xhr); + motoristasEntregaCacheByGroup[cacheKey] = []; + if (motoristaEntregaGroupAtual === context.groupId) { + renderMotoristasEntregaOptions([], context); + } }).always(function () { - motoristasEntregaLoading = false; + motoristasEntregaLoadingByGroup[cacheKey] = false; + if (motoristaEntregaGroupAtual === context.groupId) { + select.prop("disabled", false); + } }); } @@ -429,14 +510,21 @@ function normalizeMotoristasEntregaRows(values) { return out; } -function renderMotoristasEntregaOptions(rows) { +function renderMotoristasEntregaOptions(rows, context) { var select = $("#motoristaEntregaSelecionado"); if (!select.length) return; var selectedValue = String($("#motoristaEntregaLogin").val() || select.val() || "").trim(); + var placeholder = "Selecione o motorista"; + if (context && context.uf) { + placeholder = "Selecione o motorista da UF " + context.uf; + } + if ((rows || []).length === 0 && context && context.uf) { + placeholder = "Sem motoristas cadastrados para UF " + context.uf; + } select.empty(); - select.append($("").val("").text("Selecione o motorista")); + select.append($("").val("").text(placeholder)); for (var i = 0; i < rows.length; i++) { var row = rows[i]; @@ -462,6 +550,12 @@ function renderMotoristasEntregaOptions(rows) { applySelectedMotoristaEntregaOption(); } +function refreshMotoristasEntregaByUf(forceReload) { + var escolha = String($("input[name='tipoMotoristaEntrega']:checked").val() || ""); + if (escolha !== "outro") return; + loadMotoristasEntregaSelect(forceReload === true); +} + function syncMotoristaEntregaSelectFromHidden() { var select = $("#motoristaEntregaSelecionado"); if (!select.length) return; @@ -1043,7 +1137,7 @@ var beforeSendValidate = function (numState, nextState) { throw "'Complemento' é obrigatório."; } else if ($("#justificativa").val() == "") { $("#justificativa").parent("div").addClass("errorValidate"); - throw "'Qual o motivo da compra?' é obrigatório."; + throw "'Qual o motivo da transferência?' é obrigatório."; } else { $("input[id^='quantidadeItem___']").each(function (index, value) { var linha = $(value).attr("name").split("___")[1]; @@ -1152,6 +1246,9 @@ var beforeSendValidate = function (numState, nextState) { if ($("#dataEntrega").val() == "") { throw "'Data da entrega' é obrigatória."; } + if (String($("#nomerecebedor").val() || "").trim() == "") { + throw "'Nome de quem recebeu a mercadoria' é obrigatório."; + } } else if (numState == 18) { var validacaoItens = $("input[name='validacaoItens']:checked").val(); if (validacaoItens == "" || validacaoItens == undefined) { @@ -1224,6 +1321,7 @@ function setSelectedZoomItem(selectedItem) { $("#gestorEmail").val(selectedItem["emailGestor"] || ""); $("#gestor_cc").val(selectedItem["COLLEAGUE_ID"] || ""); $("#ufDestino").val(selectedItem["UF"] || ""); + refreshMotoristasEntregaByUf(true); } if (name_item == "estabelecimento") { @@ -1250,9 +1348,11 @@ function setSelectedZoomItem(selectedItem) { var itemDescricao = selectedItem["descricao"] || selectedItem["Description"] || ""; var itemCode = selectedItem["Code"] || selectedItem["sku"] || ""; var itemProductId = selectedItem["id"] || selectedItem["productId"] || ""; + var itemCategoria = selectedItem["categoria"] || selectedItem["strategicDescription"] || ""; $("#codigoItem" + "___" + indice).val(itemDescricao); $("#codigoProdutoItem" + "___" + indice).val(itemCode); $("#productIdItem" + "___" + indice).val(itemProductId); + $("#categoriaItem" + "___" + indice).val(itemCategoria); processarConferenciaNfe(); } @@ -1275,6 +1375,7 @@ function removedZoomItem(removedItem) { $("#gestorEmail").val(""); $("#gestor_cc").val(""); $("#ufDestino").val(""); + refreshMotoristasEntregaByUf(true); } else if (name_item == "estabelecimento") { $("#gestorNomeE").val(""); $("#gestorEmailE").val(""); @@ -1292,6 +1393,7 @@ function removedZoomItem(removedItem) { $("#codigoItem___" + linha[1]).val(""); $("#codigoProdutoItem___" + linha[1]).val(""); $("#productIdItem___" + linha[1]).val(""); + $("#categoriaItem___" + linha[1]).val(""); $("#quantidadeItem___" + linha[1]).val(""); processarConferenciaNfe(); } @@ -1301,6 +1403,7 @@ function removedZoomItem(removedItem) { $("#codigoItem" + "___" + indice).val(""); $("#codigoProdutoItem" + "___" + indice).val(""); $("#productIdItem" + "___" + indice).val(""); + $("#categoriaItem" + "___" + indice).val(""); processarConferenciaNfe(); } } diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/teste.html b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/teste.html new file mode 100644 index 0000000..bf98a5f --- /dev/null +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/teste.html @@ -0,0 +1,57 @@ +
+ +
+ + +
+

Transferências Ginseng

+

Notificação de Processo

+
+ + +
+ +

Nota Fiscal Emitida ✅

+ +

Olá,

+ +

+ Sua solicitação teve a Nota Fiscal emitida com sucesso. +

+ + +
+

Nº Solicitação: ${WKNumProces}

+

Chave NFe: ${chaveNfe}

+
+ +

+ Clique no botão abaixo para acessar o processo: +

+ + +
+ + Acessar Solicitação + +
+

+ Se o botao nao abrir, copie e cole este link no navegador:
+ ${linkSolicitacao} +

+ +

+ Este é um e-mail automático, não responda. +

+ +
+ + +
+ © Ginseng +
+ +
+
diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/totvsflow_solicitacao_transferencia.html b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/totvsflow_solicitacao_transferencia.html index 7338787..d9a87af 100644 --- a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/totvsflow_solicitacao_transferencia.html +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/totvsflow_solicitacao_transferencia.html @@ -25,13 +25,40 @@ } .status-pill { - background: #e9f4ff; - color: #0d5b91; - border: 1px solid #c3def6; + background: #eef2f6; + color: #5f7080; + border: 1px solid #d3dde7; padding: 6px 12px; border-radius: 999px; font-size: 11px; font-weight: 600; + transition: all .2s ease; + } + + .status-pill.is-done { + background: #e8f7ed; + color: #1f6e3e; + border-color: #b8e3c4; + } + + .status-pill.is-active { + background: #e8f2ff; + color: #0e56a2; + border-color: #8fb8e8; + box-shadow: 0 0 0 2px rgba(31, 110, 169, 0.12); + } + + .status-pill.status-pill--problem.is-active { + background: #ffecec; + color: #a12f2f; + border-color: #efb1b1; + box-shadow: 0 0 0 2px rgba(199, 58, 58, 0.12); + } + + .status-pill.status-pill--problem.is-done { + background: #fff4e6; + color: #8a5c12; + border-color: #f2d3a2; } .transfer-main-title { @@ -216,11 +243,15 @@
-
- Solicitação - Coleta - Entrega - Recebimento +
+ Solicitação + Aprovação + Emissão NFe + Coleta + Entrega + Recebimento + Verificar Problema + Finalizada

Formulário de Transferência de Mercadorias

@@ -310,6 +341,7 @@ Código do item Quantidade Descrição + Categoria @@ -319,11 +351,12 @@ + + +
- +
+
+ + +
+
+

Validação do Recebimento

diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_coleta_realizada.html b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_coleta_realizada.html new file mode 100644 index 0000000..c18f70b --- /dev/null +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_coleta_realizada.html @@ -0,0 +1,44 @@ +
+
+ +
+

Transferências Ginseng

+

Notificação de Processo

+
+ +
+

Coleta Realizada

+ +

Olá,

+

O motorista ${motoristaColetaNome} coletou o produto na data ${dataColeta}.

+

O motorista ${motoristaEntregaNome} irá realizar a entrega.

+ +
+

Nº Solicitação: ${WKNumProces}

+

Chave NFe: ${chaveNfe}

+
+ +

Clique no botão abaixo para acessar o processo:

+ + +

+ Se o botão não abrir, copie e cole este link no navegador:
+ ${linkSolicitacao} +

+ +

+ Este é um e-mail automático, não responda. +

+
+ +
+ © Ginseng +
+
+
diff --git a/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_entrega_realizada.html b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_entrega_realizada.html new file mode 100644 index 0000000..108b3fd --- /dev/null +++ b/Transferência Ginseng/forms/totvsflow_solicitacao_transferencia/tpl_entrega_realizada.html @@ -0,0 +1,44 @@ +
+
+ +
+

Transferências Ginseng

+

Notificação de Processo

+
+ +
+

Entrega Realizada

+ +

Olá,

+

O motorista ${motoristaEntregaNome} entregou a mercadoria na data ${dataEntrega}.

+

Quem recebeu foi: ${nomerecebedor}.

+ +
+

Nº Solicitação: ${WKNumProces}

+

Chave NFe: ${chaveNfe}

+
+ +

Clique no botão abaixo para acessar o processo:

+ + +

+ Se o botão não abrir, copie e cole este link no navegador:
+ ${linkSolicitacao} +

+ +

+ Este é um e-mail automático, não responda. +

+
+ +
+ © Ginseng +
+
+
diff --git a/Transferência Ginseng/workflow/.resources/Producao.ws.cache b/Transferência Ginseng/workflow/.resources/Producao.ws.cache new file mode 100644 index 0000000..a749668 --- /dev/null +++ b/Transferência Ginseng/workflow/.resources/Producao.ws.cache @@ -0,0 +1,839 @@ + + + + + mecanismoGrupo + + + + + Tecnologia e Comunicação + + + TIC + + + + + + + Compras Indiretos + + + ComprasIndiretos + + + + + + + Obras e manutenção + + + Manutencao + + + + + + + Aprovadores Compras Nvl 3 + + + AprovadoresComprasNvl3 + + + + + + + Motoristas + + + Motoristas + + + + + + + Requisitantes de Vaga + + + Requisitantesdevaga + + + + + + + Recrutamento + + + Recrutamento + + + + + + + TODOS-TODOS-DIADMISSAO + + + TODOS-TODOS-DIADMISSAO + + + + + + + ResponsavelDesligamento + + + ResponsavelDesligamento + + + + + + + GENTE & CULTURA + + + GENTE_CULTURA + + + + + + + LOJA AL + + + LOJA_AL + + + + + + + CD + + + CD + + + + + + + ESPAÇO DO REVENDEDOR AL + + + ESPACO_DO_REVENDEDOR_AL + + + + + + + FINANCEIRO + + + FINANCEIRO + + + + + + + OPERAÇÕES + + + OPERACOES + + + + + + + AMG AL + + + AMG_AL + + + + + + + REGIONAL ALAGOAS + + + REGIONAL_ALAGOAS + + + + + + + PREVENÇÃO DE PERDA + + + PREVENCAO_DE_PERDA + + + + + + + MARKETING, TREINAMENTO + + + MARKETING_TREINAMENTO + + + + + + + SECRETARIA EXECUTIVA + + + SECRETARIA_EXECUTIVA + + + + + + + DIRETORIA EXECUTIVA + + + DIRETORIA_EXECUTIVA + + + + + + + INFRAESTRUTURA + + + INFRAESTRUTURA + + + + + + + ESPAÇO DO REVENDEDOR BA + + + ESPACO_DO_REVENDEDOR_BA + + + + + + + BUSINESS INTELLIGENCE + + + BUSINESS_INTELLIGENCE + + + + + + + DEPARTAMENTO PESSOAL + + + DEPARTAMENTO_PESSOAL + + + + + + + LOJA BA + + + LOJA_BA + + + + + + + TREINAMENTO + + + TREINAMENTO + + + + + + + AMG BA + + + AMG_BA + + + + + + + MARKETING + + + MARKETING + + + + + + + COMPRAS + + + COMPRAS + + + + + + + AMG SE + + + AMG_SE + + + + + + + LOJA SE + + + LOJA_SE + + + + + + + ESPAÇO DO REVENDEDOR SE + + + ESPACO_DO_REVENDEDOR_SE + + + + + + + VENDAS IN COMPANY + + + VENDAS_IN_COMPANY + + + + + + + REGIONAL BAHIA + + + REGIONAL_BAHIA + + + + + + + CANAL LOJA 01 + + + CANAL_LOJA_01 + + + + + + + AUDITORIA + + + AUDITORIA + + + + + + + CANAL LOJA 02 + + + CANAL_LOJA_02 + + + + + + + PLANEJAMENTO DE DEMANDAS + + + PLANEJAMENTO_DE_DEMANDAS + + + + + + + PROJETOS + + + PROJETOS + + + + + + + COMPLIANCE + + + COMPLIANCE + + + + + + + ESCRITÓRIO - MATRIZ + + + ESCRITORIO_MATRIZ + + + + + + + ESCRITÓRIO - CONQUISTA + + + ESCRITORIO_CONQUISTA + + + + + + + REGIONAL SERGIPE + + + REGIONAL_SERGIPE + + + + + + + Transferencia + + + Transferencia + + + + + + + Fiscal + + + Fiscal + + + + + + + motoristaAL + + + motoristaAL + + + + + + + motoristaBA + + + motoristaBA + + + + + + + motoristaSE + + + motoristaSE + + + + + + + expediente + + + Default + + + Expediente BackOffice, Logística e Motorista + + + Expediente Escritório Matriz + + + Expediente Lojas + + + + + camposFormulario, documentoId = 590 + + + activity + + + categoriaItem + + + centroCusto + + + chaveNfe + + + codigoItem + + + codigoProdutoItem + + + currentUserId + + + currentUsermail + + + currentUserName + + + dataAbertura + + + dataColeta + + + dataEmissaoApiNfe + + + dataEmissaoNfe + + + dataEntradaNfeConsulta + + + dataEntrega + + + dataValidacaoGestor + + + descricao + + + emailSolicitante + + + estabelecimento + + + excelUpload + + + fdAnexo_Coleta + + + fdAnexo_Entrega + + + fdAnexo_recebimento + + + fnAnexo_Nfe + + + formMode + + + fornecedorNfeConsulta + + + gestorEmail + + + gestorEmailE + + + gestorNome + + + gestorNomeE + + + gestor_cc + + + gestor_cce + + + invoiceIdNfeConsulta + + + itensNfeConsulta + + + itensNfeJson + + + justificativa + + + justificativaDecisaoGestor + + + justificativaDecisaoItens + + + lojaNfeConsulta + + + motoristaColetaLogin + + + motoristaColetaNome + + + motoristaEntregaLogin + + + motoristaEntregaNome + + + motoristaEntregaSelecionado + + + nomerecebedor + + + numeroNfeConsulta + + + operacaoNfeConsulta + + + productIdItem + + + qtdDivergenciasNfe + + + quantidadeItem + + + requesterId + + + requesterMail + + + requesterName + + + serieNfeConsulta + + + situacaoNfeConsulta + + + storeIdNfeConsulta + + + tipoMotoristaEntrega + + + ufDestino + + + ufOrigem + + + userValidacaoGestor + + + usuarioEmissorNfe + + + validacaoItens + + + valorNfeConsulta + + + WKNumProces + + + + + mecanismo + + + + + Atribuição por Associação + + + Associado + + + + + + + Atribuição por Campo de Formulário + + + Campo Formulário + + + + + + + dpf_di_emp_filial_filtro + + + dpf_di_emp_filial_filtro + + + + + + + dpf_di_inicio_diadmissao + + + dpf_di_inicio_diadmissao + + + + + + + Atribuição por Executor de Atividade + + + Executor Atividade + + + + + + + Atribuição por Grupo + + + Grupo + + + + + + + Atribuição por Grupos do Colaborador + + + Grupos Colaborador + + + + + + + mecCustomAprov + + + mecCustomAprov + + + + + + + Atribuição por Papel + + + Papel + + + + + + + Atribuição para um Grupo + + + Pool Grupo + + + + + + + Atribuição para um Papel + + + Pool Papel + + + + + + + Atribuição por Usuário + + + Usuário + + + + + + + diff --git a/Transferência Ginseng/workflow/.resources/Producao.ws.cache.bkp b/Transferência Ginseng/workflow/.resources/Producao.ws.cache.bkp new file mode 100644 index 0000000..27d724c --- /dev/null +++ b/Transferência Ginseng/workflow/.resources/Producao.ws.cache.bkp @@ -0,0 +1,1372 @@ + + + + + volume + + + Default + + + + + mecanismoGrupo + + + + + Tecnologia e Comunicação + + + TIC + + + + + + + Compras Indiretos + + + ComprasIndiretos + + + + + + + Obras e manutenção + + + Manutencao + + + + + + + Aprovadores Compras Nvl 3 + + + AprovadoresComprasNvl3 + + + + + + + Motoristas + + + Motoristas + + + + + + + Requisitantes de Vaga + + + Requisitantesdevaga + + + + + + + Recrutamento + + + Recrutamento + + + + + + + TODOS-TODOS-DIADMISSAO + + + TODOS-TODOS-DIADMISSAO + + + + + + + ResponsavelDesligamento + + + ResponsavelDesligamento + + + + + + + GENTE & CULTURA + + + GENTE_CULTURA + + + + + + + LOJA AL + + + LOJA_AL + + + + + + + CD + + + CD + + + + + + + ESPAÇO DO REVENDEDOR AL + + + ESPACO_DO_REVENDEDOR_AL + + + + + + + FINANCEIRO + + + FINANCEIRO + + + + + + + OPERAÇÕES + + + OPERACOES + + + + + + + AMG AL + + + AMG_AL + + + + + + + REGIONAL ALAGOAS + + + REGIONAL_ALAGOAS + + + + + + + PREVENÇÃO DE PERDA + + + PREVENCAO_DE_PERDA + + + + + + + MARKETING, TREINAMENTO + + + MARKETING_TREINAMENTO + + + + + + + SECRETARIA EXECUTIVA + + + SECRETARIA_EXECUTIVA + + + + + + + DIRETORIA EXECUTIVA + + + DIRETORIA_EXECUTIVA + + + + + + + INFRAESTRUTURA + + + INFRAESTRUTURA + + + + + + + ESPAÇO DO REVENDEDOR BA + + + ESPACO_DO_REVENDEDOR_BA + + + + + + + BUSINESS INTELLIGENCE + + + BUSINESS_INTELLIGENCE + + + + + + + DEPARTAMENTO PESSOAL + + + DEPARTAMENTO_PESSOAL + + + + + + + LOJA BA + + + LOJA_BA + + + + + + + TREINAMENTO + + + TREINAMENTO + + + + + + + AMG BA + + + AMG_BA + + + + + + + MARKETING + + + MARKETING + + + + + + + COMPRAS + + + COMPRAS + + + + + + + AMG SE + + + AMG_SE + + + + + + + LOJA SE + + + LOJA_SE + + + + + + + ESPAÇO DO REVENDEDOR SE + + + ESPACO_DO_REVENDEDOR_SE + + + + + + + VENDAS IN COMPANY + + + VENDAS_IN_COMPANY + + + + + + + REGIONAL BAHIA + + + REGIONAL_BAHIA + + + + + + + CANAL LOJA 01 + + + CANAL_LOJA_01 + + + + + + + AUDITORIA + + + AUDITORIA + + + + + + + CANAL LOJA 02 + + + CANAL_LOJA_02 + + + + + + + PLANEJAMENTO DE DEMANDAS + + + PLANEJAMENTO_DE_DEMANDAS + + + + + + + PROJETOS + + + PROJETOS + + + + + + + COMPLIANCE + + + COMPLIANCE + + + + + + + ESCRITÓRIO - MATRIZ + + + ESCRITORIO_MATRIZ + + + + + + + ESCRITÓRIO - CONQUISTA + + + ESCRITORIO_CONQUISTA + + + + + + + REGIONAL SERGIPE + + + REGIONAL_SERGIPE + + + + + + + Transferencia + + + Transferencia + + + + + + + Fiscal + + + Fiscal + + + + + + + motoristaAL + + + motoristaAL + + + + + + + motoristaBA + + + motoristaBA + + + + + + + motoristaSE + + + motoristaSE + + + + + + + expediente + + + Default + + + Expediente BackOffice, Logística e Motorista + + + Expediente Escritório Matriz + + + Expediente Lojas + + + + + camposFormulario, documentoId = 590 + + + activity + + + categoriaItem + + + centroCusto + + + chaveNfe + + + codigoItem + + + codigoProdutoItem + + + currentUserId + + + currentUsermail + + + currentUserName + + + dataAbertura + + + dataColeta + + + dataEmissaoApiNfe + + + dataEmissaoNfe + + + dataEntradaNfeConsulta + + + dataEntrega + + + dataValidacaoGestor + + + descricao + + + emailSolicitante + + + estabelecimento + + + excelUpload + + + fdAnexo_Coleta + + + fdAnexo_Entrega + + + fdAnexo_recebimento + + + fnAnexo_Nfe + + + formMode + + + fornecedorNfeConsulta + + + gestorEmail + + + gestorEmailE + + + gestorNome + + + gestorNomeE + + + gestor_cc + + + gestor_cce + + + invoiceIdNfeConsulta + + + itensNfeConsulta + + + itensNfeJson + + + justificativa + + + justificativaDecisaoGestor + + + justificativaDecisaoItens + + + lojaNfeConsulta + + + motoristaColetaLogin + + + motoristaColetaNome + + + motoristaEntregaLogin + + + motoristaEntregaNome + + + motoristaEntregaSelecionado + + + nomerecebedor + + + numeroNfeConsulta + + + operacaoNfeConsulta + + + productIdItem + + + qtdDivergenciasNfe + + + quantidadeItem + + + requesterId + + + requesterMail + + + requesterName + + + serieNfeConsulta + + + situacaoNfeConsulta + + + storeIdNfeConsulta + + + tipoMotoristaEntrega + + + ufDestino + + + ufOrigem + + + userValidacaoGestor + + + usuarioEmissorNfe + + + validacaoItens + + + valorNfeConsulta + + + WKNumProces + + + + + mecanismo + + + + + Atribuição por Associação + + + Associado + + + + + + + Atribuição por Campo de Formulário + + + Campo Formulário + + + + + + + dpf_di_emp_filial_filtro + + + dpf_di_emp_filial_filtro + + + + + + + dpf_di_inicio_diadmissao + + + dpf_di_inicio_diadmissao + + + + + + + Atribuição por Executor de Atividade + + + Executor Atividade + + + + + + + Atribuição por Grupo + + + Grupo + + + + + + + Atribuição por Grupos do Colaborador + + + Grupos Colaborador + + + + + + + mecCustomAprov + + + mecCustomAprov + + + + + + + Atribuição por Papel + + + Papel + + + + + + + Atribuição para um Grupo + + + Pool Grupo + + + + + + + Atribuição para um Papel + + + Pool Papel + + + + + + + Atribuição por Usuário + + + Usuário + + + + + + + forms + + + + + FLUIGADHOC + + + FLUIGADHOC + + + 3 + + + + + + + FLUIGADHOCPROCESS + + + FLUIGADHOCPROCESS + + + 4 + + + + + + + totvsflow_dataset_tipo_ocorrencia + + + totvsflow_dataset_tipo_ocorrencia + + + 14 + + + + + + + totvsflow_abertura_chamado + + + totvsflow_abertura_chamado + + + 15 + + + + + + + DSFormulariodeAberturadechamado + + + Formulário de Abertura de chamado + + + 20 + + + + + + + Abertura_de_chamados + + + Solicitação de abertura de chamados + + + 21 + + + + + + + DSvistoriadeServico + + + vistoriadeServico + + + 24 + + + + + + + DSFormulariodeReservadesala + + + Formulário de Reserva de sala + + + 34 + + + + + + + totvsflow_dataset_centrocusto + + + totvsflow_dataset_centrocusto + + + 103 + + + + + + + totvsflow_dataset_cadastro_item + + + totvsflow_dataset_cadastro_item + + + 104 + + + + + + + totvsflow_dataset_estabelecimento + + + totvsflow_dataset_estabelecimento + + + 105 + + + + + + + totvsflow_solicitacao_compras + + + totvsflow_solicitacao_compras + + + 165 + + + + + + + aberturadechamado_manutencao + + + aberturadechamado_manutencao + + + 400 + + + + + + + Solicitacao_transferencia + + + Solicitacao_transferencia + + + 590 + + + + + + + recrutamento + + + recrutamento + + + 823 + + + + + + + kit_aniversariantes + + + Aniversariantes + + + 7690 + + + + + + + kit_cardapio + + + Cardápio do Dia + + + 7695 + + + + + + + kit_convenios + + + Convênios + + + 7703 + + + + + + + kit_news + + + Notícias + + + 7709 + + + + + + + compras_digital + + + compras_digital + + + 9305 + + + + + + + dpf_di_formulario_processo_admissao + + + Digte_Public_Form_Di_Formulario_Processo_Admissao_Protheus + + + 9626 + + + + + + + dpf_cadastro_status + + + Digte_Public_Form_Status + + + 9627 + + + + + + + dpf_configuracoes + + + Digte_Public_Form_Configuracoes + + + 9628 + + + + + + + dpf_cadastro_jornada + + + Digte_Public_Form_Jornada + + + 9629 + + + + + + + dpf_tipo_documento + + + Digte_Public_Form_Tipo_Documento + + + 9630 + + + + + + + dpf_dataset + + + Digte_Public_Form_Dataset + + + 9631 + + + + + + + dpf_di_configuracao + + + Digte_Public_Form_Di_Configuracoes + + + 9632 + + + + + + + dpf_di_beneficio + + + Digte_Public_Form_Di_Beneficios + + + 9633 + + + + + + + dpf_di_compl_contrato + + + Digte_Public_Form_Di_Comp_Contrato + + + 9634 + + + + + + + dpf_di_funcao_jornada + + + Digte_Public_Form_Di_Funcao_Jornada + + + 9635 + + + + + + + dpf_dataset_estrutura + + + Digte_Public_Form_Di_Dataset_Estrutura + + + 9636 + + + + + + + dpf_grupo_tipo_contrato + + + Digte_Public_Form_Grupo_Tipo_Contrato + + + 9637 + + + + + + + dpf_tipo_contrato + + + Digte_Public_Form_Tipo_Contrato + + + 9638 + + + + + + + dpf_di_traducao_campo_valor + + + Digte_Public_Form_Di_Traducao_Campo_Valor + + + 9639 + + + + + + + dpf_di_restricoes_cpf + + + Digte_Public_Form_Di_Formulario_Restricao_CPF + + + 9640 + + + + + + + dpf_di_compl_vt + + + Digte_Public_Form_Di_Compl_VT + + + 9641 + + + + + + + dpf_di_traducao_campo + + + Digte_Public_Form_Di_Traducao_Campo + + + 9995 + + + + + + + desligamento + + + desligamento + + + 12959 + + + + + + + checklist + + + checklist + + + 40213 + + + + + + + totvsflow_lancamento_documento + + + totvsflow_lancamento_documento + + + 41254 + + + + + + + diff --git a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.ecm30.xml b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.ecm30.xml index fe18df6..538ae9c 100644 --- a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.ecm30.xml +++ b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.ecm30.xml @@ -8,10 +8,10 @@ Este flow permite abertura de solicitação de transferências automatizadas, informando qual item será transferido e direcionado para as aprovações corretas. true false - Fluig teste + Default Transferência - Usuário - <AssignmentController><User>projetos</User></AssignmentController> + Grupo + <AssignmentController><Group>CD</Group></AssignmentController> 0 0 0 @@ -33,7 +33,6 @@ 590 - 0 true true false @@ -127,8 +126,8 @@ true true false - 490 - 281 + 500 + 280 0 0 false @@ -179,7 +178,7 @@ true true false - 490 + 500 490 0 0 @@ -232,7 +231,7 @@ true false 1170 - 270 + 284 0 0 false @@ -283,7 +282,7 @@ true true false - 1410 + 1400 479 0 0 @@ -319,8 +318,7 @@ false 0 - Pool Grupo - <AssignmentController><Group>Motoristas</Group></AssignmentController> + 1 false false @@ -439,7 +437,7 @@ false false 1600 - 260 + 284 0 0 false @@ -541,7 +539,7 @@ false false 1660 - 260 + 284 0 0 false @@ -598,8 +596,33 @@ 0 true - 1430 - 250 + 1420 + 268 + false + 1 + 120 + 0 + 0 + + false + + + + 1 + Transferência Ginseng + 1 + 107 + + Validar rota + Validar rota + false + false + false + + 0 + true + 520 + 663 false 1 120 @@ -778,8 +801,8 @@ false false false - 1780 - 280 + 1777 + 300 0 0 false @@ -850,6 +873,62 @@ 24 0 + + + 1 + Transferência Ginseng + 1 + 46 + 107 + + hAPI.getCardValue("ufOrigem") == "AL" + 31 + <AssignmentController><Group>motoristaAL</Group></AssignmentController> + Pool Grupo + 0 + + + + 1 + Transferência Ginseng + 2 + 46 + 107 + + hAPI.getCardValue("ufOrigem") == "BA" + 31 + <AssignmentController><Group>motoristaBA</Group></AssignmentController> + Pool Grupo + 0 + + + + 1 + Transferência Ginseng + 3 + 46 + 107 + + hAPI.getCardValue("ufOrigem") == "SE" + 31 + <AssignmentController><Group>motoristaSE</Group></AssignmentController> + Pool Grupo + 0 + + + + 1 + Transferência Ginseng + 4 + 46 + 107 + + hAPI.getCardValue("ufOrigem") == "" + 31 + <AssignmentController><Group>CD</Group></AssignmentController> + Pool Grupo + 0 + @@ -913,12 +992,12 @@ 1 26 - + Ajuste realizado false 24 18 - + Ajuste de transferência false false 0 @@ -947,12 +1026,12 @@ 1 47 - + Confirmar recebimento false 18 46 - + Confirmar recebimento false false 0 @@ -1015,7 +1094,7 @@ 1 85 - Produtos entregue + Transferência entregue false 57 18 @@ -1025,23 +1104,6 @@ false 0 - - - 1 - Transferência Ginseng - 1 - 95 - - Enviar para coleta - false - 68 - 31 - - Enviar para coleta - false - false - 0 - 1 @@ -1066,12 +1128,12 @@ 1 98 - + Pedido coletado false 31 57 - + Entregar produto false false 0 @@ -1144,9 +1206,292 @@ false 0 + + + 1 + Transferência Ginseng + 1 + 108 + + Enviar para coleta + false + 6 + 107 + + Enviar para rota + false + false + 0 + + + + 1 + Transferência Ginseng + 1 + 109 + + + false + 107 + 31 + + + false + false + 0 + + + + 1 + beforeTaskSave + Transferência Ginseng + 1 + + function beforeTaskSave(colleagueId, nextSequenceId, userList) { + try { + var currentState = parseInt(getValue("WKNumState"), 10); + var completeTask = String(getValue("WKCompletTask") || "false"); + var nextState = parseInt(String(nextSequenceId || "0"), 10); + + if (completeTask !== "true") return; + + if (currentState === 6) { + // Fluxo de cancelamento saindo da atividade 6 nao deve disparar template de nota emitida. + if (nextState === 97) return; + enviarNotificacaoNotaEmitida(); + return; + } + + if (currentState === 31) { + enviarNotificacaoColetaRealizada(); + return; + } + + if (currentState === 57) { + // 61 = cancelamento no diagrama. + if (nextState === 61) return; + enviarNotificacaoEntregaRealizada(); + } + } catch (e) { + log.error("[Transferencia.beforeTaskSave] Erro no beforeTaskSave: " + e); + } +} + +function enviarNotificacaoNotaEmitida() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + notifyTemplate("tpl_nota_emitida", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function enviarNotificacaoColetaRealizada() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var motoristaColetaNome = safeTrim(hAPI.getCardValue("motoristaColetaNome")); + var dataColeta = safeTrim(hAPI.getCardValue("dataColeta")); + var motoristaEntregaNome = safeTrim(hAPI.getCardValue("motoristaEntregaNome")); + var tipoMotoristaEntrega = safeTrim(hAPI.getCardValue("tipoMotoristaEntrega")); + + if (motoristaEntregaNome === "" && tipoMotoristaEntrega === "mesmo") { + motoristaEntregaNome = motoristaColetaNome; + } + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + params.put("motoristaColetaNome", motoristaColetaNome); + params.put("dataColeta", dataColeta); + params.put("motoristaEntregaNome", motoristaEntregaNome); + + notifyTemplate("tpl_coleta_realizada", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function enviarNotificacaoEntregaRealizada() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var motoristaEntregaNome = safeTrim(hAPI.getCardValue("motoristaEntregaNome")); + var dataEntrega = safeTrim(hAPI.getCardValue("dataEntrega")); + var nomerecebedor = safeTrim(hAPI.getCardValue("nomerecebedor")); + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + params.put("motoristaEntregaNome", motoristaEntregaNome); + params.put("dataEntrega", dataEntrega); + params.put("nomerecebedor", nomerecebedor); + + notifyTemplate("tpl_entrega_realizada", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function montarContextoEnvio() { + var requesterId = safeTrim(hAPI.getCardValue("requesterId")); + var requesterMail = safeTrim(hAPI.getCardValue("requesterMail")); + + if (requesterId === "" && requesterMail !== "") { + requesterId = findColleagueIdByMail(requesterMail); + } + + // Prioriza email explicito salvo no formulario; fallback para email do colleague. + var destinoEmail = requesterMail; + if (!isValidEmail(destinoEmail)) { + destinoEmail = resolveEmailByColleagueId(requesterId); + } + + if (!isValidEmail(destinoEmail)) { + log.warn("[Transferencia.beforeTaskSave] Email do solicitante invalido. requesterId=" + requesterId + ", requesterMail=[" + requesterMail + "], destinoEmail=[" + destinoEmail + "]"); + return { ok: false }; + } + + var processNumber = safeTrim(getValue("WKNumProces")); + var chaveNfe = onlyDigits(hAPI.getCardValue("chaveNfe")); + if (chaveNfe === "") chaveNfe = safeTrim(hAPI.getCardValue("chaveNfe")); + var processLink = buildProcessLink(processNumber); + + return { + ok: true, + requesterId: requesterId, + destinoEmail: destinoEmail, + processNumber: processNumber, + chaveNfe: chaveNfe, + processLink: processLink + }; +} + +function buildCommonParams(processNumber, chaveNfe, processLink) { + var params = new java.util.HashMap(); + params.put("WKNumProces", processNumber); + params.put("chaveNfe", chaveNfe); + params.put("linkSolicitacao", processLink); + params.put("link", processLink); + return params; +} + +function notifyTemplate(templateCode, destinoEmail, requesterId, params, processNumber, processLink) { + var NOTIFIER_SENDER_USER = "admin"; + var recipients = new java.util.ArrayList(); + recipients.add(destinoEmail); + + notifier.notify(NOTIFIER_SENDER_USER, templateCode, params, recipients, "text/html"); + log.info("[Transferencia.beforeTaskSave] " + templateCode + " enviado. processo=" + processNumber + ", destino=" + destinoEmail + ", requesterId=" + requesterId + ", link=[" + processLink + "]"); +} + +function buildProcessLink(processNumber) { + var BASE_URL_FALLBACK = "https://comerciode188007.fluig.cloudtotvs.com.br"; + var baseUrl = safeTrim(getValue("WKServerURL")); + var companyId = safeTrim(getValue("WKCompany")); + if (baseUrl === "") baseUrl = BASE_URL_FALLBACK; + if (baseUrl.indexOf("http://") !== 0 && baseUrl.indexOf("https://") !== 0) { + baseUrl = "https://" + baseUrl; + } + if (baseUrl.charAt(baseUrl.length - 1) === "/") baseUrl = baseUrl.substring(0, baseUrl.length - 1); + if (companyId === "") companyId = "1"; + if (baseUrl === "" || safeTrim(processNumber) === "") return ""; + return baseUrl + "/portal/p/" + companyId + "/pageworkflowview?app_ecm_workflowview_detailsProcessInstanceID=" + processNumber; +} + +function findColleagueIdByMail(mail) { + var email = safeTrim(mail); + if (email === "") return ""; + + try { + var cMail = DatasetFactory.createConstraint("mail", email, email, ConstraintType.MUST); + var dsColleague = DatasetFactory.getDataset("colleague", null, [cMail], null); + if (!dsColleague || dsColleague.rowsCount < 1) return ""; + + return safeTrim( + dsColleague.getValue(0, "colleaguePK.colleagueId") || + dsColleague.getValue(0, "colleagueId") || + dsColleague.getValue(0, "login") + ); + } catch (e) { + log.warn("[Transferencia.beforeTaskSave] Falha ao buscar solicitante por mail: " + e); + return ""; + } +} + +function resolveEmailByColleagueId(colleagueId) { + var id = safeTrim(colleagueId); + if (id === "") return ""; + + try { + var cActive = DatasetFactory.createConstraint("active", "true", "true", ConstraintType.MUST); + + var cId = DatasetFactory.createConstraint("colleaguePK.colleagueId", id, id, ConstraintType.MUST); + var byId = DatasetFactory.getDataset("colleague", null, [cId, cActive], null); + if (byId && byId.rowsCount > 0) { + return safeTrim(byId.getValue(0, "mail")); + } + + var cLogin = DatasetFactory.createConstraint("login", id, id, ConstraintType.MUST); + var byLogin = DatasetFactory.getDataset("colleague", null, [cLogin, cActive], null); + if (byLogin && byLogin.rowsCount > 0) { + return safeTrim(byLogin.getValue(0, "mail")); + } + } catch (e) { + log.warn("[Transferencia.beforeTaskSave] Falha ao buscar email do solicitante por colleagueId: " + e); + } + + return ""; +} + +function isValidEmail(email) { + var v = safeTrim(email); + if (v === "") return false; + if (/\s/.test(v)) return false; + + var at = v.indexOf("@"); + if (at <= 0 || at !== v.lastIndexOf("@")) return false; + + var dot = v.lastIndexOf("."); + return dot > at + 1 && dot < (v.length - 1); +} + +function safeTrim(value) { + return String(value == null ? "" : value).trim(); +} + +function onlyDigits(value) { + return String(value == null ? "" : value).replace(/\D/g, ""); +} + + + + + 1 + onNotify + Transferência Ginseng + 1 + + function onNotify(subject, receivers, template, params) { + + log.info("===== onNotify GLOBAL ===== Template: " + template); + + var validos = new java.util.ArrayList(); + + for (var i = 0; i < receivers.size(); i++) { + + var email = receivers.get(i); + + log.info("Receiver original: [" + email + "]"); + + if (email && email.indexOf("@") > 0 && email.indexOf(".") > 0) { + validos.add(email); + } else { + log.warn("REMOVIDO EMAIL INVALIDO: [" + email + "] TEMPLATE: " + template); + } + } + + receivers.clear(); + + for (var j = 0; j < validos.size(); j++) { + receivers.add(validos.get(j)); + } + + log.info("TOTAL FINAL RECEIVERS: " + receivers.size()); +} + 1 @@ -1154,54 +1499,54 @@ Transferência Ginseng 1 - function servicetask99(attempt, message) { - try { - var validacaoItens = safeTrim(hAPI.getCardValue("validacaoItens")); - - // Só precisa consultar entrada da NFe quando o recebimento foi validado como entregue. - if (validacaoItens !== "entregue") return; - - var dataEntrada = safeTrim(hAPI.getCardValue("dataEntradaNfeConsulta")); - if (dataEntrada !== "") return; - - var chaveNfe = onlyDigits(hAPI.getCardValue("chaveNfe")); - if (chaveNfe === "") { - log.warn("[servicetask99] Chave NFe vazia. Nao foi possivel consultar entrada."); - return; - } - - var cKey = DatasetFactory.createConstraint("key", chaveNfe, chaveNfe, ConstraintType.MUST); - var dsNfe = DatasetFactory.getDataset("ds_fiscal_invoice_by_keys", null, [cKey], null); - - if (!dsNfe || dsNfe.rowsCount < 1) { - log.warn("[servicetask99] Dataset sem retorno para chave: " + chaveNfe); - return; - } - - var dsSuccess = safeTrim(dsNfe.getValue(0, "success")).toLowerCase() === "true"; - var dsUpdatedAt = safeTrim(dsNfe.getValue(0, "updatedAt")); - - if (dsSuccess && dsUpdatedAt !== "") { - hAPI.setCardValue("dataEntradaNfeConsulta", dsUpdatedAt); - log.info("[servicetask99] Data de entrada atualizada automaticamente: " + dsUpdatedAt); - return; - } - - var dsMessage = safeTrim(dsNfe.getValue(0, "message")); - log.warn("[servicetask99] Consulta executada sem data de entrada. message=" + dsMessage); - } catch (e) { - log.error("[servicetask99] Erro na consulta automatica da NFe: " + e); - throw e; - } -} - -function safeTrim(value) { - return String(value == null ? "" : value).trim(); -} - -function onlyDigits(value) { - return String(value == null ? "" : value).replace(/\D/g, ""); -} + function servicetask99(attempt, message) { + try { + var validacaoItens = safeTrim(hAPI.getCardValue("validacaoItens")); + + // Só precisa consultar entrada da NFe quando o recebimento foi validado como entregue. + if (validacaoItens !== "entregue") return; + + var dataEntrada = safeTrim(hAPI.getCardValue("dataEntradaNfeConsulta")); + if (dataEntrada !== "") return; + + var chaveNfe = onlyDigits(hAPI.getCardValue("chaveNfe")); + if (chaveNfe === "") { + log.warn("[servicetask99] Chave NFe vazia. Nao foi possivel consultar entrada."); + return; + } + + var cKey = DatasetFactory.createConstraint("key", chaveNfe, chaveNfe, ConstraintType.MUST); + var dsNfe = DatasetFactory.getDataset("ds_fiscal_invoice_by_keys", null, [cKey], null); + + if (!dsNfe || dsNfe.rowsCount < 1) { + log.warn("[servicetask99] Dataset sem retorno para chave: " + chaveNfe); + return; + } + + var dsSuccess = safeTrim(dsNfe.getValue(0, "success")).toLowerCase() === "true"; + var dsUpdatedAt = safeTrim(dsNfe.getValue(0, "updatedAt")); + + if (dsSuccess && dsUpdatedAt !== "") { + hAPI.setCardValue("dataEntradaNfeConsulta", dsUpdatedAt); + log.info("[servicetask99] Data de entrada atualizada automaticamente: " + dsUpdatedAt); + return; + } + + var dsMessage = safeTrim(dsNfe.getValue(0, "message")); + log.warn("[servicetask99] Consulta executada sem data de entrada. message=" + dsMessage); + } catch (e) { + log.error("[servicetask99] Erro na consulta automatica da NFe: " + e); + throw e; + } +} + +function safeTrim(value) { + return String(value == null ? "" : value).trim(); +} + +function onlyDigits(value) { + return String(value == null ? "" : value).replace(/\D/g, ""); +} @@ -1210,7 +1555,7 @@ function onlyDigits(value) { FFFFFF 794 - 1791 + 1861 20 20 Solicitação de Transferência @@ -1226,7 +1571,7 @@ function onlyDigits(value) { 82b0b7 198 - 1761 + 1831 50 218 Gerente de loja @@ -1242,7 +1587,7 @@ function onlyDigits(value) { d0daae 198 - 1761 + 1831 50 416 Logistica @@ -1258,7 +1603,7 @@ function onlyDigits(value) { d6e0d0 198 - 1761 + 1831 50 20 Analista de suprimentos @@ -1274,7 +1619,7 @@ function onlyDigits(value) { adc9ac 200 - 1761 + 1831 50 614 Motorista @@ -1357,30 +1702,10 @@ function onlyDigits(value) { 1149 308 - - - 1 - Transferência Ginseng - 46 - 95 - 1 - - 543 - 717 - - - - 1 - Transferência Ginseng - anexo_lista1 - - Nome do arquivo - 1 - 1 @@ -1388,7 +1713,7 @@ function onlyDigits(value) { centroCusto Filial Destino - 2 + 1 @@ -1397,6 +1722,15 @@ function onlyDigits(value) { dataAbertura Data de abertura + 2 + + + + 1 + Transferência Ginseng + dataEmissaoNfe + + dataEmissaoNfe 3 @@ -1421,9 +1755,9 @@ function onlyDigits(value) { 1 Transferência Ginseng - userSolicitante + requesterName - Solicitante + requesterName 6 diff --git a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.png b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.png index 1ea384d..51df293 100644 Binary files a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.png and b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.png differ diff --git a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.processimage.svg b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.processimage.svg index 727409a..de42702 100644 --- a/Transferência Ginseng/workflow/.resources/Solicitação de transferência.processimage.svg +++ b/Transferência Ginseng/workflow/.resources/Solicitação de transferência.processimage.svg @@ -1,2 +1,2 @@ -MotoristaAnalista de suprimentosLogisticaGerente de lojaSolicitação de TransferênciaValidarLojaAprovarTransferênciaEmitir NFEde TransfReceberProdutosVerificarproblemaColetarProdutoValidarprodutoEntregarProdutoConsultarEntradaVerificarproblema delançamentoGestor IdentificadoLoja sem GestorAprovarReprovarReprovarCancelarValidar produtosrecebidosEnviar para coletaFinalizar +MotoristaAnalista de suprimentosLogisticaGerente de lojaSolicitação de TransferênciaValidarLojaAprovarTransferênciaEmitir NFEde TransfReceberProdutosVerificarproblemaColetarProdutoValidarprodutoEntregarProdutoConsultarEntradaVerificarproblema delançamentoValidarrotaGestor IdentificadoLoja sem GestorAjuste de transferênciaAprovarConfirmar recebimentoReprovarReprovarCancelarValidar produtosrecebidosFinalizarEntregar produtoEnviar para rota diff --git a/Transferência Ginseng/workflow/.resources/teste3.ws.cache b/Transferência Ginseng/workflow/.resources/teste3.ws.cache index c8f2401..f350835 100644 --- a/Transferência Ginseng/workflow/.resources/teste3.ws.cache +++ b/Transferência Ginseng/workflow/.resources/teste3.ws.cache @@ -511,6 +511,197 @@ + + camposFormulario, documentoId = 590 + + + activity + + + centroCusto + + + chaveNfe + + + codigoItem + + + codigoProdutoItem + + + currentUserId + + + currentUsermail + + + currentUserName + + + dataAbertura + + + dataColeta + + + dataEmissaoApiNfe + + + dataEmissaoNfe + + + dataEntradaNfeConsulta + + + dataEntrega + + + dataValidacaoGestor + + + descricao + + + emailSolicitante + + + estabelecimento + + + excelUpload + + + fdAnexo_Coleta + + + fdAnexo_Entrega + + + fdAnexo_recebimento + + + fnAnexo_Nfe + + + formMode + + + fornecedorNfeConsulta + + + gestorEmail + + + gestorEmailE + + + gestorNome + + + gestorNomeE + + + gestor_cc + + + gestor_cce + + + invoiceIdNfeConsulta + + + itensNfeConsulta + + + itensNfeJson + + + justificativa + + + justificativaDecisaoGestor + + + justificativaDecisaoItens + + + lojaNfeConsulta + + + motoristaColetaLogin + + + motoristaColetaNome + + + motoristaEntregaLogin + + + motoristaEntregaNome + + + motoristaEntregaSelecionado + + + numeroNfeConsulta + + + operacaoNfeConsulta + + + productIdItem + + + qtdDivergenciasNfe + + + quantidadeItem + + + requesterId + + + requesterMail + + + requesterName + + + serieNfeConsulta + + + situacaoNfeConsulta + + + storeIdNfeConsulta + + + tipoMotoristaEntrega + + + ufDestino + + + ufOrigem + + + userValidacaoGestor + + + usuarioEmissorNfe + + + validacaoItens + + + valorNfeConsulta + + + WKNumProces + + + mecanismo @@ -636,5 +827,530 @@ + + forms + + + + + FLUIGADHOC + + + FLUIGADHOC + + + 3 + + + + + + + FLUIGADHOCPROCESS + + + FLUIGADHOCPROCESS + + + 4 + + + + + + + totvsflow_dataset_tipo_ocorrencia + + + totvsflow_dataset_tipo_ocorrencia + + + 14 + + + + + + + totvsflow_abertura_chamado + + + totvsflow_abertura_chamado + + + 15 + + + + + + + DSFormulariodeAberturadechamado + + + Formulário de Abertura de chamado + + + 20 + + + + + + + Abertura_de_chamados + + + Solicitação de abertura de chamados + + + 21 + + + + + + + DSvistoriadeServico + + + vistoriadeServico + + + 24 + + + + + + + DSFormulariodeReservadesala + + + Formulário de Reserva de sala + + + 34 + + + + + + + totvsflow_dataset_centrocusto + + + totvsflow_dataset_centrocusto + + + 103 + + + + + + + totvsflow_dataset_cadastro_item + + + totvsflow_dataset_cadastro_item + + + 104 + + + + + + + totvsflow_dataset_estabelecimento + + + totvsflow_dataset_estabelecimento + + + 105 + + + + + + + totvsflow_solicitacao_compras + + + totvsflow_solicitacao_compras + + + 165 + + + + + + + aberturadechamado_manutencao + + + aberturadechamado_manutencao + + + 400 + + + + + + + Solicitacao_transferencia + + + Solicitacao_transferencia + + + 590 + + + + + + + recrutamento + + + recrutamento + + + 823 + + + + + + + kit_aniversariantes + + + Aniversariantes + + + 7690 + + + + + + + kit_cardapio + + + Cardápio do Dia + + + 7695 + + + + + + + kit_convenios + + + Convênios + + + 7703 + + + + + + + kit_news + + + Notícias + + + 7709 + + + + + + + compras_digital + + + compras_digital + + + 9305 + + + + + + + dpf_di_formulario_processo_admissao + + + Digte_Public_Form_Di_Formulario_Processo_Admissao_Protheus + + + 9626 + + + + + + + dpf_cadastro_status + + + Digte_Public_Form_Status + + + 9627 + + + + + + + dpf_configuracoes + + + Digte_Public_Form_Configuracoes + + + 9628 + + + + + + + dpf_cadastro_jornada + + + Digte_Public_Form_Jornada + + + 9629 + + + + + + + dpf_tipo_documento + + + Digte_Public_Form_Tipo_Documento + + + 9630 + + + + + + + dpf_dataset + + + Digte_Public_Form_Dataset + + + 9631 + + + + + + + dpf_di_configuracao + + + Digte_Public_Form_Di_Configuracoes + + + 9632 + + + + + + + dpf_di_beneficio + + + Digte_Public_Form_Di_Beneficios + + + 9633 + + + + + + + dpf_di_compl_contrato + + + Digte_Public_Form_Di_Comp_Contrato + + + 9634 + + + + + + + dpf_di_funcao_jornada + + + Digte_Public_Form_Di_Funcao_Jornada + + + 9635 + + + + + + + dpf_dataset_estrutura + + + Digte_Public_Form_Di_Dataset_Estrutura + + + 9636 + + + + + + + dpf_grupo_tipo_contrato + + + Digte_Public_Form_Grupo_Tipo_Contrato + + + 9637 + + + + + + + dpf_tipo_contrato + + + Digte_Public_Form_Tipo_Contrato + + + 9638 + + + + + + + dpf_di_traducao_campo_valor + + + Digte_Public_Form_Di_Traducao_Campo_Valor + + + 9639 + + + + + + + dpf_di_restricoes_cpf + + + Digte_Public_Form_Di_Formulario_Restricao_CPF + + + 9640 + + + + + + + dpf_di_compl_vt + + + Digte_Public_Form_Di_Compl_VT + + + 9641 + + + + + + + dpf_di_traducao_campo + + + Digte_Public_Form_Di_Traducao_Campo + + + 9995 + + + + + + + desligamento + + + desligamento + + + 12959 + + + + + + + form_param_sla_csc + + + Formulário de Parametrização de SLA - Atendimento de Chamado TI + + + 28647 + + + + + + + totvsflow_lancamento_documento + + + totvsflow_lancamento_documento + + + 32331 + + + + + diff --git a/Transferência Ginseng/workflow/diagrams/Solicitação de transferência.process b/Transferência Ginseng/workflow/diagrams/Solicitação de transferência.process index c8bf690..1444688 100644 --- a/Transferência Ginseng/workflow/diagrams/Solicitação de transferência.process +++ b/Transferência Ginseng/workflow/diagrams/Solicitação de transferência.process @@ -1,80 +1,79 @@ - - - - - - + + + + + - - + + - - + + - - - + + + - + - - + + - - + + - + - - + + - - + + - + - - + + - - + + - + - + - - - + + + - - - + + + - - - + + + @@ -83,100 +82,100 @@ - + - - + + - - + + - + - - + + - - - + + + - + - + - - + + - - - + + + - + - + - - + + - - - + + + - + - + - - + + - - - + + + - + - + - - + + - - - + + + - + - + - - - + + + - - - + + + - + @@ -192,9 +191,9 @@ - - - + + + @@ -203,44 +202,44 @@ - + - - + + - - + + - + - - + + - - - + + + - + - + - - - + + + - - - + + + - + @@ -256,54 +255,92 @@ - - - + + + - - - + + + - - + + - - - + + + - + - + - + - - - + + + - - - + + + - - - - - - - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -313,20 +350,6 @@ - - - - - - - - - - - - - - @@ -334,146 +357,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -493,26 +516,26 @@ - + - + - + - + - + - + @@ -525,10 +548,10 @@ - + - + @@ -542,146 +565,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -695,146 +718,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -848,146 +871,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1001,146 +1024,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1154,146 +1177,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1307,26 +1330,26 @@ - + - + - + - + - + - + @@ -1339,10 +1362,10 @@ - + - + @@ -1356,26 +1379,26 @@ - + - + - + - + - + - + @@ -1388,26 +1411,26 @@ - + - + - + - + - + - + @@ -1420,146 +1443,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1568,7 +1591,7 @@ - + @@ -1587,26 +1610,26 @@ - + - + - + - + - + - + @@ -1620,26 +1643,26 @@ - + - + - + - + - + - + @@ -1653,10 +1676,10 @@ - + - + @@ -1672,146 +1695,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1820,8 +1843,8 @@ - - + + @@ -1835,146 +1858,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1989,26 +2012,26 @@ - + - + - + - + - + - + @@ -2023,146 +2046,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2179,146 +2202,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2333,26 +2356,26 @@ - + - + - + - + - + - + @@ -2366,146 +2389,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2521,26 +2544,26 @@ - + - + - + - + - + - + @@ -2553,146 +2576,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2709,146 +2732,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2863,26 +2886,26 @@ - + - + - + - + - + - + @@ -2895,146 +2918,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3054,146 +3077,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3214,146 +3237,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3375,10 +3398,10 @@ - + - + @@ -3392,26 +3415,26 @@ - + - + - + - + - + - + @@ -3426,10 +3449,10 @@ - + - + @@ -3446,10 +3469,10 @@ - + - + @@ -3465,26 +3488,26 @@ - + - + - + - + - + - + @@ -3499,26 +3522,26 @@ - + - + - + - + - + - + @@ -3533,146 +3556,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3687,26 +3710,26 @@ - + - + - + - + - + - + @@ -3720,146 +3743,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3874,26 +3897,26 @@ - + - + - + - + - + - + @@ -3906,146 +3929,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4056,323 +4079,358 @@ - - + + + + + + + + + + + + + + + + + + + + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - - - - - - - - - - - - - - - - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Transferência Ginseng/workflow/scripts/Solicitação de transferência.beforeTaskSave.js b/Transferência Ginseng/workflow/scripts/Solicitação de transferência.beforeTaskSave.js new file mode 100644 index 0000000..0220c19 --- /dev/null +++ b/Transferência Ginseng/workflow/scripts/Solicitação de transferência.beforeTaskSave.js @@ -0,0 +1,205 @@ +function beforeTaskSave(colleagueId, nextSequenceId, userList) { + try { + var currentState = parseInt(getValue("WKNumState"), 10); + var completeTask = String(getValue("WKCompletTask") || "false"); + var nextState = parseInt(String(nextSequenceId || "0"), 10); + + if (completeTask !== "true") return; + + if (currentState === 6) { + // Fluxo de cancelamento saindo da atividade 6 nao deve disparar template de nota emitida. + if (nextState === 97) return; + enviarNotificacaoNotaEmitida(); + return; + } + + if (currentState === 31) { + enviarNotificacaoColetaRealizada(); + return; + } + + if (currentState === 57) { + // 61 = cancelamento no diagrama. + if (nextState === 61) return; + enviarNotificacaoEntregaRealizada(); + } + } catch (e) { + log.error("[Transferencia.beforeTaskSave] Erro no beforeTaskSave: " + e); + } +} + +function enviarNotificacaoNotaEmitida() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + notifyTemplate("tpl_nota_emitida", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function enviarNotificacaoColetaRealizada() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var motoristaColetaNome = safeTrim(hAPI.getCardValue("motoristaColetaNome")); + var dataColeta = safeTrim(hAPI.getCardValue("dataColeta")); + var motoristaEntregaNome = safeTrim(hAPI.getCardValue("motoristaEntregaNome")); + var tipoMotoristaEntrega = safeTrim(hAPI.getCardValue("tipoMotoristaEntrega")); + + if (motoristaEntregaNome === "" && tipoMotoristaEntrega === "mesmo") { + motoristaEntregaNome = motoristaColetaNome; + } + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + params.put("motoristaColetaNome", motoristaColetaNome); + params.put("dataColeta", dataColeta); + params.put("motoristaEntregaNome", motoristaEntregaNome); + + notifyTemplate("tpl_coleta_realizada", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function enviarNotificacaoEntregaRealizada() { + var envio = montarContextoEnvio(); + if (!envio.ok) return; + + var motoristaEntregaNome = safeTrim(hAPI.getCardValue("motoristaEntregaNome")); + var dataEntrega = safeTrim(hAPI.getCardValue("dataEntrega")); + var nomerecebedor = safeTrim(hAPI.getCardValue("nomerecebedor")); + + var params = buildCommonParams(envio.processNumber, envio.chaveNfe, envio.processLink); + params.put("motoristaEntregaNome", motoristaEntregaNome); + params.put("dataEntrega", dataEntrega); + params.put("nomerecebedor", nomerecebedor); + + notifyTemplate("tpl_entrega_realizada", envio.destinoEmail, envio.requesterId, params, envio.processNumber, envio.processLink); +} + +function montarContextoEnvio() { + var requesterId = safeTrim(hAPI.getCardValue("requesterId")); + var requesterMail = safeTrim(hAPI.getCardValue("requesterMail")); + + if (requesterId === "" && requesterMail !== "") { + requesterId = findColleagueIdByMail(requesterMail); + } + + // Prioriza email explicito salvo no formulario; fallback para email do colleague. + var destinoEmail = requesterMail; + if (!isValidEmail(destinoEmail)) { + destinoEmail = resolveEmailByColleagueId(requesterId); + } + + if (!isValidEmail(destinoEmail)) { + log.warn("[Transferencia.beforeTaskSave] Email do solicitante invalido. requesterId=" + requesterId + ", requesterMail=[" + requesterMail + "], destinoEmail=[" + destinoEmail + "]"); + return { ok: false }; + } + + var processNumber = safeTrim(getValue("WKNumProces")); + var chaveNfe = onlyDigits(hAPI.getCardValue("chaveNfe")); + if (chaveNfe === "") chaveNfe = safeTrim(hAPI.getCardValue("chaveNfe")); + var processLink = buildProcessLink(processNumber); + + return { + ok: true, + requesterId: requesterId, + destinoEmail: destinoEmail, + processNumber: processNumber, + chaveNfe: chaveNfe, + processLink: processLink + }; +} + +function buildCommonParams(processNumber, chaveNfe, processLink) { + var params = new java.util.HashMap(); + params.put("WKNumProces", processNumber); + params.put("chaveNfe", chaveNfe); + params.put("linkSolicitacao", processLink); + params.put("link", processLink); + return params; +} + +function notifyTemplate(templateCode, destinoEmail, requesterId, params, processNumber, processLink) { + var NOTIFIER_SENDER_USER = "admin"; + var recipients = new java.util.ArrayList(); + recipients.add(destinoEmail); + + notifier.notify(NOTIFIER_SENDER_USER, templateCode, params, recipients, "text/html"); + log.info("[Transferencia.beforeTaskSave] " + templateCode + " enviado. processo=" + processNumber + ", destino=" + destinoEmail + ", requesterId=" + requesterId + ", link=[" + processLink + "]"); +} + +function buildProcessLink(processNumber) { + var BASE_URL_FALLBACK = "https://comerciode188007.fluig.cloudtotvs.com.br"; + var baseUrl = safeTrim(getValue("WKServerURL")); + var companyId = safeTrim(getValue("WKCompany")); + if (baseUrl === "") baseUrl = BASE_URL_FALLBACK; + if (baseUrl.indexOf("http://") !== 0 && baseUrl.indexOf("https://") !== 0) { + baseUrl = "https://" + baseUrl; + } + if (baseUrl.charAt(baseUrl.length - 1) === "/") baseUrl = baseUrl.substring(0, baseUrl.length - 1); + if (companyId === "") companyId = "1"; + if (baseUrl === "" || safeTrim(processNumber) === "") return ""; + return baseUrl + "/portal/p/" + companyId + "/pageworkflowview?app_ecm_workflowview_detailsProcessInstanceID=" + processNumber; +} + +function findColleagueIdByMail(mail) { + var email = safeTrim(mail); + if (email === "") return ""; + + try { + var cMail = DatasetFactory.createConstraint("mail", email, email, ConstraintType.MUST); + var dsColleague = DatasetFactory.getDataset("colleague", null, [cMail], null); + if (!dsColleague || dsColleague.rowsCount < 1) return ""; + + return safeTrim( + dsColleague.getValue(0, "colleaguePK.colleagueId") || + dsColleague.getValue(0, "colleagueId") || + dsColleague.getValue(0, "login") + ); + } catch (e) { + log.warn("[Transferencia.beforeTaskSave] Falha ao buscar solicitante por mail: " + e); + return ""; + } +} + +function resolveEmailByColleagueId(colleagueId) { + var id = safeTrim(colleagueId); + if (id === "") return ""; + + try { + var cActive = DatasetFactory.createConstraint("active", "true", "true", ConstraintType.MUST); + + var cId = DatasetFactory.createConstraint("colleaguePK.colleagueId", id, id, ConstraintType.MUST); + var byId = DatasetFactory.getDataset("colleague", null, [cId, cActive], null); + if (byId && byId.rowsCount > 0) { + return safeTrim(byId.getValue(0, "mail")); + } + + var cLogin = DatasetFactory.createConstraint("login", id, id, ConstraintType.MUST); + var byLogin = DatasetFactory.getDataset("colleague", null, [cLogin, cActive], null); + if (byLogin && byLogin.rowsCount > 0) { + return safeTrim(byLogin.getValue(0, "mail")); + } + } catch (e) { + log.warn("[Transferencia.beforeTaskSave] Falha ao buscar email do solicitante por colleagueId: " + e); + } + + return ""; +} + +function isValidEmail(email) { + var v = safeTrim(email); + if (v === "") return false; + if (/\s/.test(v)) return false; + + var at = v.indexOf("@"); + if (at <= 0 || at !== v.lastIndexOf("@")) return false; + + var dot = v.lastIndexOf("."); + return dot > at + 1 && dot < (v.length - 1); +} + +function safeTrim(value) { + return String(value == null ? "" : value).trim(); +} + +function onlyDigits(value) { + return String(value == null ? "" : value).replace(/\D/g, ""); +} diff --git a/Transferência Ginseng/workflow/scripts/Solicitação de transferência.onNotify.js b/Transferência Ginseng/workflow/scripts/Solicitação de transferência.onNotify.js new file mode 100644 index 0000000..c6cd4a6 --- /dev/null +++ b/Transferência Ginseng/workflow/scripts/Solicitação de transferência.onNotify.js @@ -0,0 +1,27 @@ +function onNotify(subject, receivers, template, params) { + + log.info("===== onNotify GLOBAL ===== Template: " + template); + + var validos = new java.util.ArrayList(); + + for (var i = 0; i < receivers.size(); i++) { + + var email = receivers.get(i); + + log.info("Receiver original: [" + email + "]"); + + if (email && email.indexOf("@") > 0 && email.indexOf(".") > 0) { + validos.add(email); + } else { + log.warn("REMOVIDO EMAIL INVALIDO: [" + email + "] TEMPLATE: " + template); + } + } + + receivers.clear(); + + for (var j = 0; j < validos.size(); j++) { + receivers.add(validos.get(j)); + } + + log.info("TOTAL FINAL RECEIVERS: " + receivers.size()); +} \ No newline at end of file diff --git a/Transferência Ginseng/workflow/scripts/aberturadeChamado.beforeTaskSave.js b/Transferência Ginseng/workflow/scripts/aberturadeChamado.beforeTaskSave.js index 4fc4d00..cc1a845 100644 --- a/Transferência Ginseng/workflow/scripts/aberturadeChamado.beforeTaskSave.js +++ b/Transferência Ginseng/workflow/scripts/aberturadeChamado.beforeTaskSave.js @@ -18,4 +18,6 @@ function beforeTaskSave(colleagueId,nextSequenceId,userList){ log.error("Erro ao buscar os dados do dataset 'colleague'."); } -} \ No newline at end of file +} + + \ No newline at end of file