From 50814b913c410d6a0db110f690a69c16cfeb43db Mon Sep 17 00:00:00 2001 From: Ryan W Date: Thu, 21 Nov 2024 18:38:00 +0000 Subject: [PATCH 1/4] [feature] GraphQL: add to retrieve smart meter device id for future function to get real-time usage --- .../com/rwmobi/kunigami/queries/PropertiesQuery.graphql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composeApp/src/commonMain/graphql/com/rwmobi/kunigami/queries/PropertiesQuery.graphql b/composeApp/src/commonMain/graphql/com/rwmobi/kunigami/queries/PropertiesQuery.graphql index 8f0215f7..ed0c334a 100644 --- a/composeApp/src/commonMain/graphql/com/rwmobi/kunigami/queries/PropertiesQuery.graphql +++ b/composeApp/src/commonMain/graphql/com/rwmobi/kunigami/queries/PropertiesQuery.graphql @@ -11,6 +11,10 @@ query PropertiesQuery($accountNumber: String!) { meters { serialNumber makeAndType + smartImportElectricityMeter { + deviceId + __typename + } meterPoint { meters { serialNumber From 417a89e434c49835bdf9c3ec3fd95e1ad1d3789e Mon Sep 17 00:00:00 2001 From: Ryan W Date: Thu, 21 Nov 2024 18:42:49 +0000 Subject: [PATCH 2/4] [fix] TariffMapper: fix to properly map day-night and three-rate tariffs --- .../rwmobi/kunigami/data/repository/mapper/TariffMapper.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/data/repository/mapper/TariffMapper.kt b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/data/repository/mapper/TariffMapper.kt index e5f5edbe..4d723a32 100644 --- a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/data/repository/mapper/TariffMapper.kt +++ b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/data/repository/mapper/TariffMapper.kt @@ -25,7 +25,11 @@ fun SingleEnergyProductQuery.EnergyProduct.toTariff( tariffCode: String, ): Tariff? { val tariffNode = tariffs?.edges - ?.firstOrNull { it?.node?.onStandardTariff?.tariffCode == tariffCode } + ?.firstOrNull { + it?.node?.onStandardTariff?.tariffCode == tariffCode || + it?.node?.onDayNightTariff?.tariffCode == tariffCode || + it?.node?.onThreeRateTariff?.tariffCode == tariffCode + } ?.node if (tariffNode == null) { From dce252be67e1d76a1690cdc39b039636f341a9fd Mon Sep 17 00:00:00 2001 From: Ryan W Date: Thu, 21 Nov 2024 19:55:42 +0000 Subject: [PATCH 3/4] [fix] TariffSummaryTile: fix to show properly day-night and three-rate unit rates --- .../kunigami/domain/model/product/Tariff.kt | 23 ++- .../ui/components/TariffSummaryTile.kt | 149 ++++++++++++++---- 2 files changed, 140 insertions(+), 32 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/domain/model/product/Tariff.kt b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/domain/model/product/Tariff.kt index 7279a4d2..b3b6598b 100644 --- a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/domain/model/product/Tariff.kt +++ b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/domain/model/product/Tariff.kt @@ -88,7 +88,28 @@ data class Tariff( } } - // TODO: WIP - We do not support dual rates and don't know how it works for now + fun containsValidUnitRate(): Boolean { + return when (getElectricityTariffType()) { + ElectricityTariffType.STANDARD -> { + vatInclusiveStandardUnitRate != null || isVariable + } + + ElectricityTariffType.DAY_NIGHT -> { + vatInclusiveDayUnitRate != null && + vatInclusiveNightUnitRate != null + } + + ElectricityTariffType.THREE_RATE -> { + vatInclusiveDayUnitRate != null && + vatInclusiveNightUnitRate != null && + vatInclusiveOffPeakRate != null + } + + else -> false + } + } + + // TODO: This function will be removed once we have migrated to get billing data from GraphQL fun resolveUnitRate(referencePoint: Instant? = null): Double? { return when (getElectricityTariffType()) { ElectricityTariffType.STANDARD -> { diff --git a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/ui/components/TariffSummaryTile.kt b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/ui/components/TariffSummaryTile.kt index fac3d5d9..b06e5d10 100644 --- a/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/ui/components/TariffSummaryTile.kt +++ b/composeApp/src/commonMain/kotlin/com/rwmobi/kunigami/ui/components/TariffSummaryTile.kt @@ -35,11 +35,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.text.font.FontWeight +import com.rwmobi.kunigami.domain.extensions.roundToTwoDecimalPlaces +import com.rwmobi.kunigami.domain.model.product.ElectricityTariffType import com.rwmobi.kunigami.domain.model.product.Tariff import com.rwmobi.kunigami.ui.composehelper.getScreenSizeInfo import com.rwmobi.kunigami.ui.previewsampledata.TariffSamples import com.rwmobi.kunigami.ui.theme.getDimension import kunigami.composeapp.generated.resources.Res +import kunigami.composeapp.generated.resources.day_unit_rate +import kunigami.composeapp.generated.resources.night_unit_rate +import kunigami.composeapp.generated.resources.off_peak_rate import kunigami.composeapp.generated.resources.standard_unit_rate import kunigami.composeapp.generated.resources.standing_charge import kunigami.composeapp.generated.resources.tariffs_variable @@ -90,38 +95,11 @@ internal fun TariffSummaryTile( ) } - val resolvedUnitRate = tariff.resolveUnitRate() - val rateString = when { - tariff.isVariable -> stringResource(resource = Res.string.tariffs_variable) - resolvedUnitRate != null -> stringResource(resource = Res.string.unit_p_kwh, resolvedUnitRate) - else -> null - } - - if (rateString != null) { - HorizontalDivider( - modifier = Modifier - .padding(vertical = dimension.grid_1) - .alpha(0.5f), + val shouldShowUnitRate = tariff.containsValidUnitRate() + if (shouldShowUnitRate) { + UnitRateLayout( + tariff = tariff, ) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(space = dimension.grid_0_5), - ) { - Text( - modifier = Modifier.weight(weight = 1f), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - text = stringResource(resource = Res.string.standard_unit_rate), - ) - Text( - modifier = Modifier.wrapContentWidth(), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - text = rateString, - ) - } } Spacer(modifier = Modifier.weight(1f)) @@ -135,6 +113,115 @@ internal fun TariffSummaryTile( } } +@Composable +private fun UnitRateLayout( + modifier: Modifier = Modifier, + tariff: Tariff, +) { + val dimension = getScreenSizeInfo().getDimension() + HorizontalDivider( + modifier = Modifier + .padding(vertical = dimension.grid_1) + .alpha(0.5f), + ) + + when (tariff.getElectricityTariffType()) { + ElectricityTariffType.STANDARD -> { + val rateString = when { + tariff.isVariable -> stringResource(resource = Res.string.tariffs_variable) + tariff.vatInclusiveStandardUnitRate != null -> stringResource(resource = Res.string.unit_p_kwh, tariff.vatInclusiveStandardUnitRate) + else -> null + } + + rateString?.let { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(space = dimension.grid_0_5), + ) { + Text( + modifier = Modifier.weight(weight = 1f), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.standard_unit_rate), + ) + Text( + modifier = Modifier.wrapContentWidth(), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = rateString, + ) + } + } + } + + else -> { + tariff.vatInclusiveDayUnitRate?.let { rate -> + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(space = dimension.grid_0_5), + ) { + Text( + modifier = Modifier.weight(weight = 1f), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.day_unit_rate), + ) + Text( + modifier = Modifier.wrapContentWidth(), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.unit_p_kwh, rate.roundToTwoDecimalPlaces()), + ) + } + } + + tariff.vatInclusiveNightUnitRate?.let { rate -> + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(space = dimension.grid_0_5), + ) { + Text( + modifier = Modifier.weight(weight = 1f), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.night_unit_rate), + ) + Text( + modifier = Modifier.wrapContentWidth(), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.unit_p_kwh, rate.roundToTwoDecimalPlaces()), + ) + } + } + + tariff.vatInclusiveOffPeakRate?.let { rate -> + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(space = dimension.grid_0_5), + ) { + Text( + modifier = Modifier.weight(weight = 1f), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.off_peak_rate), + ) + Text( + modifier = Modifier.wrapContentWidth(), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = stringResource(resource = Res.string.unit_p_kwh, rate.roundToTwoDecimalPlaces()), + ) + } + } + } + } +} + @Preview @Composable private fun Preview() { From 0ea7db0e0adea4631c8efdeecd237d9d7727eee8 Mon Sep 17 00:00:00 2001 From: Ryan W Date: Thu, 21 Nov 2024 20:15:39 +0000 Subject: [PATCH 4/4] [chore] App: bump version to 2.3.1 (build 15) --- composeApp/composeApp.podspec | 4 ++-- gradle/libs.versions.toml | 4 ++-- iosApp/OctoMeter.xcodeproj/project.pbxproj | 8 ++++---- iosApp/Podfile.lock | 4 ++-- iosApp/iosApp/Info.plist | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composeApp/composeApp.podspec b/composeApp/composeApp.podspec index 41357e32..a31a7581 100644 --- a/composeApp/composeApp.podspec +++ b/composeApp/composeApp.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'composeApp' - spec.version = '2.3.0' + spec.version = '2.3.1' spec.homepage = 'https://github.com/ryanw-mobile/OctoMeter/' spec.source = { :http=> ''} spec.authors = '' @@ -51,4 +51,4 @@ Pod::Spec.new do |spec| } ] spec.resources = ['build/compose/cocoapods/compose-resources'] -end +end \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 133b8c3c..8eccd8b2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,8 +43,8 @@ apollographqlMockServer = "0.1.0" testRules = "1.6.1" # App configurations, not dependencies -versionCode = "14" -versionName = "2.3.0" +versionCode = "15" +versionName = "2.3.1" android-minSdk = "26" android-targetSdk = "34" android-compileSdk = "34" diff --git a/iosApp/OctoMeter.xcodeproj/project.pbxproj b/iosApp/OctoMeter.xcodeproj/project.pbxproj index c70a6bd1..c93e8324 100644 --- a/iosApp/OctoMeter.xcodeproj/project.pbxproj +++ b/iosApp/OctoMeter.xcodeproj/project.pbxproj @@ -384,7 +384,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 15; DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = V8M4R7N63C; ENABLE_PREVIEWS = YES; @@ -401,7 +401,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "$(inherited)", "-framework", @@ -422,7 +422,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 15; DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = V8M4R7N63C; ENABLE_PREVIEWS = YES; @@ -439,7 +439,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "$(inherited)", "-framework", diff --git a/iosApp/Podfile.lock b/iosApp/Podfile.lock index 373cfe91..6e95ba63 100644 --- a/iosApp/Podfile.lock +++ b/iosApp/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - composeApp (2.3.0) + - composeApp (2.3.1) DEPENDENCIES: - composeApp (from `../composeApp/`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../composeApp/" SPEC CHECKSUMS: - composeApp: be2eed0e93f9f2e0672a8aaf85099a186731e2d1 + composeApp: 370b588122b7702f52bd2ba74fdbb187caee68c3 PODFILE CHECKSUM: 132f4b88956762bee62e7893fe00dca16e0d8114 diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist index 99ce0e9f..07568cfb 100644 --- a/iosApp/iosApp/Info.plist +++ b/iosApp/iosApp/Info.plist @@ -19,9 +19,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 2.3.0 + 2.3.1 CFBundleVersion - 14 + 15 LSRequiresIPhoneOS UIApplicationSceneManifest