<div id="mediq-dashboard" dir="rtl">
<style>
/* ===== MediQ V63 - clean rewrite ===== */
#mediq-dashboard,#mediq-dashboard *{box-sizing:border-box}
#mediq-dashboard{--navy:#34414d;--p:#57606a;--pd:#4a525a;--text:#3d4954;--muted:#7c8791;--bd:#d7dde2;
position:fixed;inset:0;width:100vw;height:100vh;z-index:9999;overflow:hidden;direction:rtl;font-family:Tahoma,Arial,sans-serif;color:var(--text);background:#f4f5f6}
html,body,#page,#full-height-container,#main,#content,#main-content,.aui-page-panel,.aui-page-panel-inner,.aui-page-panel-content,.content-body{width:100%!important;height:100%!important;max-width:none!important;margin:0!important;padding:0!important}
html,body{overflow:hidden!important}
#footer,footer,.aui-footer,#header,#main-header,.breadcrumbs,#breadcrumbs,.page-metadata{display:none!important}
.confiforms-registration-control{position:fixed!important;left:-10000px!important;top:-10000px!important;width:1px!important;height:1px!important;overflow:hidden!important;opacity:0!important}
.mq-app{width:100%;height:100%;display:grid;grid-template-columns:minmax(0,1fr) 255px;direction:ltr}
.mq-sidebar{grid-column:2;height:100vh;padding:24px 17px;direction:rtl;color:#fff;display:flex;flex-direction:column;overflow:hidden;
background:linear-gradient(180deg,#424b55,#343c45 45%,#2b3138);box-shadow:-12px 0 38px rgba(43,49,56,.18)}
.mq-logo{text-align:center;padding:3px 5px 22px;border-bottom:1px solid rgba(255,255,255,.08)}
.mq-logo img{width:174px;max-width:92%;height:auto}
.mq-tree-title{margin:22px 7px 9px;color:rgba(255,255,255,.4);font-size:12px;font-weight:700}
.mq-tree{display:flex;flex-direction:column;gap:5px;overflow-y:auto;scrollbar-width:none}
.mq-tree::-webkit-scrollbar{display:none}
.mq-tree-row{min-height:42px;padding:0 10px;border-radius:9px;display:flex;align-items:center;gap:8px;color:rgba(255,255,255,.7);font-size:13px;font-weight:800;cursor:pointer;user-select:none;transition:background .15s,color .15s}
.mq-tree-row:hover{color:#fff;background:rgba(255,255,255,.07)}
.mq-tree-row.active{color:#fff;background:linear-gradient(90deg,#57606a,#4a525b)}
.mq-tree-row.parent-active:not(.active){color:#fff;background:rgba(255,255,255,.055)}
.mq-tree-row.level-2{padding-right:23px;font-size:12.5px}
.mq-tree-row.level-3{padding-right:36px;font-size:12px}
.mq-tree-row.level-4{padding-right:49px;font-size:11.7px;color:rgba(255,255,255,.6)}
.mq-tree-dot{width:6px;height:6px;flex:0 0 6px;border-radius:50%;background:rgba(255,255,255,.32)}
.mq-tree-row.active .mq-tree-dot{background:#fff}
.mq-tree-arrow{margin-right:auto;color:rgba(255,255,255,.45);transition:transform .18s}
.mq-tree-row.open>.mq-tree-arrow{transform:rotate(90deg)}
.mq-tree-children{display:none;margin-top:2px}.mq-tree-children.open{display:block}
.mq-tree-sep{height:1px;margin:8px 9px;background:rgba(255,255,255,.08)}
.mq-sidebar-bottom{margin-top:auto;padding-top:14px;border-top:1px solid rgba(255,255,255,.07)}
.mq-logout{min-height:43px;padding:0 13px;border-radius:11px;display:flex;align-items:center;color:rgba(255,255,255,.72);font-size:13px;font-weight:700;cursor:pointer}
.mq-logout:hover{color:#fff;background:rgba(255,255,255,.07)}
.mq-main{grid-column:1;height:100vh;direction:rtl;overflow-y:auto;padding:0 clamp(25px,4vw,55px) 45px}
.mq-header{min-height:92px;border-bottom:1px solid var(--bd);display:flex;align-items:center;justify-content:space-between;gap:20px}
.mq-page-title{color:var(--navy);font-size:23px;font-weight:900}
.mq-page-desc{margin-top:6px;color:var(--muted);font-size:13px;font-weight:600}
.mq-header-left{display:flex;align-items:center;gap:10px;margin-right:auto}
.mq-welcome{display:flex;align-items:center;gap:9px;padding:10px 16px;border:1px solid rgba(87,96,106,.2);border-radius:999px;background:rgba(255,255,255,.82);color:#587287;font-size:13px;font-weight:700;white-space:nowrap}
.mq-welcome strong{color:var(--navy);font-size:14px;font-weight:900}
.mq-welcome i{width:8px;height:8px;border-radius:50%;background:var(--p);box-shadow:0 0 0 4px rgba(87,96,106,.1)}
.mq-edit-page{display:inline-flex;align-items:center;gap:7px;min-height:38px;padding:0 14px;border:1px solid #cfd5da;border-radius:12px;background:#fff;color:var(--navy)!important;font-size:12px;font-weight:900;text-decoration:none!important}
.mq-edit-page:hover{background:#f1f2f3}
.mq-breadcrumb{min-height:46px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.mq-bread{color:#8197a8;font-size:13px;font-weight:700;padding:4px 6px;border-radius:7px}
.mq-bread.link{cursor:pointer}.mq-bread.link:hover{color:var(--p);background:rgba(87,96,106,.08)}
.mq-bread.cur{color:var(--pd);font-weight:900}.mq-bread-sep{color:#b6c4cf}
.mq-hero{margin-top:14px;position:relative;overflow:hidden;min-height:112px;padding:21px 24px;border-radius:18px;color:#fff;display:flex;align-items:center;justify-content:space-between;background:linear-gradient(105deg,#073b5c,#3c4249);box-shadow:0 18px 42px rgba(7,53,83,.12)}
.mq-hero-title{font-size:19px;font-weight:900}.mq-hero-desc{margin-top:6px;color:rgba(255,255,255,.7);font-size:13px}
.mq-back{display:none;min-width:88px;height:36px;padding:0 13px;border:1px solid rgba(255,255,255,.25);border-radius:10px;background:rgba(255,255,255,.1);color:#fff;font:800 13px Tahoma,Arial;cursor:pointer}
.mq-back:hover{background:rgba(255,255,255,.16)}
.mq-view{margin-top:23px}
.mq-sec-title{color:var(--navy);font-size:17px;font-weight:900}.mq-sec-desc{margin:4px 0 14px;color:var(--muted);font-size:12px}
.mq-grid4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
.mq-grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px}
.mq-card{position:relative;min-height:150px;padding:18px;border:1px solid var(--bd);border-radius:17px;background:#fff;cursor:pointer;transition:transform .17s,box-shadow .17s,border-color .17s;box-shadow:0 10px 30px rgba(19,65,90,.05)}
.mq-card:hover{transform:translateY(-4px);border-color:rgba(87,96,106,.45);box-shadow:0 20px 45px rgba(19,65,90,.1)}
.mq-card.row{display:flex;align-items:center;gap:16px;min-height:130px}
.mq-ico{width:48px;height:48px;flex:0 0 48px;margin-bottom:14px;border-radius:14px;display:flex;align-items:center;justify-content:center;color:var(--pd);background:#eceef0}
.mq-card.row .mq-ico{margin:0}
.mq-ico svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.mq-card-name{color:var(--navy);font-size:15px;font-weight:900;line-height:1.8}.mq-card-sub{margin-top:6px;color:var(--muted);font-size:12px}
.mq-list-layout{display:grid;grid-template-columns:300px minmax(0,1fr);gap:16px;direction:ltr}
.mq-menu,.mq-box{direction:rtl;border:1px solid var(--bd);border-radius:18px;background:#fff;box-shadow:0 10px 28px rgba(19,65,90,.035)}
.mq-menu{padding:13px;align-self:start}.mq-box{min-height:390px;padding:23px}
.mq-opt{min-height:50px;margin-bottom:5px;padding:0 13px;border-radius:10px;display:flex;align-items:center;justify-content:space-between;color:#536f84;font-size:13px;font-weight:800;cursor:pointer}
.mq-opt:hover{background:#f5f5f6}.mq-opt.active{color:#3d444a;background:#f0f1f2}
.mq-box-title{color:var(--navy);font-size:17px;font-weight:900}.mq-box-desc{margin-top:7px;color:var(--muted);font-size:12px}
.mq-head{margin-top:18px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.mq-btn{min-height:38px;padding:0 15px;border:1px solid #d8e0e5;border-radius:9px;background:#fff;color:#47677d;font:800 12px Tahoma,Arial;cursor:pointer}
.mq-btn.primary{border-color:transparent;color:#fff;background:linear-gradient(90deg,#505962,#5c6670)}
.mq-host{margin-top:14px;min-height:140px}
.mq-host table{width:100%!important;border-collapse:separate!important;border-spacing:0!important;direction:rtl!important;background:#fff!important;border:1px solid var(--bd)!important;border-radius:14px!important;overflow:hidden!important}
.mq-host th{padding:13px 16px!important;text-align:right!important;background:#f5f7f8!important;color:#34414d!important;border-bottom:1px solid var(--bd)!important;font-size:12px!important;font-weight:900!important}
.mq-host td{padding:12px 16px!important;text-align:right!important;color:#3d4954!important;border-bottom:1px solid #eef1f3!important;font-size:12px!important;font-weight:700!important;background:#fff!important}
.mq-host tr:last-child td{border-bottom:0!important}
.mq-host [class*=datepicker],.mq-host [class*=calendar]{display:none!important}
.mq-msg{min-height:140px;display:flex;align-items:center;justify-content:center;padding:22px;border:1px dashed #c5cdd3;border-radius:12px;background:#f8f9fa;color:#6f7f8c;text-align:center;font-size:12px;font-weight:700}
.mq-del,.mq-edit{min-width:54px;min-height:28px;padding:0 11px!important;margin-left:6px;border-radius:8px!important;font:800 11px Tahoma,Arial!important;cursor:pointer!important;text-decoration:none!important;display:inline-flex!important;align-items:center;justify-content:center}
.mq-del{border:1px solid #f1c9c9!important;background:#fff7f7!important;color:#b42318!important}
.mq-edit{border:1px solid rgba(87,96,106,.3)!important;background:#f4f4f5!important;color:#434a51!important}
.mq-search{width:min(390px,100%);min-height:40px;padding:0 14px;border:1px solid #d8e0e5;border-radius:10px;outline:none;font:700 12px Tahoma,Arial;direction:rtl}
.mq-empty{min-height:350px;border:1px dashed #c7ced4;border-radius:18px;display:flex;align-items:center;justify-content:center;flex-direction:column;background:rgba(255,255,255,.65);color:#7890a2}
.mq-empty strong{color:var(--navy);font-size:18px}.mq-empty span{margin-top:8px;font-size:13px}
.mq-toast{position:fixed;left:30px;bottom:27px;z-index:2147483600;min-width:260px;max-width:380px;padding:13px 16px;border-radius:11px;color:#fff;background:#34414d;box-shadow:0 16px 40px rgba(0,0,0,.15);font-size:13px;font-weight:700;opacity:0;transform:translateY(12px);pointer-events:none;transition:.2s}
.mq-toast.show{opacity:1;transform:none}
@media(max-width:1300px){.mq-grid4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:800px){.mq-sidebar{display:none}.mq-app{display:block}.mq-grid4,.mq-grid2,.mq-list-layout{grid-template-columns:1fr}}
/* ===== Wizard ===== */
#mqWizBack{position:fixed;inset:0;z-index:2147483000;display:none;align-items:center;justify-content:center;background:rgba(3,35,55,.56);backdrop-filter:blur(4px);color:#fff;font-weight:800;font-size:14px;direction:rtl}
#mqWizBack.open{display:flex}
body.mq-wiz-ready #mqWizLoad{display:none}
/* every ConfiForms panel of the wizard stays parked off-screen (but with real width) until it is the active step */
.confiFormsFormBorder[class*="cf_mediqNew"]:not(.mq-active):not(.aui-dialog *):not(.aui-dialog2 *){position:fixed!important;left:-9999px!important;top:0!important;width:760px!important;max-height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important}
.confiFormsFormBorder.mq-active{display:block!important;position:fixed!important;z-index:2147483100!important;left:50%!important;top:50%!important;transform:translate(-50%,-50%)!important;width:min(860px,94vw)!important;max-width:94vw!important;height:auto!important;max-height:88vh!important;margin:0!important;padding:0!important;overflow-x:hidden!important;overflow-y:auto!important;opacity:1!important;visibility:visible!important;pointer-events:auto!important;background:#fff!important;border:1px solid #d7dde2!important;border-radius:22px!important;box-shadow:0 32px 95px rgba(3,35,55,.32)!important;direction:rtl!important;text-align:right!important}
.mq-active .confiFormsFormTitle{display:none!important}
.mq-active .confiFormsFormContent{padding:14px 22px 8px!important;background:#fff!important;overflow:visible!important}
.mq-active .confiFormsFormFooter{padding:12px 22px 20px!important;background:#fff!important;direction:rtl!important}
.mq-active.mq-sel .confiFormsFormFooter{display:none!important}
.mq-active.mq-sel .confiFormsFormContent{padding:26px 26px 14px!important}
.mq-active form,.mq-active .table-wrap,.mq-active table{width:100%!important;max-width:100%!important;min-width:0!important;overflow-x:hidden!important;direction:rtl!important;text-align:right!important}
.mq-active table{table-layout:fixed!important;border-collapse:separate!important;border-spacing:0 6px!important;margin:0!important}
.mq-active td,.mq-active th{border:0!important;padding:6px 8px!important;background:#fff!important;direction:rtl!important;text-align:right!important;vertical-align:middle!important;min-width:0!important;max-width:100%!important;word-break:break-word}
.mq-active td:first-child{width:190px!important}
.mq-active label{color:#3d4954!important;font:900 13px Tahoma,Arial!important;direction:rtl!important}
.mq-active .mq-hide{display:none!important}
.mq-active input[type=text]:not(.select2-offscreen):not(.select2-focusser):not(.select2-input),.mq-active input[type=number],.mq-active textarea,.mq-active select:not(.select2-offscreen){width:100%!important;max-width:100%!important;min-height:44px!important;padding:8px 13px!important;border:1px solid #d5dbe0!important;border-radius:12px!important;background:#fff!important;box-shadow:0 2px 9px rgba(7,53,83,.035)!important;color:#3d4954!important;font:13px Tahoma,Arial!important;direction:rtl!important;text-align:right!important}
.mq-active .select2-container,.mq-active .aui-select2-container{display:block!important;width:100%!important;max-width:100%!important;min-width:0!important;position:relative!important}
.mq-active .select2-choice,.mq-active .select2-selection,.mq-active .aui-select2-choice{height:44px!important;min-height:44px!important;line-height:42px!important;border:1px solid #d5dbe0!important;border-radius:12px!important;background:#fff!important;box-shadow:0 2px 9px rgba(7,53,83,.035)!important;direction:rtl!important}
.mq-active .select2-chosen,.mq-active .select2-selection__rendered{display:block!important;line-height:42px!important;padding:0 14px!important;direction:rtl!important;text-align:right!important;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the Select2 v3 source/focus inputs must never render as boxes */
.mq-active select.select2-offscreen,.mq-active input.select2-offscreen,.mq-active select.select2-hidden-accessible,.mq-active input.select2-hidden-accessible,.mq-active .select2-container input.select2-focusser,.mq-active .select2-container>input.select2-input{position:absolute!important;left:-10000px!important;top:0!important;width:1px!important;height:1px!important;min-width:1px!important;min-height:1px!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;overflow:hidden!important}
.mq-active .save-cf-btn,.mq-active .aui-button-primary{min-width:145px!important;min-height:44px!important;padding:0 20px!important;border:1px solid #505962!important;border-radius:12px!important;background:linear-gradient(135deg,#57606a,#4a525a)!important;color:#fff!important;text-shadow:none!important;font:900 13px Tahoma,Arial!important}
/* dropdowns are appended to <body>: keep them above the wizard, let Select2 position them itself */
.select2-drop,.aui-select2-drop,.select2-dropdown{z-index:2147483640!important;direction:rtl;text-align:right}
.select2-drop-mask{z-index:2147483630!important}
.ui-datepicker,#ui-datepicker-div,.aui-inline-dialog,.aui-datepicker-dialog{z-index:2147483300!important}
.aui-blanket{z-index:10060!important}.aui-dialog,.aui-dialog2{z-index:10070!important}
.mq-wiz-head{position:sticky;top:0;z-index:40;padding:18px 22px 14px;background:#fff;border-bottom:1px solid #e1e5e8}
.mq-wiz-top{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}
.mq-wiz-title{color:#34414d;font-size:18px;font-weight:900;line-height:1.8}
.mq-wiz-sub{margin-top:4px;color:#7c8791;font-size:11px;font-weight:700;line-height:1.9}
.mq-wiz-close{flex:0 0 36px;width:36px;height:36px;padding:0;border:0;border-radius:10px;background:#f1f3f4;color:#68747f;font:700 21px/36px Tahoma,Arial;cursor:pointer}
.mq-wiz-close:hover{background:#e6e8ea}
.mq-wiz-steps{margin-top:15px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
.mq-wiz-step{min-height:40px;padding:7px 9px;display:flex;align-items:center;justify-content:center;gap:7px;border:1px solid #e3e7ea;border-radius:11px;background:#f8f9fa;color:#87919a;font-size:11px;font-weight:800}
.mq-wiz-step b{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;background:#e5e9ec;color:#6d7882;font-size:10px}
.mq-wiz-step.done{background:#f4f5f6;color:#636e7a}
.mq-wiz-step.active{border-color:#b9bfc5;background:#f0f1f2;color:#434a51}
.mq-wiz-step.active b{background:#57606a;color:#fff}
.mq-wiz-foot{padding:14px 22px 22px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;border-top:1px solid #eceff1;background:#fff}
.mq-wiz-foot div{display:flex;gap:9px;flex-wrap:wrap}
.mq-wiz-b{min-height:42px;padding:0 17px;border-radius:11px;font:900 12px Tahoma,Arial;cursor:pointer;border:1px solid #d7dde2;background:#fff;color:#536f84}
.mq-wiz-b.p{border-color:#505962;background:linear-gradient(135deg,#57606a,#4a525a);color:#fff}
.mq-wiz-back{padding:0 22px 20px;background:#fff}
.mq-wiz-diag{margin:18px 26px;padding:16px;border:1px dashed #e0b4b4;border-radius:12px;background:#fff8f8;color:#8a2c2c;font-size:12px;font-weight:700;line-height:2;direction:rtl}
.mq-wiz-diag code{direction:ltr;display:inline-block;background:#fff;border:1px solid #eed;padding:0 6px;border-radius:5px;margin:2px}
.mq-sec-row td{padding:12px 4px 2px!important}
.mq-sec-row div{color:#34414d;font-size:13px;font-weight:900;padding-bottom:8px;border-bottom:1px solid #e5eaee}
@media(max-width:760px){.confiFormsFormBorder.mq-active{width:96vw!important;max-height:92vh!important;border-radius:16px!important}.mq-wiz-steps{grid-template-columns:repeat(2,1fr)}.mq-active td:first-child{width:auto!important}}
</style>
<div class="mq-app">
<main class="mq-main">
<header class="mq-header">
<div><div id="mqPageTitle" class="mq-page-title">تأمین</div><div id="mqPageDesc" class="mq-page-desc">مدیریت فرآیند تأمین تجهیزات پزشکی</div></div>
<div class="mq-header-left">
<a id="mqEditPage" class="mq-edit-page" href="#">ویرایش صفحه</a>
<div class="mq-welcome"><i></i><strong id="mqWelcomeUser">کاربر مدیکیو</strong><span>خوش آمدید</span></div>
</div>
</header>
<section class="mq-hero">
<div><div id="mqHeroTitle" class="mq-hero-title"></div><div id="mqHeroDesc" class="mq-hero-desc"></div></div>
<button id="mqBack" class="mq-back" type="button">بازگشت</button>
</section>
<div id="mqBreadcrumb" class="mq-breadcrumb"></div>
<div id="mqView" class="mq-view"></div>
</main>
<aside class="mq-sidebar">
<div class="mq-logo"><img src="/download/attachments/174855060/MediQ%20Heart%20Medical%20Logo.png" alt="MediQ"></div>
<div class="mq-tree-title">ساختار تأمین</div>
<div class="mq-tree" id="mqTree"></div>
<div class="mq-sidebar-bottom"><div id="mqLogout" class="mq-logout">خروج از حساب کاربری</div></div>
</aside>
</div>
<div id="mqWizBack" aria-hidden="true"><span id="mqWizLoad">در حال آمادهسازی فرمها...</span></div>
<div id="mqToast" class="mq-toast"></div>
<script>
(function () {
"use strict";
/* ================= helpers ================= */
var D = document;
var $ = function (s, r) { return (r || D).querySelector(s); };
var $$ = function (s, r) { return Array.prototype.slice.call((r || D).querySelectorAll(s)); };
var J = function () { return (window.AJS && AJS.$) || window.jQuery || null; };
var norm = function (v) { return String(v == null ? "" : v).replace(/\s+/g, " ").trim().toLowerCase(); };
function store(k, v) {
try {
if (v === undefined) return sessionStorage.getItem(k) || "";
if (v) sessionStorage.setItem(k, v); else sessionStorage.removeItem(k);
} catch (e) {}
return "";
}
function wait(cond, ok, fail, max) {
var n = 0;
(function t() {
var r = null;
try { r = cond(); } catch (e) {}
if (r) { ok(r); return; }
if (++n >= (max || 40)) { if (fail) fail(); return; }
setTimeout(t, 100);
})();
}
var PAGE_ID = (window.AJS && AJS.Meta && AJS.Meta.get("page-id")) || "174855144";
var toastT, toastEl = $("#mqToast");
function toast(m) {
toastEl.textContent = m; toastEl.classList.add("show");
clearTimeout(toastT); toastT = setTimeout(function () { toastEl.classList.remove("show"); }, 2600);
}
/* ================= shell / tree / screens ================= */
var view = $("#mqView"), crumbEl = $("#mqBreadcrumb"), backBtn = $("#mqBack");
var ICON = {
property: '<path d="M12 3l7 4-7 4-7-4 7-4z"/><path d="M5 7v9l7 4 7-4V7"/><path d="M12 11v9"/>',
maintenance: '<circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/>',
finance: '<circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/>',
supply: '<path d="M4 7h16"/><path d="M6 7l1 13h10l1-13"/><path d="M9 4h6"/>',
purchase: '<path d="M4 5h2l2 11h9l2-7H8"/><circle cx="10" cy="20" r="1"/><circle cx="17" cy="20" r="1"/>',
newAsset: '<path d="M12 3l7 4-7 4-7-4 7-4z"/><path d="M5 7v9l7 4 7-4V7"/><path d="M18 3v6M15 6h6"/>',
edit: '<path d="M4 20h4l11-11-4-4L4 16v4z"/><path d="M13 7l4 4"/>',
consumable: '<rect x="5" y="4" width="14" height="16" rx="2"/><path d="M8 9h8M8 13h8"/>'
};
var SECTIONS = [["purchased", "لیست دستگاهها"], ["technical", "شناسنامه فنی"], ["financial", "شناسنامه مالی"], ["maintenance", "شناسنامه نگهداری و تعمیر"], ["commercial", "شناسنامه بازرگانی"]];
var NAMES = { equipment: "مدیریت تجهیزات", property: "مدیریت اموال", equipmentMaintenance: "مدیریت نگهداری و تعمیر", finance: "مدیریت مالی و بهرهوری", logistics: "مدیریت تأمین و لجستیک", purchase: "خرید دستگاه", newAsset: "ورود دستگاه جدید", editAsset: "ویرایش دستگاه", consumable: "کالاهای مصرفی", operation: "بهرهبرداری", replacement: "جایگزینی", maintenanceCycle: "نگهداری" };
var TREE = [
{ k: "equipment", t: NAMES.equipment, l: 1, ch: [
{ k: "property", t: NAMES.property, l: 2 },
{ k: "equipmentMaintenance", t: NAMES.equipmentMaintenance, l: 2 },
{ k: "finance", t: NAMES.finance, l: 2 },
{ k: "logistics", t: NAMES.logistics, l: 2, ch: [
{ k: "purchase", t: NAMES.purchase, l: 3 },
{ k: "newAsset", t: NAMES.newAsset, l: 3, ch: SECTIONS.map(function (s) { return { k: "newAsset-" + s[0], t: s[1], l: 4 }; }) },
{ k: "editAsset", t: NAMES.editAsset, l: 3 },
{ k: "consumable", t: NAMES.consumable, l: 3 }
] }
] },
{ sep: 1 },
{ k: "operation", t: NAMES.operation, l: 1 },
{ k: "replacement", t: NAMES.replacement, l: 1 },
{ k: "maintenanceCycle", t: NAMES.maintenanceCycle, l: 1 }
];
var PATH = {};
function buildTree(nodes, parents, host) {
nodes.forEach(function (n) {
if (n.sep) { var s = D.createElement("div"); s.className = "mq-tree-sep"; host.appendChild(s); return; }
var row = D.createElement("div");
row.className = "mq-tree-row level-" + n.l; row.setAttribute("data-key", n.k);
row.innerHTML = '<span class="mq-tree-dot"></span><span>' + n.t + '</span>' + (n.ch ? '<span class="mq-tree-arrow">‹</span>' : "");
row.onclick = function () { go(n.k); };
host.appendChild(row);
PATH[n.k] = parents.concat(n.k);
if (n.ch) {
var g = D.createElement("div"); g.className = "mq-tree-children"; g.setAttribute("data-group", n.k);
host.appendChild(g); buildTree(n.ch, parents.concat(n.k), g);
}
});
}
function treeActivate(key) {
var path = PATH[key] || [];
$$("#mqTree .mq-tree-row").forEach(function (r) {
var k = r.getAttribute("data-key");
r.classList.toggle("active", k === key);
r.classList.toggle("parent-active", k !== key && path.indexOf(k) >= 0);
r.classList.toggle("open", path.indexOf(k) >= 0);
});
$$("#mqTree .mq-tree-children").forEach(function (g) { g.classList.toggle("open", path.indexOf(g.getAttribute("data-group")) >= 0); });
}
/* o: key,title,desc,crumbs[[label,key]],back,html */
function frame(o) {
$("#mqHeroTitle").textContent = o.title;
$("#mqHeroDesc").textContent = o.desc || "";
backBtn.style.display = o.back ? "inline-block" : "none";
backBtn.onclick = function () { if (o.back) go(o.back); };
var h = "";
o.crumbs.forEach(function (c, i) {
var last = i === o.crumbs.length - 1;
h += '<span class="mq-bread ' + (last ? "cur" : "link") + '" data-go="' + (c[1] || "") + '">' + c[0] + "</span>" + (last ? "" : '<span class="mq-bread-sep">/</span>');
});
crumbEl.innerHTML = h;
$$(".mq-bread.link", crumbEl).forEach(function (b) { b.onclick = function () { go(b.getAttribute("data-go")); }; });
view.innerHTML = o.html;
$$("[data-go]", view).forEach(function (el) { el.onclick = function () { go(el.getAttribute("data-go")); }; });
treeActivate(o.key);
}
function card(title, icon, key) {
return '<div class="mq-card" data-go="' + key + '"><div class="mq-ico"><svg viewBox="0 0 24 24">' + ICON[icon] + '</svg></div><div class="mq-card-name">' + title + "</div></div>";
}
function acard(title, sub, icon, key) {
return '<div class="mq-card row" data-go="' + key + '"><div class="mq-ico"><svg viewBox="0 0 24 24">' + ICON[icon] + '</svg></div><div><div class="mq-card-name">' + title + '</div><div class="mq-card-sub">' + sub + "</div></div></div>";
}
var CR_EQ = [["تأمین", "equipment"], ["مدیریت تجهیزات", "equipment"]];
var CR_LG = CR_EQ.concat([["مدیریت تأمین و لجستیک", "logistics"]]);
function rEquipment() {
frame({ key: "equipment", title: "مدیریت تجهیزات", desc: "حوزه موردنظر را انتخاب کنید.", crumbs: [["تأمین"], ["مدیریت تجهیزات"]],
html: '<div class="mq-sec-title">مدیریت تجهیزات</div><div class="mq-sec-desc">یکی از حوزهها را انتخاب کنید.</div><div class="mq-grid4">' +
card(NAMES.property, "property", "property") + card(NAMES.equipmentMaintenance, "maintenance", "equipmentMaintenance") +
card(NAMES.finance, "finance", "finance") + card(NAMES.logistics, "supply", "logistics") + "</div>" });
}
function rLogistics() {
frame({ key: "logistics", title: NAMES.logistics, desc: "عملیات موردنظر را انتخاب کنید.", back: "equipment", crumbs: CR_EQ.concat([["مدیریت تأمین و لجستیک"]]),
html: '<div class="mq-sec-title">' + NAMES.logistics + '</div><div class="mq-sec-desc">عملیات مرتبط با تأمین و لجستیک تجهیزات</div><div class="mq-grid2">' +
acard("خرید دستگاه", "فرآیند خرید دستگاه", "purchase", "purchase") +
acard("ورود دستگاه جدید", "ثبت و تکمیل اطلاعات دستگاه جدید", "newAsset", "newAsset") +
acard("ویرایش دستگاه", "مشاهده و ویرایش اطلاعات دستگاه موجود", "edit", "editAsset") +
acard("کالاهای مصرفی", "مدیریت کالاهای مصرفی", "consumable", "consumable") + "</div>" });
}
function rSimple(key, crumbs, back) {
frame({ key: key, title: NAMES[key], desc: "نمای این بخش", back: back, crumbs: crumbs.concat([[NAMES[key]]]),
html: '<div class="mq-empty"><strong>' + NAMES[key] + "</strong><span>این بخش در ادامه فرآیند طراحی تکمیل میشود.</span></div>" });
}
function rCycle(key) {
frame({ key: key, title: NAMES[key], desc: "نمای ساختار این بخش", crumbs: [[NAMES[key]]],
html: '<div class="mq-empty"><strong>' + NAMES[key] + "</strong><span>ساختار این بخش در مرحله بعد طراحی میشود.</span></div>" });
}
var curSection = "purchased";
function rNewAsset() {
var name = "";
SECTIONS.forEach(function (s) { if (s[0] === curSection) name = s[1]; });
var menu = SECTIONS.map(function (s) {
return '<div class="mq-opt' + (s[0] === curSection ? " active" : "") + '" data-go="newAsset-' + s[0] + '"><span>' + s[1] + "</span><span>‹</span></div>";
}).join("");
var body;
if (curSection === "purchased") {
body = '<div class="mq-box-title">لیست دستگاهها</div><div class="mq-box-desc">دستگاههای ثبتشده</div>' +
'<div class="mq-head"><div></div><div><button class="mq-btn" id="mqRefresh" type="button">بهروزرسانی لیست</button> <button class="mq-btn primary" id="mqNew" type="button">ثبت دستگاه جدید</button></div></div>' +
'<div class="mq-host" id="mqHost"><div class="mq-msg">در حال بارگذاری...</div></div>';
} else {
body = '<div class="mq-box-title">' + name + '</div><div class="mq-box-desc">اطلاعات این بخش برای دستگاه انتخابشده تکمیل میشود.</div><div class="mq-empty" style="min-height:250px;margin-top:20px"><strong>' + name + "</strong><span>فرم این بخش هنوز تعریف نشده است.</span></div>";
}
frame({ key: "newAsset-" + curSection, title: NAMES.newAsset, desc: "بخش موردنظر را انتخاب کنید.", back: "logistics", crumbs: CR_LG.concat([[NAMES.newAsset]]),
html: '<div class="mq-list-layout"><div class="mq-menu">' + menu + '</div><div class="mq-box">' + body + "</div></div>" });
if (curSection === "purchased") {
$("#mqNew").onclick = openWizard;
$("#mqRefresh").onclick = function () { store("mqResume", "newAsset-purchased"); location.reload(); };
loadTable($("#mqHost"), "list", 0);
}
}
function rEdit() {
frame({ key: "editAsset", title: NAMES.editAsset, desc: "دستگاه را جستجو کنید و روی «ویرایش» بزنید.", back: "logistics", crumbs: CR_LG.concat([[NAMES.editAsset]]),
html: '<div class="mq-box"><div class="mq-box-title">ویرایش دستگاه</div><div class="mq-head"><input id="mqSearch" class="mq-search" type="text" placeholder="جستجو بر اساس شناسه یا نام دستگاه"></div><div class="mq-host" id="mqHost"><div class="mq-msg">در حال بارگذاری...</div></div></div>' });
loadTable($("#mqHost"), "edit", 0);
}
function go(key) {
var m = String(key).match(/^newAsset-(.+)$/);
if (m) { curSection = m[1]; return rNewAsset(); }
switch (key) {
case "equipment": return rEquipment();
case "logistics": return rLogistics();
case "newAsset": curSection = "purchased"; return rNewAsset();
case "editAsset": return rEdit();
case "property": case "equipmentMaintenance": case "finance": return rSimple(key, [["تأمین", "equipment"], ["مدیریت تجهیزات", "equipment"]], "equipment");
case "purchase": case "consumable": return rSimple(key, CR_LG, "logistics");
case "operation": case "replacement": case "maintenanceCycle": return rCycle(key);
}
rEquipment();
}
/* ================= asset table (ConfiForms TableView clone) ================= */
function findTable() {
var best = null, bs = 0;
$$("table").forEach(function (t) {
if (t.closest("#mediq-dashboard,.confiFormsFormBorder,form.aui-confiforms,.ui-datepicker,.aui-datepicker")) return;
if (t.rows.length < 2) return;
if (/datepicker|calendar/.test(norm(t.id + " " + t.className))) return;
var tx = norm(t.textContent), s = 0;
if (tx.indexOf("شناسه دستگاه") >= 0) s += 180;
if (tx.indexOf("نام دستگاه") >= 0) s += 180;
if (tx.indexOf("مدل دستگاه") >= 0) s += 80;
if (/delete|حذف/.test(tx)) s += 110;
s += Math.min(t.rows.length, 10) * 3;
if (s > bs) { bs = s; best = t; }
});
return bs >= 90 ? best : null;
}
function ctl(row, kind) {
var re = kind === "delete" ? /^(delete|حذف)$/ : /^(edit|ویرایش)$/;
var els = $$("a,button,input[type=button],input[type=submit]", row);
for (var i = 0; i < els.length; i++) {
var el = els[i], t = norm(el.tagName === "INPUT" ? el.value : el.textContent);
if (re.test(t) || (el.className + " " + (el.title || "")).toLowerCase().indexOf(kind) >= 0) return el;
}
return null;
}
function entryId(el, row) {
var raw = "";
[el, row].forEach(function (n) {
if (n && n.getAttribute) raw += " " + (n.getAttribute("href") || "") + " " + (n.getAttribute("onclick") || "") + " " + (n.outerHTML || "");
});
try { raw = decodeURIComponent(raw); } catch (e) {}
var m = raw.match(/entry[-_]?id\s*[=:]\s*["']?([\w-]+)/i) || raw.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
return m ? (m[1] || m[0]) : "";
}
function deleteEntry(id, srcRow, rowEl) {
if (!id) { toast("شناسه رکورد ConfiForms پیدا نشد."); return; }
if (!confirm("این رکورد حذف شود؟")) return;
var x = new XMLHttpRequest();
x.open("DELETE", "/rest/confiforms/1.0/deleteById/" + encodeURIComponent(PAGE_ID) + "/mediqNewAsset/" + encodeURIComponent(id) + "?skipIFTTTExecute=true", true);
x.setRequestHeader("Accept", "application/json"); x.setRequestHeader("X-Atlassian-Token", "no-check");
x.onreadystatechange = function () {
if (x.readyState !== 4) return;
if (x.status >= 200 && x.status < 300) {
[srcRow, rowEl].forEach(function (r) { if (r && r.parentNode) r.parentNode.removeChild(r); });
toast("رکورد حذف شد.");
} else toast(x.status === 401 || x.status === 403 ? "اجازه حذف این رکورد را ندارید." : "حذف انجام نشد. کد خطا: " + x.status);
};
x.send(null);
}
function loadTable(host, mode, tries) {
if (!host) return;
var t = findTable();
if (!t) {
if (tries < 12) { setTimeout(function () { loadTable(host, mode, tries + 1); }, 250); return; }
host.innerHTML = '<div class="mq-msg">خروجی لیست ConfiForms روی صفحه پیدا نشد.</div>'; return;
}
var c = t.cloneNode(true);
$$("input:not([type=button]):not([type=submit]),select,textarea", c).forEach(function (x) { x.remove(); });
var drop = mode === "list" ? "edit" : "delete", keep = mode === "list" ? "delete" : "edit";
for (var i = 0; i < c.rows.length; i++) {
var cr = c.rows[i], sr = t.rows[i];
var d = ctl(cr, drop); if (d) d.remove();
var b = ctl(cr, keep); if (!b) continue;
var sb = sr ? ctl(sr, keep) : null;
if (!sb) { b.style.display = "none"; continue; }
b.textContent = keep === "delete" ? "حذف" : "ویرایش";
b.className = keep === "delete" ? "mq-del" : "mq-edit"; b.setAttribute("href", "#");
(function (btn, src, srow, crow) {
btn.onclick = function (e) {
e.preventDefault(); e.stopPropagation();
if (keep === "delete") deleteEntry(entryId(src, srow), srow, crow);
else { store("mqReturn", "editAsset"); try { src.click(); } catch (er) { toast("فرم ویرایش ConfiForms باز نشد."); } }
return false;
};
})(b, sb, sr, cr);
}
host.innerHTML = ""; host.appendChild(c);
var s = $("#mqSearch");
if (s) s.oninput = function () {
var q = norm(this.value);
for (var r = 1; r < c.rows.length; r++) c.rows[r].style.display = (!q || norm(c.rows[r].textContent).indexOf(q) >= 0) ? "" : "none";
};
}
/* ================= ConfiForms panel plumbing ================= */
var FORMS = {
classification: { n: "mediqNewClassification", btn: "ثبت گروه جدید" },
equipmentTitle: { n: "mediqNewEquipmentTitle", btn: "ثبت عنوان دستگاه جدید" },
model: { n: "mediqNewModel", btn: "ثبت مدل جدید" },
asset: { n: "mediqNewAsset", btn: "ثبت دارایی جدید" } /* caption of the real Registration Control */
};
/* name = ConfiForms field name; al = aliases; lb = label fallbacks (used only if name/aliases fail) */
var FIELDS = {
classificationName: { lb: ["نام گروه", "name"] },
classificationParent: { al: ["parent"], lb: ["گروه والد", "parent"] },
equipmentTitleName: { lb: ["عنوان دستگاه", "name"] },
equipmentTitleGroup: { al: ["group", "titleGroup"], lb: ["گروه", "group"] },
modelName: { lb: ["سری دستگاه", "سری"] },
deviceTitle: { lb: ["عنوان دستگاه", "device title", "equipment title"] },
manufacturer: { lb: ["شرکت سازنده", "manufacturer"] },
nature: { lb: ["ماهیت"] }, modelType: { lb: ["نوع", "type"] }, modelGroup: { lb: ["گروه", "group"] },
modelFunction: { lb: ["کارکرد", "function"] }, criticality: { lb: ["سطح اهمیت", "criticality"] },
technology: { lb: ["فناوری", "technology"] }, powerRequirement: { lb: ["برق"] },
waterRequirement: { lb: ["آب"] }, gasRequirement: { lb: ["گاز"] },
deviceModel: { lb: ["مدل دستگاه", "model"] }
};
var LABELS = {
classificationName: "نام گروه", classificationParent: "گروه والد", equipmentTitleName: "عنوان دستگاه", equipmentTitleGroup: "گروه",
modelName: "سری دستگاه", deviceTitle: "عنوان دستگاه", manufacturer: "شرکت سازنده", nature: "ماهیت دستگاه", modelType: "نوع", modelGroup: "گروه",
modelFunction: "کارکرد", criticality: "سطح اهمیت", technology: "فناوری", powerRequirement: "برق مصرفی", waterRequirement: "آب مصرفی", gasRequirement: "گاز مصرفی",
deviceModel: "مدل دستگاه", deviceId: "شناسه دستگاه", deviceName: "نام دستگاه", serialNumber: "شماره سریال", assetNumber: "شماره اموال",
purchaseDate: "تاریخ خرید", supplier: "فروشنده", purchaseValueIRR: "ارزش ریالی خرید", purchaseValueUSD: "ارزش دلاری خرید", manufactureDate: "تاریخ تولید",
expiryDate: "تاریخ انقضا", department: "بخش بهرهبردار", operatingRoom: "موقعیت مکانی فعلی", businessUnit: "محل کاربری", responsibleUnit: "مسئول بهرهبرداری",
receiver: "تحویلگیرنده", accessories: "متعلقات", status: "وضعیت", accessStatus: "وضعیت دسترسی", statusReason: "علت وضعیت فعلی", usageMode: "نحوه مصرف",
fallRisk: "آیا با خرابی این جزء دستگاه ترکیبی ساقط میشود؟", combinedFunction: "عملکرد در مجموعههای ترکیبی", aggregateValue: "ارزش تجمیعی", priority: "اولویت",
emergency: "اورژانسی", portable: "قابل حمل", transportability: "قابلیت حمل", clinicalUser: "کاربر کلینیکال", entryDateTime: "زمان ورود", exitDateTime: "زمان خروج",
inStore: "در انبار", storeLocation: "محل انبار", financialCenter: "مرکز مالی"
};
var ASSET_SECTIONS = [
["مشخصات اصلی", ["deviceModel", "deviceId", "deviceName", "serialNumber", "assetNumber"]],
["خرید و اطلاعات مالی", ["purchaseDate", "supplier", "purchaseValueIRR", "purchaseValueUSD", "manufactureDate", "expiryDate"]],
["موقعیت و مسئولیت", ["department", "operatingRoom", "businessUnit", "responsibleUnit", "receiver", "accessories"]],
["وضعیت و بهرهبرداری", ["status", "accessStatus", "statusReason", "usageMode", "fallRisk", "combinedFunction", "aggregateValue", "priority", "emergency", "portable", "transportability", "clinicalUser", "entryDateTime", "exitDateTime", "inStore", "storeLocation", "financialCenter"]]
];
var ASSET_SYSTEM = ["assetObjectId", "devicePageId"];
function findPanel(key) {
var n = FORMS[key].n;
var p = $(".confiFormsFormBorder.cf_" + n);
if (p) return p;
var ms = $$('input[name="confiform_form_name"],input#confiform_form_name,input[name="registrationFormName"],input[name="formName"]');
for (var i = 0; i < ms.length; i++) {
if (String(ms[i].value).trim() === n) return ms[i].closest(".confiFormsFormBorder") || ms[i].closest("form");
}
return null;
}
function findControl(cap) {
var want = norm(cap), hit = null, part = null;
$$('button,a,input[type=button],input[type=submit],[role=button]').forEach(function (el) {
if (el.closest("#mediq-dashboard,.mq-active,#mqWizBack")) return;
var t = norm(el.tagName === "INPUT" ? el.value : el.textContent);
if (t === want) { if (!hit) hit = el; }
else if (!part && t.indexOf(want) >= 0 && t.length < want.length + 12) part = el;
});
return hit || part;
}
function ensure(key, ok, fail) {
var p = findPanel(key);
if (p) { ok(p); return; }
var c = findControl(FORMS[key].btn);
if (!c) { fail("Registration Control فرم «" + FORMS[key].n + "» روی صفحه پیدا نشد."); return; }
c.click();
wait(function () { return findPanel(key); }, ok, function () { fail("ConfiForms فرم «" + FORMS[key].n + "» را نساخت."); });
}
var formOf = function (p) { return p && (p.querySelector("form.aui-confiforms") || p.querySelector("form")); };
function rowOf(el) { return el.closest("tr") || el.closest(".field-group,.control-group") || el.parentElement; }
function findField(p, name) {
var f = formOf(p); if (!f) return null;
var def = FIELDS[name] || {}, names = [name].concat(def.al || []), el = null, i;
for (i = 0; i < names.length && !el; i++) {
var n = names[i];
el = f.querySelector('[name="' + n + '"],[name="' + n + '[]"],[id="' + n + '"],[data-field-name="' + n + '"],[id$="_' + n + '"]');
}
if (!el && def.lb) {
var rows = $$("tr", f), pass, r;
for (pass = 0; pass < 2 && !el; pass++) {
for (r = 0; r < rows.length && !el; r++) {
var lab = $("label", rows[r]) || rows[r].cells && rows[r].cells[0];
var tx = norm(lab && lab.textContent);
if (!tx) continue;
for (i = 0; i < def.lb.length; i++) {
var w = norm(def.lb[i]);
if (pass === 0 ? tx === w : tx.indexOf(w) >= 0) { el = $("input[name],select[name],textarea[name]", rows[r]); break; }
}
}
}
}
return el;
}
function setLabel(p, name) {
var t = LABELS[name], f = findField(p, name); if (!t || !f) return;
var row = rowOf(f), id = f.getAttribute("id");
var lab = (id && $('label[for="' + id + '"]', formOf(p))) || $("label", row);
if (!lab || lab.getAttribute("data-mq") === t) return;
var req = $(".aui-iconfont-required,.required,.cf_required", lab);
lab.textContent = t + (req ? " " : "");
if (req) lab.appendChild(req);
lab.setAttribute("data-mq", t);
}
function showOnly(p, names) {
var f = formOf(p), keep = [], miss = [];
if (!f) return names;
names.forEach(function (n) { var e = findField(p, n); if (e) keep.push(rowOf(e)); else miss.push(n); });
$$("tr", f).forEach(function (tr) {
var k = keep.some(function (r) { return r === tr || tr.contains(r) || r.contains(tr); });
tr.classList.toggle("mq-hide", !k);
});
return miss;
}
function diag(p, miss) {
var f = formOf(p), old = $(".mq-wiz-diag", p); if (old) old.remove();
var seen = {}, list = [];
$$("input[name],select[name],textarea[name]", f).forEach(function (c) {
if (!seen[c.name] && c.type !== "submit" && c.type !== "button") { seen[c.name] = 1; list.push(c.name); }
});
var d = D.createElement("div"); d.className = "mq-wiz-diag mq-wiz-ui";
d.innerHTML = "فیلد " + miss.map(function (m) { return "<code>" + m + "</code>"; }).join(" ") + " در این فرم پیدا نشد. فیلدهای موجود در فرم:<br>" +
list.map(function (n) { return "<code>" + n + "</code>"; }).join(" ") + "<br>اسم فیلدهای فرم را با این لیست یکی کنید (یا در FIELDS داخل کد اصلاح کنید).";
f.parentNode.insertBefore(d, f);
}
function clearControls(p, keep) {
var f = formOf(p), j = J(); if (!f) return;
$$("input[name],select[name],textarea[name]", f).forEach(function (c) {
if (keep && keep.indexOf(c.name) >= 0) return;
var t = (c.type || "").toLowerCase();
if (t === "submit" || t === "button") return;
try {
if (j && j(c).data("select2")) j(c).select2("val", "");
else if (t === "hidden") return;
else if (t === "checkbox" || t === "radio") c.checked = false;
else c.value = "";
} catch (e) {}
});
}
function closeDrops() {
var j = J();
if (j) $$(".mq-active select,.mq-active input").forEach(function (el) { try { if (j(el).data("select2")) j(el).select2("close"); } catch (e) {} });
$$(".select2-drop-mask").forEach(function (m) { m.style.display = "none"; });
if (dropObs) dropObs.disconnect();
}
/* ================= Assets (Insight) data helpers ================= */
function getData(field) {
var j = J(); if (!j || !field) return null;
try { var d = j(field).select2("data"); if (d && d.length && !d.objectKey && !d.attributes) d = d[0]; return d || null; } catch (e) { return null; }
}
function findAttr(data, id) {
var seen = [], want = String(id);
function walk(o, depth) {
if (!o || typeof o !== "object" || depth > 6 || o.nodeType || o.jquery || seen.indexOf(o) >= 0) return null;
seen.push(o);
var a = o.attributes;
if (a && typeof a.length === "number") {
for (var i = 0; i < a.length; i++) {
var x = a[i]; if (!x) continue;
var aid = x.objectTypeAttributeId != null ? x.objectTypeAttributeId : (x.objectTypeAttribute && x.objectTypeAttribute.id);
if (aid != null && String(aid) === want) return x;
}
}
var ks = ["raw", "object", "insightObject", "item", "data", "value", "result"];
for (var k = 0; k < ks.length; k++) { var r = walk(o[ks[k]], depth + 1); if (r) return r; }
return null;
}
return walk(data, 0);
}
function attrVals(data, id) {
var a = findAttr(data, id); if (!a) return null;
var v = a.objectAttributeValues || a.values || [];
return (v && typeof v.length === "number") ? v : [v];
}
function attrText(data, id) {
var v = attrVals(data, id) || [];
for (var i = 0; i < v.length; i++) {
var x = v[i]; if (x == null) continue;
var s = typeof x === "object" ? (x.displayValue != null ? x.displayValue : (x.value != null ? x.value : x.label)) : x;
if (s != null && String(s).trim()) return String(s).trim();
}
return "";
}
function attrRefs(data, id) { /* null = unknown -> do not filter */
var v = attrVals(data, id); if (!v) return null;
var out = [];
function push(x) { if (x == null) return; var s = String(x).trim(); if (s && out.indexOf(s) < 0) out.push(s); }
v.forEach(function (x) {
if (x == null) return;
if (typeof x !== "object") { push(x); return; }
var r = x.referencedObject || x.object;
if (r) { push(r.id); push(r.objectId); push(r.objectKey); push(r.key); push(r.label); }
push(x.id); push(x.objectId); push(x.objectKey); push(x.key); push(x.value); push(x.displayValue); push(x.label);
});
return out;
}
function ident(d, f) {
d = d || {};
return {
key: String(d.objectKey != null ? d.objectKey : (d.key != null ? d.key : (f && f.value) || "")).trim(),
id: String(d.objectId != null ? d.objectId : (d.id != null ? d.id : "")).trim(),
label: String(d.label != null ? d.label : (d.text != null ? d.text : (d.name || ""))).trim()
};
}
function refMatch(refs, sel) {
if (refs === null || !sel) return true;
var ts = [sel.key, sel.id, sel.label].filter(Boolean).map(norm);
if (!ts.length) return true;
return refs.some(function (r) {
r = norm(r);
return r && ts.some(function (t) { return r === t || r.indexOf(t) >= 0 || t.indexOf(r) >= 0; });
});
}
var CLS = { equipmentTitleGroup: 1, classificationParent: 1, modelGroup: 1 }; /* classification pickers show Persian Name (attr 6683) */
function persian(d, fallback, f) {
var p = attrText(d, 6683); if (!p) return fallback;
var id = ident(d, f); return id.key ? id.key + " - " + p : p;
}
function fixChosen(p, name) {
if (!CLS[name]) return;
var f = findField(p, name); if (!f) return;
var d = getData(f); if (!d) return;
var ch = $(".select2-chosen,.select2-selection__rendered", rowOf(f)); if (!ch) return;
var t = persian(d, ch.textContent, f);
if (t && ch.textContent !== t) ch.textContent = t;
}
/* ================= wizard state ================= */
var W = { open: false, step: 1, mode: "sel", panel: null, key: "", apply: null, rerun: null, init: {}, pending: "", sel: { group: null, title: null, model: null } };
var STEP = [null,
{ form: "equipmentTitle", field: "equipmentTitleGroup", title: "انتخاب گروه", label: "گروه", create: "classification", plus: "گروه", sub: "گروه را انتخاب کنید و «مرحله بعد» را بزنید. اگر گروه وجود ندارد، با دکمه + ثبتش کنید." },
{ form: "model", field: "deviceTitle", title: "انتخاب عنوان دستگاه", label: "عنوان دستگاه", create: "equipmentTitle", plus: "عنوان دستگاه", sub: "فقط عنوانهای گروه انتخابشده نمایش داده میشود." },
{ form: "asset", field: "deviceModel", title: "انتخاب مدل", label: "مدل", create: "model", plus: "مدل", sub: "فقط مدلهای عنوان دستگاه انتخابشده نمایش داده میشود." }
];
var MODEL_FIELDS = ["modelName", "deviceTitle", "manufacturer", "nature", "modelType", "modelGroup", "modelFunction", "criticality", "technology", "powerRequirement", "waterRequirement", "gasRequirement"];
var CREATE = {
classification: { step: 1, back: 1, title: "ثبت گروه جدید", sub: "نام گروه و (در صورت نیاز) گروه والد را وارد کنید.", fields: ["classificationName", "classificationParent"], keep: [], pend: "classificationName" },
equipmentTitle: { step: 2, back: 2, title: "ثبت عنوان دستگاه جدید", sub: "عنوان دستگاه را وارد کنید؛ گروه از مرحله قبل حفظ میشود.", fields: ["equipmentTitleName", "equipmentTitleGroup"], keep: ["equipmentTitleGroup"], pend: "equipmentTitleName" },
model: { step: 3, back: 3, title: "ثبت مدل جدید", sub: "عنوان دستگاه حفظ میشود. عنوان مدل بهصورت خودکار ساخته میشود.", fields: MODEL_FIELDS, keep: ["deviceTitle"], pend: "modelName" }
};
/* ---- single scoped observer (panel subtree + its parent for full redraws) ---- */
var panelObs = null, obsTimer = null;
function observe(p) {
if (panelObs) panelObs.disconnect();
panelObs = new MutationObserver(function () {
clearTimeout(obsTimer);
obsTimer = setTimeout(repair, 60);
});
attachObs(p);
}
function attachObs(p) {
if (!panelObs || !p) return;
panelObs.observe(p, { childList: true, subtree: true });
if (p.parentNode) panelObs.observe(p.parentNode, { childList: true });
}
function repair() {
if (!W.open || !W.panel) return;
var live = W.key && findPanel(W.key);
if (live && live !== W.panel) { if (W.rerun) W.rerun(); return; } /* ConfiForms replaced the whole panel */
if (!W.apply) return;
panelObs.disconnect();
try { W.apply(); } finally { attachObs(W.panel); }
}
function clearUi(p) {
$$(".mq-wiz-ui", p).forEach(function (n) { n.remove(); });
$$(".mq-hide,.mq-sec-row", p).forEach(function (n) { if (n.classList.contains("mq-sec-row")) n.remove(); else n.classList.remove("mq-hide"); });
p.classList.remove("mq-sel", "mq-create", "mq-asset");
}
function deactivate(p) {
if (!p) return;
closeDrops(); clearUi(p); p.classList.remove("mq-active");
}
function activate(p, mode, key, rerun) {
if (W.panel && W.panel !== p) deactivate(W.panel);
clearUi(p); closeDrops();
p.classList.add("mq-active", "mq-" + mode);
W.panel = p; W.key = key; W.rerun = rerun;
document.body.classList.add("mq-wiz-ready");
observe(p);
p.scrollTop = 0;
}
function head(p, step, title, sub) {
var old = $(".mq-wiz-head", p); if (old) old.remove();
var labels = ["گروه", "عنوان دستگاه", "مدل", "دستگاه"], st = "";
for (var i = 1; i <= 4; i++) st += '<div class="mq-wiz-step' + (i < step ? " done" : i === step ? " active" : "") + '"><b>' + i + "</b><span>" + labels[i - 1] + "</span></div>";
var h = D.createElement("div"); h.className = "mq-wiz-head mq-wiz-ui";
h.innerHTML = '<div class="mq-wiz-top"><div><div class="mq-wiz-title">' + title + '</div><div class="mq-wiz-sub">' + (sub || "") + '</div></div><button type="button" class="mq-wiz-close" aria-label="بستن">×</button></div><div class="mq-wiz-steps">' + st + "</div>";
p.insertBefore(h, p.firstChild);
$(".mq-wiz-close", h).onclick = function (e) { e.preventDefault(); e.stopPropagation(); closeWizard(true); };
}
function footerSel(p, c, n) {
var f = D.createElement("div"); f.className = "mq-wiz-foot mq-wiz-ui";
f.innerHTML = '<div><button type="button" class="mq-wiz-b p" data-a="plus">+ ثبت ' + c.plus + ' جدید</button></div><div>' +
(n > 1 ? '<button type="button" class="mq-wiz-b" data-a="back">مرحله قبل</button>' : "") + '<button type="button" class="mq-wiz-b p" data-a="next">مرحله بعد</button></div>';
p.appendChild(f);
f.onclick = function (e) {
var b = e.target.closest("button"); if (!b) return;
e.preventDefault(); e.stopPropagation();
var a = b.getAttribute("data-a");
if (a === "plus") showCreate(c.create);
else if (a === "back") showStep(n - 1);
else if (a === "next") {
var fld = findField(p, c.field);
if (!fld || !String(fld.value || "").trim()) { toast("ابتدا «" + c.label + "» را انتخاب کنید."); return; }
remember(c.field, fld);
showStep(n + 1);
}
};
}
function footerBack(p, step) {
var b = D.createElement("div"); b.className = "mq-wiz-back mq-wiz-ui";
b.innerHTML = '<button type="button" class="mq-wiz-b">بازگشت بدون ثبت</button>';
p.appendChild(b);
$("button", b).onclick = function (e) { e.preventDefault(); showStep(step); };
}
function remember(name, field) {
var d = getData(field), id = ident(d, field), s = W.sel;
if (!id.key && !id.id && !id.label) return;
if (name === "equipmentTitleGroup") {
var chg = s.group && s.group.key && id.key && s.group.key !== id.key;
s.group = id;
if (chg) { s.title = null; s.model = null; clearField("model", "deviceTitle"); clearField("asset", "deviceModel"); }
} else if (name === "deviceTitle") {
var chg2 = s.title && s.title.key && id.key && s.title.key !== id.key;
s.title = id;
if (chg2) { s.model = null; clearField("asset", "deviceModel"); }
} else if (name === "deviceModel") s.model = id;
}
function clearField(key, name) {
var p = findPanel(key), f = p && findField(p, name), j = J();
if (!f) return;
try { if (j && j(f).data("select2")) j(f).select2("val", ""); else f.value = ""; } catch (e) {}
}
/* ---- steps ---- */
function fail(msg) { toast(msg); }
function showStep(n) {
if (!W.open) return;
W.step = n; W.mode = "sel";
if (n === 4) return showAsset();
var c = STEP[n];
ensure(c.form, function (p) {
if (!W.init[c.form]) { clearControls(p); W.init[c.form] = 1; }
activate(p, "sel", c.form, function () { showStep(n); });
W.apply = function () {
var miss = showOnly(p, [c.field]);
var old = $(".mq-wiz-diag", p); if (old) old.remove();
if (miss.length) { diag(p, miss); return; }
setLabel(p, c.field);
fixChosen(p, c.field);
};
W.apply();
head(p, n, c.title, c.sub);
footerSel(p, c, n);
}, fail);
}
function showCreate(key) {
var cfg = CREATE[key];
W.mode = "create-" + key;
ensure(key === "model" ? "model" : key, function (p) {
activate(p, "create", key, function () { showCreate(key); });
clearControls(p, cfg.keep);
W.apply = function () {
var miss = showOnly(p, cfg.fields);
var old = $(".mq-wiz-diag", p); if (old) old.remove();
if (miss.length === cfg.fields.length) { diag(p, miss); return; }
cfg.fields.forEach(function (n) { setLabel(p, n); });
};
W.apply();
head(p, cfg.step, cfg.title, cfg.sub);
footerBack(p, cfg.back);
}, fail);
}
function showAsset() {
W.mode = "asset";
ensure("asset", function (p) {
if (!W.init.asset) { clearControls(p); W.init.asset = 1; }
activate(p, "asset", "asset", function () { showAsset(); });
W.apply = function () {
var f = formOf(p); if (!f) return;
$$("tr", f).forEach(function (r) { r.classList.remove("mq-hide"); });
$$(".mq-sec-row", f).forEach(function (r) { r.remove(); });
ASSET_SYSTEM.forEach(function (n) { var e = findField(p, n); if (e) rowOf(e).classList.add("mq-hide"); });
Object.keys(LABELS).forEach(function (n) { setLabel(p, n); });
ASSET_SECTIONS.forEach(function (s) {
for (var i = 0; i < s[1].length; i++) {
var e = findField(p, s[1][i]), r = e && rowOf(e);
if (r && r.tagName === "TR" && r.parentNode) {
var tr = D.createElement("tr"); tr.className = "mq-sec-row";
tr.innerHTML = '<td colspan="99"><div>' + s[0] + "</div></td>";
r.parentNode.insertBefore(tr, r); break;
}
}
});
["deviceId", "deviceName"].forEach(function (n) {
var e = findField(p, n);
if (e && e.tagName === "INPUT" && !e.placeholder) e.placeholder = LABELS[n] + " را وارد کنید";
});
fixChosen(p, "deviceModel");
};
W.apply();
head(p, 4, "ثبت دستگاه", "مدل انتخاب شده است؛ اطلاعات نهایی دستگاه را تکمیل و ثبت کنید.");
footerBack(p, 3);
}, fail);
}
/* ---- open / close ---- */
function openWizard() {
if (W.open) return;
W.open = true; W.step = 1; W.mode = "sel"; W.panel = null; W.init = {}; W.pending = "";
W.sel = { group: null, title: null, model: null };
$("#mqWizBack").classList.add("open");
document.body.classList.remove("mq-wiz-ready");
/* create all four ConfiForms panels in parallel once, so steps switch instantly */
Object.keys(FORMS).forEach(function (k) {
if (findPanel(k)) return;
var c = findControl(FORMS[k].btn); if (c) c.click();
});
wait(function () { return Object.keys(FORMS).every(function (k) { return findPanel(k); }); },
function () { showStep(1); }, function () { showStep(1); }, 50);
}
function closeWizard(reset) {
if (!W.open && !$("#mqWizBack.open")) return;
closeDrops();
if (panelObs) panelObs.disconnect();
Object.keys(FORMS).forEach(function (k) {
var p = findPanel(k); if (!p) return;
deactivate(p);
if (reset) clearControls(p);
});
$("#mqWizBack").classList.remove("open");
document.body.classList.remove("mq-wiz-ready");
W.open = false; W.panel = null; W.apply = null; W.rerun = null;
}
D.addEventListener("keydown", function (e) {
if (e.key !== "Escape" || !W.open) return;
if ($(".select2-drop-active")) return; /* let Select2 close its own list first */
e.preventDefault(); e.stopPropagation(); closeWizard(true);
}, true);
/* ================= Select2: ONE handler (no re-positioning, no re-parenting) ================= */
var dropObs = null, SELECT_FIELDS = ["equipmentTitleGroup", "classificationParent", "deviceTitle", "deviceModel", "manufacturer", "modelType", "modelGroup"];
function nameOf(field) {
if (W.panel) for (var i = 0; i < SELECT_FIELDS.length; i++) if (findField(W.panel, SELECT_FIELDS[i]) === field) return SELECT_FIELDS[i];
return field.name || "";
}
function dropOf(field) {
var j = J(), s = j && j(field).data("select2");
return (s && s.dropdown && s.dropdown[0]) || $(".select2-drop-active");
}
function decorate(drop, name, field) {
var j = J();
$$(".select2-results li", drop).forEach(function (li) {
var d = j && j(li).data("select2-data"); if (!d) return;
var lab = $(".select2-result-label", li) || li;
if (li.getAttribute("data-mq-o") === null) li.setAttribute("data-mq-o", lab.textContent);
if (CLS[name]) { var t = persian(d, li.getAttribute("data-mq-o"), field); if (t && lab.textContent !== t) lab.textContent = t; }
var keep = true;
if (name === "deviceTitle" && W.sel.group) keep = refMatch(attrRefs(d, 6668), W.sel.group);
if (name === "deviceModel" && W.sel.title) keep = refMatch(attrRefs(d, 6626), W.sel.title);
li.style.display = keep ? "" : "none";
});
}
function watchDrop(field) {
var name = nameOf(field), drop = dropOf(field);
if (!drop) return;
if (dropObs) dropObs.disconnect();
var t = null;
var run = function () {
dropObs.disconnect();
try { decorate(drop, name, field); } finally { dropObs.observe(drop, { childList: true, subtree: true }); }
};
dropObs = new MutationObserver(function () { clearTimeout(t); t = setTimeout(run, 30); });
run();
}
(function bindSelect2() {
var j = J(); if (!j) return;
var sel = ".mq-active select,.mq-active input";
j(D).off(".mq")
.on("select2-open.mq", sel, function () { var f = this; setTimeout(function () { watchDrop(f); }, 0); })
.on("select2-close.mq", sel, function () { if (dropObs) dropObs.disconnect(); })
.on("select2-selected.mq change.mq", sel, function () {
var f = this, name = nameOf(f);
if (SELECT_FIELDS.indexOf(name) < 0 || !String(f.value || "").trim()) return;
setTimeout(function () { remember(name, f); fixChosen(W.panel, name); }, 30); /* manual navigation: never auto-advance */
});
})();
/* select a freshly created record in its picker (search by the name the user typed) */
function autoSelect(p, name, text, onFail) {
var want = norm(text), f = p && findField(p, name), j = J(), attempts = 0;
if (!want || !f || !j) { onFail(); return; }
(function attempt() {
attempts++;
try { j(f).select2("open"); } catch (e) {}
setTimeout(function () {
var drop = dropOf(f);
if (!drop) { retry(); return; }
var s = $(".select2-search input,input.select2-input", drop);
if (s) { s.value = text; try { s.dispatchEvent(new Event("input", { bubbles: true })); s.dispatchEvent(new KeyboardEvent("keyup", { bubbles: true, key: "a" })); } catch (e) {} }
var polls = 0;
(function find() {
polls++;
var items = $$(".select2-results li", drop);
for (var i = 0; i < items.length; i++) {
if (items[i].style.display === "none") continue;
var d = j(items[i]).data("select2-data"); if (!d) continue;
var tx = [items[i].textContent, d.label, d.text, d.name, d.objectKey, attrText(d, 6683)].map(norm);
if (tx.some(function (t) { return t && (t === want || t.indexOf(want) >= 0 || want.indexOf(t) >= 0); })) {
j(items[i]).trigger("mouseup");
setTimeout(function () {
if (String(f.value || "").trim()) { remember(name, f); fixChosen(p, name); }
else retry();
}, 180);
return;
}
}
if (polls < 8) setTimeout(find, 180);
else { try { j(f).select2("close"); } catch (e) {} retry(); }
})();
}, 200);
function retry() { if (attempts < 6) setTimeout(attempt, 350); else onFail(); }
})();
}
/* ================= submit handling ================= */
function capturePending() {
if (!W.open || !W.panel) return;
var m = W.mode.match(/^create-(.+)$/); if (!m) return;
var f = findField(W.panel, CREATE[m[1]].pend);
W.pending = f ? String(f.value || "").trim() : "";
}
D.addEventListener("submit", capturePending, true);
D.addEventListener("click", function (e) {
if (!W.open || !e.target.closest) return;
var p = $(".mq-active");
if (p && p.contains(e.target) && e.target.closest('button[type=submit],input[type=submit],.save-cf-btn,.aui-button-primary')) capturePending();
}, true);
(function bindSubmitFinished() {
var prev = window.onCFSubmitFinished;
window.onCFSubmitFinished = function (formName) {
if (W.open) {
var nextStep = { mediqNewClassification: 1, mediqNewEquipmentTitle: 2, mediqNewModel: 3 }[formName];
if (nextStep) {
var txt = W.pending; W.pending = "";
var msg = { mediqNewClassification: "گروه", mediqNewEquipmentTitle: "عنوان دستگاه", mediqNewModel: "مدل" }[formName];
toast(msg + " با موفقیت ثبت شد.");
showStep(nextStep);
var c = STEP[nextStep];
setTimeout(function () {
var p = findPanel(c.form);
if (p && txt) autoSelect(p, c.field, txt, function () { toast(msg + " ثبت شد؛ آن را از لیست انتخاب کنید."); });
}, 450);
return;
}
if (formName === "mediqNewAsset") {
store("mqResume", "newAsset-purchased");
closeWizard(true);
toast("دستگاه با موفقیت ثبت شد.");
setTimeout(function () { location.reload(); }, 450);
return;
}
}
if (formName === "mediqNewAsset") { /* native edit dialog finished */
store("mqResume", store("mqReturn") || "newAsset-purchased"); store("mqReturn", "");
setTimeout(function () { location.reload(); }, 450);
return;
}
if (typeof prev === "function") return prev.apply(this, arguments);
};
})();
/* ================= user / logout / init ================= */
(function () {
var user = ""; try { user = (window.AJS && AJS.Meta && AJS.Meta.get("remote-user")) || ""; } catch (e) {}
$("#mqWelcomeUser").textContent = user || "کاربر مدیکیو";
$("#mqEditPage").href = "/pages/editpage.action?pageId=" + encodeURIComponent(PAGE_ID);
try {
var x = new XMLHttpRequest();
x.open("GET", "/rest/api/user/current", true); x.setRequestHeader("Accept", "application/json");
x.onreadystatechange = function () {
if (x.readyState !== 4 || x.status < 200 || x.status >= 300) return;
try { var u = JSON.parse(x.responseText || "{}"); if (u.displayName) $("#mqWelcomeUser").textContent = u.displayName; } catch (e) {}
};
x.send();
} catch (e) {}
$("#mqLogout").onclick = function () { location.href = "/logout.action"; };
})();
buildTree(TREE, [], $("#mqTree"));
var resume = store("mqResume"); store("mqResume", "");
if (resume === "editAsset") go("editAsset");
else if (resume === "newAsset-purchased") go("newAsset-purchased");
else go("equipment");
})();
</script>
</div>
<!-- ============================================================
MEDIQ V44 - PERSIAN (JALALI) PURCHASE DATE PICKER
Visual Persian date, Gregorian MMM dd, yyyy stored for ConfiForms
============================================================ -->
<style id="mq-v44-jalali-datepicker-style">
/* Hide the original ConfiForms purchaseDate control only after our Jalali proxy is ready. */
#mqCfBody .mq-jalali-real-date,
.confiFormsFormBorder.cf_mediqNewAsset .mq-jalali-real-date {
position: absolute !important;
width: 1px !important;
height: 1px !important;
min-width: 1px !important;
min-height: 1px !important;
opacity: 0 !important;
pointer-events: none !important;
padding: 0 !important;
margin: 0 !important;
border: 0 !important;
overflow: hidden !important;
}
.mq-jalali-shell {
position: relative !important;
display: flex !important;
align-items: center !important;
gap: 8px !important;
width: 100% !important;
direction: rtl !important;
}
.mq-jalali-input {
width: 100% !important;
min-height: 42px !important;
padding: 8px 44px 8px 13px !important;
background: #fff !important;
border: 1px solid #d7e5eb !important;
border-radius: 12px !important;
box-shadow: 0 2px 8px rgba(7,53,83,.035) !important;
color: #3d4954 !important;
font-family: inherit !important;
font-size: 13px !important;
direction: rtl !important;
text-align: right !important;
cursor: pointer !important;
outline: none !important;
}
.mq-jalali-input:focus {
border-color: #646f7b !important;
box-shadow: 0 0 0 3px rgba(87,96,106,.10) !important;
}
.mq-jalali-calendar-btn {
position: absolute !important;
left: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
width: 30px !important;
height: 30px !important;
border: 0 !important;
border-radius: 9px !important;
background: #f1f2f3 !important;
color: #444b52 !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
cursor: pointer !important;
font-size: 16px !important;
line-height: 1 !important;
padding: 0 !important;
box-shadow: none !important;
}
.mq-jalali-calendar-btn:hover {
background: #e6e8e9 !important;
}
#mqJalaliPicker {
position: fixed !important;
z-index: 2147483646 !important;
width: 326px !important;
background: #fff !important;
border: 1px solid #d7e5eb !important;
border-radius: 16px !important;
box-shadow: 0 22px 60px rgba(3,35,55,.25) !important;
padding: 12px !important;
direction: rtl !important;
font-family: inherit !important;
color: #3d4954 !important;
}
#mqJalaliPicker[hidden] { display: none !important; }
#mqJalaliPicker .mq-jp-head {
display: grid !important;
grid-template-columns: 38px 1fr 38px !important;
align-items: center !important;
gap: 8px !important;
margin-bottom: 10px !important;
}
#mqJalaliPicker .mq-jp-title {
text-align: center !important;
font-size: 14px !important;
font-weight: 900 !important;
color: #34414d !important;
}
#mqJalaliPicker .mq-jp-nav {
width: 38px !important;
height: 34px !important;
border: 1px solid #d7e5eb !important;
border-radius: 10px !important;
background: #f9fafa !important;
color: #3d444a !important;
cursor: pointer !important;
font-size: 18px !important;
font-weight: 900 !important;
padding: 0 !important;
}
#mqJalaliPicker .mq-jp-week,
#mqJalaliPicker .mq-jp-days {
display: grid !important;
grid-template-columns: repeat(7, 1fr) !important;
gap: 4px !important;
}
#mqJalaliPicker .mq-jp-week {
margin-bottom: 4px !important;
}
#mqJalaliPicker .mq-jp-week span {
min-height: 28px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
color: #6b8596 !important;
font-size: 11px !important;
font-weight: 800 !important;
}
#mqJalaliPicker .mq-jp-day,
#mqJalaliPicker .mq-jp-empty {
height: 34px !important;
border-radius: 9px !important;
}
#mqJalaliPicker .mq-jp-day {
border: 0 !important;
background: transparent !important;
color: #3d4954 !important;
cursor: pointer !important;
font-family: inherit !important;
font-size: 12px !important;
font-weight: 800 !important;
padding: 0 !important;
}
#mqJalaliPicker .mq-jp-day:hover {
background: #f1f2f3 !important;
color: #444b52 !important;
}
#mqJalaliPicker .mq-jp-day.today {
box-shadow: inset 0 0 0 1px #646f7b !important;
}
#mqJalaliPicker .mq-jp-day.selected {
background: linear-gradient(135deg,#57606a 0%,#4a525a 100%) !important;
color: #fff !important;
box-shadow: 0 5px 12px rgba(87,96,106,.18) !important;
}
#mqJalaliPicker .mq-jp-foot {
display: flex !important;
justify-content: space-between !important;
gap: 8px !important;
margin-top: 9px !important;
padding-top: 9px !important;
border-top: 1px solid #edf3f5 !important;
}
#mqJalaliPicker .mq-jp-foot button {
border: 0 !important;
border-radius: 9px !important;
min-height: 32px !important;
padding: 0 11px !important;
background: #f2f7f9 !important;
color: #47677d !important;
cursor: pointer !important;
font-family: inherit !important;
font-size: 11px !important;
font-weight: 800 !important;
}
#mqJalaliPicker .mq-jp-foot button.primary {
background: #f1f2f3 !important;
color: #444b52 !important;
}
/* Disable/hide the native AUI calendar trigger beside purchaseDate after Jalali UI is mounted. */
.mq-jalali-host .aui-iconfont-calendar,
.mq-jalali-host [class*="calendar-icon"],
.mq-jalali-host [aria-label*="calendar" i],
.mq-jalali-host [title*="calendar" i],
.mq-jalali-host [aria-label*="date" i][role="button"],
.mq-jalali-host [title*="date" i][role="button"] {
display: none !important;
}
/* The asset list must never display any calendar implementation. */
#mediq-dashboard .mq-assets-host #mqJalaliPicker,
#mediq-dashboard .mq-assets-host .mq-jalali-shell,
#mediq-dashboard .mq-assets-host .ui-datepicker,
#mediq-dashboard .mq-assets-host .aui-datepicker,
#mediq-dashboard .mq-assets-host .aui-datepicker-dialog,
#mediq-dashboard .mq-assets-host [class*="calendar"] {
display: none !important;
}
</style>
<script id="mq-v44-jalali-datepicker-script">
(function () {
'use strict';
var MONTHS_FA = [
'فروردین','اردیبهشت','خرداد','تیر','مرداد','شهریور',
'مهر','آبان','آذر','دی','بهمن','اسفند'
];
var WEEK_FA = ['ش','ی','د','س','چ','پ','ج'];
var G_MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function div(a, b) { return Math.trunc(a / b); }
function mod(a, b) { return a - Math.trunc(a / b) * b; }
function jalCal(jy, withoutLeap) {
var breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210,
1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178];
var bl = breaks.length;
var gy = jy + 621;
var leapJ = -14;
var jp = breaks[0];
var jm, jump, leap, leapG, march, n, i;
if (jy < jp || jy >= breaks[bl - 1]) throw new Error('Invalid Jalaali year ' + jy);
for (i = 1; i < bl; i += 1) {
jm = breaks[i];
jump = jm - jp;
if (jy < jm) break;
leapJ = leapJ + div(jump, 33) * 8 + div(mod(jump, 33), 4);
jp = jm;
}
n = jy - jp;
leapJ = leapJ + div(n, 33) * 8 + div(mod(n, 33) + 3, 4);
if (mod(jump, 33) === 4 && jump - n === 4) leapJ += 1;
leapG = div(gy, 4) - div((div(gy, 100) + 1) * 3, 4) - 150;
march = 20 + leapJ - leapG;
if (withoutLeap) return { gy: gy, march: march };
if (jump - n < 6) n = n - jump + div(jump + 4, 33) * 33;
leap = mod(mod(n + 1, 33) - 1, 4);
if (leap === -1) leap = 4;
return { leap: leap, gy: gy, march: march };
}
function g2d(gy, gm, gd) {
var d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4)
+ div(153 * mod(gm + 9, 12) + 2, 5)
+ gd - 34840408;
d = d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752;
return d;
}
function d2g(jdn) {
var j = 4 * jdn + 139361631;
j = j + div(div(4 * jdn + 183187720, 146097) * 3, 4) * 4 - 3908;
var i = div(mod(j, 1461), 4) * 5 + 308;
var gd = div(mod(i, 153), 5) + 1;
var gm = mod(div(i, 153), 12) + 1;
var gy = div(j, 1461) - 100100 + div(8 - gm, 6);
return { gy: gy, gm: gm, gd: gd };
}
function j2d(jy, jm, jd) {
var r = jalCal(jy, true);
return g2d(r.gy, 3, r.march) + (jm - 1) * 31 - div(jm, 7) * (jm - 7) + jd - 1;
}
function d2j(jdn) {
var g = d2g(jdn);
var jy = g.gy - 621;
var r = jalCal(jy, false);
var jdn1f = g2d(g.gy, 3, r.march);
var k = jdn - jdn1f;
if (k >= 0) {
if (k <= 185) return { jy: jy, jm: 1 + div(k, 31), jd: mod(k, 31) + 1 };
k -= 186;
} else {
jy -= 1;
k += 179;
if (r.leap === 1) k += 1;
}
return { jy: jy, jm: 7 + div(k, 30), jd: mod(k, 30) + 1 };
}
function toGregorian(jy, jm, jd) { return d2g(j2d(jy, jm, jd)); }
function toJalaali(gy, gm, gd) { return d2j(g2d(gy, gm, gd)); }
function isLeapJalaaliYear(jy) { return jalCal(jy, false).leap === 0; }
function jalaaliMonthLength(jy, jm) {
if (jm <= 6) return 31;
if (jm <= 11) return 30;
return isLeapJalaaliYear(jy) ? 30 : 29;
}
function faDigits(value) {
return String(value).replace(/\d/g, function (d) { return '۰۱۲۳۴۵۶۷۸۹'[Number(d)]; });
}
function enDigits(value) {
return String(value || '')
.replace(/[۰-۹]/g, function (d) { return '۰۱۲۳۴۵۶۷۸۹'.indexOf(d); })
.replace(/[٠-٩]/g, function (d) { return '٠١٢٣٤٥٦٧٨٩'.indexOf(d); });
}
function pad2(n) { return n < 10 ? '0' + n : String(n); }
function formatJalali(j) {
return faDigits(j.jy + '/' + pad2(j.jm) + '/' + pad2(j.jd));
}
function formatGregorianForConfiForms(g) {
return G_MONTHS[g.gm - 1] + ' ' + pad2(g.gd) + ', ' + g.gy;
}
function parseGregorian(value) {
value = enDigits(value).trim();
if (!value) return null;
var m = value.match(/^([A-Za-z]{3})\s+(\d{1,2}),\s*(\d{4})$/);
if (m) {
var gm = G_MONTHS.map(function (x) { return x.toLowerCase(); }).indexOf(m[1].toLowerCase()) + 1;
if (gm > 0) return { gy: Number(m[3]), gm: gm, gd: Number(m[2]) };
}
m = value.match(/^(\d{4})[-\/]([01]?\d)[-\/]([0-3]?\d)$/);
if (m && Number(m[1]) > 1700) {
return { gy: Number(m[1]), gm: Number(m[2]), gd: Number(m[3]) };
}
var d = new Date(value);
if (!isNaN(d.getTime())) {
return { gy: d.getFullYear(), gm: d.getMonth() + 1, gd: d.getDate() };
}
return null;
}
function parseJalali(value) {
value = enDigits(value).trim();
var m = value.match(/^(1[2-5]\d{2})[-\/]([01]?\d)[-\/]([0-3]?\d)$/);
if (!m) return null;
var j = { jy: Number(m[1]), jm: Number(m[2]), jd: Number(m[3]) };
if (j.jm < 1 || j.jm > 12 || j.jd < 1 || j.jd > jalaaliMonthLength(j.jy, j.jm)) return null;
return j;
}
var picker = null;
var active = null;
var viewJ = null;
function ensurePicker() {
if (picker) return picker;
picker = document.createElement('div');
picker.id = 'mqJalaliPicker';
picker.hidden = true;
picker.innerHTML =
'<div class="mq-jp-head">' +
'<button type="button" class="mq-jp-nav mq-jp-next" aria-label="ماه بعد">‹</button>' +
'<div class="mq-jp-title"></div>' +
'<button type="button" class="mq-jp-nav mq-jp-prev" aria-label="ماه قبل">›</button>' +
'</div>' +
'<div class="mq-jp-week">' + WEEK_FA.map(function (d) { return '<span>' + d + '</span>'; }).join('') + '</div>' +
'<div class="mq-jp-days"></div>' +
'<div class="mq-jp-foot">' +
'<button type="button" class="mq-jp-clear">پاک کردن</button>' +
'<button type="button" class="mq-jp-today primary">امروز</button>' +
'</div>';
document.body.appendChild(picker);
picker.querySelector('.mq-jp-prev').onclick = function () { changeMonth(-1); };
picker.querySelector('.mq-jp-next').onclick = function () { changeMonth(1); };
picker.querySelector('.mq-jp-today').onclick = function () {
var now = new Date();
selectJalali(toJalaali(now.getFullYear(), now.getMonth() + 1, now.getDate()));
};
picker.querySelector('.mq-jp-clear').onclick = function () {
if (!active) return;
setRealDate(active.real, '');
active.proxy.value = '';
closePicker();
};
return picker;
}
function changeMonth(delta) {
if (!viewJ) return;
var jy = viewJ.jy;
var jm = viewJ.jm + delta;
if (jm < 1) { jm = 12; jy -= 1; }
if (jm > 12) { jm = 1; jy += 1; }
viewJ = { jy: jy, jm: jm, jd: 1 };
renderPicker();
}
function selectedJalali() {
if (!active || !active.real.value) return null;
var g = parseGregorian(active.real.value);
if (g) return toJalaali(g.gy, g.gm, g.gd);
var j = parseJalali(active.real.value);
return j || null;
}
function renderPicker() {
ensurePicker();
var title = picker.querySelector('.mq-jp-title');
var daysHost = picker.querySelector('.mq-jp-days');
title.textContent = MONTHS_FA[viewJ.jm - 1] + ' ' + faDigits(viewJ.jy);
var firstG = toGregorian(viewJ.jy, viewJ.jm, 1);
var firstDate = new Date(firstG.gy, firstG.gm - 1, firstG.gd);
var offset = (firstDate.getDay() + 1) % 7; // Saturday = 0
var len = jalaaliMonthLength(viewJ.jy, viewJ.jm);
var now = new Date();
var todayJ = toJalaali(now.getFullYear(), now.getMonth() + 1, now.getDate());
var selected = selectedJalali();
var html = '';
for (var i = 0; i < offset; i++) html += '<span class="mq-jp-empty"></span>';
for (var d = 1; d <= len; d++) {
var cls = 'mq-jp-day';
if (todayJ.jy === viewJ.jy && todayJ.jm === viewJ.jm && todayJ.jd === d) cls += ' today';
if (selected && selected.jy === viewJ.jy && selected.jm === viewJ.jm && selected.jd === d) cls += ' selected';
html += '<button type="button" class="' + cls + '" data-day="' + d + '">' + faDigits(d) + '</button>';
}
daysHost.innerHTML = html;
var buttons = daysHost.querySelectorAll('.mq-jp-day');
for (var b = 0; b < buttons.length; b++) {
buttons[b].onclick = function () {
selectJalali({ jy: viewJ.jy, jm: viewJ.jm, jd: Number(this.getAttribute('data-day')) });
};
}
}
function setRealDate(real, value) {
real.value = value;
real.setAttribute('value', value);
try { real.dispatchEvent(new Event('input', { bubbles: true })); } catch (e) {}
try { real.dispatchEvent(new Event('change', { bubbles: true })); } catch (e) {}
try { real.dispatchEvent(new Event('blur', { bubbles: true })); } catch (e) {}
try {
if (window.AJS && AJS.$) {
AJS.$(real).val(value).trigger('input').trigger('change');
}
} catch (e) {}
}
function selectJalali(j) {
if (!active) return;
var g = toGregorian(j.jy, j.jm, j.jd);
setRealDate(active.real, formatGregorianForConfiForms(g));
active.proxy.value = formatJalali(j);
closePicker();
}
function positionPicker() {
if (!active || !picker || picker.hidden) return;
var r = active.proxy.getBoundingClientRect();
var width = 326;
var left = Math.max(10, Math.min(window.innerWidth - width - 10, r.right - width));
var top = r.bottom + 8;
var h = picker.offsetHeight || 355;
if (top + h > window.innerHeight - 10) top = Math.max(10, r.top - h - 8);
picker.style.left = left + 'px';
picker.style.top = top + 'px';
}
function openPicker(item) {
active = item;
ensurePicker();
var selected = selectedJalali();
if (selected) {
viewJ = { jy: selected.jy, jm: selected.jm, jd: 1 };
} else {
var now = new Date();
var j = toJalaali(now.getFullYear(), now.getMonth() + 1, now.getDate());
viewJ = { jy: j.jy, jm: j.jm, jd: 1 };
}
renderPicker();
picker.hidden = false;
positionPicker();
}
function closePicker() {
if (picker) picker.hidden = true;
active = null;
}
function hideNativeDateTrigger(host, real, shell) {
var nodes = host.querySelectorAll('*');
for (var i = 0; i < nodes.length; i++) {
var el = nodes[i];
if (el === real || el === shell || shell.contains(el)) continue;
var marker = ((el.id || '') + ' ' + (el.className || '') + ' ' + (el.getAttribute('title') || '') + ' ' + (el.getAttribute('aria-label') || '')).toLowerCase();
if (marker.indexOf('calendar') >= 0 || marker.indexOf('datepicker') >= 0 || marker.indexOf('date-picker') >= 0) {
el.style.display = 'none';
}
}
}
function syncExistingValue(real, proxy) {
var j = parseJalali(real.value);
if (j) {
var g = toGregorian(j.jy, j.jm, j.jd);
setRealDate(real, formatGregorianForConfiForms(g));
proxy.value = formatJalali(j);
return;
}
var g2 = parseGregorian(real.value);
if (g2) {
proxy.value = formatJalali(toJalaali(g2.gy, g2.gm, g2.gd));
}
}
function initRealInput(real) {
if (!real || real.getAttribute('data-mq-jalali-ready') === '1') return;
real.setAttribute('data-mq-jalali-ready', '1');
var host = real.parentElement;
if (!host) return;
host.classList.add('mq-jalali-host');
var shell = document.createElement('div');
shell.className = 'mq-jalali-shell';
var proxy = document.createElement('input');
proxy.type = 'text';
proxy.className = 'mq-jalali-input';
proxy.placeholder = 'تاریخ شمسی را انتخاب کنید';
proxy.readOnly = true;
proxy.autocomplete = 'off';
proxy.setAttribute('aria-label', 'تاریخ خرید شمسی');
var button = document.createElement('button');
button.type = 'button';
button.className = 'mq-jalali-calendar-btn';
button.setAttribute('aria-label', 'باز کردن تقویم شمسی');
button.innerHTML = '📅';
shell.appendChild(proxy);
shell.appendChild(button);
host.insertBefore(shell, real);
real.classList.add('mq-jalali-real-date');
hideNativeDateTrigger(host, real, shell);
syncExistingValue(real, proxy);
var item = { real: real, proxy: proxy, shell: shell };
proxy.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); openPicker(item); });
button.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); openPicker(item); });
proxy.addEventListener('focus', function () { openPicker(item); });
}
function scan() {
var roots = [document.getElementById('mqCfBody')];
var assetForms = document.querySelectorAll('.confiFormsFormBorder.cf_mediqNewAsset');
for (var x = 0; x < assetForms.length; x++) roots.push(assetForms[x]);
for (var r = 0; r < roots.length; r++) {
if (!roots[r]) continue;
var inputs = roots[r].querySelectorAll('input[name="purchaseDate"], input[id*="purchaseDate"], input[data-field-name="purchaseDate"]');
for (var i = 0; i < inputs.length; i++) initRealInput(inputs[i]);
}
}
document.addEventListener('click', function (e) {
if (picker && !picker.hidden && active) {
if (!picker.contains(e.target) && !active.shell.contains(e.target)) closePicker();
}
var text = ((e.target && (e.target.textContent || e.target.value)) || '').replace(/\s+/g, ' ').trim();
if (text.indexOf('ثبت دارایی جدید') >= 0) {
window.setTimeout(scan, 40);
window.setTimeout(scan, 150);
window.setTimeout(scan, 400);
}
}, true);
window.addEventListener('resize', positionPicker);
window.addEventListener('scroll', function () { if (picker && !picker.hidden) positionPicker(); }, true);
var scanT; var observer = new MutationObserver(function () { clearTimeout(scanT); scanT = setTimeout(scan, 250); });
if (document.body) observer.observe(document.body, { childList: true, subtree: true });
window.mqInitJalaliPurchaseDate = scan;
window.setTimeout(scan, 100);
window.setTimeout(scan, 600);
})();
</script>
|