att transf

This commit is contained in:
Cunha 2026-03-18 10:17:16 -03:00
parent e8445fcf2f
commit 60a17ce6d9
10 changed files with 2586 additions and 1100 deletions

View File

@ -52,6 +52,10 @@ function validateForm(form) {
message += getMessage("Data da coleta", 1, form);
hasErros = true;
}
if (form.getValue("fdAnexo_Coleta") == "") {
message += getMessage("Anexo da Coleta", 3, form);
hasErros = true;
}
var tipoMotoristaEntregaColeta = String(form.getValue("tipoMotoristaEntrega") || "");
if (tipoMotoristaEntregaColeta == "") {
message += getMessage("Quem vai fazer a entrega", 2, form);
@ -90,6 +94,7 @@ function validateForm(form) {
message += getMessage("Validação do recebimento", 2, form);
hasErros = true;
}
if (
(validacaoItens == "divergencia" || validacaoItens == "naoEntregue" || validacaoItens == "incorreto") &&
form.getValue("justificativaDecisaoItens") == ""
@ -130,4 +135,3 @@ function getMessage(texto, tipo, form) {
return 'A quantidade existente de campos "' + texto + '" deve ser maior do que 0.'
}
}

View File

@ -0,0 +1,433 @@
/**
* Plugin JQuery para trabalhar com anexos nos formulários dentro do processo
*
* @author Bruno Gasparetto
* @see https://github.com/brunogasparetto/fluig-form-attachment
*/
/**
* Configurações
*
* @typedef AttachmentSettings
* @property {boolean} showActionButton Exibe o botão de upload/delete. True por padrão.
* @property {boolean} filename Nome que será salvo como descrição do Anexo.
* @property {boolean|string} prefixName Adiciona prefixo ao anexo. False por padrão, True para prefixo aleatório, String para prefixo fixo.
* @property {string} accept Tipos de arquivos aceitos. Segue a regra do accept do input tipo file.
*/
;(function ($) {
"use strict";
const pluginName = "fluigFormAttachment";
const deleteFileClassName = "BtnDeleteFile";
const uploadFileClassname = "BtnUploadFile";
const viewerFileClassname = "BtnViewerFile";
const compressedExtensions = [
'.7z', '.zip', '.rar', '.gz', '.tar', '.tbz2', '.tgz', '.bz2', '.lz', '.lz4','.txz',
'.xz', '.z', '.zst', '.zstd', '.war', '.ear', '.jar','.apk', '.arj', '.ace', '.cab',
];
const isString = item => typeof item === "string";
/**
* Procura o índice do anexo de acordo com sua descrição
*
* @param {string} filename
* @returns {number} -1 se não encontrar
*/
const attachmentFindIndex = (filename) => parent.ECM.attachmentTable.getData().findIndex(attachment => attachment.description === filename);
/**
* Configuração padrão
*
* @type {AttachmentSettings}
*/
const defaults = {
showActionButton: true,
filename: "Anexo",
prefixName: false,
accept: "*",
};
class Plugin {
/**
* @type {AttachmentSettings}
*/
#settings;
/**
* Elemento do arquivo. Pode ser um input ou span (no modo leitura).
*
* @type {JQuery<HTMLElement>}
*/
#input;
/**
* @type {JQuery<HTMLElement>}
*/
#container;
/**
* @type {string}
*/
#attachmentFilename;
/**
* @param {HTMLElement} element
* @param {AttachmentSettings} options
*/
constructor(element, options) {
// Garantir um ID para o Input
if (!element.id && element.nodeName.toLowerCase() === "input") {
element.id = FLUIGC.utilities.randomUUID();
}
this.#settings = $.extend({}, defaults, options);
this.#input = $(element);
this.#attachmentFilename = this.#input.val() || this.#input.text().trim();
this.#input
.prop("readonly", true)
.on("change", () => {
this.#attachmentFilename = this.#input.val();
this.#changeButtonsState();
})
.wrap(`<div class="${pluginName}Component"></div>`)
.after(`<div class="${pluginName}Component_buttons">${this.#getButtonsTemplate()}</div>`);
this.#container = this.#input.closest(`.${pluginName}Component`);
this.#container
.on("click", `.${pluginName}${deleteFileClassName}`, () => this.#confirmDeleteAttachment())
.on("click", `.${pluginName}${uploadFileClassname}`, () => this.#uploadAttachment())
.on("click", `.${pluginName}${viewerFileClassname}`, () => this.#viewAttachment())
;
}
/**
* Indica que o campo está válido
*
* Caso o campo possua algum valor é obrigatório que o anexo
* esteja na tabela de anexos.
*
* @returns {boolean}
*/
isValid() {
return this.#attachmentFilename.length
? this.hasAttachment()
: true
;
}
/**
* Indica se o anexo está na tabela de anexos
*
* @returns {boolean}
*/
hasAttachment() {
const filename = this.#attachmentFilename || this.#input.val() || this.#input.text().trim();
return filename.length > 0 && attachmentFindIndex(filename) !== -1;
}
/**
* Remove o anexo
*
* Método útil para excluir anexos em tabela Pai x Filho.
*/
deleteAttachment() {
const attachmentIndex = parent.ECM.attachmentTable.getData().findIndex(
attachment => attachment.description === this.#attachmentFilename
);
setTimeout(() => this.#input.val("").trigger("change"), 500);
if (attachmentIndex === -1) {
return;
}
parent.WKFViewAttachment.removeAttach([attachmentIndex]);
}
showActionButton() {
this.#settings.showActionButton = true;
this.#input.trigger("change");
}
hideActionButton() {
this.#settings.showActionButton = false;
this.#input.trigger("change");
}
filename(fileName, prefixName) {
if (fileName === undefined) {
return this.#input.data("filename") || this.#settings.filename;
}
this.#settings.filename = fileName;
this.#input.data("filename", fileName);
if (prefixName !== undefined) {
this.prefixName(prefixName);
}
}
prefixName(prefixName) {
if (prefixName === undefined) {
return this.#settings.prefixName;
}
this.#settings.prefixName = prefixName;
}
#getButtonsTemplate() {
const hasFileSelected = this.#attachmentFilename.length !== 0;
const canShowActionButton = this.#canDisplayActionButton();
return `<button type="button" class="${pluginName}BtnAction ${pluginName}${deleteFileClassName} btn btn-danger btn-sm ${(canShowActionButton && hasFileSelected) ? '' : 'hide'}" title="Remover Anexo"><i class="flaticon flaticon-trash icon-sm"></i></button>`
+ `<button type="button" class="${pluginName}BtnAction ${pluginName}${uploadFileClassname} btn btn-success btn-sm ${(canShowActionButton && !hasFileSelected) ? '' : 'hide'}" title="Enviar Anexo"><i class="flaticon flaticon-upload icon-sm"></i></button>`
+ `<button type="button" class="${pluginName}${viewerFileClassname} btn btn-info btn-sm ${hasFileSelected ? '' : 'hide'}" title="Visualizar Anexo"><i class="flaticon flaticon-view icon-sm"></i></button>`
;
}
#canDisplayActionButton() {
const element = this.#input.get(0);
const workflowView = (parent.ECM && parent.ECM.workflowView) ? parent.ECM.workflowView : {};
const userPermissions = String(workflowView.userPermissions || "");
const hasEditPermission = userPermissions.indexOf("P") >= 0;
const isTokenView = location.href.includes('token');
const hasMobileCameraBridge = (
(window.JSInterface && typeof window.JSInterface.showCamera === "function")
|| (parent && parent.JSInterface && typeof parent.JSInterface.showCamera === "function")
);
const isMobileUA = /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent || "");
const allowByContext = !isTokenView || hasMobileCameraBridge || isMobileUA;
const allowByPermission = hasEditPermission || hasMobileCameraBridge || isMobileUA;
return this.#settings.showActionButton
&& allowByPermission
&& allowByContext
&& element.nodeName.toLowerCase() === "input"
&& !element.disabled
;
}
#changeButtonsState() {
const hasFileSelected = this.#attachmentFilename.length !== 0;
if (this.#canDisplayActionButton()) {
if (hasFileSelected) {
this.#container.find(`.${pluginName}${uploadFileClassname}`).addClass("hide");
this.#container.find(`.${pluginName}${deleteFileClassName}`).removeClass("hide");
} else {
this.#container.find(`.${pluginName}${deleteFileClassName}`).addClass("hide");
this.#container.find(`.${pluginName}${uploadFileClassname}`).removeClass("hide");
}
} else {
this.#container.find(`.${pluginName}BtnAction`).addClass("hide");
}
if (hasFileSelected) {
this.#container.find(`.${pluginName}${viewerFileClassname}`).removeClass("hide");
} else {
this.#container.find(`.${pluginName}${viewerFileClassname}`).addClass("hide");
}
}
#confirmDeleteAttachment() {
if (!this.#canDisplayActionButton()) {
return;
}
FLUIGC.message.confirm({
message: `Deseja remover o anexo <b>${this.#attachmentFilename}</b>?`,
title: 'Confirmação',
labelYes: 'Sim, quero remover',
labelNo: 'Não, quero cancelar',
}, result => {
if (!result) {
return;
}
this.deleteAttachment();
});
}
#uploadAttachment() {
if (!this.#canDisplayActionButton()) {
return;
}
let filename = this.#input.data("filename") || this.#settings.filename;
if (this.#settings.prefixName === true) {
filename = FLUIGC.utilities.randomUUID().substring(0, 9) + filename;
} else if (this.#settings.prefixName !== false && isString(this.#settings.prefixName)) {
filename = `${this.#settings.prefixName}-${filename}`;
}
// Evitar conflito de descrição do anexo
if (attachmentFindIndex(filename) !== -1) {
FLUIGC.toast({
title: "Atenção",
message: "Já existe um anexo com essa descrição",
type: "warning",
})
return;
}
parent.$("#ecm-navigation-inputFile-clone")
.attr({
"data-on-camera": "true",
"data-file-name-camera": filename,
"data-inputid": this.#input.attr("id"),
"data-filename": filename,
"multiple": false,
"accept": this.#input.data("accept") || this.#settings.accept,
})
.trigger("click")
;
}
#viewAttachment() {
const attachmentIndex = parent.ECM.attachmentTable.getData().findIndex(
attachment => attachment.description === this.#attachmentFilename
);
if (attachmentIndex === -1) {
FLUIGC.toast({
title: "Atenção",
message: "Anexo não encontrado",
type: "warning"
});
return;
}
const attachment = parent.ECM.attachmentTable.getRow(attachmentIndex);
const physicalFileName = String(
attachment.physicalFileName || attachment.fileName || attachment.name || ""
).toLowerCase();
const isCompressedFile = compressedExtensions.some(extension => physicalFileName.endsWith(extension));
if (attachment.documentId && !isCompressedFile) {
parent.WKFViewAttachment.openAttachmentView(parent.WCMAPI.userCode, attachment.documentId, attachment.version);
} else {
parent.WKFViewAttachment.downloadAttach([attachmentIndex]);
}
}
}
/**
* Instancia o Plugin ou executa algum método do plugin
*
* @param {AttachmentSettings|string} options
* @returns {undefined|boolean|void}
*/
$.fn[pluginName] = function (options) {
if (!parent.WKFViewAttachment || !parent.ECM || !parent.ECM.attachmentTable) {
console.error(`Plugin ${pluginName} executado fora de um processo.`)
return this;
}
// Executa o Método
if (isString(options)) {
const methodName = options;
const methodArgs = Array.prototype.slice.call(arguments, 1);
let returnedValue = undefined;
this.each(function () {
let pluginData = $.data(this, pluginName);
if (!pluginData) {
pluginData = new Plugin(this, {});
$.data(this, pluginName, pluginData);
}
if (!pluginData[methodName]) {
return;
}
returnedValue = pluginData[methodName](...methodArgs);
if (returnedValue !== undefined) {
return false;
}
});
return returnedValue !== undefined
? returnedValue
: this
;
}
return this.each(function () {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Plugin(this, options));
}
});
};
if (!parent.WKFViewAttachment || !parent.ECM || !parent.ECM.attachmentTable) {
return;
}
const loading = FLUIGC.loading(window, {
title: "Aguarde",
textMessage: "Enviando arquivo",
})
$(() => {
// Oculta aba anexos
$("#tab-attachments", parent.document).hide();
parent.$("#ecm_navigation_fileupload")
.on(`fileuploadadd.${pluginName}`, function(e, data) {
// Impede abrir o Loading caso tenha erro no arquivo
const file = data.files[0];
if (parent.ECM.maxUploadSize > 0 && file.size >= (parent.ECM.maxUploadSize * 1024 * 1024)) {
return;
}
if (parent.ECM.newAttachmentsDocs.length
&& parent.ECM.newAttachmentsDocs.findIndex(attachment => attachment.name === file.name) !== -1
) {
return;
}
loading.show();
})
.on(`fileuploadfail.${pluginName}`, () => loading.hide())
.on(`fileuploaddone.${pluginName}`, function() {
// Atualiza o campo do arquivo caso o upload tenha ocorrido
loading.hide();
const btnUpload = parent.document.getElementById("ecm-navigation-inputFile-clone");
const filename = btnUpload.getAttribute("data-filename");
if (attachmentFindIndex(filename) === -1) {
return;
}
$(`#${btnUpload.getAttribute("data-inputid")}`).val(filename).trigger("change");
});
parent.$(document).on(`fileuploadstop.${pluginName}`, () => loading.hide());
});
$("head").append(`<style>
.${pluginName}Component { display: flex; align-items: center; flex-wrap: nowrap; }
.${pluginName}Component input { border-top-right-radius: 0 !important; border-bottom-right-radius: 0 !important; }
.${pluginName}Component_buttons { display: flex; align-items: center; justify-content: flex-end; }
.${pluginName}Component_buttons .btn { outline: none !important; outline-offset: unset !important; border-radius: 0 !important; height: 32px; }
</style>`);
}(jQuery));

File diff suppressed because one or more lines are too long

View File

@ -52,6 +52,7 @@ $(document).ready(function () {
if ($("#formMode").val() == "VIEW") {
showAndBlock(["all"]);
$("#btnConsultarChaveNfe").prop("disabled", true).hide();
updateConferenciaNfeVisibility($("#activity").val());
} else {
//show the right fields
var activity = $("#activity").val();
@ -140,10 +141,11 @@ $(document).ready(function () {
}
updt_line();
} else if (activity == 18) {
if ($("justificativaValidaProblema") != "") {
showAndBlock([0, 4, 6, 24, 57, 31]);
var campoJustificativaProblema = $("#justificativaValidaProblema");
if (campoJustificativaProblema.length && campoJustificativaProblema.val() != "") {
showAndBlock([0, 4, 6, 24, 31, 57]);
} else {
showAndBlock([0, 4, 6, 31]);
showAndBlock([0, 4, 6, 31, 57]);
}
$("#userValidacaoItens").val($("#currentUserName").val());
$("#dataValidacaoItens").val(requestDate[0] + " - " + requestDate[1]);
@ -186,6 +188,8 @@ $(document).ready(function () {
}
updt_line();
}
updateConferenciaNfeVisibility(activity);
}
formatarMoedasTabela("preco___");
@ -197,6 +201,7 @@ $(document).ready(function () {
invisibleBtnUpload("fdAnexo_Coleta");
invisibleBtnUpload("fdAnexo_Entrega");
invisibleBtnUpload("fdAnexo_recebimento");
initAttachmentPlugins();
processarConferenciaNfe();
// gerarTabelaCotacaoIndica("tabelaCotacaoIndica", "tabelaItens");
@ -494,6 +499,70 @@ function applySelectedMotoristaEntregaOption() {
$("#tipoMotoristaEntregaOutro").prop("checked", true);
}
function updateConferenciaNfeVisibility(activity) {
var activityValue = String(activity || $("#activity").val() || "");
var exibirConferencia = (activityValue === "6" || activityValue === "18");
$("#blocoConferenciaNfe").toggle(exibirConferencia);
}
var ATTACHMENT_PLUGIN_CONFIG = {
fnAnexo_Nfe: {
filename: "Nota Fiscal",
accept: ".pdf,.xml,image/*"
},
fdAnexo_Coleta: {
filename: "Comprovante de Coleta",
accept: ".pdf,image/*"
},
fdAnexo_Entrega: {
filename: "Comprovante de Entrega",
accept: ".pdf,image/*"
},
fdAnexo_recebimento: {
filename: "Comprovante de Recebimento",
accept: ".pdf,image/*"
}
};
function initAttachmentPlugins() {
var mode = getFormMode();
var allowedInputs = getAllowedAttachmentInputs();
var hasPlugin = typeof $.fn.fluigFormAttachment === "function";
if (!hasPlugin) {
console.warn("fluigFormAttachment.js nao carregado; campos de anexo sem botoes de upload.");
return;
}
Object.keys(ATTACHMENT_PLUGIN_CONFIG).forEach(function (inputId) {
var cfg = ATTACHMENT_PLUGIN_CONFIG[inputId];
var input = $("#" + inputId);
if (!input.length) return;
var canUploadHere = (mode !== "VIEW" && allowedInputs.indexOf(inputId) >= 0);
try {
if (!input.data("fluigFormAttachment")) {
input.fluigFormAttachment({
filename: cfg.filename,
accept: cfg.accept,
showActionButton: canUploadHere
});
} else {
input.fluigFormAttachment("filename", cfg.filename);
}
if (canUploadHere) {
input.fluigFormAttachment("showActionButton");
} else {
input.fluigFormAttachment("hideActionButton");
}
} catch (e) {
console.error("Falha ao inicializar anexo '" + inputId + "':", e);
}
});
}
function normalizeNfeKey(value) {
return String(value == null ? "" : value).replace(/\D/g, "").substring(0, 44);
}
@ -952,6 +1021,12 @@ var beforeSendValidate = function (numState, nextState) {
if ($("#dataColeta").val() == "") {
throw "'Data da coleta' é obrigatória.";
}
if ($("#fdAnexo_Coleta").val() == "") {
throw "'Anexo da Coleta' é obrigatório.";
}
if (invalidFile("fdAnexo_Coleta")) {
throw "O arquivo informado em 'Anexo da Coleta' não foi encontrado na aba de anexos.";
}
var tipoMotoristaEntrega31 = $("input[name='tipoMotoristaEntrega']:checked").val();
if (!tipoMotoristaEntrega31) {
throw "Informe quem vai fazer a entrega (mesmo motorista da coleta ou outro).";

View File

@ -355,6 +355,12 @@
<input type="text" class="form-control transfer-input" name="dataEmissaoNfe" id="dataEmissaoNfe" readonly />
</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="col-md-12 col-sm-12">
<label class="transfer-label" for="fnAnexo_Nfe">Anexo da Nota Fiscal</label>
<input type="text" class="form-control transfer-input inputAnexo" name="fnAnexo_Nfe" id="fnAnexo_Nfe" placeholder="Nenhum anexo selecionado" readonly />
</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="col-md-9 col-sm-12">
<label class="transfer-label" for="chaveNfe">Chave de acesso para consulta</label>
@ -417,58 +423,7 @@
<input type="text" class="form-control transfer-input" name="lojaNfeConsulta" id="lojaNfeConsulta" readonly />
</div>
</div>
<div class="row" style="margin-top:16px;">
<div class="col-md-12">
<h3 class="transfer-label" style="margin:0 0 8px 0;">Conferência da NFe x Solicitação</h3>
<div id="resumoConferenciaNfe" class="alert alert-info" style="margin-bottom:10px;">
Consulte a chave da NFe para gerar o confronto dos itens.
</div>
<div class="table-responsive">
<table class="table table-striped table-modern">
<thead>
<tr>
<th>Chave de comparação</th>
<th>Qtd. solicitada</th>
<th>Qtd. NFe</th>
<th>Status</th>
</tr>
</thead>
<tbody id="tabelaConferenciaNfeBody">
<tr>
<td colspan="4">Sem conferência.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
<section class="transfer-card activity activity-18">
<h2 class="card-title">Validação do Recebimento</h2>
<div class="row">
<div class="col-md-12">
<label class="transfer-label">Todos os produtos chegaram na loja conforme a solicitação?</label>
<div>
<label class="radio-inline" style="margin-right:15px;">
<input type="radio" name="validacaoItens" value="entregue" />
Sim, conferido e recebido
</label>
<label class="radio-inline">
<input type="radio" name="validacaoItens" value="divergencia" />
Não, existe divergência
</label>
</div>
</div>
</div>
<div class="row justificativaDecisaoItens" style="display:none;margin-top:10px;">
<div class="col-md-12">
<label class="transfer-label" for="justificativaDecisaoItens">Descreva a divergência encontrada</label>
<textarea class="form-control transfer-input" rows="3" name="justificativaDecisaoItens" id="justificativaDecisaoItens" placeholder="Informe quais itens/quantidades divergiram"></textarea>
</div>
</div>
</section>
<section class="transfer-card activity activity-31 activity-57">
<h2 class="card-title">Rastreabilidade de Motorista - Coleta</h2>
<div class="row" style="margin-bottom:10px;">
@ -481,6 +436,12 @@
<input type="text" class="form-control transfer-input" name="dataColeta" id="dataColeta" readonly />
</div>
</div>
<div class="row" style="margin-bottom:10px;">
<div class="col-md-12 col-sm-12">
<label class="transfer-label" for="fdAnexo_Coleta">Anexo da Coleta</label>
<input type="text" class="form-control transfer-input inputAnexo" name="fdAnexo_Coleta" id="fdAnexo_Coleta" placeholder="Nenhum anexo selecionado" readonly />
</div>
</div>
<div class="row" id="blocoTipoMotoristaEntrega" style="margin-bottom:10px;">
<div class="col-md-12 col-sm-12">
<label class="transfer-label">Quem vai fazer a entrega?</label>
@ -518,8 +479,69 @@
<input type="text" class="form-control transfer-input" name="dataEntrega" id="dataEntrega" readonly />
</div>
</div>
<div class="row" style="margin-bottom:10px;">
<div class="col-md-12 col-sm-12">
<label class="transfer-label" for="fdAnexo_Entrega">Anexo da Entrega</label>
<input type="text" class="form-control transfer-input inputAnexo" name="fdAnexo_Entrega" id="fdAnexo_Entrega" placeholder="Nenhum anexo selecionado" readonly />
</div>
</div>
</section>
<section class="transfer-card activity activity-18">
<h2 class="card-title">Validação do Recebimento</h2>
<div class="row" style="margin-top:16px;" id="blocoConferenciaNfe">
<div class="col-md-12">
<h3 class="transfer-label" style="margin:0 0 8px 0;">Conferência da NFe x Solicitação</h3>
<div id="resumoConferenciaNfe" class="alert alert-info" style="margin-bottom:10px;">
Consulte a chave da NFe para gerar o confronto dos itens.
</div>
<div class="table-responsive">
<table class="table table-striped table-modern">
<thead>
<tr>
<th>Chave de comparação</th>
<th>Qtd. solicitada</th>
<th>Qtd. NFe</th>
<th>Status</th>
</tr>
</thead>
<tbody id="tabelaConferenciaNfeBody">
<tr>
<td colspan="4">Sem conferência.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label class="transfer-label">Todos os produtos chegaram na loja conforme a solicitação?</label>
<div>
<label class="radio-inline" style="margin-right:15px;">
<input type="radio" name="validacaoItens" value="entregue" />
Sim, conferido e recebido
</label>
<label class="radio-inline">
<input type="radio" name="validacaoItens" value="divergencia" />
Não, existe divergência
</label>
</div>
</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="col-md-12 col-sm-12">
<label class="transfer-label" for="fdAnexo_recebimento">Anexo de Validação do Recebimento</label>
<input type="text" class="form-control transfer-input inputAnexo" name="fdAnexo_recebimento" id="fdAnexo_recebimento" placeholder="Nenhum anexo selecionado" readonly />
</div>
</div>
<div class="row justificativaDecisaoItens" style="display:none;margin-top:10px;">
<div class="col-md-12">
<label class="transfer-label" for="justificativaDecisaoItens">Descreva a divergência encontrada</label>
<textarea class="form-control transfer-input" rows="3" name="justificativaDecisaoItens" id="justificativaDecisaoItens" placeholder="Informe quais itens/quantidades divergiram"></textarea>
</div>
</div>
</section>
<input type="hidden" name="WKNumProces" id="WKNumProces" value="" />
<input type="hidden" name="activity" id="activity" value="" />
@ -546,6 +568,7 @@
</div>
<script type="text/javascript" src="./excel.js"></script>
<script type="text/javascript" src="./fluigFormAttachment.js"></script>
<script type="text/javascript" src="./script.js"></script>
</body>
</html>

View File

@ -408,6 +408,155 @@
<digitalSignature>false</digitalSignature>
<executionType>0</executionType>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>99</sequence>
</processStatePK>
<stateName>Consultar Entrada</stateName>
<stateDescription>Consultar Entrada</stateDescription>
<instruction></instruction>
<deadlineTime>0</deadlineTime>
<deadlineFieldName></deadlineFieldName>
<joint>false</joint>
<agreementPercentage>0</agreementPercentage>
<engineAllocationId></engineAllocationId>
<selectColleague>1</selectColleague>
<initialState>false</initialState>
<notifyAuthorityDelay>false</notifyAuthorityDelay>
<notifyRequisitionerDelay>false</notifyRequisitionerDelay>
<allowanceAuthorityTime>0</allowanceAuthorityTime>
<frequenceAuthorityTime>0</frequenceAuthorityTime>
<allowanceRequisitionerTime>0</allowanceRequisitionerTime>
<frequenceRequisitionerTime>0</frequenceRequisitionerTime>
<transferAttachments>false</transferAttachments>
<subProcessId></subProcessId>
<formFolder>0</formFolder>
<notifyAuthorityFollowUp>true</notifyAuthorityFollowUp>
<notifyRequisitionerFollowUp>false</notifyRequisitionerFollowUp>
<automatic>false</automatic>
<positionX>1600</positionX>
<positionY>260</positionY>
<forecastedEffortType>0</forecastedEffortType>
<forecastedEffort>0</forecastedEffort>
<notifyManagerFollowUp>false</notifyManagerFollowUp>
<notifyManagerDelay>false</notifyManagerDelay>
<allowanceManagerTime>0</allowanceManagerTime>
<frequenceManagerTime>0</frequenceManagerTime>
<inhibitTransfer>false</inhibitTransfer>
<periodId></periodId>
<stateType>0</stateType>
<bpmnType>82</bpmnType>
<signalId>0</signalId>
<counterSign>false</counterSign>
<openInstances>0</openInstances>
<noticeExpirationAuthorityTime>0</noticeExpirationAuthorityTime>
<noticeExpirationRequisitionerTime>0</noticeExpirationRequisitionerTime>
<noticeExpirationManagerTime>0</noticeExpirationManagerTime>
<destinationStates/>
<digitalSignature>false</digitalSignature>
<executionType>1</executionType>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>104</sequence>
</processStatePK>
<stateName>Verificar problema de lançamento</stateName>
<stateDescription>Verificar problema de lançamento</stateDescription>
<instruction></instruction>
<deadlineTime>0</deadlineTime>
<deadlineFieldName></deadlineFieldName>
<joint>false</joint>
<agreementPercentage>0</agreementPercentage>
<engineAllocationId></engineAllocationId>
<selectColleague>1</selectColleague>
<initialState>false</initialState>
<notifyAuthorityDelay>true</notifyAuthorityDelay>
<notifyRequisitionerDelay>false</notifyRequisitionerDelay>
<allowanceAuthorityTime>3600</allowanceAuthorityTime>
<frequenceAuthorityTime>3600</frequenceAuthorityTime>
<allowanceRequisitionerTime>0</allowanceRequisitionerTime>
<frequenceRequisitionerTime>0</frequenceRequisitionerTime>
<transferAttachments>false</transferAttachments>
<subProcessId></subProcessId>
<formFolder>0</formFolder>
<notifyAuthorityFollowUp>true</notifyAuthorityFollowUp>
<notifyRequisitionerFollowUp>false</notifyRequisitionerFollowUp>
<automatic>false</automatic>
<positionX>1600</positionX>
<positionY>60</positionY>
<forecastedEffortType>0</forecastedEffortType>
<forecastedEffort>0</forecastedEffort>
<notifyManagerFollowUp>false</notifyManagerFollowUp>
<notifyManagerDelay>false</notifyManagerDelay>
<allowanceManagerTime>0</allowanceManagerTime>
<frequenceManagerTime>0</frequenceManagerTime>
<inhibitTransfer>false</inhibitTransfer>
<periodId></periodId>
<stateType>0</stateType>
<bpmnType>80</bpmnType>
<signalId>0</signalId>
<counterSign>false</counterSign>
<openInstances>0</openInstances>
<noticeExpirationAuthorityTime>0</noticeExpirationAuthorityTime>
<noticeExpirationRequisitionerTime>0</noticeExpirationRequisitionerTime>
<noticeExpirationManagerTime>0</noticeExpirationManagerTime>
<destinationStates/>
<digitalSignature>false</digitalSignature>
<executionType>0</executionType>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>103</sequence>
</processStatePK>
<stateName>Intermediário</stateName>
<stateDescription>Intermediário</stateDescription>
<instruction>Evento intermediário do processo</instruction>
<deadlineTime>0</deadlineTime>
<joint>false</joint>
<agreementPercentage>0</agreementPercentage>
<engineAllocationId></engineAllocationId>
<engineAllocationConfiguration></engineAllocationConfiguration>
<selectColleague>0</selectColleague>
<initialState>false</initialState>
<notifyAuthorityDelay>true</notifyAuthorityDelay>
<notifyRequisitionerDelay>false</notifyRequisitionerDelay>
<allowanceAuthorityTime>1</allowanceAuthorityTime>
<frequenceAuthorityTime>1</frequenceAuthorityTime>
<allowanceRequisitionerTime>0</allowanceRequisitionerTime>
<frequenceRequisitionerTime>0</frequenceRequisitionerTime>
<transferAttachments>false</transferAttachments>
<subProcessId></subProcessId>
<formFolder>0</formFolder>
<notifyAuthorityFollowUp>true</notifyAuthorityFollowUp>
<notifyRequisitionerFollowUp>false</notifyRequisitionerFollowUp>
<automatic>false</automatic>
<positionX>1660</positionX>
<positionY>260</positionY>
<forecastedEffortType>0</forecastedEffortType>
<forecastedEffort>0</forecastedEffort>
<notifyManagerFollowUp>false</notifyManagerFollowUp>
<notifyManagerDelay>false</notifyManagerDelay>
<frequenceManagerTime>0</frequenceManagerTime>
<inhibitTransfer>false</inhibitTransfer>
<periodId></periodId>
<stateType>0</stateType>
<bpmnType>43</bpmnType>
<signalId>0</signalId>
<counterSign>false</counterSign>
<openInstances>0</openInstances>
<destinationStates/>
<digitalSignature>false</digitalSignature>
<parentSequence>99</parentSequence>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
@ -505,53 +654,6 @@
<destinationStates/>
<digitalSignature>false</digitalSignature>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>52</sequence>
</processStatePK>
<stateName>Fim</stateName>
<stateDescription>Fim</stateDescription>
<instruction>Atividade final do processo</instruction>
<deadlineTime>0</deadlineTime>
<joint>false</joint>
<agreementPercentage>0</agreementPercentage>
<engineAllocationId></engineAllocationId>
<engineAllocationConfiguration></engineAllocationConfiguration>
<selectColleague>0</selectColleague>
<initialState>false</initialState>
<notifyAuthorityDelay>true</notifyAuthorityDelay>
<notifyRequisitionerDelay>false</notifyRequisitionerDelay>
<allowanceAuthorityTime>0</allowanceAuthorityTime>
<frequenceAuthorityTime>1</frequenceAuthorityTime>
<allowanceRequisitionerTime>0</allowanceRequisitionerTime>
<frequenceRequisitionerTime>0</frequenceRequisitionerTime>
<transferAttachments>false</transferAttachments>
<subProcessId></subProcessId>
<formFolder>0</formFolder>
<notifyAuthorityFollowUp>false</notifyAuthorityFollowUp>
<notifyRequisitionerFollowUp>false</notifyRequisitionerFollowUp>
<automatic>false</automatic>
<positionX>1610</positionX>
<positionY>284</positionY>
<forecastedEffortType>0</forecastedEffortType>
<forecastedEffort>0</forecastedEffort>
<notifyManagerFollowUp>false</notifyManagerFollowUp>
<notifyManagerDelay>false</notifyManagerDelay>
<allowanceManagerTime>0</allowanceManagerTime>
<frequenceManagerTime>0</frequenceManagerTime>
<inhibitTransfer>false</inhibitTransfer>
<periodId></periodId>
<stateType>6</stateType>
<bpmnType>60</bpmnType>
<signalId>0</signalId>
<counterSign>false</counterSign>
<openInstances>0</openInstances>
<destinationStates/>
<digitalSignature>false</digitalSignature>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
@ -646,6 +748,53 @@
<destinationStates/>
<digitalSignature>false</digitalSignature>
</ProcessState>
<ProcessState>
<processStatePK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>101</sequence>
</processStatePK>
<stateName>Fim</stateName>
<stateDescription>Fim</stateDescription>
<instruction>Atividade final do processo</instruction>
<deadlineTime>0</deadlineTime>
<joint>false</joint>
<agreementPercentage>0</agreementPercentage>
<engineAllocationId></engineAllocationId>
<engineAllocationConfiguration></engineAllocationConfiguration>
<selectColleague>0</selectColleague>
<initialState>false</initialState>
<notifyAuthorityDelay>true</notifyAuthorityDelay>
<notifyRequisitionerDelay>false</notifyRequisitionerDelay>
<allowanceAuthorityTime>0</allowanceAuthorityTime>
<frequenceAuthorityTime>1</frequenceAuthorityTime>
<allowanceRequisitionerTime>0</allowanceRequisitionerTime>
<frequenceRequisitionerTime>0</frequenceRequisitionerTime>
<transferAttachments>false</transferAttachments>
<subProcessId></subProcessId>
<formFolder>0</formFolder>
<notifyAuthorityFollowUp>false</notifyAuthorityFollowUp>
<notifyRequisitionerFollowUp>false</notifyRequisitionerFollowUp>
<automatic>false</automatic>
<positionX>1780</positionX>
<positionY>280</positionY>
<forecastedEffortType>0</forecastedEffortType>
<forecastedEffort>0</forecastedEffort>
<notifyManagerFollowUp>false</notifyManagerFollowUp>
<notifyManagerDelay>false</notifyManagerDelay>
<allowanceManagerTime>0</allowanceManagerTime>
<frequenceManagerTime>0</frequenceManagerTime>
<inhibitTransfer>false</inhibitTransfer>
<periodId></periodId>
<stateType>6</stateType>
<bpmnType>60</bpmnType>
<signalId>0</signalId>
<counterSign>false</counterSign>
<openInstances>0</openInstances>
<destinationStates/>
<digitalSignature>false</digitalSignature>
</ProcessState>
</list>
<list>
<ConditionProcessState>
@ -684,8 +833,8 @@
<version>46</version>
<sequence>46</sequence>
</conditionProcessStatePK>
<condition>hAPI.getCardValue(&quot;validacaoItens&quot;) == &quot;entregue&quot;</condition>
<destinationSequenceId>52</destinationSequenceId>
<condition>hAPI.getCardValue(&quot;validacaoItens&quot;) == &quot;entregue&quot; &amp;&amp; hAPI.getCardValue(&quot;dataEntradaNfeConsulta&quot;) != &quot;&quot;</condition>
<destinationSequenceId>99</destinationSequenceId>
<conditionType>0</conditionType>
</ConditionProcessState>
<ConditionProcessState>
@ -858,23 +1007,6 @@
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<linkSequence>82</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>46</initialStateSequence>
<finalStateSequence>52</finalStateSequence>
<returnLabel></returnLabel>
<name></name>
<automaticLink>false</automaticLink>
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
@ -882,7 +1014,7 @@
<version>1</version>
<linkSequence>85</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<actionLabel>Produtos entregue</actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>57</initialStateSequence>
<finalStateSequence>18</finalStateSequence>
@ -943,9 +1075,135 @@
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<linkSequence>100</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>46</initialStateSequence>
<finalStateSequence>99</finalStateSequence>
<returnLabel></returnLabel>
<name></name>
<automaticLink>false</automaticLink>
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<linkSequence>102</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>99</initialStateSequence>
<finalStateSequence>101</finalStateSequence>
<returnLabel></returnLabel>
<name></name>
<automaticLink>false</automaticLink>
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<linkSequence>105</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>103</initialStateSequence>
<finalStateSequence>104</finalStateSequence>
<returnLabel></returnLabel>
<name></name>
<automaticLink>false</automaticLink>
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
<ProcessLink>
<processLinkPK>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<linkSequence>106</linkSequence>
</processLinkPK>
<actionLabel></actionLabel>
<returnPermited>false</returnPermited>
<initialStateSequence>104</initialStateSequence>
<finalStateSequence>99</finalStateSequence>
<returnLabel></returnLabel>
<name></name>
<automaticLink>false</automaticLink>
<defaultLink>false</defaultLink>
<type>0</type>
</ProcessLink>
</list>
<list/>
<list/>
<list>
<WorkflowProcessEvent>
<workflowProcessEventPK>
<companyId>1</companyId>
<eventId>servicetask99</eventId>
<processId>Transferência Ginseng</processId>
<version>1</version>
</workflowProcessEventPK>
<eventDescription>function servicetask99(attempt, message) {
try {
var validacaoItens = safeTrim(hAPI.getCardValue(&quot;validacaoItens&quot;));
// Só precisa consultar entrada da NFe quando o recebimento foi validado como entregue.
if (validacaoItens !== &quot;entregue&quot;) return;
var dataEntrada = safeTrim(hAPI.getCardValue(&quot;dataEntradaNfeConsulta&quot;));
if (dataEntrada !== &quot;&quot;) return;
var chaveNfe = onlyDigits(hAPI.getCardValue(&quot;chaveNfe&quot;));
if (chaveNfe === &quot;&quot;) {
log.warn(&quot;[servicetask99] Chave NFe vazia. Nao foi possivel consultar entrada.&quot;);
return;
}
var cKey = DatasetFactory.createConstraint(&quot;key&quot;, chaveNfe, chaveNfe, ConstraintType.MUST);
var dsNfe = DatasetFactory.getDataset(&quot;ds_fiscal_invoice_by_keys&quot;, null, [cKey], null);
if (!dsNfe || dsNfe.rowsCount &lt; 1) {
log.warn(&quot;[servicetask99] Dataset sem retorno para chave: &quot; + chaveNfe);
return;
}
var dsSuccess = safeTrim(dsNfe.getValue(0, &quot;success&quot;)).toLowerCase() === &quot;true&quot;;
var dsUpdatedAt = safeTrim(dsNfe.getValue(0, &quot;updatedAt&quot;));
if (dsSuccess &amp;&amp; dsUpdatedAt !== &quot;&quot;) {
hAPI.setCardValue(&quot;dataEntradaNfeConsulta&quot;, dsUpdatedAt);
log.info(&quot;[servicetask99] Data de entrada atualizada automaticamente: &quot; + dsUpdatedAt);
return;
}
var dsMessage = safeTrim(dsNfe.getValue(0, &quot;message&quot;));
log.warn(&quot;[servicetask99] Consulta executada sem data de entrada. message=&quot; + dsMessage);
} catch (e) {
log.error(&quot;[servicetask99] Erro na consulta automatica da NFe: &quot; + e);
throw e;
}
}
function safeTrim(value) {
return String(value == null ? &quot;&quot; : value).trim();
}
function onlyDigits(value) {
return String(value == null ? &quot;&quot; : value).replace(/\D/g, &quot;&quot;);
}
</eventDescription>
</WorkflowProcessEvent>
</list>
<list/>
<list>
<SwimLane>
@ -1168,7 +1426,19 @@
<slotId>6</slotId>
</ProcessFormField>
</list>
<list/>
<list>
<ProcessStateService>
<companyId>1</companyId>
<processId>Transferência Ginseng</processId>
<version>1</version>
<sequence>99</sequence>
<attempts>10</attempts>
<sucessFullMessage>Lançamento efetuado com sucesso no RGB</sucessFullMessage>
<serviceName></serviceName>
<frequency>1</frequency>
<frequencyType>2</frequencyType>
</ProcessStateService>
</list>
<list/>
<list>
<ProcessAppConfiguration>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 47 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,48 @@
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, "");
}