222 lines
7.8 KiB
Dart
222 lines
7.8 KiB
Dart
import 'dart:io';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:environment_monitoring_app/services/base_api_service.dart';
|
|
import 'package:environment_monitoring_app/services/telegram_service.dart';
|
|
import 'package:environment_monitoring_app/services/settings_service.dart';
|
|
import 'package:environment_monitoring_app/models/in_situ_sampling_data.dart';
|
|
import 'package:environment_monitoring_app/models/tarball_data.dart';
|
|
|
|
class MarineApiService {
|
|
final BaseApiService _baseService = BaseApiService();
|
|
final TelegramService _telegramService = TelegramService();
|
|
final SettingsService _settingsService = SettingsService();
|
|
|
|
Future<Map<String, dynamic>> getTarballStations() {
|
|
return _baseService.get('marine/tarball/stations');
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getManualStations() {
|
|
return _baseService.get('marine/manual/stations');
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getTarballClassifications() {
|
|
return _baseService.get('marine/tarball/classifications');
|
|
}
|
|
|
|
Future<Map<String, dynamic>> submitTarballSample({
|
|
required Map<String, String> formData,
|
|
required Map<String, File?> imageFiles,
|
|
}) async {
|
|
debugPrint("Step 1: Submitting tarball form data to the server...");
|
|
final dataResult = await _baseService.post('marine/tarball/sample', formData);
|
|
|
|
if (dataResult['success'] != true) {
|
|
return {
|
|
'status': 'L1',
|
|
'success': false,
|
|
'message': 'Failed to submit data to server: ${dataResult['message']}',
|
|
'reportId': null,
|
|
};
|
|
}
|
|
debugPrint("Step 1 successful. Tarball data submitted.");
|
|
|
|
final recordId = dataResult['data']?['autoid'];
|
|
if (recordId == null) {
|
|
return {
|
|
'status': 'L2',
|
|
'success': false,
|
|
'message': 'Data submitted, but failed to get a record ID to link images.',
|
|
'reportId': null,
|
|
};
|
|
}
|
|
|
|
final filesToUpload = <String, File>{};
|
|
imageFiles.forEach((key, value) {
|
|
if (value != null) filesToUpload[key] = value;
|
|
});
|
|
|
|
if (filesToUpload.isEmpty) {
|
|
_handleTarballSuccessAlert(formData, isDataOnly: true);
|
|
return {
|
|
'status': 'L3',
|
|
'success': true,
|
|
'message': 'Data submitted successfully. No images were attached.',
|
|
'reportId': recordId,
|
|
};
|
|
}
|
|
|
|
debugPrint("Step 2: Uploading ${filesToUpload.length} tarball images for record ID: $recordId");
|
|
final imageResult = await _baseService.postMultipart(
|
|
endpoint: 'marine/tarball/images',
|
|
fields: {'autoid': recordId.toString()},
|
|
files: filesToUpload,
|
|
);
|
|
|
|
if (imageResult['success'] != true) {
|
|
return {
|
|
'status': 'L2',
|
|
'success': false,
|
|
'message': 'Data submitted to server, but image upload failed: ${imageResult['message']}',
|
|
'reportId': recordId,
|
|
};
|
|
}
|
|
|
|
_handleTarballSuccessAlert(formData, isDataOnly: false);
|
|
return {
|
|
'status': 'L3',
|
|
'success': true,
|
|
'message': 'Data and images submitted to server successfully.',
|
|
'reportId': recordId,
|
|
};
|
|
}
|
|
|
|
Future<Map<String, dynamic>> submitInSituSample({
|
|
required Map<String, String> formData,
|
|
required Map<String, File?> imageFiles,
|
|
required InSituSamplingData inSituData,
|
|
}) async {
|
|
debugPrint("Step 1: Submitting in-situ form data to the server...");
|
|
final dataResult = await _baseService.post('marine/manual/sample', formData);
|
|
|
|
if (dataResult['success'] != true) {
|
|
return {
|
|
'status': 'L1',
|
|
'success': false,
|
|
'message': 'Failed to submit in-situ data: ${dataResult['message']}',
|
|
'reportId': null,
|
|
};
|
|
}
|
|
debugPrint("Step 1 successful. In-situ data submitted.");
|
|
|
|
final recordId = dataResult['data']?['man_id'];
|
|
if (recordId == null) {
|
|
return {
|
|
'status': 'L2',
|
|
'success': false,
|
|
'message': 'In-situ data submitted, but failed to get a record ID for images.',
|
|
'reportId': null,
|
|
};
|
|
}
|
|
|
|
final filesToUpload = <String, File>{};
|
|
imageFiles.forEach((key, value) {
|
|
if (value != null) filesToUpload[key] = value;
|
|
});
|
|
|
|
if (filesToUpload.isEmpty) {
|
|
_handleInSituSuccessAlert(inSituData, isDataOnly: true);
|
|
return {
|
|
'status': 'L3',
|
|
'success': true,
|
|
'message': 'In-situ data submitted successfully. No images were attached.',
|
|
'reportId': recordId.toString(),
|
|
};
|
|
}
|
|
|
|
debugPrint("Step 2: Uploading ${filesToUpload.length} in-situ images for record ID: $recordId");
|
|
final imageResult = await _baseService.postMultipart(
|
|
endpoint: 'marine/manual/images',
|
|
fields: {'man_id': recordId.toString()},
|
|
files: filesToUpload,
|
|
);
|
|
|
|
if (imageResult['success'] != true) {
|
|
return {
|
|
'status': 'L2',
|
|
'success': false,
|
|
'message': 'In-situ data submitted, but image upload failed: ${imageResult['message']}',
|
|
'reportId': recordId.toString(),
|
|
};
|
|
}
|
|
|
|
_handleInSituSuccessAlert(inSituData, isDataOnly: false);
|
|
return {
|
|
'status': 'L3',
|
|
'success': true,
|
|
'message': 'In-situ data and images submitted successfully.',
|
|
'reportId': recordId.toString(),
|
|
};
|
|
}
|
|
|
|
Future<void> _handleTarballSuccessAlert(Map<String, String> formData, {required bool isDataOnly}) async {
|
|
try {
|
|
final groupChatId = await _settingsService.getTarballChatId();
|
|
if (groupChatId.isNotEmpty) {
|
|
final message = _generateTarballAlertMessage(formData, isDataOnly: isDataOnly);
|
|
final bool wasSent = await _telegramService.sendAlertImmediately('marine_tarball', message);
|
|
if (!wasSent) {
|
|
await _telegramService.queueMessage('marine_tarball', message);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
debugPrint("Failed to handle Tarball Telegram alert: $e");
|
|
}
|
|
}
|
|
|
|
String _generateTarballAlertMessage(Map<String, String> formData, {required bool isDataOnly}) {
|
|
final submissionType = isDataOnly ? "(Data Only)" : "(Data & Images)";
|
|
final stationName = formData['tbl_station_name'] ?? 'N/A';
|
|
final stationCode = formData['tbl_station_code'] ?? 'N/A';
|
|
final classification = formData['classification_name'] ?? formData['classification_id'] ?? 'N/A';
|
|
|
|
final buffer = StringBuffer()
|
|
..writeln('✅ *Tarball Sample $submissionType Submitted:*')
|
|
..writeln()
|
|
..writeln('*Station Name & Code:* $stationName ($stationCode)')
|
|
..writeln('*Date of Submission:* ${formData['sampling_date']}')
|
|
..writeln('*Submitted by User:* ${formData['first_sampler_name'] ?? 'N/A'}')
|
|
..writeln('*Classification:* $classification')
|
|
..writeln('*Status of Submission:* Successful');
|
|
|
|
if (formData['distance_difference'] != null &&
|
|
double.tryParse(formData['distance_difference']!) != null &&
|
|
double.parse(formData['distance_difference']!) > 0) {
|
|
buffer
|
|
..writeln()
|
|
..writeln('🔔 *Alert:*')
|
|
..writeln('*Distance from station:* ${(double.parse(formData['distance_difference']!) * 1000).toStringAsFixed(0)} meters');
|
|
|
|
if (formData['distance_difference_remarks'] != null && formData['distance_difference_remarks']!.isNotEmpty) {
|
|
buffer.writeln('*Remarks for distance:* ${formData['distance_difference_remarks']}');
|
|
}
|
|
}
|
|
|
|
return buffer.toString();
|
|
}
|
|
|
|
Future<void> _handleInSituSuccessAlert(InSituSamplingData data, {required bool isDataOnly}) async {
|
|
try {
|
|
final groupChatId = await _settingsService.getInSituChatId();
|
|
if (groupChatId.isNotEmpty) {
|
|
final message = data.generateTelegramAlertMessage(isDataOnly: isDataOnly);
|
|
final bool wasSent = await _telegramService.sendAlertImmediately('marine_in_situ', message);
|
|
if (!wasSent) {
|
|
await _telegramService.queueMessage('marine_in_situ', message);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
debugPrint("Failed to handle In-Situ Telegram alert: $e");
|
|
}
|
|
}
|
|
} |