release 1.3
This commit is contained in:
@@ -86,8 +86,10 @@ async def update(reqData: dict = Depends(requestDict)):
|
|||||||
).replace(hour=12, minute=0, second=0)
|
).replace(hour=12, minute=0, second=0)
|
||||||
if "attorney" in updatePractitioner and updatePractitioner["attorney"] != "":
|
if "attorney" in updatePractitioner and updatePractitioner["attorney"] != "":
|
||||||
logger.info("🔐 МЧД получена")
|
logger.info("🔐 МЧД получена")
|
||||||
|
updatePractitioner["esiaAuth"] = False
|
||||||
if "signature" in updatePractitioner:
|
if "signature" in updatePractitioner:
|
||||||
logger.info("🔐 УКЭП получен")
|
logger.info("🔐 УКЭП получен")
|
||||||
|
updatePractitioner["esiaAuth"] = True
|
||||||
fileData = updatePractitioner.pop("signature")
|
fileData = updatePractitioner.pop("signature")
|
||||||
fileInfo = p7s_save(fileData, updatePractitioner["userIdLpu"])
|
fileInfo = p7s_save(fileData, updatePractitioner["userIdLpu"])
|
||||||
if fileInfo.success:
|
if fileInfo.success:
|
||||||
|
|||||||
@@ -353,6 +353,7 @@ function updateStaffTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let rows = '';
|
let rows = '';
|
||||||
|
const showDisabled = document.getElementById('showDisabled').checked;
|
||||||
|
|
||||||
filteredPractitioners.forEach(practitioner => {
|
filteredPractitioners.forEach(practitioner => {
|
||||||
// Проверяем, что practitioner - объект
|
// Проверяем, что practitioner - объект
|
||||||
@@ -361,6 +362,10 @@ function updateStaffTable() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDisabled = practitioner.expired_at === null;
|
||||||
|
|
||||||
|
if (!showDisabled && isDisabled) return;
|
||||||
|
|
||||||
// Определяем тип подписи
|
// Определяем тип подписи
|
||||||
let signatureTypeHtml;
|
let signatureTypeHtml;
|
||||||
if (practitioner.esiaAuth) {
|
if (practitioner.esiaAuth) {
|
||||||
@@ -382,8 +387,9 @@ function updateStaffTable() {
|
|||||||
onclick="showAttorneyPopup('${snils}', this)">
|
onclick="showAttorneyPopup('${snils}', this)">
|
||||||
<i class="bi bi-eye"></i>
|
<i class="bi bi-eye"></i>
|
||||||
</button>`;
|
</button>`;
|
||||||
signatureTypeHtml = `<span class="badge bg-warning text-dark">МЧД</span>${eyeIcon}
|
mchdBadge = `<span class="badge bg-warning text-dark">МЧД</span>${eyeIcon}`;
|
||||||
<span class="badge bg-info">СНИЛС</span>${snilsIcon}`;
|
slilsBadge = `<span class="badge bg-info">СНИЛС</span>${snilsIcon}`;
|
||||||
|
signatureTypeHtml = isDisabled ? slilsBadge : `${mchdBadge} ${slilsBadge}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Форматируем дату и проверяем срок
|
// Форматируем дату и проверяем срок
|
||||||
@@ -417,25 +423,40 @@ function updateStaffTable() {
|
|||||||
} else {
|
} else {
|
||||||
expiryHtml = `
|
expiryHtml = `
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
<span class="text-muted">Не установлен</span>
|
<span class="text-muted">Без права подписи</span>
|
||||||
<span class="badge bg-secondary ms-2">-</span>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Кнопки действий
|
// Кнопки действий
|
||||||
const actionsHtml = `
|
let actionsHtml = '';
|
||||||
|
if (isDisabled) {
|
||||||
|
actionsHtml = `
|
||||||
|
<div class="btn-group btn-group-sm" role="group">
|
||||||
|
<button type="button" class="btn btn-outline-success"
|
||||||
|
onclick="editPractitioner('${practitioner.userIdLpu}', true)" title="Добавить УКЭП">
|
||||||
|
<i class="bi bi-filetype-key"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
onclick="editPractitioner('${practitioner.userIdLpu}', false)" title="Добавить МЧД">
|
||||||
|
<i class="bi bi-file-earmark-binary"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
actionsHtml = `
|
||||||
<div class="btn-group btn-group-sm" role="group">
|
<div class="btn-group btn-group-sm" role="group">
|
||||||
<button type="button" class="btn btn-outline-primary"
|
<button type="button" class="btn btn-outline-primary"
|
||||||
onclick="editPractitioner('${practitioner.userIdLpu}', ${practitioner.esiaAuth})" title="Изменить">
|
onclick="editPractitioner('${practitioner.userIdLpu}', ${practitioner.esiaAuth})" title="Изменить">
|
||||||
<i class="bi bi-pencil"></i>
|
<i class="bi bi-pencil"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-outline-danger"
|
<button type="button" class="btn btn-outline-danger"
|
||||||
onclick="confirmDelete('${practitioner.userIdLpu}')" title="Удалить">
|
onclick="confirmDelete('${practitioner.userIdLpu}')" title="Отключить">
|
||||||
<i class="bi bi-trash"></i>
|
<i class="bi bi-person-fill-slash"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
rows += `
|
rows += `
|
||||||
<tr>
|
<tr>
|
||||||
@@ -642,6 +663,7 @@ function editPractitioner(userIdLpu, isEsiaAuth) {
|
|||||||
document.getElementById('ukepPractitionerId').value = userIdLpu;
|
document.getElementById('ukepPractitionerId').value = userIdLpu;
|
||||||
document.getElementById('ukepFile').required = false;
|
document.getElementById('ukepFile').required = false;
|
||||||
document.getElementById('ukepSnilsNumber').value = practitioner.snils;
|
document.getElementById('ukepSnilsNumber').value = practitioner.snils;
|
||||||
|
document.getElementById('ukepExpiryDate').value = practitioner.expired_at || '';
|
||||||
|
|
||||||
// Очищаем data-атрибуты модального окна
|
// Очищаем data-атрибуты модального окна
|
||||||
const modal = document.getElementById('editUKEPModal');
|
const modal = document.getElementById('editUKEPModal');
|
||||||
@@ -663,6 +685,7 @@ function editPractitioner(userIdLpu, isEsiaAuth) {
|
|||||||
document.getElementById('mchdPractitionerId').value = userIdLpu;
|
document.getElementById('mchdPractitionerId').value = userIdLpu;
|
||||||
document.getElementById('mchdNumber').value = practitioner.attorney || '';
|
document.getElementById('mchdNumber').value = practitioner.attorney || '';
|
||||||
document.getElementById('mchdSnilsNumber').value = practitioner.snils;
|
document.getElementById('mchdSnilsNumber').value = practitioner.snils;
|
||||||
|
document.getElementById('mchdExpiryDate').value = practitioner.expired_at || '';
|
||||||
|
|
||||||
// Очищаем data-атрибуты модального окна
|
// Очищаем data-атрибуты модального окна
|
||||||
const modal = document.getElementById('editMCHDModal');
|
const modal = document.getElementById('editMCHDModal');
|
||||||
@@ -1093,6 +1116,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
// Обработчики попапа с номером МЧД
|
// Обработчики попапа с номером МЧД
|
||||||
document.getElementById('closeAttorneyPopupBtn').addEventListener('click', hideAttorneyPopup);
|
document.getElementById('closeAttorneyPopupBtn').addEventListener('click', hideAttorneyPopup);
|
||||||
document.getElementById('closeAttorneyBtn').addEventListener('click', hideAttorneyPopup);
|
document.getElementById('closeAttorneyBtn').addEventListener('click', hideAttorneyPopup);
|
||||||
|
document.getElementById('showDisabled').addEventListener('click', updateStaffTable);
|
||||||
|
|
||||||
document.getElementById('copyAttorneyBtn').addEventListener('click', function () {
|
document.getElementById('copyAttorneyBtn').addEventListener('click', function () {
|
||||||
const attorneyNumber = document.getElementById('attorneyNumber').textContent;
|
const attorneyNumber = document.getElementById('attorneyNumber').textContent;
|
||||||
|
|||||||
@@ -88,10 +88,16 @@
|
|||||||
|
|
||||||
<!-- Кнопка добавления -->
|
<!-- Кнопка добавления -->
|
||||||
<div class="text-end mt-3">
|
<div class="text-end mt-3">
|
||||||
|
<div class="d-flex align-items-center justify-content-end">
|
||||||
|
<div class="form-check d-flex align-items-center me-2">
|
||||||
|
<input type="checkbox" class="form-check-input" id="showDisabled">
|
||||||
|
<label class="form-check-label ms-1" for="showDisabled">Отображать сотрудников без права подписи</label>
|
||||||
|
</div>
|
||||||
<button type="button" id="addStaffBtn" class="btn btn-primary">
|
<button type="button" id="addStaffBtn" class="btn btn-primary">
|
||||||
<i class="bi bi-plus-circle"></i> Добавить сотрудника
|
<i class="bi bi-plus-circle"></i> Добавить сотрудника
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Модальное окно для добавления сотрудника -->
|
<!-- Модальное окно для добавления сотрудника -->
|
||||||
@@ -211,22 +217,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Модальное окно подтверждения удаления -->
|
<!-- Модальное окно подтверждения отключения -->
|
||||||
<div class="modal fade" id="confirmDeleteModal" tabindex="-1">
|
<div class="modal fade" id="confirmDeleteModal" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Подтверждение удаления</h5>
|
<h5 class="modal-title">Подтверждение отключения</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>Вы уверены, что хотите удалить данные сотрудника?</p>
|
<p>Вы уверены, что хотите отключить данного сотрудника?</p>
|
||||||
<p class="text-danger fw-bold">Это действие нельзя отменить.</p>
|
<p class="text-danger fw-bold">Этот сотрудник не сможет отправлять запросы</p>
|
||||||
<input type="hidden" id="deletePractitionerId">
|
<input type="hidden" id="deletePractitionerId">
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||||||
<button type="button" class="btn btn-danger" id="confirmDeleteBtn">Удалить</button>
|
<button type="button" class="btn btn-danger" id="confirmDeleteBtn">Отключить</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ class Practitioner(Base):
|
|||||||
userIdLpu = Column(String, unique=True)
|
userIdLpu = Column(String, unique=True)
|
||||||
name = Column(String)
|
name = Column(String)
|
||||||
fullName = Column(String)
|
fullName = Column(String)
|
||||||
esiaAuth = Column(Boolean)
|
esiaAuth = Column(Boolean, nullable=True)
|
||||||
attorney = Column(String, nullable=True)
|
attorney = Column(String, nullable=True)
|
||||||
snils = Column(String)
|
snils = Column(String)
|
||||||
expired_at = Column(DateTime)
|
expired_at = Column(DateTime, nullable=True)
|
||||||
created_at = Column(DateTime, default=datetime.now)
|
created_at = Column(DateTime, default=datetime.now)
|
||||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||||
|
|
||||||
@@ -35,7 +35,8 @@ class Practitioner(Base):
|
|||||||
return await CRUD.update(Practitioner, self.id, **kwargs)
|
return await CRUD.update(Practitioner, self.id, **kwargs)
|
||||||
|
|
||||||
async def delete(self) -> bool:
|
async def delete(self) -> bool:
|
||||||
return await CRUD.delete(self)
|
clear = {"esiaAuth": None, "attorney": None, "expired_at": None}
|
||||||
|
return await CRUD.update(Practitioner, self.id, **clear)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def addPractitioner(**kwargs):
|
async def addPractitioner(**kwargs):
|
||||||
@@ -79,13 +80,22 @@ class Practitioner(Base):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def getPractitionerByIdLpu(
|
async def getPractitionerByIdLpu(
|
||||||
idLpu: str, toDict: bool = True, isCheck: bool = False
|
idLpu: str,
|
||||||
|
toDict: bool = True,
|
||||||
|
isCheck: bool = False,
|
||||||
|
include_disabled: bool = False,
|
||||||
):
|
):
|
||||||
if type(idLpu) != str:
|
if type(idLpu) != str:
|
||||||
idLpu = str(idLpu)
|
idLpu = str(idLpu)
|
||||||
practitioner = await CRUD.read(
|
query = (
|
||||||
select(Practitioner).where(Practitioner.userIdLpu == idLpu)
|
select(Practitioner).where(
|
||||||
|
Practitioner.userIdLpu == idLpu, Practitioner.expired_at != None
|
||||||
)
|
)
|
||||||
|
if not include_disabled
|
||||||
|
else select(Practitioner).where(Practitioner.userIdLpu == idLpu)
|
||||||
|
)
|
||||||
|
|
||||||
|
practitioner = await CRUD.read(query)
|
||||||
if practitioner:
|
if practitioner:
|
||||||
data = practitioner.toDict() if toDict else practitioner
|
data = practitioner.toDict() if toDict else practitioner
|
||||||
return utils.answer(data=data)
|
return utils.answer(data=data)
|
||||||
@@ -96,7 +106,9 @@ class Practitioner(Base):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def editPractitionerByIdLpu(idLpu: str, **kwargs):
|
async def editPractitionerByIdLpu(idLpu: str, **kwargs):
|
||||||
practitioner = await Practitioner.getPractitionerByIdLpu(idLpu, False)
|
practitioner = await Practitioner.getPractitionerByIdLpu(
|
||||||
|
idLpu, False, include_disabled=True
|
||||||
|
)
|
||||||
if not practitioner.success:
|
if not practitioner.success:
|
||||||
utils.logger.error(f"Сотрудник не найден, idLpu: {idLpu}")
|
utils.logger.error(f"Сотрудник не найден, idLpu: {idLpu}")
|
||||||
return utils.answer(success=False, message="Сотрудник не найден")
|
return utils.answer(success=False, message="Сотрудник не найден")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from .async_request import *
|
|||||||
from .logger import *
|
from .logger import *
|
||||||
from .attachment import *
|
from .attachment import *
|
||||||
from .request_parser import RequestParser
|
from .request_parser import RequestParser
|
||||||
from .pdf_saver import *
|
|
||||||
from .to_dict import *
|
from .to_dict import *
|
||||||
from .web import *
|
from .web import *
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user