att
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
application.type=widget
|
||||
application.code=portalfornecedor
|
||||
application.title=portalfornecedor
|
||||
application.description=portalfornecedor
|
||||
application.fluig.version=null
|
||||
application.category=SYSTEM
|
||||
application.renderer=freemarker
|
||||
developer.code=DESKTOP-0E2LAA6
|
||||
developer.name=Home
|
||||
developer.url=http://www.fluig.com
|
||||
application.uiwidget=true
|
||||
application.mobileapp=false
|
||||
application.version=${build.version}-${build.revision}
|
||||
view.file=view.ftl
|
||||
edit.file=edit.ftl
|
||||
locale.file.base.name=portalfornecedor
|
||||
application.resource.js.1=/resources/js/portalfornecedor.js
|
||||
application.resource.css.2=/resources/css/portalfornecedor.css
|
||||
hash=4a16315e9e66fa7d797b3f6b1fb365b69f9a4ce2
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide" data-params="window.MyWidget && MyWidget.instance ? MyWidget.instance() : {}">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide"
|
||||
data-params="MyWidget.instance()">
|
||||
|
||||
<link rel="stylesheet" href="/style-guide/css/fluig-style-guide.min.css">
|
||||
|
||||
<div class="page-wrapper portal-shell">
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-eyebrow">Portal Fornecedor</div>
|
||||
<h2 class="page-title">
|
||||
<i class="flaticon flaticon-account-box"></i>
|
||||
Portal de Envio de Documentos
|
||||
</h2>
|
||||
<p class="page-subtitle">Informe os dados da nota fiscal para comprovação no sistema.</p>
|
||||
</div>
|
||||
|
||||
<div class="form-card">
|
||||
<h4 class="titulo-secao">Dados do documento</h4>
|
||||
<p class="sub-secao">Preencha os campos obrigatórios para iniciar a solicitação.</p>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="form-group col-md-3">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_abertura" id="data_abertura" class="form-control" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3 divEmitidoPor alertaCampo">
|
||||
<label>Emitido por <strong class="text-danger">*</strong></label>
|
||||
|
||||
<select name="emitido_por" id="emitido_por" class="form-control">
|
||||
<option value="">Selecionar emissor</option>
|
||||
<option value="fornecedor">Fornecedor</option>
|
||||
<option value="colaborador">Colaborador</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3 divEntidadeResponsavel alertaCampo">
|
||||
<label>Responsavel pela emissão <strong class="text-danger">*</strong></label>
|
||||
|
||||
<input type="text" class="form-control"
|
||||
name="entidade_responsavel"
|
||||
id="entidade_responsavel"
|
||||
placeholder="Empresa ou colaborador">
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3">
|
||||
<label>E-mail do solicitante</label>
|
||||
|
||||
<input type="email"
|
||||
name="emailSolicitante"
|
||||
id="emailSolicitante"
|
||||
class="form-control"
|
||||
placeholder="email@empresa.com">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="form-group col-md-3 divTipoCadastro alertaCampo">
|
||||
<label>Tipo de cadastro <strong class="text-danger">*</strong></label>
|
||||
|
||||
<select name="tipo_cadastro" id="tipo_cadastro" class="form-control">
|
||||
<option value="">Selecionar</option>
|
||||
<option value="cpf">CPF</option>
|
||||
<option value="cnpj">CNPJ</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3 divCnpj alertaCampo">
|
||||
<label>CNPJ <strong class="text-danger">*</strong></label>
|
||||
|
||||
<input type="text"
|
||||
name="cnpj"
|
||||
id="cnpj"
|
||||
class="form-control"
|
||||
placeholder="00.000.000/0000-00"
|
||||
mask="00.000.000/0000-00">
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3 divCpf alertaCampo" style="display:none;">
|
||||
<label>CPF <strong class="text-danger">*</strong></label>
|
||||
|
||||
<input type="text"
|
||||
name="cpf"
|
||||
id="cpf"
|
||||
class="form-control"
|
||||
placeholder="000.000.000-00"
|
||||
mask="000.000.000-00">
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3">
|
||||
<label>Tipo de documento</label>
|
||||
|
||||
<select name="tipo_documento" id="tipo_documento" class="form-control">
|
||||
<option value="">Selecionar</option>
|
||||
<option value="danfe">Nota Fiscal Mercadoria</option>
|
||||
<option value="nota_fiscal_servico">Nota Fiscal Servico</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="form-group col-md-6 alertaCampo">
|
||||
<label>Numero do documento <strong class="text-danger">*</strong></label>
|
||||
|
||||
<input type="text"
|
||||
name="numero_documento"
|
||||
id="numero_documento"
|
||||
class="form-control"
|
||||
placeholder="Numero da nota">
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-6">
|
||||
<label>Valor do documento</label>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">R$</span>
|
||||
|
||||
<input type="text"
|
||||
name="valor"
|
||||
id="valor"
|
||||
class="form-control"
|
||||
mask="#000.000.000,00"
|
||||
placeholder="0,00">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="form-group col-md-12">
|
||||
|
||||
<label>Anexar documento <strong class="text-danger">*</strong></label>
|
||||
|
||||
<p class="text-muted">
|
||||
Utilize o botão abaixo para anexar o documento.
|
||||
</p>
|
||||
|
||||
<button type="button" class="btn btn-primary btn-anexo" id="anexaDocumento">
|
||||
<i class="flaticon flaticon-paperclip"></i>
|
||||
Anexar documento
|
||||
</button>
|
||||
|
||||
<input type="file" id="arquivoLocal" style="display:none">
|
||||
|
||||
<div id="arquivoLocalNome" class="arquivo-nome"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-card">
|
||||
|
||||
<h4 class="titulo-secao">Descrição dos serviços</h4>
|
||||
<p class="sub-secao">Inclua detalhes para facilitar a análise.</p>
|
||||
|
||||
<textarea class="form-control"
|
||||
rows="4"
|
||||
id="justificativa"
|
||||
name="justificativa"
|
||||
placeholder="Descreva os serviços prestados"></textarea>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="envioStatus" class="envio-status hidden"></div>
|
||||
|
||||
<div class="text-center">
|
||||
|
||||
<button type="button" id="btnEnviarNota" class="btn btn-enviar btn-lg">
|
||||
Enviar documento
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jboss-web>
|
||||
<context-root>/portalfornecedor</context-root>
|
||||
<disable-cross-context>false</disable-cross-context>
|
||||
</jboss-web>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
</web-app>
|
||||
+346
@@ -0,0 +1,346 @@
|
||||
.wcm-widget-class {
|
||||
background:
|
||||
radial-gradient(circle at 2px 2px, rgba(13, 109, 141, 0.06) 1px, transparent 0) 0 0 / 18px 18px,
|
||||
linear-gradient(180deg, #f8fbfd 0%, #eef3f7 100%);
|
||||
}
|
||||
|
||||
.portal-shell {
|
||||
--pf-bg: #f2f5f8;
|
||||
--pf-card: #ffffff;
|
||||
--pf-border: #d9e2ec;
|
||||
--pf-ink: #133045;
|
||||
--pf-muted: #5f7282;
|
||||
--pf-primary: #0a6d8d;
|
||||
--pf-primary-strong: #085a74;
|
||||
--pf-success: #0f766e;
|
||||
--pf-success-bg: #ecfdf5;
|
||||
--pf-danger: #b42318;
|
||||
|
||||
max-width: 980px;
|
||||
margin: 28px auto;
|
||||
padding: 0 12px 32px;
|
||||
color: var(--pf-ink);
|
||||
}
|
||||
|
||||
.page-header {
|
||||
position: relative;
|
||||
margin: 0 0 20px;
|
||||
padding: 18px 16px 14px;
|
||||
border: 1px solid #0b4a5f;
|
||||
border-radius: 12px;
|
||||
background: #0b556b;
|
||||
box-shadow: 0 8px 20px rgba(11, 85, 107, 0.24);
|
||||
}
|
||||
|
||||
.page-header::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 180px;
|
||||
height: 4px;
|
||||
border-radius: 99px;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.page-brand {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 6px;
|
||||
width: 188px;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page-brand img {
|
||||
max-width: 94%;
|
||||
max-height: 82%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.brand-fallback-text {
|
||||
display: none;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.page-brand.brand-fallback .brand-fallback-text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.page-eyebrow {
|
||||
display: inline-block;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #d7f0f7;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 34px;
|
||||
line-height: 1.15;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.page-title i {
|
||||
margin-right: 8px;
|
||||
color: #d7f0f7;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
margin: 8px 0 0;
|
||||
color: #d5e8ef;
|
||||
font-size: 15px;
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: var(--pf-card);
|
||||
border: 1px solid var(--pf-border);
|
||||
border-radius: 14px;
|
||||
padding: 22px 20px 16px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 8px 24px rgba(16, 24, 40, 0.06);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.portal-shell .page-header .page-title,
|
||||
.portal-shell .page-header .page-title i {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.portal-shell .page-header .page-subtitle {
|
||||
color: #e6f2f6 !important;
|
||||
}
|
||||
|
||||
.portal-shell .page-header .page-eyebrow {
|
||||
color: #dff6ff !important;
|
||||
}
|
||||
|
||||
.portal-shell .form-card {
|
||||
background: #ffffff !important;
|
||||
border-color: #cfdce8 !important;
|
||||
}
|
||||
|
||||
.portal-shell .arquivo-nome:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 12px 30px rgba(16, 24, 40, 0.08);
|
||||
}
|
||||
|
||||
.titulo-secao {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
line-height: 1.2;
|
||||
font-weight: 800;
|
||||
color: #0b3f55;
|
||||
}
|
||||
|
||||
.sub-secao {
|
||||
margin: 6px 0 18px;
|
||||
color: var(--pf-muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-group > label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #324b5d;
|
||||
}
|
||||
|
||||
.portal-shell .form-control,
|
||||
.portal-shell .input-group-addon,
|
||||
.portal-shell select.form-control {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.portal-shell .form-control {
|
||||
height: 40px;
|
||||
border: 1px solid #c9d5e2;
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.portal-shell textarea.form-control {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.portal-shell .form-control:hover {
|
||||
border-color: #8fb5c3;
|
||||
}
|
||||
|
||||
.portal-shell .form-control:focus {
|
||||
border-color: #0a6d8d;
|
||||
box-shadow: 0 0 0 3px rgba(10, 109, 141, 0.12);
|
||||
}
|
||||
|
||||
.portal-shell .has-error .form-control,
|
||||
.portal-shell .alertaCampo.has-error .form-control {
|
||||
border-color: var(--pf-danger);
|
||||
}
|
||||
|
||||
.btn-anexo {
|
||||
background: #eef4f7;
|
||||
border: 1px dashed #9db7c5;
|
||||
color: #133045;
|
||||
border-radius: 8px;
|
||||
padding: 10px 14px;
|
||||
font-weight: 700;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-anexo:hover {
|
||||
background: #e4eef3;
|
||||
}
|
||||
|
||||
.arquivo-nome {
|
||||
margin-top: 10px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: #f4f8fb;
|
||||
border: 1px solid #d7e5ef;
|
||||
color: #365266;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.btn-enviar {
|
||||
margin-top: 10px;
|
||||
min-width: 220px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #0a6d8d 0%, #0f8f98 100%);
|
||||
border: none;
|
||||
padding: 12px 28px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-enviar:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 10px 22px rgba(10, 109, 141, 0.25);
|
||||
}
|
||||
|
||||
.envio-status {
|
||||
margin: 0 0 14px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid transparent;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.envio-status.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.envio-status.success {
|
||||
color: #065f46;
|
||||
background: var(--pf-success-bg);
|
||||
border-color: #a7f3d0;
|
||||
}
|
||||
|
||||
.envio-status.error {
|
||||
color: #7a271a;
|
||||
background: #fef3f2;
|
||||
border-color: #fecdca;
|
||||
}
|
||||
|
||||
.portal-success-state {
|
||||
max-width: 760px;
|
||||
margin: 32px auto;
|
||||
padding: 26px 24px;
|
||||
border: 1px solid #b7ebd8;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(180deg, #f4fffb 0%, #ecfdf5 100%);
|
||||
animation: fadeIn 0.4s ease;
|
||||
}
|
||||
|
||||
.portal-success-title {
|
||||
margin: 0 0 8px;
|
||||
color: #0f5132;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.portal-success-desc {
|
||||
margin: 0;
|
||||
color: #1f5f46;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.portal-shell {
|
||||
padding: 0 10px 24px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
max-width: 100%;
|
||||
padding-right: 184px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding-top: 76px;
|
||||
}
|
||||
|
||||
.page-brand {
|
||||
left: 0;
|
||||
right: auto;
|
||||
top: 8px;
|
||||
width: 164px;
|
||||
height: 58px;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
padding: 16px 14px 10px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.btn-enviar {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
+460
@@ -0,0 +1,460 @@
|
||||
if (typeof window !== "undefined") {
|
||||
window.WCMAPI = window.WCMAPI || {};
|
||||
if (typeof window.WCMAPI.isMobileAppMode !== "function") {
|
||||
window.WCMAPI.isMobileAppMode = function () { return false; };
|
||||
}
|
||||
}
|
||||
function showCamera(param) {
|
||||
if (typeof JSInterface !== "undefined" && JSInterface && typeof JSInterface.showCamera === "function") {
|
||||
JSInterface.showCamera(param);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var MyWidget = SuperWidget.extend({
|
||||
init: function () {
|
||||
this.root = $("#MyWidget_" + this.instanceId);
|
||||
this.anexoInfo = null;
|
||||
this.gedParentFolderId = 10;
|
||||
this.isSending = false;
|
||||
this.bindEvents();
|
||||
this.setupInitialValues();
|
||||
},
|
||||
|
||||
bindEvents: function () {
|
||||
var self = this;
|
||||
|
||||
this.root.find("#btnEnviarNota_" + this.instanceId + ", #btnEnviarNota").off("click").on("click", function () {
|
||||
self.enviarDocumento();
|
||||
});
|
||||
|
||||
this.root.find("#anexaDocumento").off("click").on("click", function () {
|
||||
self.handleAnexo();
|
||||
});
|
||||
|
||||
this.root.find("#arquivoLocal").off("change").on("change", function () {
|
||||
self.onArquivoSelecionado(this);
|
||||
});
|
||||
|
||||
this.root.find("#tipo_cadastro").off("change").on("change", function () {
|
||||
self.toggleTipoCadastro(this.value);
|
||||
self.clearFieldError("#cpf");
|
||||
self.clearFieldError("#cnpj");
|
||||
});
|
||||
|
||||
this.root.find("#cpf").off("input").on("input", function () {
|
||||
this.value = self.mascaraCPF(this.value);
|
||||
});
|
||||
|
||||
this.root.find("#cnpj").off("input").on("input", function () {
|
||||
this.value = self.mascaraCNPJ(this.value);
|
||||
});
|
||||
},
|
||||
|
||||
setupInitialValues: function () {
|
||||
this.root.find("#data_abertura").val(this.getCurrentDate());
|
||||
this.root.find("#tipo_cadastro").val("cpf").trigger("change");
|
||||
this.root.find("#emitido_por").val("fornecedor");
|
||||
this.root.find("#tipo_documento").val("danfe");
|
||||
this.clearStatus();
|
||||
},
|
||||
|
||||
onArquivoSelecionado: function (inputEl) {
|
||||
var file = inputEl && inputEl.files && inputEl.files[0] ? inputEl.files[0] : null;
|
||||
|
||||
if (!file) {
|
||||
this.anexoInfo = null;
|
||||
this.root.find("#arquivoLocalNome").text("");
|
||||
return;
|
||||
}
|
||||
|
||||
this.anexoInfo = {
|
||||
fileName: file.name,
|
||||
mimeType: file.type || "application/octet-stream",
|
||||
fileSize: file.size || 0,
|
||||
file: file
|
||||
};
|
||||
|
||||
this.root.find("#arquivoLocalNome").text("Arquivo selecionado: " + file.name + " (" + this.formatFileSize(file.size || 0) + ")");
|
||||
this.clearStatus();
|
||||
|
||||
console.log("[portalfornecedor] anexo preparado para envio:", {
|
||||
fileName: this.anexoInfo.fileName,
|
||||
mimeType: this.anexoInfo.mimeType,
|
||||
fileSize: this.anexoInfo.fileSize
|
||||
});
|
||||
},
|
||||
|
||||
handleAnexo: function () {
|
||||
if (showCamera("anexo_documento")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.openAttachmentTab()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.root.find("#arquivoLocal").trigger("click");
|
||||
},
|
||||
|
||||
openAttachmentTab: function () {
|
||||
try {
|
||||
var parentDoc = window.parent && window.parent.document ? window.parent.document : document;
|
||||
var selectors = [
|
||||
"#tab-attachments",
|
||||
"a[href*='attachments']",
|
||||
"a[aria-controls*='attachments']",
|
||||
"[data-tab*='attachments']"
|
||||
];
|
||||
|
||||
for (var i = 0; i < selectors.length; i++) {
|
||||
var el = parentDoc.querySelector(selectors[i]);
|
||||
if (el) {
|
||||
el.click();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
toggleTipoCadastro: function (tipo) {
|
||||
tipo = this.normalizeTipoCadastro(tipo);
|
||||
var divCpf = this.root.find(".divCpf");
|
||||
var divCnpj = this.root.find(".divCnpj");
|
||||
var cpf = this.root.find("#cpf");
|
||||
var cnpj = this.root.find("#cnpj");
|
||||
|
||||
if (tipo === "cpf") {
|
||||
divCpf.show();
|
||||
divCnpj.hide();
|
||||
cpf.prop("readonly", false);
|
||||
cnpj.prop("readonly", true).val("");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tipo === "cnpj") {
|
||||
divCpf.hide();
|
||||
divCnpj.show();
|
||||
cnpj.prop("readonly", false);
|
||||
cpf.prop("readonly", true).val("");
|
||||
return;
|
||||
}
|
||||
|
||||
divCpf.hide();
|
||||
divCnpj.show();
|
||||
cpf.prop("readonly", true).val("");
|
||||
cnpj.prop("readonly", true).val("");
|
||||
},
|
||||
|
||||
enviarDocumento: function () {
|
||||
var self = this;
|
||||
|
||||
if (this.isSending) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.validateRequiredFields()) {
|
||||
this.setStatus("error", "Revise os campos obrigatorios destacados para continuar.");
|
||||
FLUIGC.toast({
|
||||
title: "Aviso",
|
||||
message: "Preencha os campos obrigatorios antes de enviar.",
|
||||
type: "warning"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.anexoInfo || !this.anexoInfo.file) {
|
||||
this.setStatus("error", "Selecione um anexo antes de enviar o documento.");
|
||||
FLUIGC.toast({
|
||||
title: "Aviso",
|
||||
message: "Selecione um anexo antes de enviar o documento.",
|
||||
type: "warning"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var tipoCadastro = this.normalizeTipoCadastro(this.value("#tipo_cadastro"));
|
||||
var cpf = this.onlyDigits(this.value("#cpf"));
|
||||
var cnpj = this.onlyDigits(this.value("#cnpj"));
|
||||
var numeroDocumento = this.value("#numero_documento");
|
||||
var valor = this.normalizeMoney(this.value("#valor"));
|
||||
var documentoPessoa = tipoCadastro === "cpf" ? cpf : cnpj;
|
||||
var cpfField = tipoCadastro === "cpf" ? cpf : "";
|
||||
|
||||
this.setLoading(true, "Enviando documento, aguarde...");
|
||||
|
||||
this.uploadAnexoToECM(this.anexoInfo.file)
|
||||
.done(function (docData) {
|
||||
var payloadProcesso = {
|
||||
targetState: 0,
|
||||
subProcessTargetState: 0,
|
||||
comment: "Solicitacao criada via widget",
|
||||
formFields: {
|
||||
data_abertura: self.value("#data_abertura"),
|
||||
emitido_por: self.value("#emitido_por"),
|
||||
entidade_responsavel: self.value("#entidade_responsavel"),
|
||||
tipo_cadastro: tipoCadastro,
|
||||
emailSolicitante: self.value("#emailSolicitante"),
|
||||
cpf: cpfField || documentoPessoa,
|
||||
tipo_documento: self.value("#tipo_documento"),
|
||||
numero_documento: numeroDocumento,
|
||||
valor: valor,
|
||||
justificativa: self.value("#justificativa"),
|
||||
anexo_documento_id: String(docData.documentId || ""),
|
||||
anexo_documento_nome: self.anexoInfo.fileName,
|
||||
anexo_documento_mime: self.anexoInfo.mimeType
|
||||
}
|
||||
};
|
||||
|
||||
window.__portalfornecedor_lastProcessPayload = payloadProcesso;
|
||||
console.log("[portalfornecedor] payload direto processo:", payloadProcesso);
|
||||
|
||||
self.enviarDiretoProcesso(payloadProcesso)
|
||||
.done(function (response) {
|
||||
console.log("[portalfornecedor] response processo direto:", response);
|
||||
self.setLoading(false);
|
||||
self.renderSuccessState(response);
|
||||
})
|
||||
.fail(function (xhrDireto) {
|
||||
self.setLoading(false);
|
||||
console.warn("[portalfornecedor] falha no envio direto:", xhrDireto);
|
||||
console.error("[portalfornecedor] detalhe erro processo direto:", {
|
||||
status: xhrDireto.status,
|
||||
statusText: xhrDireto.statusText,
|
||||
responseText: xhrDireto.responseText
|
||||
});
|
||||
self.setStatus("error", "Falha ao iniciar processo. Veja o console para detalhes.");
|
||||
FLUIGC.toast({
|
||||
title: "Erro",
|
||||
message: "Falha ao iniciar processo. Veja o console para detalhes.",
|
||||
type: "danger"
|
||||
});
|
||||
});
|
||||
})
|
||||
.fail(function (uploadErr) {
|
||||
self.setLoading(false);
|
||||
console.error("[portalfornecedor] falha upload documento ECM:", uploadErr);
|
||||
self.setStatus("error", "Falha ao enviar anexo para o GED.");
|
||||
FLUIGC.toast({
|
||||
title: "Erro",
|
||||
message: "Falha ao enviar anexo para o GED.",
|
||||
type: "danger"
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
renderSuccessState: function (response) {
|
||||
var processInstanceId = this.extractProcessInstanceId(response);
|
||||
var idText = processInstanceId ? ("Solicitação " + processInstanceId) : "Solicitação";
|
||||
var html = ""
|
||||
+ "<div class='portal-success-state'>"
|
||||
+ " <h3 class='portal-success-title'>" + idText + " enviada com sucesso.</h3>"
|
||||
+ " <p class='portal-success-desc'>Sua Solicitação foi encaminhada para o Grupo Ginseng para análise.</p>"
|
||||
+ "</div>";
|
||||
|
||||
this.root.html(html);
|
||||
console.log("[portalfornecedor] success state renderizado.");
|
||||
},
|
||||
|
||||
extractProcessInstanceId: function (response) {
|
||||
if (!response) return "";
|
||||
if (response.processInstanceId) return response.processInstanceId;
|
||||
if (response.content && response.content.processInstanceId) return response.content.processInstanceId;
|
||||
if (response.content && response.content.processInstanceid) return response.content.processInstanceid;
|
||||
if (response.content && response.content.requestNumber) return response.content.requestNumber;
|
||||
return "";
|
||||
},
|
||||
|
||||
enviarDiretoProcesso: function (payloadProcesso) {
|
||||
return $.ajax({
|
||||
url: "/process-management/api/v2/processes/FlowEssentials_LancamentodeDocumento/start",
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(payloadProcesso)
|
||||
});
|
||||
},
|
||||
|
||||
uploadAnexoToECM: function (file) {
|
||||
var self = this;
|
||||
var dfd = $.Deferred();
|
||||
var fileName = file.name;
|
||||
var uploadUrl = "/api/public/2.0/contentfiles/upload/?fileName=" + encodeURIComponent(fileName);
|
||||
|
||||
fetch(uploadUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream"
|
||||
},
|
||||
body: file
|
||||
})
|
||||
.then(function (resp) {
|
||||
if (!resp.ok) throw new Error("Falha no upload binario");
|
||||
return resp.text();
|
||||
})
|
||||
.then(function () {
|
||||
var companyId = (window.WCMAPI && WCMAPI.organizationId) ? String(WCMAPI.organizationId) : "1";
|
||||
var createPayload = {
|
||||
companyId: companyId,
|
||||
description: fileName,
|
||||
parentId: self.gedParentFolderId,
|
||||
immutable: true,
|
||||
isPrivate: false,
|
||||
downloadEnabled: true,
|
||||
attachments: [{ fileName: fileName }]
|
||||
};
|
||||
|
||||
return fetch("/api/public/ecm/document/createDocument", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8"
|
||||
},
|
||||
body: JSON.stringify(createPayload)
|
||||
});
|
||||
})
|
||||
.then(function (resp) {
|
||||
if (!resp.ok) throw new Error("Falha ao criar documento no GED");
|
||||
return resp.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
var content = data && data.content ? data.content : {};
|
||||
var documentId = content.id || content.documentId;
|
||||
if (!documentId) throw new Error("GED nao retornou documentId");
|
||||
dfd.resolve({ documentId: documentId, raw: data });
|
||||
})
|
||||
.catch(function (err) {
|
||||
dfd.reject(err);
|
||||
});
|
||||
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
setLoading: function (isLoading, message) {
|
||||
this.isSending = !!isLoading;
|
||||
var btn = this.root.find("#btnEnviarNota");
|
||||
|
||||
if (isLoading) {
|
||||
btn.prop("disabled", true).text("Enviando...");
|
||||
this.setStatus("success", message || "Processando...");
|
||||
return;
|
||||
}
|
||||
|
||||
btn.prop("disabled", false).text("Enviar documento");
|
||||
},
|
||||
|
||||
setStatus: function (type, message) {
|
||||
var box = this.root.find("#envioStatus");
|
||||
if (!box.length) return;
|
||||
|
||||
box.removeClass("hidden success error");
|
||||
box.addClass(type === "error" ? "error" : "success");
|
||||
box.text(message || "");
|
||||
},
|
||||
|
||||
clearStatus: function () {
|
||||
var box = this.root.find("#envioStatus");
|
||||
if (!box.length) return;
|
||||
box.removeClass("success error").addClass("hidden").text("");
|
||||
},
|
||||
|
||||
validateRequiredFields: function () {
|
||||
var ok = true;
|
||||
var tipoCadastro = this.normalizeTipoCadastro(this.value("#tipo_cadastro"));
|
||||
|
||||
if (!this.value("#emitido_por")) ok = this.markRequired("#emitido_por") && ok;
|
||||
if (!this.value("#entidade_responsavel")) ok = this.markRequired("#entidade_responsavel") && ok;
|
||||
if (!this.value("#tipo_cadastro")) ok = this.markRequired("#tipo_cadastro") && ok;
|
||||
if (!this.value("#numero_documento")) ok = this.markRequired("#numero_documento") && ok;
|
||||
if (!this.value("#justificativa")) ok = this.markRequired("#justificativa") && ok;
|
||||
|
||||
if (tipoCadastro === "cpf") {
|
||||
if (!this.onlyDigits(this.value("#cpf"))) ok = this.markRequired("#cpf") && ok;
|
||||
this.clearFieldError("#cnpj");
|
||||
} else if (tipoCadastro === "cnpj") {
|
||||
if (!this.onlyDigits(this.value("#cnpj"))) ok = this.markRequired("#cnpj") && ok;
|
||||
this.clearFieldError("#cpf");
|
||||
}
|
||||
|
||||
return ok;
|
||||
},
|
||||
|
||||
markRequired: function (selector) {
|
||||
var input = this.root.find(selector);
|
||||
if (!input.length) return false;
|
||||
|
||||
var container = input.closest(".alertaCampo, .form-group");
|
||||
if (container.length) container.addClass("has-error");
|
||||
|
||||
input.one("input change", function () {
|
||||
if ($.trim($(this).val())) {
|
||||
$(this).closest(".alertaCampo, .form-group").removeClass("has-error");
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
clearFieldError: function (selector) {
|
||||
var input = this.root.find(selector);
|
||||
if (!input.length) return;
|
||||
input.closest(".alertaCampo, .form-group").removeClass("has-error");
|
||||
},
|
||||
|
||||
value: function (selector) {
|
||||
return (this.root.find(selector).val() || "").toString().trim();
|
||||
},
|
||||
|
||||
getCurrentDate: function () {
|
||||
var now = new Date();
|
||||
var yyyy = now.getFullYear();
|
||||
var mm = ("0" + (now.getMonth() + 1)).slice(-2);
|
||||
var dd = ("0" + now.getDate()).slice(-2);
|
||||
return yyyy + "-" + mm + "-" + dd;
|
||||
},
|
||||
|
||||
mascaraCPF: function (value) {
|
||||
var v = (value || "").replace(/\D/g, "").slice(0, 11);
|
||||
v = v.replace(/(\d{3})(\d)/, "$1.$2");
|
||||
v = v.replace(/(\d{3})(\d)/, "$1.$2");
|
||||
v = v.replace(/(\d{3})(\d{1,2})$/, "$1-$2");
|
||||
return v;
|
||||
},
|
||||
|
||||
mascaraCNPJ: function (value) {
|
||||
var v = (value || "").replace(/\D/g, "").slice(0, 14);
|
||||
v = v.replace(/^(\d{2})(\d)/, "$1.$2");
|
||||
v = v.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3");
|
||||
v = v.replace(/\.(\d{3})(\d)/, ".$1/$2");
|
||||
v = v.replace(/(\d{4})(\d)/, "$1-$2");
|
||||
return v;
|
||||
},
|
||||
|
||||
onlyDigits: function (value) {
|
||||
return (value || "").replace(/\D/g, "");
|
||||
},
|
||||
|
||||
normalizeMoney: function (value) {
|
||||
var raw = (value || "").toString().trim();
|
||||
if (!raw) return "0,00";
|
||||
if (raw.indexOf(",") >= 0) return raw;
|
||||
if (raw.indexOf(".") >= 0) return raw.replace(".", ",");
|
||||
return raw + ",00";
|
||||
},
|
||||
|
||||
normalizeTipoCadastro: function (value) {
|
||||
return (value || "").toString().trim().toLowerCase();
|
||||
},
|
||||
|
||||
formatFileSize: function (bytes) {
|
||||
var b = Number(bytes || 0);
|
||||
if (b <= 0) return "0 KB";
|
||||
if (b < 1024) return b + " B";
|
||||
if (b < 1048576) return (b / 1024).toFixed(1) + " KB";
|
||||
return (b / 1048576).toFixed(2) + " MB";
|
||||
}
|
||||
});
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user