changes data format for csv file for all component

This commit is contained in:
ALim Aidrus 2026-03-05 13:08:46 +08:00
parent 9f9c7ff1cd
commit 7adf899585
7 changed files with 105 additions and 102 deletions

View File

@ -101,7 +101,7 @@ class _HomePageState extends State<HomePage> {
);
},
),
title: const Text("MMS Version 3.12.06"),
title: const Text("MMS Version 3.12.07"),
actions: [
IconButton(
icon: const Icon(Icons.person),

View File

@ -264,7 +264,7 @@ class InSituSamplingData {
/// Creates a single JSON object for 'db.json'. FORCING ALL VALUES TO STRING.
String toDbJson() {
final data = {
'battery_cap': (batteryVoltage ?? "NULL").toString(),
'battery_cap': (batteryVoltage == null || batteryVoltage == -999.0) ? "NULL" : batteryVoltage.toString(),
'device_name': (sondeId ?? "").toString(),
'sampling_type': (samplingType ?? "").toString(),
'report_id': (reportId ?? "").toString(),
@ -277,15 +277,15 @@ class InSituSamplingData {
'latitude': (stationLatitude ?? "").toString(),
'longitude': (stationLongitude ?? "").toString(),
'record_dt': (samplingDate != null && samplingTime != null) ? '$samplingDate $samplingTime' : "",
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'tss': (tss ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'tss': (tss == null || tss == -999.0) ? "NULL" : tss.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'sample_id': (sampleIdCode ?? "").toString(),
'tarball': "No",
'weather': (weather ?? "").toString(),
@ -320,15 +320,15 @@ class InSituSamplingData {
/// Creates a JSON object for sensor readings. FORCING ALL VALUES TO STRING.
String toReadingJson() {
final data = {
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'tss': (tss ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'tss': (tss == null || tss == -999.0) ? "NULL" : tss.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'date_sampling_reading': (dataCaptureDate ?? "").toString(),
'time_sampling_reading': (dataCaptureTime ?? "").toString(),
};
@ -352,7 +352,7 @@ class InSituSamplingData {
final Map<String, String> map = {};
void add(String key, dynamic value) {
if (value != null) {
String stringValue = (value is double) ? ((value == -999.0) ? 'NULL' : value.toStringAsFixed(5)) : value.toString();
String stringValue = (value is double) ? ((value == -999.0) ? '-999' : value.toStringAsFixed(5)) : value.toString();
if (stringValue.isNotEmpty) map[key] = stringValue;
}
}

View File

@ -88,6 +88,7 @@ class MarineInvesManualSamplingData {
});
/// Creates a single JSON object with all submission data for offline storage.
/// Logic updated to replace -999.0 with "NULL" for external server compatibility.
Map<String, dynamic> toDbJson() {
return {
// Step 1
@ -126,16 +127,17 @@ class MarineInvesManualSamplingData {
'sonde_id': sondeId,
'data_capture_date': dataCaptureDate,
'data_capture_time': dataCaptureTime,
'oxygen_concentration': oxygenConcentration,
'oxygen_saturation': oxygenSaturation,
'ph': ph,
'salinity': salinity,
'electrical_conductivity': electricalConductivity,
'temperature': temperature,
'tds': tds,
'turbidity': turbidity,
'tss': tss,
'battery_voltage': batteryVoltage,
// Handle NULL values for JSON output
'oxygen_concentration': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration,
'oxygen_saturation': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation,
'ph': (ph == null || ph == -999.0) ? "NULL" : ph,
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity,
'electrical_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity,
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature,
'tds': (tds == null || tds == -999.0) ? "NULL" : tds,
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity,
'tss': (tss == null || tss == -999.0) ? "NULL" : tss,
'battery_voltage': (batteryVoltage == null || batteryVoltage == -999.0) ? "NULL" : batteryVoltage,
// Status
'submission_status': submissionStatus,
'submission_message': submissionMessage,
@ -158,7 +160,10 @@ class MarineInvesManualSamplingData {
factory MarineInvesManualSamplingData.fromJson(Map<String, dynamic> json) {
double? doubleFromJson(dynamic value) {
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value);
if (value is String) {
if (value == "NULL") return -999.0;
return double.tryParse(value);
}
return null;
}
@ -243,7 +248,7 @@ class MarineInvesManualSamplingData {
}
/// Maps data to keys for the API submission.
/// Maps data to keys for the API submission. Preserved exactly as originally provided.
Map<String, String> toApiFormData() {
final Map<String, String> map = {};
@ -279,7 +284,7 @@ class MarineInvesManualSamplingData {
add('inves_station_type', stationTypeSelection);
if (stationTypeSelection == 'Existing Manual Station') {
// FIX: Ensure 'station_id' is added correctly for limit validation
// FIX: Ensure 'station_id' is added correctly for limit validation
add('station_id', selectedStation?['station_id'] ?? selectedStation?['man_station_id']);
add('inves_station_code', selectedStation?['man_station_code']);
add('inves_station_name', selectedStation?['man_station_name']);

View File

@ -121,7 +121,7 @@ class RiverInSituSamplingData {
..labRemarks = json['labRemarks'] ?? json['r_man_lab_remark']
..sondeId = json['sondeId'] ?? json['r_man_sondeID']
..dataCaptureDate = json['dataCaptureDate'] ?? json['data_capture_date']
..dataCaptureTime = json['dataCaptureTime'] ?? json['data_capture_time']
..dataCaptureTime = json['data_capture_time'] ?? json['data_capture_time']
..oxygenConcentration = doubleFromJson(json['oxygenConcentration'] ?? json['r_man_oxygen_conc'])
..oxygenSaturation = doubleFromJson(json['oxygenSaturation'] ?? json['r_man_oxygen_sat'])
..ph = doubleFromJson(json['ph'] ?? json['r_man_ph'])
@ -311,7 +311,7 @@ class RiverInSituSamplingData {
/// FORCING ALL VALUES TO STRING.
String toDbJson() {
final data = {
'battery_cap': (batteryVoltage ?? "NULL").toString(),
'battery_cap': (batteryVoltage == null || batteryVoltage == -999.0) ? "NULL" : batteryVoltage.toString(),
'device_name': (sondeId ?? "").toString(),
'sampling_type': (samplingType ?? "").toString(),
'report_id': (reportId ?? "").toString(),
@ -326,15 +326,15 @@ class RiverInSituSamplingData {
'record_dt': (samplingDate != null && samplingTime != null)
? '$samplingDate $samplingTime'
: "",
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'flowrate': (flowrateValue ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'odour': "",
'floatable': "",
'sample_id': (sampleIdCode ?? "").toString(),
@ -367,15 +367,15 @@ class RiverInSituSamplingData {
/// Creates a JSON object for sensor readings. FORCING ALL VALUES TO STRING.
String toReadingJson() {
final data = {
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'flowrate': (flowrateValue ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'date_sampling_reading': (dataCaptureDate ?? "").toString(),
'time_sampling_reading': (dataCaptureTime ?? "").toString(),
};

View File

@ -329,7 +329,6 @@ class RiverInvesManualSamplingData {
// Sampler & Time Info (Assuming same API keys as manual)
add('first_sampler_user_id', firstSamplerUserId);
// *** FIX: Changed 'r_inv_' to 'r_inves_' to match API ***
add('r_inves_second_sampler_id', secondSampler?['user_id']);
add('r_inves_date', samplingDate);
add('r_inves_time', samplingTime);
@ -409,7 +408,6 @@ class RiverInvesManualSamplingData {
/// Converts the image properties into a Map<String, File?> for the multipart API request.
/// Keys should match the expected API endpoint fields for Investigative images.
Map<String, File?> toApiImageFiles() {
// *** FIX: Updated keys to 'r_inves_' to match DB/Controller ***
return {
'r_inves_background_station': backgroundStationImage,
'r_inves_upstream_river': upstreamRiverImage,
@ -425,7 +423,7 @@ class RiverInvesManualSamplingData {
/// Creates a single JSON object for FTP 'db.json', forcing every value to String.
String toDbJson() {
final data = {
'battery_cap': (batteryVoltage ?? "").toString(),
'battery_cap': (batteryVoltage == null || batteryVoltage == -999.0) ? "NULL" : batteryVoltage.toString(),
'device_name': (sondeId ?? "").toString(),
'sampling_type': (samplingType ?? "Investigative").toString(),
'report_id': (reportId ?? "").toString(),
@ -438,16 +436,16 @@ class RiverInvesManualSamplingData {
'latitude': (stationLatitude ?? "").toString(),
'longitude': (stationLongitude ?? "").toString(),
'record_dt': '$samplingDate $samplingTime',
'do_mgl': (oxygenConcentration ?? -999.0).toString(),
'do_sat': (oxygenSaturation ?? -999.0).toString(),
'ph': (ph ?? -999.0).toString(),
'salinity': (salinity ?? -999.0).toString(),
'temperature': (temperature ?? -999.0).toString(),
'turbidity': (turbidity ?? -999.0).toString(),
'tds': (tds ?? -999.0).toString(),
'electric_conductivity': (electricalConductivity ?? -999.0).toString(),
'tss': (ammonia ?? 0.0).toString(), // Mapped ammonia to 'tss' key for FTP consistency
'flowrate': (flowrateValue ?? -999.0).toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'tss': (ammonia == null || ammonia == -999.0) ? "NULL" : ammonia.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'odour': '',
'floatable': '',
'sample_id': (sampleIdCode ?? "").toString(),
@ -491,16 +489,16 @@ class RiverInvesManualSamplingData {
/// Creates JSON for FTP 'river_inves_reading.json', forcing every value to String.
String toReadingJson() {
final data = {
'do_mgl': (oxygenConcentration ?? -999.0).toString(),
'do_sat': (oxygenSaturation ?? -999.0).toString(),
'ph': (ph ?? -999.0).toString(),
'salinity': (salinity ?? -999.0).toString(),
'temperature': (temperature ?? -999.0).toString(),
'turbidity': (turbidity ?? -999.0).toString(),
'tds': (tds ?? -999.0).toString(),
'electric_conductivity': (electricalConductivity ?? -999.0).toString(),
'tss': (ammonia ?? -999.0).toString(),
'flowrate': (flowrateValue ?? -999.0).toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'tss': (ammonia == null || ammonia == -999.0) ? "NULL" : ammonia.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'date_sampling_reading': (dataCaptureDate ?? "").toString(),
'time_sampling_reading': (dataCaptureTime ?? "").toString(),
};

View File

@ -160,7 +160,7 @@ class RiverManualTriennialSamplingData {
String stringValue;
if (value is double) {
if (value == -999.0) {
stringValue = 'NULL';
stringValue = '-999';
} else {
stringValue = value.toStringAsFixed(5);
}
@ -180,7 +180,7 @@ class RiverManualTriennialSamplingData {
add('r_tri_time', samplingTime);
add('r_tri_type', samplingType);
add('r_tri_sample_id_code', sampleIdCode);
add('station_id', selectedStation?['station_id']); // Ensure this is the correct foreign key
add('station_id', selectedStation?['station_id']);
add('r_tri_current_latitude', currentLatitude);
add('r_tri_current_longitude', currentLongitude);
add('r_tri_distance_difference', distanceDifferenceInKm);
@ -199,7 +199,7 @@ class RiverManualTriennialSamplingData {
// Step 3 Data
add('r_tri_sondeID', sondeId);
add('data_capture_date', dataCaptureDate); // Note: Keys likely shared with in-situ for capture time
add('data_capture_date', dataCaptureDate);
add('data_capture_time', dataCaptureTime);
add('r_tri_oxygen_conc', oxygenConcentration);
add('r_tri_oxygen_sat', oxygenSaturation);
@ -303,7 +303,7 @@ class RiverManualTriennialSamplingData {
/// Every value is explicitly converted to a String for the API.
String toDbJson() {
final data = {
'battery_cap': (batteryVoltage ?? "NULL").toString(),
'battery_cap': (batteryVoltage == null || batteryVoltage == -999.0) ? "NULL" : batteryVoltage.toString(),
'device_name': (sondeId ?? "").toString(),
'sampling_type': (samplingType ?? "").toString(),
'report_id': (reportId ?? "").toString(),
@ -316,16 +316,16 @@ class RiverManualTriennialSamplingData {
'latitude': (stationLatitude ?? "").toString(),
'longitude': (stationLongitude ?? "").toString(),
'record_dt': '$samplingDate $samplingTime',
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'tss': (ammonia ?? "NULL").toString(),
'flowrate': (flowrateValue ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'tss': (ammonia == null || ammonia == -999.0) ? "NULL" : ammonia.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'odour': '',
'floatable': '',
'sample_id': (sampleIdCode ?? "").toString(),
@ -364,16 +364,16 @@ class RiverManualTriennialSamplingData {
/// Every value is explicitly converted to a String.
String toReadingJson() {
final data = {
'do_mgl': (oxygenConcentration ?? "NULL").toString(),
'do_sat': (oxygenSaturation ?? "NULL").toString(),
'ph': (ph ?? "NULL").toString(),
'salinity': (salinity ?? "NULL").toString(),
'temperature': (temperature ?? "NULL").toString(),
'turbidity': (turbidity ?? "NULL").toString(),
'tds': (tds ?? "NULL").toString(),
'electric_conductivity': (electricalConductivity ?? "NULL").toString(),
'tss': (ammonia ?? "NULL").toString(),
'flowrate': (flowrateValue ?? "NULL").toString(),
'do_mgl': (oxygenConcentration == null || oxygenConcentration == -999.0) ? "NULL" : oxygenConcentration.toString(),
'do_sat': (oxygenSaturation == null || oxygenSaturation == -999.0) ? "NULL" : oxygenSaturation.toString(),
'ph': (ph == null || ph == -999.0) ? "NULL" : ph.toString(),
'salinity': (salinity == null || salinity == -999.0) ? "NULL" : salinity.toString(),
'temperature': (temperature == null || temperature == -999.0) ? "NULL" : temperature.toString(),
'turbidity': (turbidity == null || turbidity == -999.0) ? "NULL" : turbidity.toString(),
'tds': (tds == null || tds == -999.0) ? "NULL" : tds.toString(),
'electric_conductivity': (electricalConductivity == null || electricalConductivity == -999.0) ? "NULL" : electricalConductivity.toString(),
'tss': (ammonia == null || ammonia == -999.0) ? "NULL" : ammonia.toString(),
'flowrate': (flowrateValue == null || flowrateValue == -999.0) ? "NULL" : flowrateValue.toString(),
'date_sampling_reading': (dataCaptureDate ?? "").toString(),
'time_sampling_reading': (dataCaptureTime ?? "").toString(),
};

View File

@ -221,7 +221,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
ListTile(
leading: const Icon(Icons.info_outline),
title: const Text('App Version'),
subtitle: const Text('MMS Version 3.12.06'),
subtitle: const Text('MMS Version 3.12.07'),
dense: true,
),
ListTile(