967 lines
49 KiB
HTML
967 lines
49 KiB
HTML
<!-- Toast (Sucesso) -->
|
||
<div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 10000;">
|
||
<div #successToast class="toast text-bg-success border-0 shadow" role="alert" aria-live="assertive" aria-atomic="true">
|
||
<div class="toast-header border-bottom-0">
|
||
<strong class="me-auto text-primary">LineGestão</strong>
|
||
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Fechar"></button>
|
||
</div>
|
||
<div class="toast-body bg-white rounded-bottom text-dark">
|
||
{{ toastMessage }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<section class="geral-page" (click)="closeClientDropdown()">
|
||
<span class="page-blob blob-1" aria-hidden="true"></span>
|
||
<span class="page-blob blob-2" aria-hidden="true"></span>
|
||
<span class="page-blob blob-3" aria-hidden="true"></span>
|
||
<span class="page-blob blob-4" aria-hidden="true"></span>
|
||
|
||
<!-- ✅ classe extra para permitir “crescer” em notebook/TV via SCSS sem mexer no monitor -->
|
||
<div class="container-geral container-geral-responsive">
|
||
<div class="geral-card geral-card-responsive" data-animate>
|
||
<div class="geral-header">
|
||
<div class="header-row-top">
|
||
<div class="title-badge" data-animate>
|
||
<i class="bi bi-grid-1x2"></i> Gerenciar Linhas
|
||
</div>
|
||
|
||
<div class="header-title" data-animate>
|
||
<h5 class="title mb-0">Geral</h5>
|
||
<small class="subtitle">Tabela de linhas e dados de telefonia</small>
|
||
</div>
|
||
|
||
<div class="header-actions d-flex gap-2 justify-content-end" data-animate>
|
||
<button
|
||
type="button"
|
||
class="btn btn-glass btn-sm"
|
||
(click)="onImportExcel()"
|
||
[disabled]="loading">
|
||
<i class="bi bi-file-earmark-excel me-1"></i> Importar Dados Excel
|
||
</button>
|
||
|
||
<input #excelInput type="file" class="d-none" accept=".xlsx" (change)="onExcelSelected($event)" />
|
||
|
||
<button
|
||
type="button"
|
||
class="btn btn-brand btn-sm"
|
||
(click)="onCadastrarLinha()"
|
||
[disabled]="loading">
|
||
<i class="bi bi-plus-circle me-1"></i> Novo Cliente
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="filters-row mt-4" data-animate>
|
||
<div class="filter-tabs">
|
||
<button type="button" class="filter-tab" [class.active]="filterSkil === 'ALL'" (click)="setFilter('ALL')" [disabled]="loading">
|
||
Todos
|
||
</button>
|
||
<button type="button" class="filter-tab" [class.active]="filterSkil === 'PF'" (click)="setFilter('PF')" [disabled]="loading">
|
||
<i class="bi bi-person me-1"></i> Pessoa Física
|
||
</button>
|
||
<button type="button" class="filter-tab" [class.active]="filterSkil === 'PJ'" (click)="setFilter('PJ')" [disabled]="loading">
|
||
<i class="bi bi-building me-1"></i> Pessoa Jurídica
|
||
</button>
|
||
<button type="button" class="filter-tab" [class.active]="filterSkil === 'RESERVA'" (click)="setFilter('RESERVA')" [disabled]="loading">
|
||
<i class="bi bi-archive me-1"></i> Reservas
|
||
</button>
|
||
</div>
|
||
|
||
<!-- CLIENTE MULTI-SELECT -->
|
||
<div class="client-filter-wrap" (click)="$event.stopPropagation()">
|
||
<button
|
||
type="button"
|
||
class="btn-client-filter"
|
||
[class.has-selection]="selectedClients.length > 0"
|
||
(click)="toggleClientMenu()"
|
||
[disabled]="loading">
|
||
|
||
<ng-container *ngIf="selectedClients.length === 0">
|
||
<i class="bi bi-people-fill me-2"></i>
|
||
<span>Clientes</span>
|
||
<i class="bi bi-chevron-down ms-2 small"></i>
|
||
</ng-container>
|
||
|
||
<ng-container *ngIf="selectedClients.length > 0">
|
||
<div class="chips-container">
|
||
<span *ngFor="let client of selectedClients" class="client-chip" (click)="$event.stopPropagation()">
|
||
{{ client }}
|
||
<i class="bi bi-x chip-close" (click)="removeClient(client, $event)"></i>
|
||
</span>
|
||
</div>
|
||
<i class="bi bi-chevron-down ms-1 small text-muted"></i>
|
||
</ng-container>
|
||
</button>
|
||
|
||
<div class="client-dropdown" *ngIf="showClientMenu">
|
||
<div class="dropdown-header-search">
|
||
<input
|
||
type="text"
|
||
class="form-control form-control-sm"
|
||
placeholder="Buscar na lista..."
|
||
[(ngModel)]="clientSearchTerm"
|
||
autofocus
|
||
(click)="$event.stopPropagation()">
|
||
</div>
|
||
|
||
<div class="dropdown-list">
|
||
<div class="dropdown-item-custom" [class.selected]="selectedClients.length === 0" (click)="selectClient(null)">
|
||
<i class="bi bi-grid me-2"></i> Todos os Clientes
|
||
</div>
|
||
|
||
<ng-container *ngFor="let client of filteredClientsList">
|
||
<div class="dropdown-item-custom" [class.selected]="isClientSelected(client)" (click)="selectClient(client)">
|
||
<div class="d-flex align-items-center justify-content-between w-100">
|
||
<span>{{ client }}</span>
|
||
<i class="bi bi-check-lg text-brand" *ngIf="isClientSelected(client)"></i>
|
||
</div>
|
||
</div>
|
||
</ng-container>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- KPIs -->
|
||
<div class="geral-kpis mt-4 animate-fade-in" *ngIf="isGroupMode">
|
||
<div class="kpi">
|
||
<span class="lbl">Total Clientes</span>
|
||
<span class="val">
|
||
<span *ngIf="loadingKpis" class="spinner-border spinner-border-sm text-muted"></span>
|
||
<span *ngIf="!loadingKpis">{{ kpiTotalClientes || 0 }}</span>
|
||
</span>
|
||
</div>
|
||
|
||
<div class="kpi">
|
||
<span class="lbl">Total Linhas</span>
|
||
<span class="val">
|
||
<span *ngIf="loadingKpis" class="spinner-border spinner-border-sm text-muted"></span>
|
||
<span *ngIf="!loadingKpis">{{ kpiTotalLinhas || 0 }}</span>
|
||
</span>
|
||
</div>
|
||
|
||
<div class="kpi">
|
||
<span class="lbl text-success">Ativas</span>
|
||
<span class="val">
|
||
<span *ngIf="loadingKpis" class="spinner-border spinner-border-sm text-muted"></span>
|
||
<span *ngIf="!loadingKpis">{{ kpiAtivas || 0 }}</span>
|
||
</span>
|
||
</div>
|
||
|
||
<div class="kpi">
|
||
<span class="lbl text-danger">Bloqueadas</span>
|
||
<span class="val">
|
||
<span *ngIf="loadingKpis" class="spinner-border spinner-border-sm text-muted"></span>
|
||
<span *ngIf="!loadingKpis">{{ kpiBloqueadas || 0 }}</span>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CONTROLS -->
|
||
<div class="controls mt-3 mb-2" data-animate>
|
||
<div class="input-group input-group-sm search-group">
|
||
<span class="input-group-text">
|
||
<i
|
||
class="bi"
|
||
[class.bi-search]="!loading"
|
||
[class.bi-hourglass-split]="loading"
|
||
[class.text-brand]="loading"></i>
|
||
</span>
|
||
|
||
<input class="form-control" placeholder="Pesquisar..." [(ngModel)]="searchTerm" (ngModelChange)="onSearch()" />
|
||
|
||
<button class="btn btn-outline-secondary btn-clear" type="button" (click)="clearSearch()" *ngIf="searchTerm">
|
||
<i class="bi bi-x-lg"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="page-size d-flex align-items-center gap-2">
|
||
<span class="text-muted small fw-bold text-uppercase" style="letter-spacing: 0.5px; font-size: 0.75rem;">
|
||
Itens por pág:
|
||
</span>
|
||
|
||
<div class="select-wrapper">
|
||
<app-select class="select-glass" size="sm" [options]="pageSizeOptions" [(ngModel)]="pageSize" (ngModelChange)="onPageSizeChange()" [disabled]="loading"></app-select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="geral-body">
|
||
<!-- VIEW: GRUPOS -->
|
||
<div class="groups-container" *ngIf="isGroupMode; else tableView">
|
||
<div class="text-center p-5" *ngIf="loading">
|
||
<span class="spinner-border text-brand"></span>
|
||
</div>
|
||
|
||
<div class="empty-group" *ngIf="!loading && clientGroups.length === 0">
|
||
Nenhum dado encontrado.
|
||
</div>
|
||
|
||
<div class="group-list" *ngIf="!loading">
|
||
<div *ngFor="let group of clientGroups" class="client-group-card" [class.expanded]="expandedGroup === group.cliente">
|
||
<div class="group-header" (click)="toggleGroup(group.cliente)">
|
||
<div class="group-info">
|
||
<h6 class="mb-0 fw-bold text-dark">{{ group.cliente }}</h6>
|
||
<div class="group-badges">
|
||
<span class="badge-pill total">{{ group.totalLinhas }} Linhas</span>
|
||
<span class="badge-pill active" *ngIf="group.ativos > 0">{{ group.ativos }} Ativas</span>
|
||
<span class="badge-pill blocked" *ngIf="group.bloqueados > 0">{{ group.bloqueados }} Bloq.</span>
|
||
</div>
|
||
</div>
|
||
<div class="group-toggle-icon"><i class="bi bi-chevron-down"></i></div>
|
||
</div>
|
||
|
||
<div class="group-body" *ngIf="expandedGroup === group.cliente">
|
||
<div class="d-flex justify-content-between align-items-center px-4 py-2 border-bottom bg-white">
|
||
<small class="text-muted fw-bold">Gerenciar Grupo</small>
|
||
<button class="btn btn-sm btn-primary" (click)="onAddLineToGroup(group.cliente)">
|
||
<i class="bi bi-plus-lg me-1"></i> Adicionar Linha
|
||
</button>
|
||
</div>
|
||
|
||
<!-- ✅ wrapper com classe extra para permitir MAIS ALTURA em notebook/TV via SCSS -->
|
||
<div class="table-wrap inner-table-wrap table-wrap-responsive table-wrap-tall">
|
||
<div *ngIf="loadingLines" class="p-4 text-center text-muted">
|
||
<span class="spinner-border spinner-border-sm me-2"></span> Carregando linhas...
|
||
</div>
|
||
|
||
<table class="table table-modern table-modern-responsive align-middle text-center mb-0" *ngIf="!loadingLines">
|
||
<thead>
|
||
<tr>
|
||
<th>ITEM</th>
|
||
<th>LINHA</th>
|
||
<th>USUÁRIO</th>
|
||
<th>STATUS</th>
|
||
<th>VENCIMENTO</th>
|
||
<th>AÇÕES</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<tr *ngFor="let r of groupLines" class="table-row-item">
|
||
<td class="text-muted fw-bold">{{ r.item }}</td>
|
||
<td class="fw-black text-blue">{{ r.linha }}</td>
|
||
<td class="text-dark">{{ r.usuario || '-' }}</td>
|
||
<td>
|
||
<span class="status-pill" [ngClass]="statusClass(r.status)">{{ statusLabel(r.status) }}</span>
|
||
</td>
|
||
<td class="text-muted small fw-bold">{{ r.contrato }}</td>
|
||
<td>
|
||
<div class="action-group justify-content-center">
|
||
<button class="btn-icon" (click)="onDetalhes(r)" title="Detalhes"><i class="bi bi-eye"></i></button>
|
||
<button class="btn-icon success" (click)="onFinanceiro(r)" title="Financeiro"><i class="bi bi-cash-coin"></i></button>
|
||
<button class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
|
||
<button class="btn-icon danger" (click)="onRemover(r, true)" title="Remover"><i class="bi bi-trash"></i></button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- ✅ espaçador para afastar da área do footer (notebook/TV via SCSS) -->
|
||
<div class="footer-spacer footer-spacer-responsive" aria-hidden="true"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- VIEW: TABELA -->
|
||
<ng-template #tableView>
|
||
<!-- ✅ wrapper com classe extra para permitir MAIS ALTURA em notebook/TV via SCSS -->
|
||
<div class="table-wrap table-wrap-responsive table-wrap-tall">
|
||
<table class="table table-modern table-modern-responsive align-middle text-center">
|
||
<colgroup>
|
||
<col style="width: 80px;">
|
||
<col style="width: 140px;">
|
||
<col style="width: 280px;">
|
||
<col style="width: 160px;">
|
||
<col style="width: 130px;">
|
||
<col style="width: 130px;">
|
||
<col style="width: 160px;">
|
||
</colgroup>
|
||
|
||
<thead>
|
||
<tr>
|
||
<th class="sortable text-center" (click)="setSort('item')">
|
||
<div class="th-content justify-content-center">
|
||
ITEM
|
||
<span class="sort-caret" [class.active]="sortKey==='item'">
|
||
{{ sortKey==='item' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="sortable text-center" (click)="setSort('linha')">
|
||
<div class="th-content justify-content-center">
|
||
LINHA
|
||
<span class="sort-caret" [class.active]="sortKey==='linha'">
|
||
{{ sortKey==='linha' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="sortable text-center" (click)="setSort('cliente')">
|
||
<div class="th-content justify-content-center">
|
||
CLIENTE
|
||
<span class="sort-caret" [class.active]="sortKey==='cliente'">
|
||
{{ sortKey==='cliente' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="sortable text-center" (click)="setSort('status')">
|
||
<div class="th-content justify-content-center">
|
||
STATUS
|
||
<span class="sort-caret" [class.active]="sortKey==='status'">
|
||
{{ sortKey==='status' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="sortable text-center" (click)="setSort('skil')">
|
||
<div class="th-content justify-content-center">
|
||
SKIL
|
||
<span class="sort-caret" [class.active]="sortKey==='skil'">
|
||
{{ sortKey==='skil' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="sortable text-center" (click)="setSort('contrato')">
|
||
<div class="th-content justify-content-center">
|
||
VENCIMENTO
|
||
<span class="sort-caret" [class.active]="sortKey==='contrato'">
|
||
{{ sortKey==='contrato' && sortDir==='desc' ? '▼' : '▲' }}
|
||
</span>
|
||
</div>
|
||
</th>
|
||
|
||
<th class="text-center">AÇÕES</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<tr *ngIf="loading">
|
||
<td colspan="7" class="text-center py-5 empty-state">
|
||
<span class="spinner-border spinner-border-sm me-2 text-brand"></span> Carregando...
|
||
</td>
|
||
</tr>
|
||
|
||
<tr *ngIf="!loading && pagedRows.length === 0">
|
||
<td colspan="7" class="text-center py-5 empty-state text-muted fw-bold">
|
||
Nenhum registro encontrado.
|
||
</td>
|
||
</tr>
|
||
|
||
<tr *ngFor="let r of pagedRows; trackBy: trackById" class="table-row-item">
|
||
<td class="text-center text-muted fw-bold">{{ r.item }}</td>
|
||
<td class="text-center fw-black text-blue">{{ r.linha }}</td>
|
||
<td class="text-center fw-bold text-dark td-clip" [title]="r.cliente">{{ r.cliente }}</td>
|
||
<td class="text-center">
|
||
<span class="status-pill" [ngClass]="statusClass(r.status)" [title]="r.status || ''">{{ statusLabel(r.status) }}</span>
|
||
</td>
|
||
<td class="text-center fw-bold text-muted small">{{ r.skil }}</td>
|
||
<td class="text-center fw-bold text-muted small">{{ r.contrato }}</td>
|
||
<td class="text-center">
|
||
<div class="action-group justify-content-center">
|
||
<button class="btn-icon" (click)="onDetalhes(r)" title="Detalhes"><i class="bi bi-eye"></i></button>
|
||
<button class="btn-icon success" (click)="onFinanceiro(r)" title="Financeiro"><i class="bi bi-cash-coin"></i></button>
|
||
<button class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
|
||
<button class="btn-icon danger" (click)="onRemover(r)" title="Remover"><i class="bi bi-trash"></i></button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- ✅ espaçador para afastar da área do footer (notebook/TV via SCSS) -->
|
||
<div class="footer-spacer footer-spacer-responsive" aria-hidden="true"></div>
|
||
</ng-template>
|
||
</div>
|
||
|
||
<div class="geral-footer">
|
||
<div class="small text-muted fw-bold">Mostrando {{ pageStart }}–{{ pageEnd }} de {{ filteredCount }}</div>
|
||
|
||
<nav>
|
||
<ul class="pagination pagination-sm mb-0 pagination-modern">
|
||
<li class="page-item" [class.disabled]="page === 1 || loading">
|
||
<button class="page-link" (click)="goToPage(page - 1)">Anterior</button>
|
||
</li>
|
||
|
||
<li class="page-item" *ngFor="let p of pageNumbers" [class.active]="p === page">
|
||
<button class="page-link" (click)="goToPage(p)">{{ p }}</button>
|
||
</li>
|
||
|
||
<li class="page-item" [class.disabled]="page === totalPages || loading">
|
||
<button class="page-link" (click)="goToPage(page + 1)">Próxima</button>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- =========================================================
|
||
✅ MODAIS (corrigido: remove duplicações e divs soltas)
|
||
- fechamento centralizado em closeAllModals()
|
||
========================================================= -->
|
||
|
||
<!-- Backdrop -->
|
||
<div
|
||
class="modal-backdrop-custom"
|
||
*ngIf="detailOpen || financeOpen || editOpen || createOpen"
|
||
(click)="closeAllModals()">
|
||
</div>
|
||
|
||
<!-- Overlay (captura clique fora) -->
|
||
<div
|
||
class="modal-custom"
|
||
*ngIf="detailOpen || financeOpen || editOpen || createOpen"
|
||
(click)="closeAllModals()"
|
||
>
|
||
<!-- CREATE MODAL -->
|
||
<div
|
||
*ngIf="createOpen"
|
||
#createModal
|
||
class="modal-card modal-lg"
|
||
(click)="$event.stopPropagation()"
|
||
style="width: 1100px; max-width: 95vw;"
|
||
>
|
||
<div class="modal-header">
|
||
<div class="modal-title">
|
||
<span class="icon-bg brand-soft"><i class="bi bi-plus-lg"></i></span>
|
||
{{ createMode === 'NEW_CLIENT' ? 'Cadastrar Novo Cliente' : 'Nova Linha para ' + createModel.cliente }}
|
||
</div>
|
||
|
||
<div class="d-flex align-items-center gap-2">
|
||
<button class="btn btn-glass btn-sm" (click)="closeAllModals()" [disabled]="createSaving">
|
||
<i class="bi bi-x-lg me-1"></i> Cancelar
|
||
</button>
|
||
|
||
<button class="btn btn-brand btn-sm" (click)="saveCreate()" [disabled]="createSaving">
|
||
<span *ngIf="!createSaving"><i class="bi bi-check2-circle me-1"></i> Cadastrar</span>
|
||
<span *ngIf="createSaving"><span class="spinner-border spinner-border-sm me-2"></span> Salvando...</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-body modern-body bg-light-gray">
|
||
<div class="details-dashboard">
|
||
<div class="dashboard-column">
|
||
<details class="detail-box" open>
|
||
<summary class="box-header">
|
||
<span><i class="bi bi-person-badge me-2"></i> Identificação</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field span-2" *ngIf="createMode === 'NEW_CLIENT'">
|
||
<div class="d-flex gap-4 p-2 bg-white rounded border align-items-center justify-content-center">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="radio" name="docType" value="PF" [(ngModel)]="createModel.docType" (change)="onDocTypeChange()">
|
||
<label class="form-check-label fw-bold small">Pessoa Física</label>
|
||
</div>
|
||
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="radio" name="docType" value="PJ" [(ngModel)]="createModel.docType" (change)="onDocTypeChange()">
|
||
<label class="form-check-label fw-bold small">Pessoa Jurídica</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-field span-2" *ngIf="createMode === 'NEW_CLIENT'">
|
||
<label>Nome do Cliente <span class="text-danger">*</span></label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.cliente" placeholder="Razão Social ou Nome Completo" />
|
||
</div>
|
||
|
||
<div class="form-field span-2" *ngIf="createMode === 'NEW_CLIENT'">
|
||
<label>{{ createModel.docType === 'PF' ? 'CPF' : 'CNPJ' }}</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.docNumber" (input)="onDocInput($event)" placeholder="Somente números" />
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Item (Automático)</label>
|
||
<input class="form-control form-control-sm bg-light fst-italic text-muted" value="Gerado ao Salvar" readonly title="O ID será gerado automaticamente pelo sistema" />
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Conta <span class="text-danger">*</span></label>
|
||
<app-select class="form-select" size="sm" [options]="contaOptions" [(ngModel)]="createModel.conta"></app-select>
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Linha <span class="text-danger">*</span></label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.linha" placeholder="119..." />
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Chip (ICCID) <span class="text-danger">*</span></label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.chip" />
|
||
</div>
|
||
|
||
<div class="form-field span-2">
|
||
<label>Usuário da Linha</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.usuario" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box mt-3">
|
||
<summary class="box-header">
|
||
<span><i class="bi bi-sliders me-2"></i> Gestão</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field">
|
||
<label>Skil (Automático)</label>
|
||
<input class="form-control form-control-sm bg-light" [(ngModel)]="createModel.skil" readonly />
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Cedente</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.cedente" />
|
||
</div>
|
||
|
||
<div class="form-field span-2">
|
||
<label>Solicitante</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.solicitante" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<div class="dashboard-column">
|
||
<details class="detail-box" open>
|
||
<summary class="box-header">
|
||
<span><i class="bi bi-file-earmark-text me-2"></i> Contrato & Status</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field span-2">
|
||
<label>Plano Contrato <span class="text-danger">*</span></label>
|
||
<app-select class="form-select" size="sm" [options]="planOptions" [(ngModel)]="createModel.planoContrato"></app-select>
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Venc. Conta</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.vencConta" placeholder="ex: Dia 10" />
|
||
</div>
|
||
|
||
<div class="form-field">
|
||
<label>Modalidade</label>
|
||
<input class="form-control form-control-sm" [(ngModel)]="createModel.modalidade" />
|
||
</div>
|
||
|
||
<div class="form-field span-2">
|
||
<label>Status <span class="text-danger">*</span></label>
|
||
<app-select class="form-select" size="sm" [options]="statusOptions" [(ngModel)]="createModel.status"></app-select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box mt-3">
|
||
<summary class="box-header">
|
||
<span><i class="bi bi-calendar-event me-2"></i> Datas Importantes</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field span-2">
|
||
<label>Data Entrega Operadora</label>
|
||
<input class="form-control form-control-sm" type="date" [(ngModel)]="createModel.dataEntregaOpera" />
|
||
</div>
|
||
|
||
<div class="form-field span-2">
|
||
<label>Data Entrega Cliente</label>
|
||
<input class="form-control form-control-sm" type="date" [(ngModel)]="createModel.dataEntregaCliente" />
|
||
</div>
|
||
|
||
<div class="form-field span-2">
|
||
<label>Data de Bloqueio</label>
|
||
<input class="form-control form-control-sm" type="date" [(ngModel)]="createModel.dataBloqueio" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<div class="dashboard-column">
|
||
<details class="detail-box vivo-border">
|
||
<summary class="box-header header-vivo">
|
||
<span><i class="bi bi-telephone-fill me-2"></i> Financeiro Vivo</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Franquia (GB)</label><input class="form-control form-control-sm" type="number" step="0.1" [(ngModel)]="createModel.franquiaVivo" /></div>
|
||
<div class="form-field"><label>Valor Plano</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.valorPlanoVivo" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label>Gestão Voz</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.gestaoVozDados" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label>Skeelo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.skeelo" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label>News+</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.vivoNewsPlus" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label>Travel Mundo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.vivoTravelMundo" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label>Gestão Disp.</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.vivoGestaoDispositivo" (change)="onFinancialChange(false)" /></div>
|
||
<div class="form-field"><label class="text-vivo fw-bold">Total Vivo (Auto)</label><input class="form-control form-control-sm fw-bold border-vivo bg-light" type="number" step="0.01" [(ngModel)]="createModel.valorContratoVivo" readonly /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box line-border mt-3">
|
||
<summary class="box-header header-line">
|
||
<span><i class="bi bi-hdd-network-fill me-2"></i> Financeiro Line</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Franquia Line</label><input class="form-control form-control-sm" type="number" step="0.1" [(ngModel)]="createModel.franquiaLine" /></div>
|
||
<div class="form-field"><label>Franquia Gestão</label><input class="form-control form-control-sm" type="number" step="0.1" [(ngModel)]="createModel.franquiaGestao" /></div>
|
||
<div class="form-field"><label>Locação Ap.</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.locacaoAp" /></div>
|
||
<div class="form-field"><label class="text-line fw-bold">Total Line (Manual)</label><input class="form-control form-control-sm fw-bold border-line" type="number" step="0.01" [(ngModel)]="createModel.valorContratoLine" (change)="onFinancialChange(false)" /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box mt-3">
|
||
<summary class="box-header">
|
||
<span><i class="bi bi-graph-up-arrow me-2"></i> Resultados</span>
|
||
<i class="bi bi-chevron-down ms-auto transition-icon"></i>
|
||
</summary>
|
||
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label class="text-danger fw-bold">DESCONTO</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="createModel.desconto" /></div>
|
||
<div class="form-field"><label class="text-brand">LUCRO ESTIMADO</label><input class="form-control form-control-sm bg-light fw-bold" type="number" step="0.01" [(ngModel)]="createModel.lucro" readonly /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DETAIL MODAL -->
|
||
<div
|
||
*ngIf="detailOpen"
|
||
#detailModal
|
||
class="modal-card modal-xl-custom"
|
||
(click)="$event.stopPropagation()"
|
||
>
|
||
<div class="modal-header">
|
||
<div class="modal-title">
|
||
<span class="icon-bg primary-soft"><i class="bi bi-sim"></i></span>
|
||
Detalhes da Linha
|
||
</div>
|
||
<button class="btn btn-sm btn-icon" (click)="closeAllModals()"><i class="bi bi-x-lg"></i></button>
|
||
</div>
|
||
|
||
<div class="modal-body modern-body bg-light-gray" *ngIf="detailData; else detailLoading">
|
||
<div class="details-dashboard">
|
||
<div class="dashboard-column">
|
||
<div class="detail-box h-100">
|
||
<div class="box-header justify-content-center">
|
||
<span><i class="bi bi-person-badge me-2"></i> Identificação</span>
|
||
</div>
|
||
<div class="box-body">
|
||
<div class="info-grid">
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Linha</span>
|
||
<span class="val text-blue fs-4">{{ detailData.linha || '-' }}</span>
|
||
</div>
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Cliente</span>
|
||
<span class="val text-dark" [title]="detailData.cliente">{{ detailData.cliente || '-' }}</span>
|
||
</div>
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Usuário</span>
|
||
<span class="val">{{ detailData.usuario || '-' }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Item</span>
|
||
<span class="val">{{ detailData.item }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Chip (ICCID)</span>
|
||
<span class="val small-text">{{ detailData.chip || '-' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dashboard-column d-flex flex-column gap-2">
|
||
<div class="detail-box">
|
||
<div class="box-header justify-content-center">
|
||
<span><i class="bi bi-sliders me-2"></i> Gestão</span>
|
||
</div>
|
||
<div class="box-body compact-padding">
|
||
<div class="info-grid compact-gap">
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Tipo (Skil)</span>
|
||
<span class="val">{{ detailData.skil || '-' }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Cedente</span>
|
||
<span class="val">{{ detailData.cedente || '-' }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Solicitante</span>
|
||
<span class="val">{{ detailData.solicitante || '-' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="detail-box flex-grow-1">
|
||
<div class="box-header justify-content-center">
|
||
<span><i class="bi bi-calendar-event me-2"></i> Datas</span>
|
||
</div>
|
||
<div class="box-body compact-padding">
|
||
<div class="info-grid compact-gap">
|
||
<div class="info-item">
|
||
<span class="lbl">Entrega Operadora</span>
|
||
<span class="val">{{ formatDateBr(detailData.dataEntregaOpera) }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Entrega Cliente</span>
|
||
<span class="val">{{ formatDateBr(detailData.dataEntregaCliente) }}</span>
|
||
</div>
|
||
<div class="info-item span-2">
|
||
<span class="lbl text-danger">Data Bloqueio</span>
|
||
<span class="val">{{ formatDateBr(detailData.dataBloqueio) }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dashboard-column">
|
||
<div class="detail-box h-100">
|
||
<div class="box-header justify-content-center">
|
||
<span><i class="bi bi-file-earmark-text me-2"></i> Contrato & Status</span>
|
||
</div>
|
||
<div class="box-body">
|
||
<div class="info-grid">
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Plano Contratado</span>
|
||
<span class="val fw-bold text-brand">{{ detailData.planoContrato || '-' }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Conta</span>
|
||
<span class="val">{{ detailData.conta || '-' }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="lbl">Vencimento</span>
|
||
<span class="val">{{ detailData.vencConta || '-' }}</span>
|
||
</div>
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Status Atual</span>
|
||
<div class="mt-1">
|
||
<span class="status-pill static scale-up" [ngClass]="statusClass(detailData.status)">{{ statusLabel(detailData.status) }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="info-item span-2">
|
||
<span class="lbl">Modalidade</span>
|
||
<span class="val">{{ detailData.modalidade || '-' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<ng-template #detailLoading>
|
||
<div class="p-5 text-center text-muted">Carregando detalhes...</div>
|
||
</ng-template>
|
||
</div>
|
||
|
||
<!-- FINANCE MODAL -->
|
||
<div
|
||
*ngIf="financeOpen"
|
||
#financeModal
|
||
class="modal-card modal-lg"
|
||
(click)="$event.stopPropagation()"
|
||
>
|
||
<div class="modal-header">
|
||
<div class="modal-title">
|
||
<span class="icon-bg success"><i class="bi bi-wallet2"></i></span> Financeiro
|
||
</div>
|
||
<button class="btn btn-sm btn-icon" (click)="closeAllModals()"><i class="bi bi-x-lg"></i></button>
|
||
</div>
|
||
|
||
<div class="modal-body modern-body bg-light-gray" *ngIf="financeData; else financeLoading">
|
||
<div class="finance-dashboard">
|
||
<div class="finance-card vivo-card">
|
||
<div class="card-header-f"><i class="bi bi-telephone-fill me-2"></i> Vivo</div>
|
||
<div class="card-body-f">
|
||
<div class="row-item"><span>Franquia</span> <strong>{{ formatFranquia(financeData.franquiaVivo) }}</strong></div>
|
||
<div class="row-item"><span>Valor Plano</span> <strong>{{ formatMoney(financeData.valorPlanoVivo) }}</strong></div>
|
||
<div class="row-item"><span>Gestão Voz/Dados</span> <strong>{{ formatMoney(financeData.gestaoVozDados) }}</strong></div>
|
||
<div class="row-item"><span>Skeelo</span> <strong>{{ formatMoney(financeData.skeelo) }}</strong></div>
|
||
<div class="row-item"><span>Vivo News+</span> <strong>{{ formatMoney(financeData.vivoNewsPlus) }}</strong></div>
|
||
<div class="row-item"><span>Travel Mundo</span> <strong>{{ formatMoney(financeData.vivoTravelMundo) }}</strong></div>
|
||
<div class="row-item"><span>Gestão Disp.</span> <strong>{{ formatMoney(financeData.vivoGestaoDispositivo) }}</strong></div>
|
||
<div class="divider"></div>
|
||
<div class="row-item total"><span>Total Vivo</span> <strong>{{ formatMoney(financeData.valorContratoVivo) }}</strong></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="finance-card line-card">
|
||
<div class="card-header-f"><i class="bi bi-hdd-network-fill me-2"></i> Line Móvel</div>
|
||
<div class="card-body-f">
|
||
<div class="row-item"><span>Franquia Line</span> <strong>{{ formatFranquia(financeData.franquiaLine) }}</strong></div>
|
||
<div class="row-item"><span>Franquia Gestão</span> <strong>{{ formatFranquia(financeData.franquiaGestao) }}</strong></div>
|
||
<div class="row-item"><span>Locação Ap.</span> <strong>{{ formatMoney(financeData.locacaoAp) }}</strong></div>
|
||
<div class="divider"></div>
|
||
<div class="row-item total"><span>Total Line</span> <strong>{{ formatMoney(financeData.valorContratoLine) }}</strong></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="finance-summary mt-3">
|
||
<div class="summary-item">
|
||
<span class="lbl text-danger">Desconto</span>
|
||
<span class="val text-danger">{{ formatMoney(financeData.desconto) }}</span>
|
||
</div>
|
||
<div class="vertical-line"></div>
|
||
<div class="summary-item">
|
||
<span class="lbl">Lucro Estimado</span>
|
||
<span class="val text-brand">{{ formatMoney(financeData.lucro) }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<ng-template #financeLoading>
|
||
<div class="p-5 text-center text-muted">Carregando financeiro...</div>
|
||
</ng-template>
|
||
</div>
|
||
|
||
<!-- EDIT MODAL -->
|
||
<div
|
||
*ngIf="editOpen"
|
||
#editModal
|
||
class="modal-card modal-edit"
|
||
(click)="$event.stopPropagation()"
|
||
>
|
||
<div class="modal-header">
|
||
<div class="modal-title">
|
||
<span class="icon-bg primary-soft"><i class="bi bi-pencil-square"></i></span> Editar Linha
|
||
</div>
|
||
|
||
<div class="d-flex align-items-center gap-2">
|
||
<button class="btn btn-glass btn-sm" (click)="closeAllModals()" [disabled]="editSaving">
|
||
<i class="bi bi-x-lg me-1"></i> Cancelar
|
||
</button>
|
||
<button class="btn btn-brand btn-sm" (click)="saveEdit()" [disabled]="!editModel || editSaving">
|
||
Salvar
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-body modern-body bg-light-gray">
|
||
<ng-container *ngIf="editModel; else editLoadingTpl">
|
||
<div class="edit-sections">
|
||
<details open class="detail-box">
|
||
<summary class="box-header"><span><i class="bi bi-person-badge me-2"></i> Identificação</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Item</label><input class="form-control form-control-sm bg-light" type="number" [(ngModel)]="editModel.item" disabled title="O ID não pode ser alterado" /></div>
|
||
<div class="form-field"><label>Conta</label><app-select class="form-select" size="sm" [options]="contaOptionsForEdit" [(ngModel)]="editModel.conta"></app-select></div>
|
||
<div class="form-field"><label>Linha</label><input class="form-control form-control-sm" [(ngModel)]="editModel.linha" /></div>
|
||
<div class="form-field"><label>Chip</label><input class="form-control form-control-sm" [(ngModel)]="editModel.chip" /></div>
|
||
<div class="form-field"><label>Cliente</label><input class="form-control form-control-sm" [(ngModel)]="editModel.cliente" /></div>
|
||
<div class="form-field"><label>Usuário</label><input class="form-control form-control-sm" [(ngModel)]="editModel.usuario" /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details open class="detail-box">
|
||
<summary class="box-header"><span><i class="bi bi-file-earmark-text me-2"></i> Contrato & Plano</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field span-2"><label>Plano Contrato</label><app-select class="form-select" size="sm" [options]="planOptionsForEdit" [(ngModel)]="editModel.planoContrato"></app-select></div>
|
||
<div class="form-field"><label>Venc. da Conta</label><input class="form-control form-control-sm" [(ngModel)]="editModel.vencConta" /></div>
|
||
<div class="form-field"><label>Modalidade</label><input class="form-control form-control-sm" [(ngModel)]="editModel.modalidade" /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details open class="detail-box">
|
||
<summary class="box-header"><span><i class="bi bi-activity me-2"></i> Status & Logística</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Status</label><app-select class="form-select" size="sm" [options]="statusOptionsForEdit" [(ngModel)]="editModel.status"></app-select></div>
|
||
<div class="form-field"><label>Data do Bloqueio</label><input class="form-control form-control-sm" type="date" [(ngModel)]="editModel.dataBloqueio" /></div>
|
||
<div class="form-field"><label>Entrega Operadora</label><input class="form-control form-control-sm" type="date" [(ngModel)]="editModel.dataEntregaOpera" /></div>
|
||
<div class="form-field"><label>Entrega Cliente</label><input class="form-control form-control-sm" type="date" [(ngModel)]="editModel.dataEntregaCliente" /></div>
|
||
<div class="form-field"><label>Skil</label><app-select class="form-select" size="sm" [options]="skilOptionsForEdit" [(ngModel)]="editModel.skil"></app-select></div>
|
||
<div class="form-field"><label>Cedente</label><input class="form-control form-control-sm" [(ngModel)]="editModel.cedente" /></div>
|
||
<div class="form-field span-2"><label>Solicitante</label><input class="form-control form-control-sm" [(ngModel)]="editModel.solicitante" /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box vivo-border">
|
||
<summary class="box-header header-vivo"><span><i class="bi bi-telephone-fill me-2"></i> Financeiro Vivo</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Franquia Vivo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.franquiaVivo" /></div>
|
||
<div class="form-field"><label>Valor Plano Vivo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.valorPlanoVivo" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label>Gestão Voz/Dados</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.gestaoVozDados" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label>Skeelo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.skeelo" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label>Vivo News+</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.vivoNewsPlus" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label>Vivo Travel Mundo</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.vivoTravelMundo" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label>Vivo Gestão Disp.</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.vivoGestaoDispositivo" (change)="onFinancialChange(true)" /></div>
|
||
<div class="form-field"><label class="text-vivo fw-bold">Valor Contrato Vivo</label><input class="form-control form-control-sm fw-bold border-vivo bg-light" type="number" step="0.01" [(ngModel)]="editModel.valorContratoVivo" readonly /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box line-border">
|
||
<summary class="box-header header-line"><span><i class="bi bi-hdd-network-fill me-2"></i> Financeiro Line</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label>Franquia Line</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.franquiaLine" /></div>
|
||
<div class="form-field"><label>Franquia Gestão</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.franquiaGestao" /></div>
|
||
<div class="form-field"><label>Locação Ap.</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.locacaoAp" /></div>
|
||
<div class="form-field"><label class="text-line fw-bold">Valor Contrato Line</label><input class="form-control form-control-sm fw-bold border-line" type="number" step="0.01" [(ngModel)]="editModel.valorContratoLine" (change)="onFinancialChange(true)" /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="detail-box">
|
||
<summary class="box-header"><span><i class="bi bi-graph-up-arrow me-2"></i> Resultado</span><i class="bi bi-chevron-down ms-auto transition-icon"></i></summary>
|
||
<div class="box-body">
|
||
<div class="form-grid">
|
||
<div class="form-field"><label class="text-danger fw-bold">Desconto</label><input class="form-control form-control-sm" type="number" step="0.01" [(ngModel)]="editModel.desconto" /></div>
|
||
<div class="form-field"><label class="text-brand">Lucro Estimado</label><input class="form-control form-control-sm bg-light fw-bold" type="number" step="0.01" [(ngModel)]="editModel.lucro" readonly /></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
</ng-container>
|
||
|
||
<ng-template #editLoadingTpl>
|
||
<div class="p-5 text-center text-muted">Carregando...</div>
|
||
</ng-template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|