전체 학생 허용 시 장시간(1시간 59분 이상) 요청은 자동 제외
기존엔 전체 승인이 장시간 요청도 구분 없이 다 승인해버렸음. 이제 1시간 59분 넘는 요청은 자동으로 빼고 대기중 상태로 남겨서, "많은 시간요청 학생" 목록에서 따로 검토 후 개별 승인/거절하게 함. 확인 다이얼로그에도 몇 건이 승인되고 몇 건이 제외되는지 미리 보여줌. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,24 +96,37 @@ class DeviceCheckoutLedgerController extends ChangeNotifier {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🙌 [전체 학생 허용] 대상이 될 요청 id 목록 (대기 중이면서 장시간 요청은 아닌 것만).
|
||||||
|
/// 확인 다이얼로그에서 몇 건이 승인되고 몇 건이 제외되는지 미리 보여주는 데 쓴다.
|
||||||
|
List<int> get autoApprovableIds => _requests
|
||||||
|
.where((r) => r['status'] == 'PENDING' && !isLongRequest(r))
|
||||||
|
.map<int>((r) => r['id'] as int)
|
||||||
|
.toList();
|
||||||
|
|
||||||
// 🙌 [전체 학생 허용] 대기 중인 요청을 한 명씩 누르기 귀찮을 때, 한 번에 전부 승인한다.
|
// 🙌 [전체 학생 허용] 대기 중인 요청을 한 명씩 누르기 귀찮을 때, 한 번에 전부 승인한다.
|
||||||
// 서버에 일괄 승인 API가 따로 없어서, 대기 중인 요청마다 승인 요청을 순서대로 보낸다.
|
// 단, 1시간 59분 넘는 장시간 요청은 자동으로 제외하고 대기중 상태로 남겨서,
|
||||||
|
// "많은 시간요청 학생" 목록에서 따로 검토/승인하게 한다.
|
||||||
|
// 서버에 일괄 승인 API가 따로 없어서, 대상 요청마다 승인 요청을 순서대로 보낸다.
|
||||||
Future<(bool success, String message)> approveAllPending({
|
Future<(bool success, String message)> approveAllPending({
|
||||||
required String teacherId,
|
required String teacherId,
|
||||||
required String teacherName,
|
required String teacherName,
|
||||||
}) async {
|
}) async {
|
||||||
final pendingIds = _requests
|
final targetIds = autoApprovableIds;
|
||||||
.where((r) => r['status'] == 'PENDING')
|
final excludedCount = longPendingRequests.length;
|
||||||
.map<int>((r) => r['id'] as int)
|
|
||||||
.toList();
|
if (targetIds.isEmpty) {
|
||||||
if (pendingIds.isEmpty) {
|
return (
|
||||||
return (true, '승인 대기 중인 요청이 없습니다.');
|
true,
|
||||||
|
excludedCount > 0
|
||||||
|
? '장시간 요청 $excludedCount건을 제외하면 승인할 대기 요청이 없습니다.'
|
||||||
|
: '승인 대기 중인 요청이 없습니다.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_isWorking = true;
|
_isWorking = true;
|
||||||
_safeNotify();
|
_safeNotify();
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
for (final id in pendingIds) {
|
for (final id in targetIds) {
|
||||||
try {
|
try {
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
Uri.parse('$baseUrl/api/device-checkout/approve'),
|
Uri.parse('$baseUrl/api/device-checkout/approve'),
|
||||||
@@ -136,10 +149,13 @@ class DeviceCheckoutLedgerController extends ChangeNotifier {
|
|||||||
_isWorking = false;
|
_isWorking = false;
|
||||||
_safeNotify();
|
_safeNotify();
|
||||||
|
|
||||||
final allOk = successCount == pendingIds.length;
|
final allOk = successCount == targetIds.length;
|
||||||
|
final excludedNote = excludedCount > 0
|
||||||
|
? ' (장시간 요청 $excludedCount건은 제외 - 대기중으로 남음)'
|
||||||
|
: '';
|
||||||
return (
|
return (
|
||||||
allOk,
|
allOk,
|
||||||
'${pendingIds.length}건 중 $successCount건 승인 완료${allOk ? '' : ' (일부 실패)'}',
|
'${targetIds.length}건 중 $successCount건 승인 완료${allOk ? '' : ' (일부 실패)'}$excludedNote',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 🙌 [전체 학생 허용] 한 명씩 누르기 귀찮을 때, 대기 중인 요청을 한 번에 전부 승인한다.
|
// 🙌 [전체 학생 허용] 한 명씩 누르기 귀찮을 때, 대기 중인 요청을 한 번에 전부 승인한다.
|
||||||
|
// 1시간 59분 넘는 장시간 요청은 자동으로 제외되어 대기중으로 남는다 - 따로 검토가 필요해서.
|
||||||
void _showApproveAllConfirmDialog() {
|
void _showApproveAllConfirmDialog() {
|
||||||
final pendingCount = _controller.requests
|
final pendingCount = _controller.requests
|
||||||
.where((r) => r['status'] == 'PENDING')
|
.where((r) => r['status'] == 'PENDING')
|
||||||
@@ -58,11 +59,18 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
|
|||||||
AppNotice.show(context, '승인 대기 중인 요청이 없습니다.');
|
AppNotice.show(context, '승인 대기 중인 요청이 없습니다.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final approvableCount = _controller.autoApprovableIds.length;
|
||||||
|
final excludedCount = pendingCount - approvableCount;
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (dialogContext) => AlertDialog(
|
builder: (dialogContext) => AlertDialog(
|
||||||
title: const Text('전체 학생 허용'),
|
title: const Text('전체 학생 허용'),
|
||||||
content: Text('대기 중인 요청 $pendingCount건을 한 번에 전부 승인하시겠습니까?'),
|
content: Text(
|
||||||
|
excludedCount > 0
|
||||||
|
? '대기 중인 요청 $pendingCount건 중 $approvableCount건을 승인합니다.\n'
|
||||||
|
'장시간(1시간 59분 이상) 요청 $excludedCount건은 제외되어 "많은 시간요청 학생"에서 따로 확인해야 합니다.'
|
||||||
|
: '대기 중인 요청 $pendingCount건을 한 번에 전부 승인하시겠습니까?',
|
||||||
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(dialogContext),
|
onPressed: () => Navigator.pop(dialogContext),
|
||||||
|
|||||||
Reference in New Issue
Block a user