This commit is contained in:
2026-03-22 16:12:12 -03:00
parent 4bb50f0716
commit 822aa68197
15 changed files with 2878 additions and 1318 deletions
@@ -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:
@@ -353,30 +353,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 +427,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 +474,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($("<option></option>").val("").text("Selecione o motorista"));
select.append($("<option></option>").val("").text(placeholder));
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
@@ -462,6 +514,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 +1101,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 +1210,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 +1285,7 @@ function setSelectedZoomItem(selectedItem) {
$("#gestorEmail").val(selectedItem["emailGestor"] || "");
$("#gestor_cc").val(selectedItem["COLLEAGUE_ID"] || "");
$("#ufDestino").val(selectedItem["UF"] || "");
refreshMotoristasEntregaByUf(true);
}
if (name_item == "estabelecimento") {
@@ -1275,6 +1337,7 @@ function removedZoomItem(removedItem) {
$("#gestorEmail").val("");
$("#gestor_cc").val("");
$("#ufDestino").val("");
refreshMotoristasEntregaByUf(true);
} else if (name_item == "estabelecimento") {
$("#gestorNomeE").val("");
$("#gestorEmailE").val("");
@@ -0,0 +1,57 @@
<div style="font-family: Arial, sans-serif; background-color:#f4f6f8; padding:20px;">
<div style="max-width:600px; margin:auto; background:#ffffff; border-radius:8px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.1);">
<!-- 🔷 HEADER -->
<div style="background:#0a6d8d; padding:15px; text-align:center; color:#ffffff;">
<h2 style="margin:0;">Transferências Ginseng</h2>
<p style="margin:0; font-size:13px;">Notificação de Processo</p>
</div>
<!-- 📄 BODY -->
<div style="padding:25px; color:#333;">
<h3 style="margin-top:0; color:#0a6d8d;">Nota Fiscal Emitida ✅</h3>
<p>Olá,</p>
<p>
Sua solicitação teve a <b>Nota Fiscal emitida com sucesso</b>.
</p>
<!-- 🔹 CARD INFO -->
<div style="background:#f1f5f9; padding:15px; border-radius:6px; margin:20px 0;">
<p style="margin:5px 0;"><b>Nº Solicitação:</b> ${WKNumProces}</p>
<p style="margin:5px 0;"><b>Chave NFe:</b> ${chaveNfe}</p>
</div>
<p>
Clique no botão abaixo para acessar o processo:
</p>
<!-- 🔘 BOTÃO -->
<div style="text-align:center; margin:25px 0;">
<a href="${linkSolicitacao}"
target="_blank"
style="display:inline-block; background:#0a6d8d; color:#ffffff; padding:12px 20px; text-decoration:none; border-radius:5px; font-weight:bold;">
Acessar Solicitação
</a>
</div>
<p style="font-size:12px; color:#888; margin-top:-10px;">
Se o botao nao abrir, copie e cole este link no navegador:<br/>
<span>${linkSolicitacao}</span>
</p>
<p style="font-size:13px; color:#777;">
Este é um e-mail automático, não responda.
</p>
</div>
<!-- 🔻 FOOTER -->
<div style="background:#f1f5f9; text-align:center; padding:10px; font-size:12px; color:#777;">
© Ginseng
</div>
</div>
</div>
@@ -517,8 +517,14 @@
<input type="text" class="form-control transfer-input inputAnexo" name="fdAnexo_Entrega" id="fdAnexo_Entrega" placeholder="Nenhum anexo selecionado" readonly />
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<label class="transfer-label" for="nomerecebedor">Nome de quem recebeu a mercadoria:</label>
<input type="text" class="form-control transfer-input" name="nomerecebedor" id="nomerecebedor" />
</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">
@@ -0,0 +1,44 @@
<div style="font-family: Arial, sans-serif; background-color:#f4f6f8; padding:20px;">
<div style="max-width:600px; margin:auto; background:#ffffff; border-radius:8px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.1);">
<div style="background:#0a6d8d; padding:15px; text-align:center; color:#ffffff;">
<h2 style="margin:0;">Transferências Ginseng</h2>
<p style="margin:0; font-size:13px;">Notificação de Processo</p>
</div>
<div style="padding:25px; color:#333;">
<h3 style="margin-top:0; color:#0a6d8d;">Coleta Realizada</h3>
<p>Olá,</p>
<p>O motorista <b>${motoristaColetaNome}</b> coletou o produto na data <b>${dataColeta}</b>.</p>
<p>O motorista <b>${motoristaEntregaNome}</b> irá realizar a entrega.</p>
<div style="background:#f1f5f9; padding:15px; border-radius:6px; margin:20px 0;">
<p style="margin:5px 0;"><b>Nº Solicitação:</b> ${WKNumProces}</p>
<p style="margin:5px 0;"><b>Chave NFe:</b> ${chaveNfe}</p>
</div>
<p>Clique no botão abaixo para acessar o processo:</p>
<div style="text-align:center; margin:25px 0;">
<a href="${linkSolicitacao}"
target="_blank"
style="display:inline-block; background:#0a6d8d; color:#ffffff; padding:12px 20px; text-decoration:none; border-radius:5px; font-weight:bold;">
Acessar Solicitação
</a>
</div>
<p style="font-size:12px; color:#888; margin-top:-10px;">
Se o botão não abrir, copie e cole este link no navegador:<br/>
<span>${linkSolicitacao}</span>
</p>
<p style="font-size:13px; color:#777;">
Este é um e-mail automático, não responda.
</p>
</div>
<div style="background:#f1f5f9; text-align:center; padding:10px; font-size:12px; color:#777;">
© Ginseng
</div>
</div>
</div>
@@ -0,0 +1,44 @@
<div style="font-family: Arial, sans-serif; background-color:#f4f6f8; padding:20px;">
<div style="max-width:600px; margin:auto; background:#ffffff; border-radius:8px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.1);">
<div style="background:#0a6d8d; padding:15px; text-align:center; color:#ffffff;">
<h2 style="margin:0;">Transferências Ginseng</h2>
<p style="margin:0; font-size:13px;">Notificação de Processo</p>
</div>
<div style="padding:25px; color:#333;">
<h3 style="margin-top:0; color:#0a6d8d;">Entrega Realizada</h3>
<p>Olá,</p>
<p>O motorista <b>${motoristaEntregaNome}</b> entregou a mercadoria na data <b>${dataEntrega}</b>.</p>
<p>Quem recebeu foi: <b>${nomerecebedor}</b>.</p>
<div style="background:#f1f5f9; padding:15px; border-radius:6px; margin:20px 0;">
<p style="margin:5px 0;"><b>Nº Solicitação:</b> ${WKNumProces}</p>
<p style="margin:5px 0;"><b>Chave NFe:</b> ${chaveNfe}</p>
</div>
<p>Clique no botão abaixo para acessar o processo:</p>
<div style="text-align:center; margin:25px 0;">
<a href="${linkSolicitacao}"
target="_blank"
style="display:inline-block; background:#0a6d8d; color:#ffffff; padding:12px 20px; text-decoration:none; border-radius:5px; font-weight:bold;">
Acessar Solicitação
</a>
</div>
<p style="font-size:12px; color:#888; margin-top:-10px;">
Se o botão não abrir, copie e cole este link no navegador:<br/>
<span>${linkSolicitacao}</span>
</p>
<p style="font-size:13px; color:#777;">
Este é um e-mail automático, não responda.
</p>
</div>
<div style="background:#f1f5f9; text-align:center; padding:10px; font-size:12px; color:#777;">
© Ginseng
</div>
</div>
</div>