chashmazar / index.html
Really-amin's picture
Rename index.htm to index.html
daef7c1 verified
raw
history blame contribute delete
98.5 kB
<script type="text/javascript">
var gk_isXlsx = false;
var gk_xlsxFileLookup = {};
var gk_fileData = {};
function filledCell(cell) {
return cell !== '' && cell != null;
}
function loadFileData(filename) {
if (gk_isXlsx && gk_xlsxFileLookup[filename]) {
try {
var workbook = XLSX.read(gk_fileData[filename], { type: 'base64' });
var firstSheetName = workbook.SheetNames[0];
var worksheet = workbook.Sheets[firstSheetName];
// Convert sheet to JSON to filter blank rows
var jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, blankrows: false, defval: '' });
// Filter out blank rows (rows where all cells are empty, null, or undefined)
var filteredData = jsonData.filter(row => row.some(filledCell));
// Heuristic to find the header row by ignoring rows with fewer filled cells than the next row
var headerRowIndex = filteredData.findIndex((row, index) =>
row.filter(filledCell).length >= filteredData[index + 1]?.filter(filledCell).length
);
// Fallback
if (headerRowIndex === -1 || headerRowIndex > 25) {
headerRowIndex = 0;
}
// Convert filtered JSON back to CSV
var csv = XLSX.utils.aoa_to_sheet(filteredData.slice(headerRowIndex)); // Create a new sheet from filtered array of arrays
csv = XLSX.utils.sheet_to_csv(csv, { header: 1 });
return csv;
} catch (e) {
console.error(e);
return "";
}
}
return gk_fileData[filename] || "";
}
</script><!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>سامانه تعیین حدود اختیارات تعمیرات جزئی</title>
<!-- فونت‌آیکون -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@font-face {
font-family: 'Vazirmatn';
src: url('https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/fonts/webfonts/Vazirmatn-Regular.woff2') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap;
}
*, *::before, *::after {
box-sizing: border-box;
}
:root {
--primary-color: #2563eb;
--primary-dark: #1d4ed8;
--primary-light: #dbeafe;
--secondary-color: #0ea5e9;
--secondary-dark: #0284c7;
--secondary-light: #e0f7ff;
--warning-color: #f59e0b;
--warning-dark: #d97706;
--warning-light: #fef3c7;
--danger-color: #ef4444;
--danger-dark: #dc2626;
--danger-light: #fee2e2;
--success-color: #10b981;
--success-dark: #059669;
--success-light: #ecfdf5;
--light-bg: #f8fafc;
--dark-text: #1e293b;
--gray-text: #64748b;
--border-color: #e2e8f0;
--card-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
--transition-speed: 0.3s;
--focus-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
}
body {
font-family: 'Vazirmatn', Tahoma, 'Iran Sans', Arial, sans-serif;
line-height: 1.7;
margin: 0;
padding: 0;
background-color: #f1f5f9;
color: var(--dark-text);
font-size: 14px;
}
.site-header {
background: linear-gradient(to left, #1e40af, #0284c7);
color: white;
padding: 1rem 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
position: relative;
}
.header-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
font-size: 1.5rem;
font-weight: bold;
}
.logo i {
font-size: 1.8rem;
margin-left: 0.5rem;
}
.nav-menu {
display: flex;
gap: 1.5rem;
}
.nav-link {
color: white;
text-decoration: none;
display: flex;
align-items: center;
padding: 0.5rem;
border-radius: var(--radius-sm);
transition: background-color 0.3s;
}
.nav-link:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-link i {
margin-left: 0.5rem;
}
.container {
max-width: 1100px;
margin: 2rem auto;
padding: 0 1rem;
}
.page-header {
text-align: center;
margin-bottom: 2rem;
}
.page-title {
color: var(--primary-color);
margin-bottom: 0.5rem;
font-size: 1.8rem;
font-weight: bold;
position: relative;
display: inline-block;
padding-bottom: 0.75rem;
}
.page-title::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 4px;
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
border-radius: 2px;
}
.page-subtitle {
color: var(--gray-text);
font-size: 1rem;
}
.card {
background-color: #fff;
border-radius: var(--radius-lg);
box-shadow: var(--card-shadow);
margin-bottom: 2rem;
overflow: hidden;
border: 1px solid var(--border-color);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
background: linear-gradient(to left, var(--primary-color), var(--secondary-color));
color: white;
padding: 1rem 1.5rem;
font-size: 1.2rem;
font-weight: 500;
}
.card-header-title {
display: flex;
align-items: center;
}
.card-header-title i {
margin-left: 0.75rem;
font-size: 1.25rem;
}
.card-header-actions {
display: flex;
gap: 0.5rem;
}
.card-header-btn {
background: rgba(255, 255, 255, 0.2);
border: none;
color: white;
width: 2rem;
height: 2rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background-color 0.3s;
}
.card-header-btn:hover {
background: rgba(255, 255, 255, 0.3);
}
.card-body {
padding: 1.5rem;
}
.tabs {
display: flex;
margin-bottom: 1.5rem;
border-radius: var(--radius-md);
background-color: var(--light-bg);
padding: 0.25rem;
border: 1px solid var(--border-color);
position: relative;
overflow: hidden;
}
.tab-button {
flex: 1;
padding: 0.75rem 1rem;
text-align: center;
cursor: pointer;
font-weight: 500;
color: var(--gray-text);
border: none;
background: transparent;
position: relative;
transition: all 0.3s ease;
border-radius: var(--radius-sm);
white-space: nowrap;
font-family: 'Vazirmatn', Tahoma, Arial, sans-serif;
font-size: 0.875rem;
}
.tab-button:hover:not(.active) {
color: var(--primary-color);
background-color: rgba(59, 130, 246, 0.05);
}
.tab-button.active {
color: white;
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
box-shadow: 0 4px 10px rgba(59, 130, 246, 0.2);
}
.form-group .tabs .tab-button.active {
color: white;
background: linear-gradient(to right, #FF6B8B, #FF8E8E);
box-shadow: 0 4px 10px rgba(255, 107, 139, 0.3);
}
.tab-button i {
margin-left: 0.5rem;
font-size: 1rem;
}
.tab-content {
display: none;
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.tab-content.active {
display: block;
}
@media (max-width: 576px) {
.tabs {
flex-direction: column;
background-color: transparent;
border: none;
padding: 0;
}
.tab-button {
margin-bottom: 0.5rem;
border-radius: var(--radius-md);
border: 1px solid var(--border-color);
background-color: var(--light-bg);
}
}
.accordion {
margin-bottom: 1.5rem;
border-radius: var(--radius-md);
overflow: hidden;
border: 1px solid var(--border-color);
}
.accordion-header {
background-color: var(--light-bg);
padding: 1rem 1.25rem;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: background-color 0.3s;
user-select: none;
}
.accordion-header:hover {
background-color: #f0f7ff;
}
.accordion-title {
font-weight: 500;
font-size: 1rem;
color: var(--dark-text);
display: flex;
align-items: center;
}
.accordion-title i {
margin-left: 0.625rem;
color: var(--primary-color);
}
.accordion-icon {
color: var(--primary-color);
transition: transform 0.3s;
}
.accordion-icon.active {
transform: rotate(180deg);
}
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
background-color: white;
}
.accordion-content.active {
max-height: 500px;
}
.accordion-body {
padding: 1.25rem;
border-top: 1px solid var(--border-color);
}
.form-section {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
margin-bottom: 1.5rem;
}
@media (max-width: 768px) {
.form-section {
grid-template-columns: 1fr;
}
}
.form-group {
margin-bottom: 1.25rem;
position: relative;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: var(--dark-text);
font-size: 0.875rem;
position: relative;
}
.form-control {
width: 100%;
padding: 0.875rem 1rem;
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
font-size: 0.875rem;
font-family: 'Vazirmatn', Tahoma, Arial, sans-serif;
background-color: #fcfcfc;
transition: all 0.25s ease-in-out;
color: var(--dark-text);
}
.form-control:focus {
border-color: var(--primary-color);
outline: none;
background-color: #fff;
box-shadow: var(--focus-shadow);
}
.form-control::placeholder {
color: #a0aec0;
}
.input-group {
display: flex;
position: relative;
}
.input-group .form-control {
flex: 1;
border-radius: var(--radius-md);
padding-left: 3.125rem;
}
.input-group .input-suffix {
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
color: var(--gray-text);
font-weight: 500;
pointer-events: none;
}
select.form-control {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: left 1rem center;
padding-left: 2.5rem;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 500;
text-align: center;
white-space: nowrap;
vertical-align: middle;
user-select: none;
border: 1px solid transparent;
padding: 0.875rem 1.5rem;
font-size: 0.875rem;
line-height: 1.5;
border-radius: var(--radius-md);
transition: all 0.25s ease-in-out;
cursor: pointer;
font-family: 'Vazirmatn', Tahoma, Arial, sans-serif;
position: relative;
overflow: hidden;
}
.btn::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
background-image: radial-gradient(circle, #fff 10%, transparent 10.01%);
background-repeat: no-repeat;
background-position: 50%;
transform: scale(10, 10);
opacity: 0;
transition: transform .5s, opacity 1s;
}
.btn:active::after {
transform: scale(0, 0);
opacity: .3;
transition: 0s;
}
.btn-primary {
color: #fff;
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
border-color: transparent;
}
.btn-primary:hover {
background: linear-gradient(to right, var(--primary-dark), var(--secondary-dark));
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
transform: translateY(-2px);
}
.btn-secondary {
color: white;
background: linear-gradient(to right, var(--warning-color), var(--warning-dark));
border-color: transparent;
}
.btn-secondary:hover {
background: linear-gradient(to right, var(--warning-dark), #b45309);
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
transform: translateY(-2px);
}
.btn i {
margin-left: 0.5rem;
}
.result-section {
background-color: #fff;
border-radius: var(--radius-md);
padding: 0;
margin-bottom: 1.5rem;
border: 1px solid var(--border-color);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
overflow: hidden;
transition: all var(--transition-speed);
}
.result-section:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.result-header {
background-color: var(--light-bg);
padding: 1rem 1.25rem;
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
}
.result-title {
font-weight: 600;
color: var(--dark-text);
font-size: 1rem;
display: flex;
align-items: center;
}
.result-title i {
margin-left: 0.625rem;
color: var(--primary-color);
}
.result-actions {
display: flex;
align-items: center;
}
.result-action-btn {
background-color: transparent;
border: none;
width: 2rem;
height: 2rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--gray-text);
cursor: pointer;
transition: all 0.3s;
margin-right: 0.3125rem;
}
.result-action-btn:hover {
background-color: var(--primary-light);
color: var(--primary-color);
}
.result-body {
padding: 1.25rem;
}
.result-item {
display: flex;
justify-content: space-between;
padding: 0.75rem 0.9375rem;
margin-bottom: 0.625rem;
background-color: var(--light-bg);
border-radius: var(--radius-sm);
transition: all var(--transition-speed);
}
.result-item:hover {
background-color: #f0f7ff;
transform: translateY(-2px);
}
.result-item:last-child {
margin-bottom: 0;
}
.result-label {
font-weight: 500;
color: var(--gray-text);
}
.result-value {
font-weight: 600;
color: var(--dark-text);
}
.badge {
display: inline-flex;
align-items: center;
padding: 0.375rem 0.75rem;
border-radius: var(--radius-sm);
font-size: 0.75rem;
font-weight: 500;
}
.badge i {
margin-left: 0.375rem;
}
.badge-success {
background-color: var(--success-light);
color: var(--success-dark);
}
.badge-warning {
background-color: var(--warning-light);
color: var(--warning-dark);
}
.badge-danger {
background-color: var(--danger-light);
color: var(--danger-dark);
}
.badge-primary {
background-color: var(--primary-light);
color: var(--primary-dark);
}
.info-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.25rem;
height: 1.25rem;
border-radius: 50%;
background-color: var(--primary-light);
color: var(--primary-color);
font-size: 0.75rem;
cursor: help;
margin-right: 0.5rem;
transition: all var(--transition-speed);
position: relative;
}
.info-icon:hover {
background-color: var(--primary-color);
color: white;
}
.info-icon .tooltip {
position: absolute;
top: -0.5rem;
right: 1.875rem;
background-color: var(--dark-text);
color: white;
padding: 0.625rem 0.9375rem;
border-radius: var(--radius-sm);
font-size: 0.75rem;
width: 15.625rem;
opacity: 0;
visibility: hidden;
transform: translateY(10px);
transition: all var(--transition-speed);
z-index: 10;
text-align: right;
font-weight: normal;
line-height: 1.6;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.info-icon:hover .tooltip {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.guide-section {
margin-bottom: 1.875rem;
animation: slideInUp 0.5s ease-out;
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.guide-title {
font-size: 1.125rem;
font-weight: 600;
color: var(--primary-color);
margin-bottom: 1.25rem;
display: flex;
align-items: center;
position: relative;
padding-right: 0.9375rem;
}
.guide-title::before {
content: '';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 5px;
height: 20px;
background: linear-gradient(to bottom, var(--primary-color), var(--secondary-color));
border-radius: 3px;
}
.guide-title i {
margin-left: 0.625rem;
color: var(--primary-color);
}
.limits-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5625rem;
margin-bottom: 2.5rem;
}
@media (max-width: 768px) {
.limits-container {
grid-template-columns: 1fr;
}
}
.limit-box {
background-color: white;
border-radius: var(--radius-md);
padding: 1.5625rem;
box-shadow: var(--card-shadow);
transition: all var(--transition-speed);
position: relative;
overflow: hidden;
border: 1px solid var(--border-color);
display: flex;
flex-direction: column;
height: 100%;
min-height: 13.75rem;
}
.limit-box:hover {
transform: translateY(-8px);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.12);
}
.limit-box::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 6px;
height: 100%;
border-radius: 3px;
}
.limit-box.primary::before {
background: linear-gradient(to bottom, var(--primary-color), var(--secondary-color));
}
.limit-box.warning::before {
background: linear-gradient(to bottom, var(--warning-color), var(--warning-dark));
}
.limit-box-icon {
width: 4rem;
height: 4rem;
border-radius: 1rem;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.25rem;
position: relative;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
}
70% {
box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
}
}
.limit-box.primary .limit-box-icon {
background: linear-gradient(135deg, var(--primary-light), #c7deff);
color: var(--primary-color);
}
.limit-box.warning .limit-box-icon {
background: linear-gradient(135deg, var(--warning-light), #ffebc7);
color: var(--warning-dark);
}
.limit-box-icon i {
font-size: 1.75rem;
}
.limit-box-title {
font-size: 1.0625rem;
font-weight: 600;
margin-bottom: 0.9375rem;
color: var(--dark-text);
display: flex;
align-items: center;
}
.limit-box-content {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.limit-amount {
font-size: 1.625rem;
font-weight: bold;
margin-bottom: 0.9375rem;
position: relative;
display: inline-block;
}
.limit-box.primary .limit-amount {
color: var(--primary-color);
animation: fadeInUp 0.7s ease-out;
}
.limit-box.warning .limit-amount {
color: var(--warning-dark);
animation: fadeInUp 0.7s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.limit-amount::after {
content: '';
position: absolute;
bottom: -8px;
left: 0;
width: 40px;
height: 3px;
border-radius: 2px;
}
.limit-box.primary .limit-amount::after {
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
}
.limit-box.warning .limit-amount::after {
background: linear-gradient(to right, var(--warning-color), var(--warning-dark));
}
.limit-description {
color: var(--gray-text);
font-size: 0.875rem;
line-height: 1.7;
margin-top: auto;
padding-top: 0.9375rem;
border-top: 1px dashed var(--border-color);
}
.units-info {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.25rem;
margin-bottom: 1.875rem;
}
@media (max-width: 768px) {
.units-info {
grid-template-columns: 1fr;
}
}
.unit-box {
background-color: white;
border-radius: var(--radius-md);
overflow: hidden;
box-shadow: var(--card-shadow);
transition: all var(--transition-speed);
animation: fadeIn 0.5s ease-out;
animation-fill-mode: both;
}
.unit-box:nth-child(1) {
animation-delay: 0.1s;
}
.unit-box:nth-child(2) {
animation-delay: 0.2s;
}
.unit-box:nth-child(3) {
animation-delay: 0.3s;
}
.unit-box:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}
.unit-header {
padding: 0.9375rem;
color: white;
font-weight: 600;
display: flex;
align-items: center;
}
.branch .unit-header {
background: linear-gradient(to right, var(--success-color), var(--success-dark));
}
.regional .unit-header {
background: linear-gradient(to right, var(--warning-color), var(--warning-dark));
}
.central .unit-header {
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
}
.unit-header i {
margin-left: 0.625rem;
font-size: 1.125rem;
}
.unit-body {
padding: 1.25rem;
}
.unit-limit {
display: flex;
align-items: center;
margin-bottom: 0.9375rem;
}
.unit-limit-percent {
width: 3.125rem;
height: 3.125rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: white;
margin-left: 0.9375rem;
flex-shrink: 0;
}
.branch .unit-limit-percent {
background-color: var(--success-color);
}
.regional .unit-limit-percent {
background-color: var(--warning-color);
}
.central .unit-limit-percent {
background-color: var(--primary-color);
}
.unit-limit-text {
flex: 1;
}
.unit-limit-amount {
font-weight: 600;
margin-bottom: 0.3125rem;
}
.unit-limit-desc {
color: var(--gray-text);
font-size: 0.8125rem;
}
.unit-notes {
background-color: var(--light-bg);
padding: 0.75rem;
border-radius: var(--radius-sm);
font-size: 0.8125rem;
}
.progress-container {
margin-bottom: 0.9375rem;
}
.progress-title {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
font-weight: 500;
font-size: 0.8125rem;
}
.progress-bar-container {
width: 100%;
height: 8px;
background-color: var(--light-bg);
border-radius: 4px;
overflow: hidden;
}
.progress-bar {
height: 100%;
border-radius: 4px;
transition: width 0.5s ease;
}
.progress-bar.success {
background: linear-gradient(to right, var(--success-color), var(--success-dark));
}
.progress-bar.warning {
background: linear-gradient(to right, var(--warning-color), var(--warning-dark));
}
.progress-bar.danger {
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
}
.approval-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.875rem;
background-color: white;
border-radius: var(--radius-md);
overflow: hidden;
box-shadow: var(--card-shadow);
}
.approval-table th, .approval-table td {
padding: 0.9375rem;
text-align: right;
border-bottom: 1px solid var(--border-color);
}
.approval-table th {
background-color: var(--light-bg);
color: var(--dark-text);
font-weight: 600;
}
.approval-table tr:last-child td {
border-bottom: none;
}
.approval-table .badge {
display: inline-flex;
align-items: center;
padding: 0.3125rem 0.625rem;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 500;
margin-right: 0.3125rem;
}
.approval-table .badge i {
margin-left: 0.3125rem;
}
.timeline {
position: relative;
margin: 2.5rem 0;
padding-right: 1.875rem;
}
.timeline::before {
content: '';
position: absolute;
top: 0;
right: 0.625rem;
height: 100%;
width: 2px;
background: linear-gradient(to bottom, var(--primary-color), var(--secondary-color));
}
.timeline-item {
position: relative;
padding-bottom: 1.875rem;
}
.timeline-item:last-child {
padding-bottom: 0;
}
.timeline-dot {
position: absolute;
top: 0;
right: -1.875rem;
width: 1.375rem;
height: 1.375rem;
border-radius: 50%;
background-color: white;
border: 3px solid var(--primary-color);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.625rem;
color: var(--primary-color);
}
.timeline-content {
background-color: white;
border-radius: var(--radius-md);
padding: 1.25rem;
box-shadow: var(--card-shadow);
position: relative;
transition: all var(--transition-speed);
animation: fadeIn 0.5s ease-out;
animation-fill-mode: both;
}
.timeline-item:nth-child(1) .timeline-content {
animation-delay: 0.1s;
}
.timeline-item:nth-child(2) .timeline-content {
animation-delay: 0.2s;
}
.timeline-item:nth-child(3) .timeline-content {
animation-delay: 0.3s;
}
.timeline-item:nth-child(4) .timeline-content {
animation-delay: 0.4s;
}
.timeline-content:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}
.timeline-title {
font-weight: 600;
margin-bottom: 0.625rem;
color: var(--primary-color);
display: flex;
align-items: center;
}
.timeline-title i {
margin-left: 0.625rem;
color: var(--primary-color);
}
.timeline-desc {
color: var(--gray-text);
font-size: 0.875rem;
line-height: 1.6;
}
.letter-header {
margin-bottom: 1.5625rem;
border-bottom: 1px solid var(--border-color);
padding-bottom: 0.9375rem;
}
.letter-header-details {
display: flex;
flex-wrap: wrap;
gap: 1.5625rem;
}
.letter-header-item {
display: flex;
align-items: center;
}
.letter-header-label {
font-weight: 600;
margin-left: 0.625rem;
color: var(--gray-text);
}
.letter-header-value {
color: var(--dark-text);
}
.letter-recipients {
background-color: var(--light-bg);
border-radius: var(--radius-md);
padding: 0.9375rem;
margin-bottom: 1.5625rem;
}
.letter-recipient-item {
display: flex;
margin-bottom: 0.625rem;
align-items: center;
}
.letter-recipient-item:last-child {
margin-bottom: 0;
}
.letter-recipient-label {
font-weight: 600;
width: 3.75rem;
color: var(--gray-text);
}
.letter-recipient-value {
color: var(--dark-text);
font-weight: 500;
}
.letter-content {
line-height: 2;
color: var(--dark-text);
}
.letter-content p {
margin-bottom: 0.9375rem;
}
.letter-details {
background-color: var(--light-bg);
border-radius: var(--radius-md);
padding: 0.9375rem;
margin: 1.25rem 0;
}
.letter-detail-item {
display: flex;
margin-bottom: 0.625rem;
align-items: center;
}
.letter-detail-item:last-child {
margin-bottom: 0;
}
.letter-detail-label {
font-weight: 600;
width: 7.5rem;
color: var(--gray-text);
}
.letter-detail-value {
color: var(--dark-text);
}
.letter-signature {
margin-top: 2.5rem;
text-align: left;
line-height: 1.8;
}
.text-primary { color: var(--primary-color); font-weight: 600; }
.text-warning { color: var(--warning-dark); font-weight: 600; }
.text-danger { color: var(--danger-color); font-weight: 600; }
.text-success { color: var(--success-color); font-weight: 600; }
.mt-4 { margin-top: 1.5625rem; }
.mb-4 { margin-bottom: 1.5625rem; }
.mt-3 { margin-top: 1.25rem; }
.mb-3 { margin-bottom: 1.25rem; }
.text-center { text-align: center; }
.d-none { display: none !important; }
.d-flex { display: flex; }
.justify-content-between { justify-content: space-between; }
.align-items-center { align-items: center; }
@media print {
@page {
size: A4;
margin: 1cm;
}
body {
background-color: white;
font-size: 12pt;
color: black;
}
.site-header, .nav-menu, .tabs:not(.calculation-result-tabs), .hamburger,
.card-header-actions, .tab-button[data-tab="tabGuide"] {
display: none !important;
}
.container {
max-width: 100%;
padding: 0;
margin: 0;
}
.card {
box-shadow: none;
border: 1px solid #ddd;
break-inside: avoid;
}
.card-header {
background: #f1f5f9 !important;
color: #000 !important;
border-bottom: 1px solid #ddd;
padding: 0.5cm 1cm;
}
.card-header-title {
font-size: 16pt;
font-weight: bold;
}
.card-body {
padding: 1cm;
}
.tab-content {
display: block !important;
}
.result-section {
page-break-inside: avoid;
border: 1px solid #ddd;
margin-top: 1cm;
}
.result-header {
background-color: #f1f5f9 !important;
color: #000 !important;
border-bottom: 1px solid #ddd;
}
#calculationResults, #letterPreview {
display: block !important;
page-break-before: auto;
page-break-after: auto;
page-break-inside: avoid;
}
.btn, .nav-link {
display: none !important;
}
#tabGuide {
page-break-before: always;
}
.timeline::before {
background: #333;
}
.limit-box, .unit-box, .timeline-content {
box-shadow: none;
border: 1px solid #ddd;
}
.unit-header, .progress-bar, .timeline::before, .limit-box::before {
background: #333 !important;
background-image: none !important;
}
.branch .unit-header, .progress-bar.success {
background: #0d9488 !important;
}
.regional .unit-header, .progress-bar.warning {
background: #d97706 !important;
}
.central .unit-header, .progress-bar.danger {
background: #2563eb !important;
}
.letter-content {
font-size: 12pt;
line-height: 1.8;
}
body::after {
content: counter(page);
counter-increment: page;
position: fixed;
bottom: 0.5cm;
right: 1cm;
font-size: 10pt;
}
}
</style>
</head>
<body>
<!-- هدر سایت -->
<header class="site-header">
<div class="header-container">
<div class="logo">
<i class="fas fa-tools"></i>
<span>سامانه تعمیرات جزئی</span>
</div>
<nav class="nav-menu">
<a href="#" class="nav-link">
<i class="fas fa-home"></i> خانه
</a>
<a href="#" class="nav-link">
<i class="fas fa-book"></i> راهنما
</a>
<a href="#" class="nav-link">
<i class="fas fa-history"></i> تاریخچه
</a>
</nav>
</div>
</header>
<!-- محتوای اصلی -->
<main class="container">
<div class="page-header">
<h1 class="page-title">سامانه تعیین حدود اختیارات تعمیرات جزئی</h1>
<p class="page-subtitle">مطابق با بخشنامه ۷۰۵/ویرایش ۴</p>
</div>
<div class="card">
<div class="card-header">
<div class="card-header-title">
<i class="fas fa-calculator"></i> محاسبه حدود اختیارات تعمیرات
</div>
<div class="card-header-actions">
<button class="card-header-btn" id="printBtn" title="چاپ فرم">
<i class="fas fa-print"></i>
</button>
<button class="card-header-btn" id="helpBtn" title="راهنما">
<i class="fas fa-question"></i>
</button>
</div>
</div>
<div class="card-body">
<!-- تب‌ها -->
<div class="tabs">
<button class="tab-button active" data-tab="tabCalculator">
<i class="fas fa-calculator"></i> محاسبه و تعیین
</button>
<button class="tab-button" data-tab="tabGuide">
<i class="fas fa-book"></i> راهنما
</button>
</div>
<!-- تب محاسبه و تعیین -->
<div class="tab-content active" id="tabCalculator">
<!-- بخش اصلی فرم محاسبه -->
<div class="accordion mb-4">
<div class="accordion-header" id="authorityGuideHeader">
<div class="accordion-title">
<i class="fas fa-info-circle"></i> راهنمای حدود اختیارات
</div>
<div class="accordion-icon">
<i class="fas fa-chevron-down"></i>
</div>
</div>
<div class="accordion-content" id="authorityGuideContent">
<div class="accordion-body">
<div class="result-item">
<div class="result-label">شعبه:</div>
<div class="result-value">تا سقف <span class="text-primary">۱,۰۹۵,۰۰۰,۰۰۰</span> ریال (۷۵٪ بودجه سالانه)</div>
</div>
<div class="result-item">
<div class="result-label">منطقه:</div>
<div class="result-value">تا سقف <span class="text-warning">۷۳۰,۰۰۰,۰۰۰</span> ریال (۵۰٪ بودجه سالانه)</div>
</div>
<div class="result-item">
<div class="result-label">نیاز به سه استعلام:</div>
<div class="result-value">برای مبالغ بالای <span class="text-primary">۲۰۰,۰۰۰,۰۰۰</span> ریال</div>
</div>
</div>
</div>
</div>
<div class="form-group mb-4">
<label>دسته‌بندی تعمیرات</label>
<div class="tabs">
<button class="tab-button active" data-repair-group="building">
<i class="fas fa-building"></i> تعمیرات ساختمان
</button>
<button class="tab-button" data-repair-group="furniture">
<i class="fas fa-chair"></i> تعمیرات اثاثیه
</button>
</div>
</div>
<div class="form-section mb-3">
<div class="form-group">
<label>نوع واحد درخواست‌کننده
<span class="info-icon">
<i class="fas fa-info"></i>
<span class="tooltip">نوع واحد درخواست‌کننده تعمیرات را مشخص کنید. حدود اختیارات بر اساس نوع واحد متفاوت است.</span>
</span>
</label>
<select id="unitType" class="form-control">
<option value="branch">شعبه</option>
<option value="regional">منطقه</option>
<option value="headquarters">ستاد</option>
</select>
</div>
<div class="form-group">
<label>نوع تعمیرات
<span class="info-icon">
<i class="fas fa-question-circle"></i>
<span class="tooltip">نوع دقیق تعمیرات مورد نیاز را انتخاب کنید.</span>
</span>
</label>
<select id="repairCategory" class="form-control">
<option value="">انتخاب کنید</option>
<option value="electrical">تعمیرات برقی</option>
<option value="plumbing">تعمیرات تأسیساتی</option>
<option value="construction">تعمیرات ساختمانی</option>
<option value="other_building">سایر موارد ساختمان</option>
</select>
</div>
</div>
<div class="form-section mb-3">
<div class="form-group">
<label>برآورد هزینه (ریال)</label>
<div class="input-group">
<input type="text" id="estimatedCost" class="form-control" placeholder="مثال: 45,000,000" inputmode="numeric">
<span class="input-suffix">ریال</span>
</div>
</div>
<div class="form-group">
<label>مبلغ هزینه شده طی سال (ریال)
<span class="info-icon">
<i class="fas fa-info"></i>
<span class="tooltip">مجموع مبالغی که تا کنون در سال جاری برای تعمیرات جزئی هزینه شده است.</span>
</span>
</label>
<div class="input-group">
<input type="text" id="yearlySpent" class="form-control" placeholder="مثال: 120,000,000" inputmode="numeric">
<span class="input-suffix">ریال</span>
</div>
</div>
</div>
<div class="text-center mt-4">
<button class="btn btn-primary" id="calculateBtn">
<i class="fas fa-calculator"></i> محاسبه و تعیین حدود اختیارات
</button>
</div>
<!-- نتایج محاسبات -->
<div class="result-section mt-4 d-none" id="calculationResults">
<div class="result-header">
<div class="result-title">
<i class="fas fa-clipboard-check"></i> نتیجه محاسبه حدود اختیارات
</div>
<div class="result-actions">
<button class="result-action-btn" id="printResultBtn" title="چاپ نتایج">
<i class="fas fa-print"></i>
</button>
<button class="result-action-btn" id="shareResultBtn" title="اشتراک‌گذاری">
<i class="fas fa-share-alt"></i>
</button>
</div>
</div>
<div class="result-body">
<div class="result-item">
<div class="result-label">برآورد هزینه:</div>
<div class="result-value" id="resultCost">۰ ریال</div>
</div>
<div class="result-item">
<div class="result-label">نیاز به سه استعلام/فاکتور:</div>
<div class="result-value" id="resultQuotes">
<span class="badge badge-primary"><i class="fas fa-file-invoice"></i> خیر</span>
</div>
</div>
<div class="result-item">
<div class="result-label">سطح تصویب:</div>
<div class="result-value" id="resultApprovalLevel">
<span class="badge badge-success"><i class="fas fa-check-circle"></i> واحد</span>
</div>
</div>
<div class="result-item">
<div class="result-label">نیاز به هماهنگی با واحد بالاتر:</div>
<div class="result-value" id="resultRegionCoordination">
<span class="badge badge-primary"><i class="fas fa-handshake"></i> خیر</span>
</div>
</div>
<div class="result-item">
<div class="result-label">مدارک مورد نیاز:</div>
<div class="result-value" id="resultDocuments">
<span class="badge badge-primary"><i class="fas fa-file-alt"></i> یک فاکتور / پیش‌فاکتور</span>
</div>
</div>
<div class="mt-3 text-center">
<button class="btn btn-secondary" id="showLetterBtn">
<i class="fas fa-envelope"></i> مشاهده پیش‌نویس نامه
</button>
</div>
</div>
</div>
<!-- پیش‌نویس نامه -->
<div class="result-section mt-4 d-none" id="letterPreview">
<div class="result-header">
<div class="result-title">
<i class="fas fa-envelope"></i> پیش‌نویس نامه درخواست تعمیرات
</div>
<div class="result-actions">
<button class="result-action-btn" id="copyLetterBtn" title="کپی متن">
<i class="fas fa-copy"></i>
</button>
<button class="result-action-btn" id="editLetterBtn" title="ویرایش متن">
<i class="fas fa-edit"></i>
</button>
<button class="result-action-btn" id="downloadLetterBtn" title="دانلود فایل">
<i class="fas fa-download"></i>
</button>
</div>
</div>
<div class="result-body">
<div class="letter-header">
<div class="letter-header-details">
<div class="letter-header-item">
<span class="letter-header-label">شماره:</span>
<span class="letter-header-value" id="letterNumber">۱۴۰۳/ت ج/___</span>
</div>
<div class="letter-header-item">
<span class="letter-header-label">تاریخ:</span>
<span class="letter-header-value" id="letterDate">۱۴۰۳/__/__</span>
</div>
<div class="letter-header-item">
<span class="letter-header-label">پیوست:</span>
<span class="letter-header-value">دارد</span>
</div>
</div>
</div>
<div class="letter-recipients">
<div class="letter-recipient-item">
<span class="letter-recipient-label">از:</span>
<span class="letter-recipient-value" id="letterFrom">___</span>
</div>
<div class="letter-recipient-item">
<span class="letter-recipient-label">به:</span>
<span class="letter-recipient-value" id="letterTo">___</span>
</div>
<div class="letter-recipient-item">
<span class="letter-recipient-label">موضوع:</span>
<span class="letter-recipient-value">درخواست مجوز تعمیرات جزئی</span>
</div>
</div>
<div class="letter-content" id="letterContent">
<p>با سلام و احترام</p>
<p>به استحضار می‌رساند با عنایت به بخشنامه شماره ۷۰۵/ویرایش ۴ در خصوص تعمیرات جزئی، با توجه به نیاز این واحد به انجام تعمیرات در بخش <span id="letterRepairType">___</span>، خواهشمند است دستور فرمایید نسبت به صدور مجوز برای انجام تعمیرات با مشخصات ذیل اقدام لازم صورت پذیرد:</p>
<div class="letter-details">
<div class="letter-detail-item">
<div class="letter-detail-label">نوع تعمیرات:</div>
<div class="letter-detail-value" id="letterRepairCategory">___</div>
</div>
<div class="letter-detail-item">
<div class="letter-detail-label">برآورد هزینه:</div>
<div class="letter-detail-value" id="letterCost">___</div>
</div>
<div class="letter-detail-item">
<div class="letter-detail-label">مستندات همراه:</div>
<div class="letter-detail-value" id="letterDocuments">___</div>
</div>
</div>
<p>شایان ذکر است تاکنون در سال جاری مبلغ <span id="letterYearlySpent">___</span> ریال از سقف اختیارات این واحد استفاده شده است.</p>
<p>خواهشمند است دستور فرمایید اقدام لازم در این خصوص صورت پذیرد.</p>
<p class="letter-signature">با تشکر<br>___<br>مسئول واحد</p>
</div>
</div>
</div>
</div>
<!-- تب راهنما -->
<div class="tab-content" id="tabGuide">
<!-- بخش اول: مقادیر اصلی -->
<div class="guide-section">
<div class="guide-title">
<i class="fas fa-info-circle"></i> مقادیر اصلی بخشنامه ۷۰۵ - ویرایش ۴
</div>
<div class="limits-container">
<div class="limit-box primary">
<div class="limit-box-icon">
<i class="fas fa-coins"></i>
</div>
<div class="limit-box-content">
<div class="limit-box-title">سقف کل معاملات جزئی سالانه</div>
<div class="limit-amount">۱,۴۶۰,۰۰۰,۰۰۰ ریال</div>
<div class="limit-description">کل سقف مجاز برای معاملات جزئی در سال بر اساس بخشنامه ۷۰۵ - ویرایش ۴</div>
</div>
</div>
<div class="limit-box warning">
<div class="limit-box-icon">
<i class="fas fa-file-invoice"></i>
</div>
<div class="limit-box-content">
<div class="limit-box-title">حد نصاب سه استعلام</div>
<div class="limit-amount">۲۰۰,۰۰۰,۰۰۰ ریال</div>
<div class="limit-description">برای مبالغ بیشتر یا مساوی این مقدار، حتماً نیاز به سه استعلام قیمت است</div>
</div>
</div>
</div>
</div>
<!-- بخش دوم: حدود اختیارات واحدها -->
<div class="guide-section">
<div class="guide-title">
<i class="fas fa-building"></i> حدود اختیارات واحدها
</div>
<div class="units-info">
<div class="unit-box branch">
<div class="unit-header">
<i class="fas fa-store"></i> شعبه
</div>
<div class="unit-body">
<div class="unit-limit">
<div class="unit-limit-percent">۷۵٪</div>
<div class="unit-limit-text">
<div class="unit-limit-amount">۱,۰۹۵,۰۰۰,۰۰۰ ریال</div>
<div class="unit-limit-desc">سقف مجاز بدون مکاتبه</div>
</div>
</div>
<div class="progress-container">
<div class="progress-title">
<span>نیاز به مکاتبه با منطقه</span>
<span>۷۵٪ تا ۱۰۰٪</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar warning" style="width: 25%"></div>
</div>
</div>
<div class="progress-container">
<div class="progress-title">
<span>نیاز به مکاتبه با ستاد</span>
<span>بیش از ۱۰۰٪</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar danger" style="width: 30%"></div>
</div>
</div>
<div class="unit-notes">
<i class="fas fa-exclamation-circle"></i>
اگر هزینه درخواستی + هزینه‌های قبلی از ۷۵٪ سقف بیشتر شود، مکاتبه با منطقه الزامی است
</div>
</div>
</div>
<div class="unit-box regional">
<div class="unit-header">
<i class="fas fa-map-marker-alt"></i> سرپرستی منطقه
</div>
<div class="unit-body">
<div class="unit-limit">
<div class="unit-limit-percent">۵۰٪</div>
<div class="unit-limit-text">
<div class="unit-limit-amount">۷۳۰,۰۰۰,۰۰۰ ریال</div>
<div class="unit-limit-desc">سقف مجاز بدون مکاتبه</div>
</div>
</div>
<div class="progress-container">
<div class="progress-title">
<span>نیاز به مکاتبه با ستاد</span>
<span>بیش از ۵۰٪</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar danger" style="width: 50%"></div>
</div>
</div>
<div class="unit-notes">
<i class="fas fa-exclamation-circle"></i>
اگر هزینه درخواستی + هزینه‌های قبلی از ۵۰٪ سقف بیشتر شود، مکاتبه با ستاد الزامی است
</div>
</div>
</div>
<div class="unit-box central">
<div class="unit-header">
<i class="fas fa-building"></i> ستاد مرکزی
</div>
<div class="unit-body">
<div class="unit-limit">
<div class="unit-limit-percent">۱۰۰٪</div>
<div class="unit-limit-text">
<div class="unit-limit-amount">۱,۴۶۰,۰۰۰,۰۰۰ ریال</div>
<div class="unit-limit-desc">سقف مجاز کل</div>
</div>
</div>
<div class="unit-notes">
<i class="fas fa-check-circle"></i>
ستاد مرکزی خود تأیید‌کننده است و نیازی به مکاتبهٔ بالادستی ندارد
</div>
</div>
</div>
</div>
</div>
<!-- بخش سوم: نیاز به استعلام -->
<div class="guide-section">
<div class="guide-title">
<i class="fas fa-file-invoice"></i> راهنمای استعلام قیمت
</div>
<table class="approval-table">
<thead>
<tr>
<th>مبلغ برآوردی</th>
<th>تعداد استعلام</th>
<th>مستندات مورد نیاز</th>
</tr>
</thead>
<tbody>
<tr>
<td>کمتر از ۲۰۰,۰۰۰,۰۰۰ ریال</td>
<td><span class="badge badge-success"><i class="fas fa-file"></i> یک استعلام</span></td>
<td>یک فاکتور یا پیش‌فاکتور معتبر</td>
</tr>
<tr>
<td>بیشتر یا مساوی ۲۰۰,۰۰۰,۰۰۰ ریال</td>
<td><span class="badge badge-warning"><i class="fas fa-file"></i> سه استعلام</span></td>
<td>سه فاکتور از سه تأمین‌کننده مختلف + فرم مقایسه قیمت</td>
</tr>
</tbody>
</table>
</div>
<!-- بخش چهارم: مراحل فرآیند -->
<div class="guide-section">
<div class="guide-title">
<i class="fas fa-tasks"></i> مراحل فرآیند تعمیرات جزئی
</div>
<div class="timeline">
<div class="timeline-item">
<div class="timeline-dot">1</div>
<div class="timeline-content">
<div class="timeline-title">
<i class="fas fa-calculator"></i> محاسبه و تعیین
</div>
<div class="timeline-desc">
بررسی مبلغ درخواستی، تعیین نیاز به استعلام و مکاتبه با توجه به سقف‌های مجاز
</div>
</div>
</div>
<div class="timeline-item">
<div class="timeline-dot">2</div>
<div class="timeline-content">
<div class="timeline-title">
<i class="fas fa-edit"></i> تکمیل اطلاعات
</div>
<div class="timeline-desc">
تکمیل اطلاعات درخواست تعمیرات شامل: نوع تعمیرات، شرح جزئیات، توجیه فنی و سایر اطلاعات لازم
</div>
</div>
</div>
<div class="timeline-item">
<div class="timeline-dot">3</div>
<div class="timeline-content">
<div class="timeline-title">
<i class="fas fa-file-alt"></i> بارگذاری مدارک
</div>
<div class="timeline-desc">
بارگذاری مدارک مورد نیاز شامل: فاکتور/استعلام قیمت، تصویر محل نیازمند تعمیر و در صورت لزوم فرم مکاتبه با منطقه
</div>
</div>
</div>
<div class="timeline-item">
<div class="timeline-dot">4</div>
<div class="timeline-content">
<div class="timeline-title">
<i class="fas fa-check-circle"></i> تایید و ارسال
</div>
<div class="timeline-desc">
بررسی نهایی اطلاعات، مشاهده پیش‌نویس نامه و ارسال درخواست برای بررسی و تأیید
</div>
</div>
</div>
</div>
</div>
<!-- دکمه بازگشت به فرم -->
<div class="text-center mt-4">
<button class="btn btn-primary" id="backToFormBtn">
<i class="fas fa-arrow-right"></i> بازگشت به فرم محاسبه
</button>
</div>
</div>
</div>
</div>
</main>
<script>
document.addEventListener('DOMContentLoaded', function() {
const appState = {
calculationPerformed: false,
letterGenerated: false,
currentTab: 'tabCalculator',
repairGroup: 'building',
updateState(key, value) {
this[key] = value;
}
};
const config = {
totalLimit: 1460000000,
quoteThreshold: 200000000,
percentLimits: {
branch: 0.75,
regional: 0.50,
headquarters: 1.0
}
};
function faDigitToEn(str) {
if (!str) return '';
return str.toString()
.replace(/[۰-۹]/g, d => '۰۱۲۳۴۵۶۷۸۹'.indexOf(d))
.replace(/[٠-٩]/g, d => '٠١٢٣٤٥٦٧٨٩'.indexOf(d));
}
function parseNumber(str) {
if (!str) return 0;
const englishStr = faDigitToEn(str);
const numericString = englishStr.replace(/[^0-9.-]/g, '');
return parseInt(numericString, 10) || 0;
}
function formatNumber(num) {
if (isNaN(num) || num === null) return '۰';
return new Intl.NumberFormat('fa-IR').format(num);
}
function setupTabSystem() {
const tabButtons = document.querySelectorAll('.tab-button[data-tab]');
tabButtons.forEach(button => {
button.addEventListener('click', () => {
const tabId = button.getAttribute('data-tab');
const targetTab = document.getElementById(tabId);
tabButtons.forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
button.classList.add('active');
targetTab.classList.add('active');
appState.updateState('currentTab', tabId);
});
});
}
function setupAccordion() {
const accordionHeader = document.getElementById('authorityGuideHeader');
const accordionContent = document.getElementById('authorityGuideContent');
const accordionIcon = document.querySelector('.accordion-icon i');
accordionHeader.addEventListener('click', function() {
const isActive = accordionContent.classList.contains('active');
accordionContent.classList.toggle('active');
accordionIcon.classList.toggle('active');
accordionContent.style.maxHeight = accordionContent.classList.contains('active') ?
accordionContent.scrollHeight + 'px' : '0';
});
accordionContent.classList.remove('active');
accordionIcon.classList.remove('active');
accordionContent.style.maxHeight = '0';
}
function setupRepairGroups() {
const repairGroupBtns = document.querySelectorAll('[data-repair-group]');
repairGroupBtns.forEach(btn => {
btn.addEventListener('click', () => {
const group = btn.getAttribute('data-repair-group');
repairGroupBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
updateRepairOptions(group);
appState.updateState('repairGroup', group);
});
});
updateRepairOptions('building');
}
function updateRepairOptions(group) {
const repairCategory = document.getElementById('repairCategory');
while (repairCategory.options.length > 1) {
repairCategory.remove(1);
}
if (group === 'building') {
addOption(repairCategory, 'electrical', 'تعمیرات برقی');
addOption(repairCategory, 'plumbing', 'تعمیرات تأسیساتی');
addOption(repairCategory, 'construction', 'تعمیرات ساختمانی');
addOption(repairCategory, 'other_building', 'سایر موارد ساختمان');
} else if (group === 'furniture') {
addOption(repairCategory, 'office_equipment', 'تجهیزات اداری');
addOption(repairCategory, 'furniture', 'مبلمان و اثاثیه');
addOption(repairCategory, 'electronic', 'تجهیزات الکترونیکی');
addOption(repairCategory, 'other_furniture', 'سایر موارد اثاثیه');
}
}
function addOption(selectElement, value, text) {
const option = document.createElement('option');
option.value = value;
option.textContent = text;
selectElement.add(option);
}
function setupNumberInputs() {
const numberInputs = document.querySelectorAll('#estimatedCost, #yearlySpent');
numberInputs.forEach(input => {
input.addEventListener('input', function(e) {
this.value = this.value.replace(/[^\d,۰-۹٠-٩]/g, '');
});
input.addEventListener('blur', function() {
const numericValue = parseNumber(this.value);
if (numericValue > 0) {
this.value = formatNumber(numericValue);
} else if (this.value) {
this.value = '';
}
});
});
}
function setupCalculateButton() {
const calculateBtn = document.getElementById('calculateBtn');
calculateBtn.addEventListener('click', calculateAndShowResults);
}
function calculateAndShowResults() {
const repairCategory = document.getElementById('repairCategory');
const estimatedCostInput = document.getElementById('estimatedCost');
if (!repairCategory.value) {
alert('لطفاً نوع تعمیرات را انتخاب کنید.');
repairCategory.focus();
return;
}
if (!estimatedCostInput.value) {
alert('لطفاً برآورد هزینه را وارد کنید.');
estimatedCostInput.focus();
return;
}
const unitType = document.getElementById('unitType').value;
const estimatedCost = parseNumber(estimatedCostInput.value);
const yearlySpent = parseNumber(document.getElementById('yearlySpent').value);
if (estimatedCost <= 0) {
alert('لطفاً مبلغ برآورد هزینه را به صورت عددی معتبر وارد کنید.');
estimatedCostInput.focus();
return;
}
const totalSpent = yearlySpent + estimatedCost;
const unitLimit = config.totalLimit * config.percentLimits[unitType];
const needsThreeQuotes = estimatedCost >= config.quoteThreshold;
const needsHigherApproval = totalSpent > unitLimit;
const needsCentralApproval = totalSpent > config.totalLimit;
let approvalLevel = needsCentralApproval ? 'مرکزی' :
(needsHigherApproval ? (unitType === 'branch' ? 'منطقه' : 'مرکزی') : 'واحد');
const percentOfLimit = Math.round((totalSpent / config.totalLimit) * 100);
document.getElementById('resultCost').textContent = formatNumber(estimatedCost) + ' ریال';
document.getElementById('resultQuotes').innerHTML = needsThreeQuotes ?
'<span class="badge badge-warning"><i class="fas fa-file-invoice"></i> بله - نیاز به سه استعلام</span>' :
'<span class="badge badge-primary"><i class="fas fa-file-invoice"></i> خیر - یک استعلام کافیست</span>';
document.getElementById('resultApprovalLevel').innerHTML = approvalLevel === 'مرکزی' ?
'<span class="badge badge-danger"><i class="fas fa-building"></i> واحد مرکزی</span>' :
(approvalLevel === 'منطقه' ?
'<span class="badge badge-warning"><i class="fas fa-map-marker-alt"></i> سرپرستی منطقه</span>' :
'<span class="badge badge-success"><i class="fas fa-check-circle"></i> واحد</span>');
document.getElementById('resultRegionCoordination').innerHTML = needsHigherApproval ?
`<span class="badge badge-warning"><i class="fas fa-handshake"></i> بله (${formatNumber(percentOfLimit)}% از سقف مجاز)</span>` :
`<span class="badge badge-primary"><i class="fas fa-handshake"></i> خیر (${formatNumber(percentOfLimit)}% از سقف مجاز)</span>`;
document.getElementById('resultDocuments').innerHTML = needsThreeQuotes ?
'<span class="badge badge-warning"><i class="fas fa-file-alt"></i> سه استعلام قیمت / فاکتور</span>' :
'<span class="badge badge-primary"><i class="fas fa-file-alt"></i> یک فاکتور / پیش‌فاکتور</span>';
let additionalInfo = document.getElementById('additionalResultInfo');
if (!additionalInfo) {
additionalInfo = document.createElement('div');
additionalInfo.id = 'additionalResultInfo';
additionalInfo.classList.add('result-item');
const resultBody = document.querySelector('#calculationResults .result-body');
const letterBtn = document.querySelector('#calculationResults .mt-3');
resultBody.insertBefore(additionalInfo, letterBtn);
}
additionalInfo.innerHTML = `
<div class="result-label">وضعیت مصرف بودجه:</div>
<div class="result-value">
<span class="badge ${percentOfLimit > 75 ? 'badge-warning' : 'badge-success'}">
<i class="fas fa-chart-pie"></i> ${formatNumber(percentOfLimit)}% از سقف سالانه
</span>
</div>
`;
const calculationResults = document.getElementById('calculationResults');
calculationResults.classList.remove('d-none');
appState.updateState('calculationPerformed', true);
calculationResults.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
function setupLetterButton() {
const showLetterBtn = document.getElementById('showLetterBtn');
showLetterBtn.addEventListener('click', function() {
const letterPreview = document.getElementById('letterPreview');
letterPreview.classList.remove('d-none');
updateLetterTemplate();
appState.updateState('letterGenerated', true);
letterPreview.scrollIntoView({ behavior: 'smooth' });
});
}
function updateLetterTemplate() {
const today = new Date();
const persianDate = getPersianDate(today);
document.getElementById('letterDate').textContent = persianDate;
const unitType = document.getElementById('unitType').value;
const repairCategory = document.getElementById('repairCategory');
const repairCategoryText = repairCategory.options[repairCategory.selectedIndex].text;
const estimatedCost = parseNumber(document.getElementById('estimatedCost').value);
const yearlySpent = parseNumber(document.getElementById('yearlySpent').value);
const totalSpent = estimatedCost + yearlySpent;
const unitLimit = config.totalLimit * config.percentLimits[unitType];
const needsHigherApproval = totalSpent > unitLimit;
document.getElementById('letterFrom').textContent = getUnitTypeText(unitType);
document.getElementById('letterTo').textContent = getNeedApprovalFrom(unitType, estimatedCost, yearlySpent);
const repairGroupBtn = document.querySelector('[data-repair-group].active');
let repairTypeText = repairGroupBtn.textContent.trim().replace(/^\S+\s+/, '');
document.getElementById('letterRepairType').textContent = repairTypeText;
document.getElementById('letterRepairCategory').textContent = repairCategoryText;
document.getElementById('letterCost').textContent = formatNumber(estimatedCost) + ' ریال';
document.getElementById('letterYearlySpent').textContent = formatNumber(yearlySpent);
const letterContent = document.getElementById('letterContent');
let contentHTML = letterContent.innerHTML;
if (needsHigherApproval && !contentHTML.includes('نیاز به هماهنگی')) {
let newP = `<p>با توجه به اینکه مجموع هزینه‌های تعمیرات جزئی این واحد از حد مجاز تعیین شده فراتر رفته است، نیاز به هماهنگی با آن واحد محترم می‌باشد.</p>`;
contentHTML = contentHTML.replace('<p>خواهشمند است', newP + '<p>خواهشمند است');
} else if (!needsHigherApproval && contentHTML.includes('نیاز به هماهنگی')) {
contentHTML = contentHTML.replace(/<p>با توجه به اینکه.*?<\/p>/g, '');
}
letterContent.innerHTML = contentHTML;
const needsThreeQuotes = estimatedCost >= config.quoteThreshold;
document.getElementById('letterDocuments').textContent = needsThreeQuotes ?
'سه فقره استعلام قیمت، فرم مقایسه قیمت، تصویر محل نیازمند تعمیر' :
'یک فقره فاکتور یا پیش‌فاکتور، تصویر محل نیازمند تعمیر';
}
function getUnitTypeText(type) {
switch(type) {
case 'branch': return 'شعبه ...';
case 'regional': return 'سرپرستی منطقه ...';
case 'headquarters': return 'اداره کل ...';
default: return '...';
}
}
function getNeedApprovalFrom(unitType, cost, yearly) {
const totalSpent = cost + yearly;
const unitLimit = config.totalLimit * config.percentLimits[unitType];
if (totalSpent > config.totalLimit) {
return 'اداره کل پشتیبانی و خدمات عمومی';
} else if (totalSpent > unitLimit) {
return unitType === 'branch' ? 'سرپرستی منطقه' : 'اداره کل پشتیبانی و خدمات عمومی';
} else {
return 'مدیریت محترم شعبه';
}
}
function setupLetterActions() {
document.getElementById('copyLetterBtn').addEventListener('click', function() {
const letterContent = document.getElementById('letterContent');
navigator.clipboard.writeText(letterContent.innerText).then(() => {
alert('متن نامه با موفقیت کپی شد.');
}).catch(() => {
alert('خطا در کپی متن. لطفاً مجدداً تلاش کنید.');
});
});
document.getElementById('editLetterBtn').addEventListener('click', function() {
alert('این قابلیت در نسخه آزمایشی فعال نیست.');
});
document.getElementById('downloadLetterBtn').addEventListener('click', function() {
alert('این قابلیت در نسخه آزمایشی فعال نیست.');
});
}
function setupPrintButtons() {
document.getElementById('printBtn').addEventListener('click', function() {
prepareForPrint();
window.print();
});
document.getElementById('printResultBtn').addEventListener('click', function() {
prepareForPrint();
window.print();
});
document.getElementById('shareResultBtn').addEventListener('click', function() {
alert('این قابلیت در نسخه آزمایشی فعال نیست.');
});
}
function prepareForPrint() {
const calculationResults = document.getElementById('calculationResults');
if (calculationResults.classList.contains('d-none')) {
calculateAndShowResults();
}
const letterPreview = document.getElementById('letterPreview');
if (letterPreview.classList.contains('d-none')) {
letterPreview.classList.remove('d-none');
updateLetterTemplate();
}
document.querySelectorAll('.tab-content').forEach(content => {
content.dataset.printVisible = content.classList.contains('active') ? 'true' : 'false';
content.classList.add('active');
});
}
window.addEventListener('afterprint', function() {
document.querySelectorAll('.tab-content').forEach(content => {
if (content.dataset.printVisible === 'false') {
content.classList.remove('active');
}
});
});
function getPersianDate(date) {
const persianMonths = [
'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور',
'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
];
const persianYear = date.getFullYear() - 621;
const persianMonth = persianMonths[date.getMonth()];
const persianDay = date.getDate();
return `${persianYear}/${persianMonth}/${persianDay}`;
}
function setupHelpButton() {
document.getElementById('helpBtn').addEventListener('click', function() {
document.querySelector('.tab-button[data-tab="tabGuide"]').click();
});
document.getElementById('backToFormBtn').addEventListener('click', function() {
document.querySelector('.tab-button[data-tab="tabCalculator"]').click();
});
}
function initializeApp() {
setupTabSystem();
setupAccordion();
setupRepairGroups();
setupNumberInputs();
setupCalculateButton();
setupLetterButton();
setupLetterActions();
setupPrintButtons();
setupHelpButton();
}
initializeApp();
setTimeout(function() {
document.querySelectorAll('.tab-button[data-tab]').forEach(function(btn) {
var newBtn = btn.cloneNode(true);
btn.parentNode.replaceChild(newBtn, btn);
newBtn.onclick = function() {
var target = this.getAttribute('data-tab');
document.querySelectorAll('.tab-content').forEach(function(c) {
c.classList.remove('active');
});
document.querySelectorAll('.tab-button[data-tab]').forEach(function(b) {
b.classList.remove('active');
});
this.classList.add('active');
document.getElementById(target).classList.add('active');
};
});
document.querySelectorAll('[data-repair-group]').forEach(function(btn) {
var newBtn = btn.cloneNode(true);
btn.parentNode.replaceChild(newBtn, btn);
newBtn.onclick = function() {
var group = this.getAttribute('data-repair-group');
document.querySelectorAll('[data-repair-group]').forEach(function(b) {
b.classList.remove('active');
});
this.classList.add('active');
var repairCategory = document.getElementById('repairCategory');
while (repairCategory.options.length > 1) {
repairCategory.remove(1);
}
if (group === 'building') {
var options = [
{ value: 'electrical', text: 'تعمیرات برقی' },
{ value: 'plumbing', text: 'تعمیرات تأسیساتی' },
{ value: 'construction', text: 'تعمیرات ساختمانی' },
{ value: 'other_building', text: 'سایر موارد ساختمان' }
];
} else {
var options = [
{ value: 'office_equipment', text: 'تجهیزات اداری' },
{ value: 'furniture', text: 'مبلمان و اثاثیه' },
{ value: 'electronic', text: 'تجهیزات الکترونیکی' },
{ value: 'other_furniture', text: 'سایر موارد اثاثیه' }
];
}
options.forEach(function(opt) {
var option = document.createElement('option');
option.value = opt.value;
option.textContent = opt.text;
repairCategory.add(option);
});
};
});
}, 1000);
});
</script>
</body>
</html>