Novo git da alteração
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,729 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Solicitação de compra</title>
|
||||
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="/style-guide/css/fluig-style-guide.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="comprasV2.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
<!-- JS -->
|
||||
<script src="/resources/js/jquery/jquery.js"></script>
|
||||
<script src="/resources/js/jquery/jquery-ui.min.js"></script>
|
||||
<script src="/resources/js/mustache/mustache-min.js"></script>
|
||||
<script src="/style-guide/js/fluig-style-guide.min.js"></script>
|
||||
<script type="text/javascript" src="/webdesk/vcXMLRPC.js"></script>
|
||||
<script type="text/javascript" src="compras_digital.js"></script>
|
||||
<script type="text/javascript" src="anexos.js"></script>
|
||||
|
||||
<style>
|
||||
/* Ajuste de altura e alinhamento dos botões com inputs */
|
||||
.input-group .form-control,
|
||||
.input-group .btn {
|
||||
height: 34px;
|
||||
line-height: 1.42857143;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.input-group .btn {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
h6 { color: #AFB0B3 !important; font-weight: normal !important; }
|
||||
h2 {
|
||||
color: #04506b !important;
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
}
|
||||
h2:after {
|
||||
content: "" !important;
|
||||
flex: 1 1 auto !important;
|
||||
border-bottom: 2px solid #04506b !important;
|
||||
margin-left: .5rem !important;
|
||||
}
|
||||
.flaticon { color: #04506b !important; }
|
||||
|
||||
#rcorners {
|
||||
height: 110px;
|
||||
line-height: 110px;
|
||||
color: #fff;
|
||||
border-radius: 0 0 50px 50px;
|
||||
background: linear-gradient(90deg, rgba(4,80,107,1) 0%, rgba(4,80,107,1) 50%, rgba(4,80,107,1) 100%);
|
||||
text-align: center !important;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.change-weight { font-weight: 400 !important; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="fluig-style-guide" style="background-color:white;">
|
||||
<h1 id="rcorners" style="margin:0;">Solicitação de compra</h1>
|
||||
<ul id="wizard-steps" class="steps m-t-20">
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Solicitação</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Validando necessidade</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Solicitando...</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Dados Adicionais</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Indicar Cotação</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Confirmação Cotação</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação Ccusto</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação GERF</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Aprovação CEO</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Receber Produto</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Problema</span></li>
|
||||
<li class="step-item"><span class="step-bullet"></span><span class="step-label">Fim</span></li>
|
||||
</ul>
|
||||
|
||||
<form name="form" role="form">
|
||||
<!-- Campos ocultos -->
|
||||
<input type="hidden" id="WKNumProces" name="WKNumProces">
|
||||
<input type="hidden" id="activity" name="activity">
|
||||
<input type="hidden" id="formMode" name="formMode">
|
||||
<input type="hidden" id="empresa" name="empresa">
|
||||
<input type="hidden" id="requesterMail" name="requesterMail">
|
||||
<input type="hidden" id="requesterId" name="requesterId">
|
||||
<input type="hidden" id="currentUserName" name="currentUserName">
|
||||
<input type="hidden" id="currentUsermail" name="currentUsermail">
|
||||
<input type="hidden" id="currentUserId" name="currentUserId">
|
||||
<input type="hidden" id="moreInfo" name="moreInfo">
|
||||
<input type="hidden" id="gestor_cc" name="gestor_cc">
|
||||
<input type="hidden" id="filialest" name="filialest">
|
||||
<input type="hidden" id="filialdest" name="filialdest">
|
||||
<input type="hidden" id="filialprotheus" name="filialprotheus">
|
||||
<input type="hidden" id="codigocentroCusto" name="codigocentroCusto">
|
||||
<input type="hidden" name="numeroSCProtheus" id="numeroSCProtheus">
|
||||
<input type="hidden" name="statusSCProtheus" id="statusSCProtheus">
|
||||
<input type="hidden" name="solicitanteSCProtheus" id="solicitanteSCProtheus">
|
||||
<input type="hidden" name="emissaoSCProtheus" id="emissaoSCProtheus">
|
||||
<input type="hidden" name="qtdItensSCProtheus" id="qtdItensSCProtheus">
|
||||
<input type="hidden" name="dataCadastroSCProtheus" id="dataCadastroSCProtheus">
|
||||
<input type="hidden" name="horaCadastroSCProtheus" id="horaCadastroSCProtheus">
|
||||
<input type="hidden" name="cotacaoSCProtheus" id="cotacaoSCProtheus">
|
||||
<input type="hidden" name="pedidoSCProtheus" id="pedidoSCProtheus">
|
||||
<input type="hidden" name="statusAtendimento" id="statusAtendimento">
|
||||
|
||||
|
||||
|
||||
<div class="container activity-all">
|
||||
<!-- ACTIVITY 0 / 1 - Dados da solicitação -->
|
||||
<div class="activity activity-0 activity-1">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-tests-central icon-md" aria-hidden="true"></i>Dados da solicitação</h2>
|
||||
<button type="button" class="btn btn-info btn-sm" id="btnHistorico"
|
||||
style="background-color:#04506b; border-color:#04506b;">
|
||||
<i class="fluigicon fluigicon-eye-open"></i> Ver Histórico
|
||||
</button>
|
||||
<h6>Dados referentes aos responsáveis pela abertura e pela solicitação do atual processo.</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Linha 1 -->
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-2 col-xs-12">
|
||||
<label>Tipo de Solicitação</label>
|
||||
<select name="tipoSolicitacao" id="tipoSolicitacao" class="form-control" required>
|
||||
<option value="">Selecione</option>
|
||||
<option>Material</option>
|
||||
<option>Serviço</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Usuário solicitante</label>
|
||||
<input type="text" name="usuarioSolicitante" id="usuarioSolicitante" class="form-control"
|
||||
placeholder="Inserir nome completo do solicitante. Ex: João da Silva"
|
||||
data-protection="Usuário solicitante" data-protection-anonymizable data-protection-sensitive
|
||||
data-protection-name data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>E-mail do solicitante</label>
|
||||
<input type="email" name="emailSolicitante" id="emailSolicitante" class="form-control"
|
||||
placeholder="Inserir e-mail do solicitante. Ex: joaodasilva@mail.com"
|
||||
data-protection="E-mail do solicitante" data-protection-anonymizable data-protection-sensitive
|
||||
data-protection-mail data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-4 col-xs-12 divEstabelecimentoFilial alertaCampo">
|
||||
<label for="zoom">Estabelecimento/Filial <span class="required text-danger"><strong>*</strong></span></label>
|
||||
<input type="zoom" class="form-control" name="estabelecimento" id="estabelecimento" data-zoom="{
|
||||
'displayKey':'LOJA',
|
||||
'placeholder': 'Buscar nome do estabelecimento ou filial',
|
||||
'datasetId':'dsSysCompan',
|
||||
'fields':[
|
||||
{'field':'LOJA','label':'Filial','standard':'true','search':'true'},
|
||||
{'field':'CNPJ','label':'CNPJ','standard':'true'},
|
||||
{'field':'ESTADO','label':'ESTADO','standard':'true'}
|
||||
]
|
||||
}">
|
||||
<p class="help-block" id="estabelecimentoFilial" style="display:none;position:absolute;font-size:12px;">
|
||||
Preenchimento obrigatório
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12 divCentroCusto alertaCampo">
|
||||
<label for="zoom">Centro de custo <span class="required text-danger"><strong>*</strong></span></label>
|
||||
<input type="zoom" class="form-control" name="centro_custo" id="centro_custo" data-zoom="{
|
||||
'displayKey':'centroCusto',
|
||||
'placeholder': 'Buscar número ou nome do centro de custo',
|
||||
'datasetId':'ds_centroCusto',
|
||||
'fields':[
|
||||
{'field':'codigoCentroCusto','label':'Código','standard':'true','search':'true'},
|
||||
{'field':'centroCusto','label':'Nome','search':'true'},
|
||||
{'field':'gestorCentroCusto','label':'gestorCentroCusto','visible':'false'},
|
||||
{'field':'idGestor','label':'idGestor','visible':'false'},
|
||||
{'field':'emailGestor','label':'emailGestor','visible':'false'}
|
||||
]
|
||||
}">
|
||||
<p class="help-block" id="centroCusto" style="display:none;position:absolute;font-size:12px;">
|
||||
Preenchimento obrigatório
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group col-md-2 col-xs-12">
|
||||
<label>Urgência</label>
|
||||
<select name="urgencia" id="urgencia" class="form-control">
|
||||
<option value="">Selecione</option>
|
||||
<option>Normal</option>
|
||||
<option>Urgente</option>
|
||||
<option>Emergencial</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Linha 3 -->
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-4 col-xs-12">
|
||||
<label for="descProduto">Produto/serviço</label>
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="produtoCod" id="produtoCod">
|
||||
<input type="text" name="descProduto" id="descProduto" class="form-control" placeholder="Buscar..." readonly>
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-info" type="button" id="btnBuscaProd">
|
||||
<span class="fluigicon fluigicon-search"></span>
|
||||
</button>
|
||||
<button class="btn btn-danger" type="button" id="btnLimpaProd">
|
||||
<span class="fluigicon fluigicon-trash"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-2 col-xs-12">
|
||||
<label>Quantidade </label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button type="button" class="btn btn-danger" id="qtdMenos">−</button></span>
|
||||
<input type="number" min="0" step="1" name="quantidade" id="quantidade" class="form-control text-center" value="0" required>
|
||||
<span class="input-group-btn"><button type="button" class="btn btn-success" id="qtdMais">+</button></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Botão adicionar item (oculto) -->
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-8 col-xs-12 text-center">
|
||||
<button type="button" id="btnAddItem" class="btn btn-primary" style="display:none;">
|
||||
<span class="fluigicon fluigicon-add"></span> Adicionar Item
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Painel Itens -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>Itens</strong></div>
|
||||
<div class="panel-body">
|
||||
<table id="tbItens" tablename="tbItens" class="table table-bordered" noaddbutton="true" nodeletebutton="true">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Código</th>
|
||||
<th>Descrição</th>
|
||||
<th>Qtd</th>
|
||||
<th>Data Limite</th>
|
||||
<th>*</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Linha modelo -->
|
||||
<tr class="tableRow" detail="true">
|
||||
<td><span class="tableIndex"></span></td>
|
||||
<td><input type="text" name="Codproduto" class="form-control" readonly></td>
|
||||
<td><input type="text" name="produtoDesc" class="form-control" readonly></td>
|
||||
<td><input type="number" name="qtd" class="form-control text-right" min="0" step="1"></td>
|
||||
<td><input type="date" name="dataNec" class="form-control" placeholder="dd/mm/aa"></td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-link" onclick="fnWdkRemoveChild(this)">
|
||||
<span class="fluigicon fluigicon-trash"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-link" onclick="handleProductLink(this)" data-link="">
|
||||
<span class="fluigicon fluigicon-link"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- campo hidden que o Fluig vai gravar -->
|
||||
<input type="hidden" name="produtoLink" class="produto-link">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Linha 5 - Anexo + Observações -->
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Adicionar Anexo?</label>
|
||||
<div class="componentAnexo">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="hidden" class="descAnexo" name="fdComprovante" value="Anexo" />
|
||||
<input type="text" id="fnComprovante" name="fnComprovante" class="form-control inputAnexo input-sm" placeholder="Selecione um arquivo" readonly />
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btnUpFile btn btn-success btn-sm" data-acao="upload" onclick="anexo(event)" title="Selecionar">
|
||||
<i class="fluigicon fluigicon-file-upload icon-sm"></i>
|
||||
</button>
|
||||
<button style="display:none;" type="button" class="btnViewerFile btn btn-info btn-sm" data-acao="viewer" onclick="anexo(event)" title="Visualizar" disabled>
|
||||
<i class="fluigicon fluigicon-eye-open icon-sm"></i>
|
||||
</button>
|
||||
<button style="display:none;" type="button" class="btnDownloadFile btn btn-info btn-sm" data-acao="download" onclick="anexo(event)" title="Download" disabled>
|
||||
<i class="fluigicon fluigicon-download icon-sm"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-8 col-xs-12">
|
||||
<label>Motivo da compra<span class="required text-danger"><strong>*</strong></span></label>
|
||||
<textarea class="form-control" rows="3" id="observacoes" name="observacoes"
|
||||
placeholder="Descreva aqui alguma informação adicional que julgar importante."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-0/1 -->
|
||||
|
||||
<!-- ACTIVITY 4 - Análise da necessidade -->
|
||||
<div class="activity activity-121">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-check-circle" aria-hidden="true"></i>Análise da Necessidade</h2>
|
||||
<h6>Informações complementares sobre a análise da solicitação pelo gestor responsável</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-6 col-xs-12">
|
||||
<label>Responsável por aprovar a solicitação</label>
|
||||
<input type="text" name="user_validacao_gestor" id="user_validacao_gestor" class="form-control" readonly
|
||||
data-protection="Responsável por lançamento de documentos" data-protection-anonymizable
|
||||
data-protection-sensitive data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_validacao_gestor" id="data_validacao_gestor" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_gestor">Justificativa</label>
|
||||
<textarea class="form-control" name="justi_decisao_gestor" id="justi_decisao_gestor"></textarea>
|
||||
<p class="help-block" id="justiDecisaoGestor" style="display:none;">Preenchimento obrigatório</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-4 -->
|
||||
|
||||
<!-- DADOS DO DOCUMENTO -->
|
||||
<div class="activity activity-114">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-totvs-forms icon-md" aria-hidden="true"></i>Dados da Solicitação</h2>
|
||||
<h6>Dados referentes a solicitação.</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="margin-top:15px; border-radius:8px; box-shadow:0 2px 5px rgba(0,0,0,0.1);">
|
||||
<div class="card-body" style="padding:15px; background-color:#f9f9f9;">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p><strong>Número:</strong> <span id="numeroSCProtheus_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Status:</strong> <span id="statusSCProtheus_label" class="badge bg-secondary">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Solicitante:</strong> <span id="solicitanteSCProtheus_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Emissão:</strong> <span id="emissaoSCProtheus_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Qtd. Itens:</strong> <span id="qtdItensSCProtheus_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Data da aprovação:</strong> <span id="dataCadastroSCProtheus_label">-</span> às <span id="horaCadastroSCProtheus_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Status:</strong> <span id="statusSC_label" class="badge bg-secondary">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Cotação:</strong> <span id="cotacaoSC_label">-</span></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p><strong>Pedido:</strong> <span id="pedidoSC_label">-</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CONSULTA COTAÇÃO -->
|
||||
<div class="activity activity-105">
|
||||
<div class="row">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>Consulta Cotação</strong></div>
|
||||
|
||||
<!-- Campo hidden para guardar o total -->
|
||||
<input type="hidden" name="valorTotalCotacao" id="valorTotalCotacao" value="0"/>
|
||||
|
||||
<!-- Tabela Pai-Filho -->
|
||||
<table tablename="tbCotacao" id="tbCotacao" class="table table-bordered" noaddbutton="true" nodeletebutton="true">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Item</th>
|
||||
<th>Produto</th>
|
||||
<th>Qtd</th>
|
||||
<th>Preço</th>
|
||||
<th>Total</th>
|
||||
<th>Selecionar</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- O Fluig precisa de uma linha “modelo” -->
|
||||
<tr>
|
||||
<td><input type="text" name="item" id="item" readonly></td>
|
||||
<td><input type="text" name="produto" id="produto" readonly></td>
|
||||
<td><input type="text" name="qtdc" id="qtdc" readonly></td>
|
||||
<td><input type="text" name="preco" id="preco" readonly></td>
|
||||
<td><input type="text" name="total" id="total" readonly></td>
|
||||
<td><input type="checkbox" name="selecionado" id="selecionado" value="S"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ACTIVITY 137- Aprovar cotação Compras -->
|
||||
<div class="activity activity-137">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-check-circle" aria-hidden="true"></i>Aprovar cotação</h2>
|
||||
<h6>Análise da cotação</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-6 col-xs-12">
|
||||
<label>Usuário responsável da Cotação</label>
|
||||
<input type="text" name="user_validacao_aprova" id="user_validacao_aprova" class="form-control" readonly
|
||||
data-protection="Responsável por aprovar de documentos" data-protection-anonymizable
|
||||
data-protection-sensitive data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_validacao_aprova" id="data_validacao_aprova" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_aprova">Justificativa</label>
|
||||
<textarea class="form-control" name="justi_decisao_aprova" id="justi_decisao_aprova"></textarea>
|
||||
<p class="help-block" id="justiDecisaoGestor" style="display:none;">Preenchimento obrigatório</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ACTIVITY 133- Aprovar cotação Compras -->
|
||||
<div class="activity activity-133">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-check-circle" aria-hidden="true"></i>Aprovação do Gestor do C.Custo</h2>
|
||||
<h6>Aprovação da cotação</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-6 col-xs-12">
|
||||
<label>Gestor responsável da Cotação</label>
|
||||
<input type="text" name="gestor_validacao_aprova" id="gestor_validacao_aprova" class="form-control" readonly
|
||||
data-protection="Responsável por aprovar de documentos" data-protection-anonymizable
|
||||
data-protection-sensitive data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_validacao_aprova_gestor" id="data_validacao_aprova_gestor" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_aprova_gestor">Justificativa</label>
|
||||
<textarea class="form-control" name="justi_decisao_aprova_gestor" id="justi_decisao_aprova_gestor"></textarea>
|
||||
<p class="help-block" id="justi_decisao_aprova_gestor" style="display:none;">Preenchimento obrigatório</p>
|
||||
</div>
|
||||
<div class="form-group col-md-8 col-xs-12">
|
||||
<label>Jusiticativa do solicitante <span class="required text-danger"><strong>*</strong></span></label>
|
||||
<textarea class="form-control" rows="3" id="observacoesdosolicitante" name="observacoesdosolicitante" readonly
|
||||
placeholder="Descreva aqui alguma informação adicional que julgar importante."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-131 -->
|
||||
<!-- ACTIVITY 147- Aprovar cotação Compras -->
|
||||
<div class="activity activity-147">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-check-circle" aria-hidden="true"></i>Aprovação do Gerente Financeiro</h2>
|
||||
<h6>Aprovação do Gerente Financeiro</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-6 col-xs-12">
|
||||
<label>Ger. Financeiro responsável pela Aprovação</label>
|
||||
<input type="text" name="gerf_validacao_aprova" id="gerf_validacao_aprova" class="form-control" readonly
|
||||
data-protection="Responsável por aprovar de documentos" data-protection-anonymizable
|
||||
data-protection-sensitive data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_validacao_aprova_gerf" id="data_validacao_aprova_gerf" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_aprova_gerente">Justificativa</label>
|
||||
<textarea class="form-control" name="justi_decisao_aprova_gerente" id="justi_decisao_aprova_gerente" readonly></textarea>
|
||||
<p class="help-block" id="justi_decisao_aprova_gerente" style="display:none;">Preenchimento obrigatório</p>
|
||||
</div>
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_gc">Justificativa do Gestor do Centro de Custo</label>
|
||||
<textarea class="form-control" name="justi_decisao_gc" id="justi_decisao_gc"readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao__soli">Justificativa do Solicitante</label>
|
||||
<textarea class="form-control" name="justi_decisao__soli" id="justi_decisao__soli" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-131 -->
|
||||
<!-- ACTIVITY 137- Aprovar cotação Compras -->
|
||||
<div class="activity activity-158">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2><i class="flaticon flaticon-check-circle" aria-hidden="true"></i>Aprovação CEO</h2>
|
||||
<h6> Aprovação do CEO</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-6 col-xs-12">
|
||||
<label>Usuário responsável</label>
|
||||
<input type="text" name="ceo_validacao_aprova" id="ceo_validacao_aprova" class="form-control" readonly
|
||||
data-protection="Responsável por aprovar de documentos" data-protection-anonymizable
|
||||
data-protection-sensitive data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo" />
|
||||
</div>
|
||||
<div class="form-group col-md-3 col-xs-12">
|
||||
<label>Data</label>
|
||||
<input type="text" name="data_validacao_aprova_ceo" id="data_validacao_aprova_ceo" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_aprova_ceo">Justificativa</label>
|
||||
<textarea class="form-control" name="justi_decisao_aprova_ceo" id="justi_decisao_aprova_ceo" readonly></textarea>
|
||||
<p class="help-block" id="justi_decisao_aprova_ceo" style="display:none;">Preenchimento obrigatório</p>
|
||||
</div>
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_aprova_ceo">Justificativa do Gerente Financeiro</label>
|
||||
<textarea class="form-control" name="justi_decisao_gerf" id="justi_decisao_gerf" readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisaogc">Justificativa do Gestor do Centro de custo</label>
|
||||
<textarea class="form-control" name="justi_decisaogc" id="justi_decisaogc" readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group col-md-12 divJustiDecisaoGestor alertaCampo">
|
||||
<label for="justi_decisao_solic">Justificativa do Solicitante</label>
|
||||
<textarea class="form-control" name="justi_decisao_solic" id="justi_decisao_solic" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-131 -->
|
||||
<div class="activity activity-18">
|
||||
<div>
|
||||
<br />
|
||||
<h2>
|
||||
<i class="flaticon flaticon-check-circle" aria-hidden="true"></i>
|
||||
Validação do pedido e entrega dos itens
|
||||
</h2>
|
||||
<br />
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- Botão para consultar agora -->
|
||||
<div id="espelhoPedido" style="margin-top:15px;">
|
||||
⏳ Aguardando geração do pedido...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-10 col-xs-6">
|
||||
<label for="userValidacaoItens"> Solicitante </label>
|
||||
<input type="text" name="userValidacaoItens" id="userValidacaoItens" class="form-control"
|
||||
data-protection="Solicitante" data-protection-anonymizable data-protection-sensitive
|
||||
data-protection-name
|
||||
data-protection-class-legitimate-interests="Dado coletado para o funcionamento do processo"
|
||||
readonly />
|
||||
</div>
|
||||
<div class="form-group col-md-2 col-xs-6">
|
||||
<label for="dataValidacaoItens"> Data </label>
|
||||
<input type="text" name="dataValidacaoItens" id="dataValidacaoItens" class="form-control" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12">
|
||||
<label>Houve algum problema com a compra?</label>
|
||||
<span class="text-danger"><strong>*</strong></span><br />
|
||||
<div>
|
||||
<label>
|
||||
<input name="validacaoItens" id="validacaoItensEntregue" value="entregue" type="radio" />
|
||||
<span class="change-weight">Não houve problema</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input name="validacaoItens" id="validacaoItensNaoEntregue" value="naoEntregue" type="radio" />
|
||||
<span class="change-weight">Pedido não entregue</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input name="validacaoItens" id="validacaoItensIncorreto" value="incorreto" type="radio" />
|
||||
<span class="change-weight">Entregue com inconsistência (qualidade, quantidade,
|
||||
embalagem)</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justificativaDecisaoItens">
|
||||
<div class="form-field">
|
||||
<div class="form-input">
|
||||
<div class="form-group col-md-12">
|
||||
<label for="justificativaDecisaoItens">Justificativa</label>
|
||||
<span class="text-danger"><strong>*</strong></span>
|
||||
<textarea class="form-control requiredInput"
|
||||
placeholder="Insira a justificativa sobre a validação dos itens" name="justificativaDecisaoItens"
|
||||
id="justificativaDecisaoItens"></textarea>
|
||||
<p class="text-danger text-error">
|
||||
Preenchimento obrigatório.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="activity activity-24">
|
||||
<div>
|
||||
<br />
|
||||
<h2>
|
||||
<i class="flaticon flaticon-document-check" aria-hidden="true"></i>
|
||||
Validar problema: considerações de compras
|
||||
</h2>
|
||||
<h6>Dados referentes às possíveis implicações desta compra.</h6>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label for="justificativaValidaProblema">Quais as suas considerações?</label>
|
||||
<span class="text-danger"><strong>*</strong></span>
|
||||
<textarea placeholder="Insira as considerções desta compra." class="form-control"
|
||||
name="justificativaValidaProblema" id="justificativaValidaProblema"></textarea>
|
||||
<p class="text-danger text-error">
|
||||
Preenchimento obrigatório.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /activity-18 -->
|
||||
<br><br>
|
||||
<h6>Todos os campos com * são de preenchimento obrigatório.</h6>
|
||||
</div><!-- /container -->
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,437 @@
|
||||
/**
|
||||
* Toda a lógica para o correto funcionamento desse componente foi feito em cima das classes abaixo:
|
||||
* .componentAnexo, .descAnexo, .inputAnexo, .btnUpFile, .btnViewerFile, .btnDownloadFile e o atributo data-acao
|
||||
* Sem elas o código não irá funcionar, então se por acaso você quiser alterar os nomes dessas classes
|
||||
* lembre-se de alterar nas funções desse arquivo e também no css
|
||||
*/
|
||||
|
||||
/**
|
||||
* Direciona para cada função correspondente ao valor que esta no atributo data-acao do botão
|
||||
* @param {object} event Parâmetro obrigatório, o própio elemento que sofreu o evento click
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function anexo(event){
|
||||
console.log("event")
|
||||
console.log(event)
|
||||
try{
|
||||
const acao = event.currentTarget.getAttribute("data-acao");
|
||||
const inputFile = $(event.currentTarget).parent().parent().find(".inputAnexo")[0]
|
||||
const fileDescription = $(event.currentTarget).parent().parent().find(".descAnexo").val()
|
||||
if(acao == "upload"){
|
||||
uploadFile(fileDescription, inputFile.id)
|
||||
}
|
||||
if(acao == "viewer"){
|
||||
viewerFile(fileDescription)
|
||||
}
|
||||
if(acao == "download"){
|
||||
downloadFile(fileDescription, inputFile.id)
|
||||
}
|
||||
if(acao == "delete"){
|
||||
removeFileConfirm(fileDescription, inputFile.id)
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função anexo")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Envia arquivos para a aba Anexos do Fluig
|
||||
* Função adaptada por Sérgio Machado
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que ficará na aba anexos do Fluig
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @return {void}
|
||||
*/
|
||||
function uploadFile(fileDescription, idInput) {
|
||||
try{
|
||||
var tabAttachments = parent.document.getElementById("tab-attachments");
|
||||
if (tabAttachments) {
|
||||
//Verifica se o navegador é o Ie9 para realizar o devido tratamento
|
||||
if (parent.WCMAPI.isIe9()) {
|
||||
$(".ecm-navigation-silverlight", parent.document).show("fade").css("top", 0);
|
||||
$("#ecm-navigation-silverlight", parent.document).attr({
|
||||
"data-on-camera": "true", "data-file-name-camera": fileDescription, "data-inputNameFile": idInput
|
||||
});
|
||||
$(parent.document).on("keyup", this.actionKeyup)
|
||||
} else {
|
||||
var element = parent.document.getElementById("ecm-navigation-inputFile-clone");
|
||||
if (element && document.createEvent) {
|
||||
element.setAttribute("data-on-camera", "true");
|
||||
if (fileDescription && idInput) {
|
||||
element.setAttribute("data-file-name-camera", fileDescription)
|
||||
element.setAttribute("data-inputNameFile", idInput)
|
||||
}
|
||||
//Realiza o click no botão "Carregar arquivos" que tem na aba de anexos
|
||||
element.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função uploadFile")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Função executada após a escolha do arquivo a ser enviado para o Fluig.
|
||||
* Verifica se o anexo já existe, seta o valor do arquivo fisico no campo e altera o estado dos botões
|
||||
* @return {void}
|
||||
*/
|
||||
$(function(){
|
||||
try{
|
||||
window.parent.$("#ecm-navigation-inputFile-clone").on('change', function(e) {
|
||||
const inputNameFile = this.getAttribute("data-inputNameFile");
|
||||
const fileDescription = this.getAttribute("data-file-name-camera");
|
||||
const filePhisical = this.files[0].name;
|
||||
if(fileDescription && fileDescription){
|
||||
/**
|
||||
* O trecho de código abaixo percorre os anexos do Fluig e caso já exista um anexo com a mesma descrição, ele será removido.
|
||||
* Em seguida limpa o campo onde é armazenado o nome fisico do arquivo
|
||||
*/
|
||||
$.each(parent.ECM.attachmentTable.getData(), function(i, attachment) {
|
||||
var descricao = attachment.description;
|
||||
if (fileDescription == descricao) {
|
||||
parent.WKFViewAttachment.removeAttach([i]);
|
||||
setFilePhisicalName(inputNameFile, "");
|
||||
}
|
||||
});
|
||||
setFilePhisicalName(inputNameFile, filePhisical)
|
||||
if(getFormMode() == "ADD"){
|
||||
btnState(inputNameFile, 'delete', 'download');
|
||||
}
|
||||
if(getFormMode() == "MOD"){
|
||||
btnState(inputNameFile, 'delete', 'viewer');
|
||||
}
|
||||
if(getFormMode() == "VIEW"){
|
||||
btnState(inputNameFile, 'download', 'viewer');
|
||||
}
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado ao selecionar o arquivo")
|
||||
console.error(e)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Visualizar arquivos que esta na aba Anexos do Fluig
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do anexo
|
||||
* @return {void}
|
||||
*/
|
||||
function viewerFile(fileDescription) {
|
||||
try{
|
||||
if(hasFileFluig(fileDescription)){
|
||||
const anexos = parent.ECM.attachmentTable.getData();
|
||||
for(let i = 0; i < anexos.length; i++){
|
||||
var descricao = anexos[i].description;
|
||||
if (fileDescription == descricao) {
|
||||
parent.WKFViewAttachment.openAttachmentView('adm', anexos[i].documentId);
|
||||
return
|
||||
}
|
||||
}
|
||||
}else{
|
||||
FLUIGC.toast({
|
||||
title: "Atenção",
|
||||
message: "Anexo não encontrado",
|
||||
type: "warning"
|
||||
});
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função viewerFile")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Realiza o download do arquivo que esta na aba Anexos do Fluig
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig
|
||||
* @return {void}
|
||||
*/
|
||||
function downloadFile(fileDescription, idInput) {
|
||||
try{
|
||||
const filename = getFormMode() == "VIEW" ? $(`#${idInput}`).text() : $(`#${idInput}`).val()
|
||||
FLUIGC.message.confirm({
|
||||
message: `Deseja baixar o anexo <b>${filename}</b>?`,
|
||||
title: 'Confirmação',
|
||||
labelYes: 'Sim, quero baixar',
|
||||
labelNo: 'Não, quero cancelar',
|
||||
}, function(result) {
|
||||
if (result) {
|
||||
$.each(parent.ECM.attachmentTable.getData(), function(i, attachment) {
|
||||
var descricao = attachment.description;
|
||||
if (fileDescription == descricao) {
|
||||
parent.WKFViewAttachment.downloadAttach([i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função downloadFile")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmação para Remove arquivo que esta na aba Anexos do Fluig
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function removeFileConfirm(fileDescription, idInput) {
|
||||
try{
|
||||
const filename = $(`#${idInput}`).val()
|
||||
FLUIGC.message.confirm({
|
||||
message: `Deseja remover o anexo <b>${filename}</b>?`,
|
||||
title: 'Confirmação',
|
||||
labelYes: 'Sim, quero remover',
|
||||
labelNo: 'Não, quero cancelar',
|
||||
}, function(result) {
|
||||
if (result) {
|
||||
removeFile(fileDescription)
|
||||
setFilePhisicalName(idInput, "")
|
||||
btnState(idInput, "upload", "download")
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função removeFileConfirm")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove arquivo que esta na aba Anexos do Fluig
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo que esta na aba anexos do Fluig
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function removeFile(fileDescription) {
|
||||
try{
|
||||
$.each(parent.ECM.attachmentTable.getData(), function(i, attachment) {
|
||||
if (attachment.description == fileDescription) {
|
||||
parent.WKFViewAttachment.removeAttach([i]);
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função removeFile")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Seta o nome do arquivo fisico no campo e realiza tratativa caso o campo esteja bloqueado pelo enableFields
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @param {String} filePhisical Parâmetro obrigatório, nome do arquivo fisico
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function setFilePhisicalName(idInput, filePhisical){
|
||||
try{
|
||||
if(idInput.indexOf("_") == 0){
|
||||
$("#" + idInput.substring(1)).val(filePhisical);
|
||||
}
|
||||
$("#" + idInput).val(filePhisical);
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função setFilePhisicalName")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Altera o estado e visibilidade dos botões de anexos
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @param {String} acao Parâmetro obrigatório, ação para ser executada no momento do click, se é delete ou upload
|
||||
* @param {String} btn Parâmetro obrigatório, botão secundário que deve sofrer ação de ficar visível ou não. Botão de Download ou Viewer
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function btnState(idInput, acao, btn){
|
||||
try{
|
||||
let btnUpFile = $(`#${idInput}`).parent().parent().find(".btnUpFile");
|
||||
let btnDownloadFile = $(`#${idInput}`).parent().parent().find(".btnDownloadFile");
|
||||
let btnViewerFile = $(`#${idInput}`).parent().parent().find(".btnViewerFile");
|
||||
if(acao == "delete"){
|
||||
btnUpFile.removeClass("btn-success").addClass("btn-danger");
|
||||
btnUpFile.attr({'data-acao': acao, 'title': 'Excluir'});
|
||||
btnUpFile.find("i").removeClass("fluigicon-file-upload").addClass("fluigicon-trash");
|
||||
if(btn == "download"){
|
||||
btnDownloadFile.prop("disabled", false);
|
||||
btnDownloadFile.show()
|
||||
}
|
||||
if(btn == "viewer"){
|
||||
btnViewerFile.prop("disabled", false);
|
||||
btnViewerFile.show()
|
||||
}
|
||||
}
|
||||
if(acao == "upload"){
|
||||
btnUpFile.removeClass("btn-danger").addClass("btn-success");
|
||||
btnUpFile.attr({'data-acao': acao, 'title': 'Selecionar'});
|
||||
btnUpFile.find("i").removeClass("fluigicon-trash").addClass("fluigicon-file-upload");
|
||||
btnDownloadFile.prop("disabled", true);
|
||||
btnDownloadFile.hide()
|
||||
btnViewerFile.prop("disabled", true);
|
||||
btnViewerFile.hide()
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função btnState")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Faz tratativa nos botões do anexos percorrente cada class .componentAnexo
|
||||
* Em modo de visualização o botão de upload é removido, e caso tenha anexo, habilita o botão de visualização do anexo
|
||||
* Se em modo de edição e conter anexo o botão de upload é alterado para o botão de deletar anexos e habilita o botão de visualização
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function displayBtnFiles(){
|
||||
try{
|
||||
$('.componentAnexo').each(function(i, element) {
|
||||
let inputFile = $(element).find(".inputAnexo")
|
||||
let inputFileVew = $(element).find(".componentAnexo")
|
||||
let btnUpFile = $(element).find(".btnUpFile");
|
||||
let btnViewerFile = $(element).find(".btnViewerFile");
|
||||
let btnDownloadFile = $(element).find(".btnDownloadFile");
|
||||
|
||||
if(getFormMode() == "VIEW"){
|
||||
btnUpFile.remove();
|
||||
if(inputFileVew.val() != ""){
|
||||
btnViewerFile.prop("disabled", false);
|
||||
btnViewerFile.show()
|
||||
}
|
||||
}
|
||||
if(getFormMode() == "MOD" && inputFile.val() != ""){
|
||||
btnUpFile.remove();
|
||||
// btnState(inputFile[0].id, "delete", "viewer")
|
||||
btnViewerFile.prop("disabled", false);
|
||||
btnViewerFile.show()
|
||||
btnDownloadFile.prop("disabled", false);
|
||||
btnDownloadFile.show()
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função displayBtnFiles")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove o botão de upload/delete
|
||||
* @param {String} inputFile Parâmetro obrigatório, Id do campo
|
||||
* @return {void}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function invisibleBtnUpload(inputFile){
|
||||
try{
|
||||
if(getFormMode() == "MOD" || getFormMode() == "VIEW"){
|
||||
if($(`#_${inputFile}`).length){
|
||||
let btnUpFile = $(`#_${inputFile}`).parent().parent().find(".btnUpFile");
|
||||
btnUpFile.remove();
|
||||
} else{
|
||||
let btnUpFile = $(`#${inputFile}`).parent().parent().find(".btnUpFile");
|
||||
btnUpFile.remove();
|
||||
}
|
||||
}
|
||||
if($(`#_${inputFile}`).length){
|
||||
if($(`#_${inputFile}`).val() == ""){
|
||||
$(`#_${inputFile}`).attr({placeholder:"Nenhum anexo selecionado"});
|
||||
}
|
||||
} else{
|
||||
if($(`#${inputFile}`).val() == ""){
|
||||
$(`#${inputFile}`).attr({placeholder:"Nenhum anexo selecionado"});
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Houve um erro inesperado na função invisibleBtnUpload")
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifica se os campos do anexo de uma tabela pai e filho esta preenchido,
|
||||
* caso esteja, ele verifica se o anexo esta presente na aba de anexos do Fluig
|
||||
* @param {String} tablename Parâmetro obrigatório, tablename da tabela pai e filho.
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo de anexo que deseja verificar
|
||||
* @return {String} - Retorna string de erros caso apresente erros
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function invalidFilesTable(tablename, idInput){
|
||||
try {
|
||||
let errors = "";
|
||||
const countRows = $(`[tablename='${tablename}']`).find('tbody tr').not(':first');
|
||||
for(let i = 0; i < countRows.length; i++){
|
||||
let indice = getIndice(countRows.eq(i).find("input")[0].id);
|
||||
let inputNameFile = $(`#_${idInput}___${indice}`).length ? $(`#_${idInput}___${indice}`) : $(`#${idInput}___${indice}`)
|
||||
let fileDescription = inputNameFile.parent().find(".descAnexo").val()
|
||||
if(inputNameFile.val() && !hasFileFluig(fileDescription)){
|
||||
errors += `<li style='margin-bottom: 5px;'>O anexo <b>${inputNameFile.val()}</b> da linha <b>${i+1}</b> não foi encontrado</li>`
|
||||
}
|
||||
}
|
||||
return errors
|
||||
} catch (e) {
|
||||
console.error('Houve um erro inesperado na função invalidFileTable')
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica se o campo do anexo esta preenchido, caso esteja, ele verifica se o anexo esta válido
|
||||
* @param {String} idInput Parâmetro obrigatório, Id do campo em que o nome do arquivo fisico é gravado
|
||||
* @return {Boolean}
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function invalidFile(idInput){
|
||||
try {
|
||||
const inputNameFile = $(`#${idInput}`).val()
|
||||
if(inputNameFile){
|
||||
if($(`#_${idInput}`).length){
|
||||
let fileDescription = $(`#_${idInput}`).parent().find(".descAnexo").val()
|
||||
return !hasFileFluig(fileDescription)
|
||||
} else{
|
||||
let fileDescription = $(`#${idInput}`).parent().find(".descAnexo").val()
|
||||
return !hasFileFluig(fileDescription)
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Houve um erro inesperado na função invalidFile')
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifica se o anexo existe na aba de anexos do Fluig
|
||||
* @param {String} fileDescription Parâmetro obrigatório, Descrição do arquivo
|
||||
* @return {Boolean} - Retorna verdadeiro caso o arquivo exista
|
||||
* @author Sérgio Machado
|
||||
*/
|
||||
function hasFileFluig(fileDescription){
|
||||
try {
|
||||
const anexos = parent.ECM.attachmentTable.getData();
|
||||
for(let i = 0; i < anexos.length; i++){
|
||||
var descricao = anexos[i].description;
|
||||
if (fileDescription == descricao) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
} catch (e) {
|
||||
console.error('Houve um erro inesperado na função hasFileFluig')
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
$(document).ready(function () {
|
||||
if ($("#formMode").val() == "VIEW") {
|
||||
showAndBlock(["all"]);
|
||||
} else {
|
||||
var activity = $("#activity").val();
|
||||
var requestDate = getCurrentDate();
|
||||
|
||||
$(".activity").hide();
|
||||
$(".activity-" + activity).show();
|
||||
|
||||
// Atividade 4: Abertura
|
||||
if (activity == 4) {
|
||||
$("#dataNec").val(requestDate[0]); // já coloca a data de hoje
|
||||
toggleBotaoAddItem();
|
||||
|
||||
// Atividade 6: Validação do Centro de Custo
|
||||
} else if (activity == 5) {
|
||||
showAndBlock([4]); // bloqueia os campos da abertura
|
||||
$("#userValidacaoGestor").val($("#currentUserName").val());
|
||||
$("#dataValidacaoGestor").val(requestDate[0] + " - " + requestDate[1]);
|
||||
|
||||
if ($("#justificativaDecisaoGestor").val() == "") {
|
||||
$(".justificativa-activity-4").hide();
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
$(document).ready(function () {
|
||||
try {
|
||||
FLUIGC.calendar('#dataNec');
|
||||
} catch (e) {
|
||||
console.warn("Erro ao iniciar calendário:", e);
|
||||
}
|
||||
|
||||
toggleBotaoAddItem(); // inicia escondido
|
||||
|
||||
/* ========= Eventos ========= */
|
||||
$('#precoRef, #quantidade').on('input', recalcTotal);
|
||||
|
||||
$('#qtdMais').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
$('#quantidade').val(v + 1);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#qtdMenos').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
v = Math.max(0, v - 1);
|
||||
$('#quantidade').val(v);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#btnBuscaProd').on('click', consultarProdutos);
|
||||
$('#btnLimpaProd').on('click', limparCamposPrincipais);
|
||||
$('#btnAddItem').on('click', adicionarItem);
|
||||
});
|
||||
|
||||
function showAndBlock(activity) {
|
||||
for (var i = 0; i < activity.length; i++) {
|
||||
$(".activity-" + activity[i]).show();
|
||||
$(".hideButton").hide();
|
||||
$(".activity-" + activity[i] + " :input").each(function () {
|
||||
$(this).attr("readonly", "readonly")
|
||||
.css("background-color", "#eee")
|
||||
.children("option:not(:selected)").prop("disabled", true);
|
||||
|
||||
if ($(this).is(":checkbox") || $(this).is(":radio")) {
|
||||
$(this).attr("disabled", true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getCurrentDate() {
|
||||
var newDate = new Date();
|
||||
var h = newDate.getHours();
|
||||
if (h < 10) {
|
||||
h = "0" + h;
|
||||
}
|
||||
var m = newDate.getMinutes();
|
||||
if (m < 10) {
|
||||
m = "0" + m;
|
||||
}
|
||||
var hour = h + ":" + m; // + ":" + s;
|
||||
var day = newDate.getDate();
|
||||
if (day < 10) {
|
||||
day = "0" + day;
|
||||
}
|
||||
var month = newDate.getMonth() + 1;
|
||||
if (month < 10) {
|
||||
month = "0" + month;
|
||||
}
|
||||
newDate = day + "/" + month + "/" + newDate.getFullYear();
|
||||
var currentDate = [newDate, hour];
|
||||
return currentDate;
|
||||
}
|
||||
|
||||
|
||||
function toggleBotaoAddItem() {
|
||||
const temProduto = $('#produtoCod').val() || $('#DescoProduto').val();
|
||||
if (temProduto && temProduto.trim() !== "") {
|
||||
$('#btnAddItem').show();
|
||||
} else {
|
||||
$('#btnAddItem').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function setSelectedZoomItem(selectedItem) {
|
||||
if (selectedItem.inputId === "estabelecimento") {
|
||||
// joga o código da filial (cnpj, etc.)
|
||||
$("#filialDesc").val(selectedItem.CNPJ); // supondo que o dataset dsSysCompany devolva o campo CNPJ
|
||||
$("#filialest").val(selectedItem.ESTADO); // supondo que o dataset dsSysCompany devolva o campo ESTADO
|
||||
}
|
||||
if (selectedItem.inputId === "centroCusto") {
|
||||
// joga o nome do gestor
|
||||
$("#gestorCentroCusto").val(selectedItem.gestorCentroCusto); // supondo que o dataset dsCentroCusto devolva o campo GestorCentroCusto
|
||||
}
|
||||
}
|
||||
|
||||
function removedZoomItem(removedItem) {
|
||||
if (removedItem.inputId === "estabelecimento") {
|
||||
// Quando remover a empresa, limpa os campos relacionados
|
||||
$("#filialDesc").val('');
|
||||
$("#filialest").val('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ========= Config ========= */
|
||||
const DATASET_PRODUTOS = "dsProd"; // dataset de produtos
|
||||
let todosProdutos = [];
|
||||
let paginaAtual = 1;
|
||||
const itensPorPagina = 10;
|
||||
|
||||
/* ========= Utils ========= */
|
||||
function escapeHTML(txt) {
|
||||
return $('<div>').text(txt == null ? '' : String(txt)).html();
|
||||
}
|
||||
|
||||
function brMoneyToFloat(v) {
|
||||
if (!v) return 0;
|
||||
return parseFloat(String(v).replace(/\./g, '').replace(',', '.')) || 0;
|
||||
}
|
||||
|
||||
function floatToBRL(n) {
|
||||
try {
|
||||
return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(n || 0);
|
||||
} catch (_) {
|
||||
return 'R$ ' + (n || 0).toFixed(2).replace('.', ',');
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Modal Consulta Produtos ========= */
|
||||
function consultarProdutos() {
|
||||
FLUIGC.modal({
|
||||
title: 'Consulta de Produtos',
|
||||
content:
|
||||
'<div id="buscaProduto" style="margin-bottom:10px;">' +
|
||||
'<input type="text" id="filtroDescricao" class="form-control" placeholder="Buscar por descrição..." onkeyup="filtrarProdutos()">' +
|
||||
'</div>' +
|
||||
'<div id="listaProdutos"></div>' +
|
||||
'<div id="paginacaoProdutos" style="margin-top:10px; text-align:center;"></div>',
|
||||
id: 'modalConsultaProdutos',
|
||||
size: 'large',
|
||||
actions: [{ 'label': 'Fechar', 'autoClose': true }]
|
||||
}, function (err) {
|
||||
if (!err) carregaListaProdutos();
|
||||
});
|
||||
}
|
||||
|
||||
function carregaListaProdutos(filtro) {
|
||||
// Só chama o dataset se ainda não carregou nada
|
||||
if (todosProdutos.length === 0) {
|
||||
let dataset = DatasetFactory.getDataset(DATASET_PRODUTOS, null, null, null);
|
||||
todosProdutos = dataset && dataset.values ? dataset.values : [];
|
||||
console.log("Produtos carregados do dataset:", todosProdutos.length);
|
||||
}
|
||||
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos(filtro);
|
||||
}
|
||||
|
||||
|
||||
function filtrarProdutos() {
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
function renderizaProdutos(filtro) {
|
||||
filtro = (filtro || $('#filtroDescricao').val() || '').toLowerCase();
|
||||
|
||||
// Agora filtra no cache (sem chamar dataset de novo)
|
||||
const produtosFiltrados = todosProdutos.filter(p =>
|
||||
(p.descricao || '').toLowerCase().includes(filtro) ||
|
||||
(p.codigo || '').toLowerCase().includes(filtro) ||
|
||||
(p.medida || '').toLowerCase().includes(filtro)
|
||||
);
|
||||
|
||||
const inicio = (paginaAtual - 1) * itensPorPagina;
|
||||
const fim = inicio + itensPorPagina;
|
||||
const produtosPagina = produtosFiltrados.slice(inicio, fim);
|
||||
|
||||
let html = `
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Codigo</th>
|
||||
<th>Descricao</th>
|
||||
<th>UM</th>
|
||||
<th>Ultimo Preco</th>
|
||||
<th>Acao</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (produtosPagina.length === 0) {
|
||||
html += `
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
Nenhum produto encontrado
|
||||
</td>
|
||||
</tr>`;
|
||||
} else {
|
||||
produtosPagina.forEach(produto => {
|
||||
const codigo = escapeHTML(produto['codigo']);
|
||||
const descricao = escapeHTML(produto['descricao']);
|
||||
const um = escapeHTML(produto['medida'] || '');
|
||||
const preco = produto['ultimoPreco'] || '0,00';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>${codigo}</td>
|
||||
<td>${descricao}</td>
|
||||
<td>${um}</td>
|
||||
<td>${preco}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-success selecionar-produto"
|
||||
data-codigo="${codigo}"
|
||||
data-descricao="${descricao}"
|
||||
data-preco="${preco}">
|
||||
Selecionar
|
||||
</button>
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `</tbody></table>`;
|
||||
$('#listaProdutos').html(html);
|
||||
|
||||
renderizaPaginacao(produtosFiltrados.length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function renderizaPaginacao(totalItens) {
|
||||
const totalPaginas = Math.ceil(totalItens / itensPorPagina);
|
||||
let html = '';
|
||||
if (totalPaginas > 1) {
|
||||
if (paginaAtual > 1) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual - 1) + ')">Anterior</button> ';
|
||||
}
|
||||
html += ' Pagina ' + paginaAtual + ' de ' + totalPaginas + ' ';
|
||||
if (paginaAtual < totalPaginas) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual + 1) + ')">Proxima</button>';
|
||||
}
|
||||
}
|
||||
$('#paginacaoProdutos').html(html);
|
||||
}
|
||||
|
||||
function mudarPagina(n) {
|
||||
paginaAtual = n;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
/* ========= Seleção ========= */
|
||||
function selecionarProduto(codigo, descricao, preco) {
|
||||
$('#produtoCod').val(codigo);
|
||||
$('#DescoProduto').val(codigo + ' - ' + descricao);
|
||||
$('#ultimoPreco').val(preco);
|
||||
|
||||
FLUIGC.toast({ title: 'Produto', message: 'Selecionado: ' + descricao, type: 'success' });
|
||||
$('#modalConsultaProdutos').modal('hide');
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
|
||||
/* ========= Eventos delegados ========= */
|
||||
$(document).on('click', '.selecionar-produto', function () {
|
||||
const codigo = $(this).data('codigo');
|
||||
const descricao = $(this).data('descricao');
|
||||
const preco = $(this).data('preco');
|
||||
selecionarProduto(codigo, descricao, preco);
|
||||
});
|
||||
|
||||
// Digitação em Qtd ou Preço Ref → recalcula automaticamente
|
||||
$(document).on('input', 'input[name^="qtd___"], input[name^="Refpreco___"]', function () {
|
||||
recalcLinha(this);
|
||||
});
|
||||
|
||||
/* ========= Total / Quantidade ========= */
|
||||
function recalcTotal() {
|
||||
const q = parseFloat($('#quantidade').val() || '0');
|
||||
const p = brMoneyToFloat($('#precoRef').val());
|
||||
const t = (q * p) || 0;
|
||||
$('#total').val(floatToBRL(t));
|
||||
}
|
||||
|
||||
/* ========= Index das linhas ========= */
|
||||
function atualizarIndex() {
|
||||
$('#tbItens tbody tr.tableRow').each(function (i) {
|
||||
if (!$(this).is('[detail=true]')) {
|
||||
$(this).find('.tableIndex').text(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ========= Totais da tabela ========= */
|
||||
function atualizarTotais() {
|
||||
let totalItens = 0;
|
||||
let totalGeral = 0;
|
||||
|
||||
// Pega todos os valores da tabela
|
||||
const dadosTabela = $('#tbItens').find('input').serializeArray();
|
||||
|
||||
// Transforma em objeto chave:valor para fácil acesso
|
||||
const mapValores = {};
|
||||
dadosTabela.forEach(item => {
|
||||
mapValores[item.name] = item.value;
|
||||
});
|
||||
|
||||
// Percorre por linha (cada linha tem um sufixo ___1, ___2...)
|
||||
let idx = 1;
|
||||
while (mapValores['qtd___' + idx] !== undefined) {
|
||||
const qtd = parseFloat(mapValores['qtd___' + idx] || 0);
|
||||
const preco = brMoneyToFloat(mapValores['Refpreco___' + idx] || "0");
|
||||
const total = qtd * preco;
|
||||
|
||||
totalItens += qtd;
|
||||
totalGeral += total;
|
||||
|
||||
// Atualiza campo total da linha
|
||||
if ($(`#totalValor___${idx}`).length) {
|
||||
$(`#totalValor___${idx}`).val(floatToBRL(total));
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Atualiza rodapé
|
||||
$('#totalItens').val(totalItens);
|
||||
$('#totalGeral').val(floatToBRL(totalGeral));
|
||||
}
|
||||
|
||||
/* ========= Recalcula uma linha ========= */
|
||||
function recalcLinha(el) {
|
||||
const $linha = $(el).closest('tr');
|
||||
const qtd = parseFloat($linha.find('input[name^="qtd___"]').val() || '0');
|
||||
const preco = brMoneyToFloat($linha.find('input[name^="Refpreco___"]').val() || '0');
|
||||
const total = qtd * preco;
|
||||
|
||||
$linha.find('input[name^="totalValor___"]').val(floatToBRL(total));
|
||||
atualizarTotais();
|
||||
}
|
||||
|
||||
/* ========= Remover linha ========= */
|
||||
function fnWdkRemoveChild(el) {
|
||||
$(el).closest('tr').remove();
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}
|
||||
|
||||
/* ========= Adicionar Item ========= */
|
||||
function adicionarItem() {
|
||||
const cod = $('#produtoCod').val();
|
||||
const desc = $('#DescoProduto').val();
|
||||
const ult = $('#ultimoPreco').val() || '0,00';
|
||||
const qtd = $('#quantidade').val();
|
||||
const prec = $('#precoRef').val();
|
||||
const tot = $('#total').val();
|
||||
const dataN = $('#dataNec').val();
|
||||
|
||||
if (!cod) {
|
||||
FLUIGC.toast({ title: 'Atenção', message: 'Selecione um produto/serviço', type: 'warning' });
|
||||
return;
|
||||
}
|
||||
|
||||
const idx = wdkAddChild('tbItens');
|
||||
|
||||
setTimeout(() => {
|
||||
$('input[name="Codproduto___' + idx + '"]').val(cod);
|
||||
|
||||
const somenteDesc = desc.includes('-') ? desc.split('-').slice(1).join('-').trim() : desc;
|
||||
$('input[name="produtoDesc___' + idx + '"]').val(somenteDesc);
|
||||
|
||||
$('input[name="ultimoPrecoItem___' + idx + '"]').val(ult);
|
||||
$('input[name="qtd___' + idx + '"]').val(qtd).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="Refpreco___' + idx + '"]').val(prec).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="totalValor___' + idx + '"]').val(tot);
|
||||
$('input[name="dataNecItem___' + idx + '"]').val(dataN);
|
||||
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}, 0);
|
||||
|
||||
FLUIGC.toast({ title: 'Item', message: 'Adicionado à lista', type: 'success' });
|
||||
|
||||
limparCamposPrincipais();
|
||||
}
|
||||
|
||||
/* ========= Limpar campos principais ========= */
|
||||
function limparCamposPrincipais() {
|
||||
$('#produtoCod, #DescoProduto').val('');
|
||||
$('#ultimoPreco').val('0,00');
|
||||
$('#quantidade').val('0');
|
||||
$('#precoRef').val('0,00');
|
||||
$('#total').val('R$ 0,00');
|
||||
$('#fnComprovante').val('');
|
||||
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
.painel-ginseng > .panel-heading {
|
||||
background-color: #7a113a !important; /* azul do logo */
|
||||
color: #fff !important; /* texto branco */
|
||||
border-color: #0b556b !important;
|
||||
}
|
||||
|
||||
.painel-ginseng {
|
||||
border-color: #0b556b !important;
|
||||
}
|
||||
|
||||
/* tabela ocupa 100% */
|
||||
#tbItens {
|
||||
table-layout: fixed; /* força obedecer larguras definidas */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* todas as células centralizam por padrão */
|
||||
#tbItens td, #tbItens th {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* coluna # */
|
||||
#tbItens th:nth-child(1),
|
||||
#tbItens td:nth-child(1) {
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
/* coluna Código (maior espaço) */
|
||||
#tbItens th:nth-child(2),
|
||||
#tbItens td:nth-child(2) {
|
||||
width: 18%;
|
||||
white-space: normal; /* deixa quebrar */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Descrição */
|
||||
#tbItens th:nth-child(3),
|
||||
#tbItens td:nth-child(3) {
|
||||
width: 27%;
|
||||
}
|
||||
|
||||
/* Preço Ref. */
|
||||
#tbItens th:nth-child(4),
|
||||
#tbItens td:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
|
||||
/* qtd */
|
||||
#tbItens th:nth-child(5),
|
||||
#tbItens td:nth-child(5) {
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
/* Data limite */
|
||||
#tbItens th:nth-child(6),
|
||||
#tbItens td:nth-child(6) {
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
/* Excluir */
|
||||
#tbItens th:nth-child(7),
|
||||
#tbItens td:nth-child(7) {
|
||||
width: 6%;
|
||||
}
|
||||
|
||||
td.text-center .btn-link {
|
||||
margin: 0 2px; /* espaçamento horizontal */
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,432 @@
|
||||
$(document).ready(function () {
|
||||
try {
|
||||
FLUIGC.calendar('#dataNec');
|
||||
} catch (e) {
|
||||
console.warn("Erro ao iniciar calendário:", e);
|
||||
}
|
||||
|
||||
toggleBotaoAddItem(); // inicia escondido
|
||||
|
||||
/* ========= Eventos ========= */
|
||||
$('#precoRef, #quantidade').on('input', recalcTotal);
|
||||
|
||||
// formata o teto de preço só quando o usuário sair do campo
|
||||
$('#precoRef').on('blur', function() {
|
||||
const p = brMoneyToFloat($(this).val());
|
||||
$(this).val(floatToBRL(p));
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#qtdMais').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
$('#quantidade').val(v + 1);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#qtdMenos').on('click', function () {
|
||||
let v = parseInt($('#quantidade').val() || '0', 10);
|
||||
v = Math.max(0, v - 1);
|
||||
$('#quantidade').val(v);
|
||||
recalcTotal();
|
||||
});
|
||||
|
||||
$('#btnBuscaProd').on('click', consultarProdutos);
|
||||
$('#btnLimpaProd').on('click', limparCamposPrincipais);
|
||||
$('#btnAddItem').on('click', adicionarItem);
|
||||
});
|
||||
|
||||
/* ========= Total / Quantidade ========= */
|
||||
function recalcTotal() {
|
||||
const q = parseFloat($('#quantidade').val() || '0');
|
||||
const p = brMoneyToFloat($('#precoRef').val());
|
||||
const t = (q * p) || 0;
|
||||
$('#total').val(floatToBRL(t));
|
||||
|
||||
}
|
||||
|
||||
function setSelectedZoomItem(selectedItem) {
|
||||
if (selectedItem.inputId === "estabelecimento") {
|
||||
// joga o código da filial (cnpj, etc.)
|
||||
$("#filialdest").val(selectedItem.CNPJ); // supondo que o dataset dsSysCompany devolva o campo CNPJ
|
||||
$("#filialest").val(selectedItem.ESTADO); // supondo que o dataset dsSysCompany devolva o campo ESTADO
|
||||
$("#filialprotheus").val(selectedItem.CODIGO); // supondo que o dataset dsSysCompany devolva o campo CODIGO
|
||||
}
|
||||
if (selectedItem.inputId === "centro_custo") {
|
||||
// joga o código da filial (cnpj, etc.)
|
||||
$("#gestor_cc").val(selectedItem.idGestor); // supondo que o dataset Centro_custo devolva o campo GestorCentroCusto
|
||||
$("#codigocentroCusto").val(selectedItem.codigoCentroCusto); // supondo que o dataset Centro_custo devolva o campo GestorCentroCusto
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function removedZoomItem(removedItem) {
|
||||
if (removedItem.inputId === "estabelecimento") {
|
||||
// Quando remover a empresa, limpa os campos relacionados
|
||||
$("#filialDesc").val('');
|
||||
$("#filialest").val('');
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Config ========= */
|
||||
const DATASET_PRODUTOS = "dsProd"; // dataset de produtos
|
||||
let todosProdutos = [];
|
||||
let paginaAtual = 1;
|
||||
const itensPorPagina = 10;
|
||||
|
||||
/* ========= Utils ========= */
|
||||
function escapeHTML(txt) {
|
||||
return $('<div>').text(txt == null ? '' : String(txt)).html();
|
||||
}
|
||||
|
||||
function brMoneyToFloat(v) {
|
||||
if (!v) return 0;
|
||||
return parseFloat(
|
||||
String(v)
|
||||
.replace(/R\$/g, '') // remove "R$"
|
||||
.replace(/\s/g, '') // remove espaços
|
||||
.replace(/\./g, '') // remove pontos de milhar
|
||||
.replace(',', '.') // troca vírgula por ponto
|
||||
) || 0;
|
||||
}
|
||||
|
||||
function floatToBRL(n) {
|
||||
try {
|
||||
return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(n || 0);
|
||||
} catch (_) {
|
||||
return 'R$ ' + (n || 0).toFixed(2).replace('.', ',');
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= Modal Consulta Produtos ========= */
|
||||
function consultarProdutos() {
|
||||
FLUIGC.modal({
|
||||
title: 'Consulta de Produtos',
|
||||
content:
|
||||
'<div id="buscaProduto" style="margin-bottom:10px;">' +
|
||||
'<input type="text" id="filtroDescricao" class="form-control" placeholder="Buscar por nome..." onkeyup="filtrarProdutos()">' +
|
||||
'</div>' +
|
||||
'<div id="listaProdutos"></div>' +
|
||||
'<div id="paginacaoProdutos" style="margin-top:10px; text-align:center;"></div>',
|
||||
id: 'modalConsultaProdutos',
|
||||
size: 'large',
|
||||
actions: [{ 'label': 'Fechar', 'autoClose': true }]
|
||||
}, function (err) {
|
||||
if (!err) carregaListaProdutos();
|
||||
});
|
||||
}
|
||||
|
||||
function carregaListaProdutos(filtro) {
|
||||
// Só chama o dataset se ainda não carregou nada
|
||||
if (todosProdutos.length === 0) {
|
||||
let dataset = DatasetFactory.getDataset(DATASET_PRODUTOS, null, null, null);
|
||||
todosProdutos = dataset && dataset.values ? dataset.values : [];
|
||||
console.log("Produtos carregados do dataset:", todosProdutos.length);
|
||||
}
|
||||
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos(filtro);
|
||||
}
|
||||
|
||||
|
||||
function filtrarProdutos() {
|
||||
paginaAtual = 1;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
function renderizaProdutos(filtro) {
|
||||
filtro = (filtro || $('#filtroDescricao').val() || '').toLowerCase();
|
||||
|
||||
// Agora filtra no cache (sem chamar dataset de novo)
|
||||
const produtosFiltrados = todosProdutos.filter(p =>
|
||||
(p.descricao || '').toLowerCase().includes(filtro) ||
|
||||
(p.codigo || '').toLowerCase().includes(filtro) ||
|
||||
(p.medida || '').toLowerCase().includes(filtro)
|
||||
);
|
||||
|
||||
const inicio = (paginaAtual - 1) * itensPorPagina;
|
||||
const fim = inicio + itensPorPagina;
|
||||
const produtosPagina = produtosFiltrados.slice(inicio, fim);
|
||||
|
||||
let html = `
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Codigo</th>
|
||||
<th>Descricao</th>
|
||||
<th>UM</th>
|
||||
<th>Ultimo Preco</th>
|
||||
<th>Acao</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (produtosPagina.length === 0) {
|
||||
html += `
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
Nenhum produto encontrado
|
||||
</td>
|
||||
</tr>`;
|
||||
} else {
|
||||
produtosPagina.forEach(produto => {
|
||||
const codigo = escapeHTML(produto['codigo']);
|
||||
const descricao = escapeHTML(produto['descricao']);
|
||||
const um = escapeHTML(produto['medida'] || '');
|
||||
const preco = produto['ultimo_preco'] || '0,00';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>${codigo}</td>
|
||||
<td>${descricao}</td>
|
||||
<td>${um}</td>
|
||||
<td>${preco}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-success selecionar-produto"
|
||||
data-codigo="${codigo}"
|
||||
data-descricao="${descricao}"
|
||||
data-preco="${preco}">
|
||||
Selecionar
|
||||
</button>
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `</tbody></table>`;
|
||||
$('#listaProdutos').html(html);
|
||||
|
||||
renderizaPaginacao(produtosFiltrados.length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function renderizaPaginacao(totalItens) {
|
||||
const totalPaginas = Math.ceil(totalItens / itensPorPagina);
|
||||
let html = '';
|
||||
if (totalPaginas > 1) {
|
||||
if (paginaAtual > 1) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual - 1) + ')">Anterior</button> ';
|
||||
}
|
||||
html += ' Pagina ' + paginaAtual + ' de ' + totalPaginas + ' ';
|
||||
if (paginaAtual < totalPaginas) {
|
||||
html += '<button class="btn btn-sm btn-default" onclick="mudarPagina(' + (paginaAtual + 1) + ')">Proxima</button>';
|
||||
}
|
||||
}
|
||||
$('#paginacaoProdutos').html(html);
|
||||
}
|
||||
|
||||
function mudarPagina(n) {
|
||||
paginaAtual = n;
|
||||
renderizaProdutos();
|
||||
}
|
||||
|
||||
/* ========= Seleção ========= */
|
||||
function selecionarProduto(codigo, descricao, preco) {
|
||||
$('#produtoCod').val(codigo);
|
||||
$('#descProduto').val(codigo + ' - ' + descricao);
|
||||
$('#ultimoPreco').val(preco);
|
||||
|
||||
FLUIGC.toast({ title: 'Produto', message: 'Selecionado: ' + descricao, type: 'success' });
|
||||
$('#modalConsultaProdutos').modal('hide');
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
|
||||
function toggleBotaoAddItem() {
|
||||
const temProduto = $('#produtoCod').val() || $('#descProduto').val();
|
||||
if (temProduto && temProduto.trim() !== "") {
|
||||
$('#btnAddItem').show();
|
||||
} else {
|
||||
$('#btnAddItem').hide();
|
||||
}
|
||||
}
|
||||
/* ========= Adicionar Item ========= */
|
||||
function adicionarItem() {
|
||||
const cod = $('#produtoCod').val();
|
||||
const desc = $('#descProduto').val();
|
||||
const qtd = $('#quantidade').val();
|
||||
|
||||
if (!cod) {
|
||||
FLUIGC.toast({ title: 'Atenção', message: 'Selecione um produto/serviço', type: 'warning' });
|
||||
return;
|
||||
}
|
||||
|
||||
const idx = wdkAddChild('tbItens');
|
||||
|
||||
setTimeout(() => {
|
||||
$('input[name="Codproduto___' + idx + '"]').val(cod);
|
||||
|
||||
const somenteDesc = desc.includes('-') ? desc.split('-').slice(1).join('-').trim() : desc;
|
||||
$('input[name="produtoDesc___' + idx + '"]').val(somenteDesc);
|
||||
$('input[name="qtd___' + idx + '"]').val(qtd).on('input', function () { recalcLinha(this); });
|
||||
$('input[name="ultimoPreco___' + idx + '"]').val(prec).on('input', function () { recalcLinha(this); });
|
||||
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}, 0);
|
||||
|
||||
FLUIGC.toast({ title: 'Item', message: 'Adicionado à lista', type: 'success' });
|
||||
|
||||
limparCamposPrincipais();
|
||||
}
|
||||
|
||||
/* ========= Limpar campos principais ========= */
|
||||
function limparCamposPrincipais() {
|
||||
$('#produtoCod, #descProduto').val('');
|
||||
$('#quantidade').val('0');
|
||||
$('#precoRef').val('0,00');
|
||||
$('#fnComprovante').val('');
|
||||
|
||||
|
||||
toggleBotaoAddItem(); // 👈 mostra botão
|
||||
}
|
||||
|
||||
/* ========= Eventos delegados ========= */
|
||||
$(document).on('click', '.selecionar-produto', function () {
|
||||
const codigo = $(this).data('codigo');
|
||||
const descricao = $(this).data('descricao');
|
||||
const preco = $(this).data('preco');
|
||||
selecionarProduto(codigo, descricao, preco);
|
||||
});
|
||||
|
||||
|
||||
/* ========= Index das linhas ========= */
|
||||
function atualizarIndex() {
|
||||
$('#tbItens tbody tr.tableRow').each(function (i) {
|
||||
if (!$(this).is('[detail=true]')) {
|
||||
$(this).find('.tableIndex').text(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ========= Remover linha ========= */
|
||||
function fnWdkRemoveChild(el) {
|
||||
$(el).closest('tr').remove();
|
||||
atualizarIndex();
|
||||
atualizarTotais();
|
||||
}
|
||||
|
||||
/* ========= Link do produto ========= */
|
||||
function handleProductLink(el) {
|
||||
const $row = $(el).closest("tr");
|
||||
const $hidden = $row.find("input.produto-link");
|
||||
let linkAtual = $hidden.val();
|
||||
|
||||
if (!linkAtual) {
|
||||
// ainda não tem link → pedir ao usuário
|
||||
let novoLink = prompt("Insira o link do produto:");
|
||||
if (novoLink && novoLink.trim() !== "") {
|
||||
$hidden.val(novoLink.trim()); // grava no hidden (vai persistir no Fluig)
|
||||
}
|
||||
} else {
|
||||
// já existe link → abrir
|
||||
window.open(linkAtual, "_blank");
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
var steps = [
|
||||
{ state: 1, label: "Solicitação" },
|
||||
{ state: 121, label: "Validando Necessidade" },
|
||||
{ state: 82, label: "Enviando pedido" },
|
||||
{ state: 114, label: "Cotação Iniciada" },
|
||||
{ state: 105, label: "Indicar Cotação" },
|
||||
{ state: 137, label: "Confirmação da cotação" },
|
||||
{ state: 133, label: "Aprovação Gestor" },
|
||||
{ state: 147, label: "Aprovação Ger. Financeiro" },
|
||||
{ state: 158, label: "Aprovação CEO" },
|
||||
{ state: 18, label: "Recebimento do Produto" },
|
||||
{ state: 24, label: "Problema" },
|
||||
{ state: 52, label: "Fim" }
|
||||
];
|
||||
|
||||
var current = parseInt($("#activity").val() || "0", 10);
|
||||
var idxAtual = steps.findIndex(function (s) { return s.state === current; });
|
||||
if (idxAtual < 0) idxAtual = 0;
|
||||
|
||||
$("#wizard-steps .step-item").each(function (i) {
|
||||
if (i < idxAtual) $(this).addClass("done");
|
||||
if (i === idxAtual) $(this).addClass("active");
|
||||
});
|
||||
|
||||
// clique nos steps
|
||||
$("#wizard-steps .step-item").on("click", function () {
|
||||
var index = $(this).index();
|
||||
var step = steps[index];
|
||||
if (!step) return;
|
||||
|
||||
// 👉 se já estava ativo, mostra tudo de novo
|
||||
if ($(this).hasClass("active") && $(".activity:visible").length === 1) {
|
||||
$(".activity").show();
|
||||
$("#wizard-steps .step-item").removeClass("active");
|
||||
return;
|
||||
}
|
||||
|
||||
// senão, mostra só a activity clicada
|
||||
$(".activity").hide();
|
||||
$(".activity-" + step.state).show();
|
||||
|
||||
$("#wizard-steps .step-item").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
// Quando carregar a página, já pinta o status se tiver valor nos inputs
|
||||
let status = $("#statusSCProtheus").val() || "";
|
||||
let badgeClass = "badge bg-secondary";
|
||||
|
||||
if (status.toLowerCase().includes("sucesso")) badgeClass = "badge bg-success";
|
||||
if (status.toLowerCase().includes("erro")) badgeClass = "badge bg-danger";
|
||||
|
||||
$("#statusSCProtheus_label")
|
||||
.text(status || "-")
|
||||
.removeClass()
|
||||
.addClass(badgeClass);
|
||||
});
|
||||
|
||||
function recalcularTotalCotacao() {
|
||||
var soma = 0;
|
||||
|
||||
$("input[name^='selecionado___']").each(function() {
|
||||
var idx = $(this).attr("id").split("___")[1];
|
||||
|
||||
// pega qtd e preço da linha
|
||||
var qtd = parseFloat($("#qtdc___" + idx).val() || "0");
|
||||
var preco = parseFloat($("#preco___" + idx).val() || "0");
|
||||
|
||||
// calcula total da linha
|
||||
var total = qtd * preco;
|
||||
|
||||
// atualiza campo total da linha
|
||||
$("#total___" + idx).val(total.toFixed(2));
|
||||
|
||||
// se marcado, acumula na soma
|
||||
if ($(this).is(":checked")) {
|
||||
soma += total;
|
||||
}
|
||||
});
|
||||
|
||||
// Atualiza o hidden e dispara change pro Fluig gravar
|
||||
$("#valorTotalCotacao").val(soma.toFixed(2)).trigger("change");
|
||||
}
|
||||
// dispara sempre que marcar/desmarcar
|
||||
$(document).on("change", "input[name^='selecionado___']", function() {
|
||||
recalcularTotalCotacao();
|
||||
});
|
||||
|
||||
// recalcula ao abrir a atividade
|
||||
$(document).ready(function() {
|
||||
recalcularTotalCotacao();
|
||||
});
|
||||
|
||||
// garante que o total seja salvo antes de enviar a atividade
|
||||
function beforeSendValidate(numState, nextState) {
|
||||
console.log("Executando beforeSendValidate, recalculando total...");
|
||||
recalcularTotalCotacao();
|
||||
return true; // precisa retornar true senão bloqueia o envio
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
function displayFields(form, customHTML) {
|
||||
|
||||
var activity = getValue('WKNumState');
|
||||
var userId = getValue('WKUser');
|
||||
|
||||
form.setShowDisabledFields(true);
|
||||
form.setHidePrintLink(true);
|
||||
|
||||
form.setValue("WKNumProces", getValue('WKNumProces'));
|
||||
form.setValue("activity", activity);
|
||||
form.setValue("formMode", form.getFormMode());
|
||||
form.setValue("empresa", getValue("WKCompany"));
|
||||
|
||||
var c1 = DatasetFactory.createConstraint("colleagueId", userId, userId, ConstraintType.MUST);
|
||||
var filter = new Array(c1);
|
||||
var fields = new Array("colleagueName");
|
||||
var retorno = DatasetFactory.getDataset("colleague", fields, filter, null);
|
||||
|
||||
//requester
|
||||
if (activity == 0) {
|
||||
form.setValue("usuario_abertura", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("requesterMail", retorno.getValue(0, "mail"));
|
||||
form.setValue("requesterId", userId);
|
||||
} else {
|
||||
form.setValue("currentUserName", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("currentUsermail", retorno.getValue(0, "mail"));
|
||||
form.setValue("currentUserId", userId);
|
||||
}
|
||||
|
||||
// ✅ Quando for atividade de aprovação do gestor
|
||||
if (activity == 121) {
|
||||
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
|
||||
form.setValue("user_validacao_gestor", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("data_validacao_gestor", hoje);
|
||||
}
|
||||
|
||||
if (activity == 133) {
|
||||
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
|
||||
form.setValue("gestor_validacao_aprova", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("data_validacao_aprova_gestor", hoje);
|
||||
}
|
||||
|
||||
if (activity == 137) {
|
||||
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
|
||||
form.setValue("user_validacao_aprova", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("data_validacao_aprova", hoje);
|
||||
}
|
||||
|
||||
if (activity == 147) {
|
||||
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
|
||||
form.setValue("gerf_validacao_aprova", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("data_validacao_aprova_gerf", hoje);
|
||||
}
|
||||
|
||||
if (activity == 18) {
|
||||
var hoje = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());
|
||||
form.setValue("userValidacaoItens", retorno.getValue(0, "colleagueName"));
|
||||
form.setValue("dataValidacaoItens", hoje);
|
||||
}
|
||||
|
||||
// ✅ Injetar dados da SC do Protheus (se já tiverem sido preenchidos no servicetask)
|
||||
var camposSC = [
|
||||
"numeroSCProtheus",
|
||||
"statusSCProtheus",
|
||||
"solicitanteSCProtheus",
|
||||
"emissaoSCProtheus",
|
||||
"qtdItensSCProtheus",
|
||||
"dataCadastroSCProtheus",
|
||||
"horaCadastroSCProtheus"
|
||||
];
|
||||
|
||||
camposSC.forEach(function(campo) {
|
||||
var valor = form.getValue(campo);
|
||||
if (valor) {
|
||||
customHTML.append("<script>$('#" + campo + "_label').text('" + valor + "');</script>");
|
||||
}
|
||||
});
|
||||
|
||||
// cor no status
|
||||
var status = form.getValue("statusSCProtheus");
|
||||
if (status) {
|
||||
var badgeClass = "badge bg-secondary";
|
||||
if (status.toLowerCase().indexOf("sucesso") >= 0) badgeClass = "badge bg-success";
|
||||
if (status.toLowerCase().indexOf("erro") >= 0) badgeClass = "badge bg-danger";
|
||||
|
||||
customHTML.append("<script>$('#statusSCProtheus_label').removeClass().addClass('" + badgeClass + "').text('" + status + "');</script>");
|
||||
}
|
||||
|
||||
// Consultar informações adicionais da SC no Protheus
|
||||
var numSC = form.getValue("numeroSCProtheus");
|
||||
if (numSC) {
|
||||
try {
|
||||
var c1 = DatasetFactory.createConstraint("numeroSCProtheus", numSC, numSC, ConstraintType.MUST);
|
||||
var ds = DatasetFactory.getDataset("ds_consultaSC", null, [c1], null);
|
||||
|
||||
if (ds && ds.rowsCount > 0) {
|
||||
var status = ds.getValue(0, "STATUS") || "";
|
||||
var cotacao = ds.getValue(0, "C1_COTACAO") || "";
|
||||
var pedido = ds.getValue(0, "C1_PEDIDO") || "";
|
||||
|
||||
// grava nos hidden inputs
|
||||
form.setValue("statusAtendimento", status);
|
||||
form.setValue("cotacaoSCProtheus", cotacao);
|
||||
form.setValue("pedidoSCProtheus", pedido);
|
||||
|
||||
// mostra nos cards (HTML)
|
||||
customHTML.append("<script>$('#statusSC_label').text('" + status + "');</script>");
|
||||
customHTML.append("<script>$('#cotacaoSC_label').text('" + cotacao + "');</script>");
|
||||
customHTML.append("<script>$('#pedidoSC_label').text('" + pedido + "');</script>");
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("❌ Erro ao consultar dataset ds_consultaSC: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var msgs = [];
|
||||
|
||||
var numeroSC = form.getValue("numeroSCProtheus");
|
||||
var cotacaoSC = form.getValue("cotacaoSCProtheus");
|
||||
var pedidoSC = form.getValue("pedidoSCProtheus");
|
||||
|
||||
if (numeroSC) msgs.push("📌 Gerou SC Protheus nº " + numeroSC);
|
||||
if (cotacaoSC) msgs.push("📌 SC originou Cotação nº " + cotacaoSC);
|
||||
if (pedidoSC) msgs.push("📌 Cotação finalizou → Pedido nº " + pedidoSC);
|
||||
|
||||
if (msgs.length === 0) {
|
||||
msgs.push("ℹ️ Nenhum dado de integração Protheus encontrado no formulário");
|
||||
}
|
||||
|
||||
// Monta conteúdo HTML do histórico
|
||||
var htmlHistorico = "<ul class='hist-list'>";
|
||||
for (var i = 0; i < msgs.length; i++) {
|
||||
htmlHistorico += "<li class='hist-item'>" + msgs[i] + "</li>";
|
||||
}
|
||||
htmlHistorico += "</ul>";
|
||||
|
||||
// Script para abrir modal ao clicar no botão
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("$('#btnHistorico').off('click').on('click', function(){");
|
||||
customHTML.append(" var myModal = FLUIGC.modal({");
|
||||
customHTML.append(" title: 'Histórico do Processo',");
|
||||
customHTML.append(" content: `" + htmlHistorico + "`,");
|
||||
customHTML.append(" id: 'modalHistorico',");
|
||||
customHTML.append(" size: 'large'");
|
||||
customHTML.append(" });");
|
||||
customHTML.append("});");
|
||||
customHTML.append("</script>");
|
||||
|
||||
} catch (e) {
|
||||
log.error("[displayFields] Erro ao montar histórico: " + e);
|
||||
}
|
||||
|
||||
var numCot = form.getValue("cotacaoSCProtheus");
|
||||
var numSC = form.getValue("numeroSCProtheus"); // pega a SC atual
|
||||
|
||||
function formatCurrency(v) {
|
||||
if (!v || isNaN(v)) return "R$ 0,00";
|
||||
var num = parseFloat(v).toFixed(2);
|
||||
return "R$ " + num.replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
||||
}
|
||||
|
||||
function formatDate(v) {
|
||||
if (!v || v.length !== 8) return v || "";
|
||||
var y = v.substring(0,4);
|
||||
var m = v.substring(4,6);
|
||||
var d = v.substring(6,8);
|
||||
return d + "/" + m + "/" + y;
|
||||
}
|
||||
|
||||
function formatPrazo(v) {
|
||||
if (!v) return "";
|
||||
return v + " dias úteis";
|
||||
}
|
||||
|
||||
if (!numCot) {
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("$('#cotacaoContainer').html('<p>⚠️ Cotação não informada no formulário.</p>');");
|
||||
customHTML.append("</script>");
|
||||
return;
|
||||
}
|
||||
|
||||
var c = DatasetFactory.createConstraint("numCotacao", numCot, numCot, ConstraintType.MUST);
|
||||
var ds = DatasetFactory.getDataset("dsComprasCotacao", null, [c], null);
|
||||
var precoFormatado = formatCurrency(preco);
|
||||
var totalFormatado = formatCurrency(total);
|
||||
|
||||
if (ds && ds.rowsCount > 0) {
|
||||
for (var i = 0; i < ds.rowsCount; i++) {
|
||||
var item = ds.getValue(i, "C8_ITEM");
|
||||
var desc = ds.getValue(i, "B1_DESC");
|
||||
var qtd = ds.getValue(i, "C8_QUANT");
|
||||
var preco = ds.getValue(i, "C8_PRECO");
|
||||
var total = ds.getValue(i, "C8_TOTAL");
|
||||
|
||||
// adiciona linha na tabela pai-filho
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("var idx = wdkAddChild('tbCotacao');");
|
||||
customHTML.append("$('#item___'+idx).val('" + item + "');");
|
||||
customHTML.append("$('#produto___'+idx).val('" + desc + "');");
|
||||
customHTML.append("$('#qtdc___'+idx).val('" + qtd + "');");
|
||||
customHTML.append("$('#preco___' + idx).val('" + precoFormatado + "');");
|
||||
customHTML.append("$('#total___' + idx).val('" + totalFormatado + "');");
|
||||
customHTML.append("</script>");
|
||||
}
|
||||
} else {
|
||||
customHTML.append("<script>$('#tbCotacao tbody').html('<tr><td colspan=6>⏳ Nenhum item encontrado.</td></tr>');</script>");
|
||||
}
|
||||
|
||||
try {
|
||||
var numPedido = form.getValue("pedidoSCProtheus"); // hidden no formulário
|
||||
if (!numPedido) {
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-warning\">⏳ O pedido ainda não foi criado</span>');");
|
||||
customHTML.append("</script>");
|
||||
return;
|
||||
}
|
||||
|
||||
var c = DatasetFactory.createConstraint("numeroPed", numPedido, numPedido, ConstraintType.MUST);
|
||||
var ds = DatasetFactory.getDataset("dsComprasGateway", null, [c], null);
|
||||
|
||||
if (!ds || ds.rowsCount === 0) {
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-warning\">⏳ O pedido ainda não foi criado</span>');");
|
||||
customHTML.append("</script>");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var html = "";
|
||||
for (var i = 0; i < ds.rowsCount; i++) {
|
||||
var rowNum = ds.getValue(i, "C7_NUM");
|
||||
var desc = ds.getValue(i, "B1_DESC");
|
||||
var qtd = ds.getValue(i, "C7_QUANT");
|
||||
var valor = ds.getValue(i, "C7_TOTAL");
|
||||
var un = ds.getValue(i, "B1_UM");
|
||||
var pr = ds.getValue(i, "C7_DATPRF");
|
||||
|
||||
html += "<div class='pedido-card'>"
|
||||
+ " <div class='pedido-header'>Pedido nº " + (rowNum || "-") + "</div>"
|
||||
+ " <div class='pedido-grid'>"
|
||||
+ " <div class='pedido-box'><b>Descrição</b><br>" + (desc || "-") + "</div>"
|
||||
+ " <div class='pedido-box'><b>Quantidade</b><br>" + parseInt(qtd || 0) + " " + (un || "") + "</div>"
|
||||
+ " <div class='pedido-box'><b>Valor</b><br>" + formatCurrency(valor) + "</div>"
|
||||
+ " <div class='pedido-box'><b>Data de Entrega</b><br>" + formatDate(pr) + "</div>"
|
||||
+ " </div>"
|
||||
+ "</div>";
|
||||
|
||||
}
|
||||
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("$('#espelhoPedido').html(" + JSON.stringify(html) + ");");
|
||||
customHTML.append("</script>");
|
||||
|
||||
} catch (e) {
|
||||
var msg = "❌ Erro displayFields Pedido: " + (e && e.message ? e.message : e);
|
||||
log.error(msg);
|
||||
|
||||
customHTML.append("<script>");
|
||||
customHTML.append("console.error(" + JSON.stringify(msg) + ");"); // aparece no console do navegador
|
||||
customHTML.append("$('#espelhoPedido').html('<span class=\"badge bg-danger\">" + msg + "</span>');");
|
||||
customHTML.append("</script>");
|
||||
}
|
||||
|
||||
// Se estou na atividade do Gestor do CC (ex: 133)
|
||||
if (activity == 133) {
|
||||
// Copia a justificativa do solicitante para o campo de exibição
|
||||
form.setValue("observacoesdosolicitante", form.getValue("observacoes"));
|
||||
}
|
||||
|
||||
// Se estou na atividade do GERF (ex: 147)
|
||||
if (activity == 147) {
|
||||
form.setValue("justi_decisao__soli", form.getValue("observacoes")); // solicitante
|
||||
form.setValue("justi_decisao_gc", form.getValue("justi_decisao_aprova_gestor")); // gestor
|
||||
}
|
||||
|
||||
// Se estou na atividade do CEO (ex: 158)
|
||||
if (activity == 158) {
|
||||
form.setValue("justi_decisao_solic", form.getValue("observacoes")); // solicitante
|
||||
form.setValue("justi_decisaogc", form.getValue("justi_decisao_aprova_gestor")); // gestor
|
||||
form.setValue("justi_decisao_gerf", form.getValue("justi_decisao_aprova_gerente")); // gerente financeiro
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
function enableFields(form) {
|
||||
var atividade = getValue("WKNumState");
|
||||
|
||||
if (atividade != 0 && atividade != 4 && atividade != 9) {
|
||||
|
||||
form.setEnabled("emitido_por", false);
|
||||
form.setEnabled("tipo_cadastro", false);
|
||||
form.setEnabled("radio_ged", false);
|
||||
form.setEnabled("radio_data_validade", false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
function validateForm(form){
|
||||
var msg = "";
|
||||
var activity = getValue("WKNumState");
|
||||
|
||||
// Só valida "Justificativa do Gestor" quando estiver na atividade do gestor (ex.: 5)
|
||||
if (activity == 121) {
|
||||
if (form.getValue("justi_decisao_gestor") == "") {
|
||||
msg += "Campo Justificativa do Gestor não foi preenchido\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (msg != "") {
|
||||
throw msg;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
||||
.componentAnexo{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.componentAnexo .input-group{
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.componentAnexo .inputAnexo{
|
||||
color: blue!important;
|
||||
border-radius: 0!important;
|
||||
}
|
||||
|
||||
.componentAnexo .icones{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn{
|
||||
outline: none!important;
|
||||
outline-offset: unset!important;
|
||||
border-radius: 0;
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn-default,
|
||||
.componentAnexo .icones .btn-default:focus,
|
||||
.componentAnexo .icones .btn-default:active,
|
||||
.componentAnexo .icones .btn-default:hover{
|
||||
border: solid 1px #58595b!important;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn-primary,
|
||||
.componentAnexo .icones .btn-primary:focus,
|
||||
.componentAnexo .icones .btn-primary:active,
|
||||
.componentAnexo .icones .btn-primary:hover{
|
||||
border: solid 1px #58595b!important;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn-success,
|
||||
.componentAnexo .icones .btn-success:focus,
|
||||
.componentAnexo .icones .btn-success:active,
|
||||
.componentAnexo .icones .btn-success:hover{
|
||||
border: solid 1px #1ab83f!important;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn-info,
|
||||
.componentAnexo .icones .btn-info:focus,
|
||||
.componentAnexo .icones .btn-info:active,
|
||||
.componentAnexo .icones .btn-info:hover{
|
||||
border: solid 1px #1eaad9!important;
|
||||
}
|
||||
.componentAnexo .icones .btn-warning,
|
||||
.componentAnexo .icones .btn-warning:focus,
|
||||
.componentAnexo .icones .btn-warning:active,
|
||||
.componentAnexo .icones .btn-warning:hover{
|
||||
border: solid 1px #e3b420!important;
|
||||
}
|
||||
|
||||
.componentAnexo .icones .btn-danger,
|
||||
.componentAnexo .icones .btn-danger:focus,
|
||||
.componentAnexo .icones .btn-danger:active,
|
||||
.componentAnexo .icones .btn-danger:hover{
|
||||
border: solid 1px #cc3d3d!important;
|
||||
}
|
||||
|
||||
/* Etapas concluídas */
|
||||
#wizard-steps .step-item.done .step-bullet {
|
||||
background-color: #28a745; /* verde */
|
||||
border-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
#wizard-steps .step-item.done .step-label {
|
||||
color: #28a745;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Etapa atual */
|
||||
#wizard-steps .step-item.active .step-bullet {
|
||||
background-color: #007bff; /* azul */
|
||||
border-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
#wizard-steps .step-item.active .step-label {
|
||||
color: #007bff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Etapas futuras */
|
||||
#wizard-steps .step-item .step-bullet {
|
||||
background-color: #e9ecef; /* cinza claro */
|
||||
border: 2px solid #ccc;
|
||||
color: #6c757d;
|
||||
}
|
||||
#wizard-steps .step-item .step-label {
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* Deixar as bolinhas maiores e destacadas */
|
||||
#wizard-steps .step-bullet {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.hist-list {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
list-style: none;
|
||||
}
|
||||
.hist-list .hist-item {
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px dashed #ddd;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.hist-list .hist-item:last-child { border-bottom: 0; }
|
||||
|
||||
|
||||
.pedido-card {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
box-shadow: 2px 2px 5px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.pedido-header {
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
background: #f5f5f5;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.pedido-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.pedido-box {
|
||||
flex: 1 1 120px; /* mínimo 120px, ajusta conforme espaço */
|
||||
background: #fafafa;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
Reference in New Issue
Block a user