From 4fa29da79def6ca0494b3a860f80dc1088dc4855 Mon Sep 17 00:00:00 2001 From: soraefir Date: Thu, 2 Jul 2026 02:37:40 +0200 Subject: [PATCH] Better category/paymentmode storage and handling --- .../android/bill_edit/EditBillActivity.kt | 30 ++++++------ .../android/bill_edit/EditBillScreen.kt | 12 ++--- .../android/bill_edit/EditBillViewModel.kt | 8 ++-- .../android/bill_label/LabelBillsActivity.kt | 8 ++-- .../android/bill_label/LabelBillsScreen.kt | 8 ++-- .../android/bill_label/LabelBillsViewModel.kt | 14 +++--- .../android/main/BillsListViewActivity.kt | 6 +-- .../android/project/ProjectImportHelper.kt | 20 ++++++-- .../statistics/ProjectSankeyDiagram.kt | 14 +++--- .../statistics/ProjectStatisticsScreen.kt | 2 +- .../java/net/helcel/cowspent/model/DBBill.kt | 47 +++++++++---------- .../net/helcel/cowspent/model/GroupedBill.kt | 4 +- .../persistence/CowspentServerSyncHelper.kt | 24 +++++++--- .../net/helcel/cowspent/util/BillFormatter.kt | 8 ++-- .../net/helcel/cowspent/util/CategoryUtils.kt | 35 +++++++------- .../net/helcel/cowspent/util/ExportUtil.kt | 2 +- .../helcel/cowspent/util/ServerResponse.kt | 14 +++--- .../net/helcel/cowspent/util/SupportUtil.kt | 6 +-- .../util/VersatileProjectSyncClient.kt | 28 ++++++++--- 19 files changed, 164 insertions(+), 126 deletions(-) diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillActivity.kt b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillActivity.kt index 7906472..ef21ca1 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillActivity.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillActivity.kt @@ -57,7 +57,7 @@ class EditBillActivity : AppCompatActivity() { val hardcoded = if (projectType == ProjectType.LOCAL) { defaultCategories } else { - listOfNotNull(defaultCategories.find { it.remoteId.toInt() == DBBill.CATEGORY_REIMBURSEMENT }) + listOfNotNull(defaultCategories.find { it.remoteId == DBBill.CATEGORY_REIMBURSEMENT.toLong() }) } syncedCategories + hardcoded } @@ -144,7 +144,7 @@ class EditBillActivity : AppCompatActivity() { bill = DBBill( first.id, 0, first.projectId, first.payerId, totalAmount, first.timestamp, first.what, first.state, first.repeat, - first.paymentMode, first.categoryRemoteId, first.comment, first.paymentModeRemoteId + first.paymentMode, first.categoryId, first.comment, first.paymentModeId ) val splits = mutableMapOf() @@ -168,15 +168,15 @@ class EditBillActivity : AppCompatActivity() { bill = DBBill( 0, 0, projectId, 0, 0.0, timeNowSeconds, "", DBBill.STATE_ADDED, DBBill.NON_REPEATED, - DBBill.PAYMODE_NONE, DBBill.CATEGORY_NONE, "", DBBill.PAYMODE_ID_NONE + DBBill.PAYMODE_NONE, DBBill.CATEGORY_NONE.toLong(), "", DBBill.PAYMODE_ID_NONE.toLong() ) } else { val btd = db.getBill(billIdToDuplicate)!! bill = DBBill( 0, 0, projectId, btd.payerId, btd.amount, timeNowSeconds, btd.what, DBBill.STATE_ADDED, - btd.repeat, btd.paymentMode, btd.categoryRemoteId, - btd.comment, btd.paymentModeRemoteId + btd.repeat, btd.paymentMode, btd.categoryId, + btd.comment, btd.paymentModeId ) val btdOwers = btd.billOwers val newBillOwers = btdOwers.filter { @@ -239,8 +239,8 @@ class EditBillActivity : AppCompatActivity() { bill = DBBill( 0, 0, bill.projectId, viewModel.payerId, viewModel.amountAsDouble, System.currentTimeMillis() / 1000, viewModel.what, DBBill.STATE_ADDED, - viewModel.repeat, bill.paymentMode, viewModel.categoryRemoteId, - viewModel.getFinalComment(), viewModel.paymentModeRemoteId + viewModel.repeat, bill.paymentMode, viewModel.categoryId, + viewModel.getFinalComment(), viewModel.paymentModeId ) calendar.timeInMillis = System.currentTimeMillis() viewModel.timestamp = calendar.timeInMillis / 1000 @@ -326,8 +326,8 @@ class EditBillActivity : AppCompatActivity() { bill.payerId == viewModel.payerId && bill.comment == viewModel.getFinalComment() && bill.repeat == viewModel.repeat && - bill.categoryRemoteId == viewModel.categoryRemoteId && - bill.paymentModeRemoteId == viewModel.paymentModeRemoteId && + bill.categoryId == viewModel.categoryId && + bill.paymentModeId == viewModel.paymentModeId && !owersChanged) } @@ -386,8 +386,8 @@ class EditBillActivity : AppCompatActivity() { listOf(memberId), viewModel.repeat, existingBill.paymentMode, - viewModel.paymentModeRemoteId, - viewModel.categoryRemoteId, + viewModel.paymentModeId, + viewModel.categoryId, finalComment ) if (firstSavedId == 0L) firstSavedId = billToUseId @@ -396,7 +396,7 @@ class EditBillActivity : AppCompatActivity() { val newBill = DBBill( 0, 0, bill.projectId, viewModel.payerId, amount, viewModel.timestamp, viewModel.what, DBBill.STATE_ADDED, viewModel.repeat, - bill.paymentMode, viewModel.categoryRemoteId, finalComment, viewModel.paymentModeRemoteId + bill.paymentMode, viewModel.categoryId, finalComment, viewModel.paymentModeId ) newBill.billOwers = listOf(DBBillOwer(0, 0, memberId)) val newId = db.addBill(newBill) @@ -441,8 +441,8 @@ class EditBillActivity : AppCompatActivity() { newOwersIds, viewModel.repeat, bill.paymentMode, - viewModel.paymentModeRemoteId, - viewModel.categoryRemoteId, + viewModel.paymentModeId, + viewModel.categoryId, finalComment ) if (groupedBillIds != null) { @@ -460,7 +460,7 @@ class EditBillActivity : AppCompatActivity() { val newBill = DBBill( 0, 0, bill.projectId, viewModel.payerId, newAmount, viewModel.timestamp, viewModel.what, DBBill.STATE_ADDED, viewModel.repeat, - bill.paymentMode, viewModel.categoryRemoteId, finalComment, viewModel.paymentModeRemoteId + bill.paymentMode, viewModel.categoryId, finalComment, viewModel.paymentModeId ) newOwersIds.forEach { newBill.billOwers += DBBillOwer(0, 0, it) } val newBillId = db.addBill(newBill) diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt index 89412fc..9f179d8 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt @@ -468,7 +468,7 @@ fun BillAdditionalDetailsSection( var categoryExpanded by remember { mutableStateOf(false) } val selectedCategory = - categories.find { it.remoteId.toInt() == viewModel.categoryRemoteId } + categories.find { (if (it.id > 0) it.id else it.remoteId) == viewModel.categoryId } EditableExposedDropdownMenu( value = selectedCategory?.name ?: "", @@ -488,7 +488,7 @@ fun BillAdditionalDetailsSection( }, content = { DropdownMenuItem(onClick = { - viewModel.categoryRemoteId = 0 + viewModel.categoryId = 0 categoryExpanded = false }) { Icon(Icons.Default.Close, tint = Color.Red, contentDescription = null) @@ -497,7 +497,7 @@ fun BillAdditionalDetailsSection( } categories.forEach { category -> DropdownMenuItem(onClick = { - viewModel.categoryRemoteId = category.remoteId.toInt() + viewModel.categoryId = if (category.id > 0) category.id else category.remoteId categoryExpanded = false }) { Text(text = category.icon, fontSize = 20.sp) @@ -512,7 +512,7 @@ fun BillAdditionalDetailsSection( var pmExpanded by remember { mutableStateOf(false) } val selectedPm = - paymentModes.find { it.remoteId.toInt() == viewModel.paymentModeRemoteId } + paymentModes.find { (if (it.id > 0) it.id else it.remoteId) == viewModel.paymentModeId } EditableExposedDropdownMenu( value = selectedPm?.name ?: "", @@ -532,7 +532,7 @@ fun BillAdditionalDetailsSection( }, content = { DropdownMenuItem(onClick = { - viewModel.paymentModeRemoteId = 0 + viewModel.paymentModeId = 0 pmExpanded = false }) { Icon(Icons.Default.Close, tint = Color.Red, contentDescription = null) @@ -541,7 +541,7 @@ fun BillAdditionalDetailsSection( } paymentModes.forEach { pm -> DropdownMenuItem(onClick = { - viewModel.paymentModeRemoteId = pm.remoteId.toInt() + viewModel.paymentModeId = if (pm.id > 0) pm.id else pm.remoteId pmExpanded = false }) { Text(text = pm.icon, fontSize = 20.sp) diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt index 8e46b44..cd9b3ba 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt @@ -25,8 +25,8 @@ class EditBillViewModel : ViewModel() { var timestamp by mutableLongStateOf(0L) var payerId by mutableLongStateOf(0L) var repeat by mutableStateOf(DBBill.NON_REPEATED) - var paymentModeRemoteId by mutableIntStateOf(0) - var categoryRemoteId by mutableIntStateOf(0) + var paymentModeId by mutableLongStateOf(0L) + var categoryId by mutableLongStateOf(0L) var isNewBill by mutableStateOf(false) var currencies by mutableStateOf>(emptyList()) @@ -166,8 +166,8 @@ class EditBillViewModel : ViewModel() { timestamp = bill.timestamp payerId = bill.payerId repeat = bill.repeat ?: DBBill.NON_REPEATED - paymentModeRemoteId = bill.paymentModeRemoteId - categoryRemoteId = bill.categoryRemoteId + paymentModeId = bill.paymentModeId + categoryId = bill.categoryId val rawComment = bill.comment ?: "" diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsActivity.kt b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsActivity.kt index 07545c1..a0ad915 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsActivity.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsActivity.kt @@ -39,15 +39,15 @@ class LabelBillsActivity : AppCompatActivity() { val members = db.getMembersOfProject(projectId, null) val allBills = db.getBillsOfProject(projectId) - val billsToLabel = allBills.filter { it.categoryRemoteId == 0 && it.state != DBBill.STATE_DELETED } - val allCategorized = allBills.filter { it.categoryRemoteId != 0 && it.state != DBBill.STATE_DELETED } + val billsToLabel = allBills.filter { it.categoryId == 0L && it.state != DBBill.STATE_DELETED } + val allCategorized = allBills.filter { it.categoryId != 0L && it.state != DBBill.STATE_DELETED } val syncedCategories = db.getCategories(projectId) val defaultCategories = CategoryUtils.getDefaultCategories(this@LabelBillsActivity, projectId) val hardcoded = if (projectType == ProjectType.LOCAL) { defaultCategories } else { - listOfNotNull(defaultCategories.find { it.remoteId.toInt() == DBBill.CATEGORY_REIMBURSEMENT }) + listOfNotNull(defaultCategories.find { it.remoteId == DBBill.CATEGORY_REIMBURSEMENT.toLong() }) } val categories = syncedCategories + hardcoded @@ -56,7 +56,7 @@ class LabelBillsActivity : AppCompatActivity() { viewModel.billsToLabel = billsToLabel viewModel.categories = categories - viewModel.categoriesMap = categories.associateBy { it.remoteId } + viewModel.categoriesMap = categories.associateBy { it.id } viewModel.allCategorizedBills = allCategorized viewModel.updateSuggestions() diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsScreen.kt b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsScreen.kt index f1e06bb..51dc338 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsScreen.kt @@ -84,7 +84,7 @@ fun LabelBillsScreen( CategoryButton( icon = category.icon, name = category.name ?: "", - onClick = { viewModel.labelCurrentBill(db, category.remoteId.toInt()) } + onClick = { viewModel.labelCurrentBill(db, category.id) } ) } } @@ -126,7 +126,7 @@ fun LabelBillsScreen( CategoryButton( icon = category.icon, name = category.name ?: "", - onClick = { viewModel.labelCurrentBill(db, category.remoteId.toInt()) } + onClick = { viewModel.labelCurrentBill(db, category.id) } ) } } @@ -245,7 +245,7 @@ fun CategoryButton(icon: String, name: String, onClick: () -> Unit) { fun LabelBillsScreenPreview() { val viewModel = LabelBillsViewModel().apply { billsToLabel = listOf( - DBBill(1L, 0, 1L, 1L, 120.5, System.currentTimeMillis() / 1000, "Groceries at Aldi", 0, null, null, 0, null, -1) + DBBill(1L, 0, 1L, 1L, 120.5, System.currentTimeMillis() / 1000, "Groceries at Aldi", 0, null, null, 0L, null, -1L) ) val cats = listOf( DBCategory(1, 1, 1, "Groceries", "🛒", ""), @@ -254,7 +254,7 @@ fun LabelBillsScreenPreview() { DBCategory(4, 4, 1, "Bills", "💸", "") ) categories = cats - categoriesMap = cats.associateBy { it.remoteId } + categoriesMap = cats.associateBy { it.id } } val members = listOf( DBMember(1L, 0, 1L, "Alice", true, 1.0, 0, 255, 100, 100, null, null), diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsViewModel.kt b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsViewModel.kt index af27cc4..194f575 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsViewModel.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_label/LabelBillsViewModel.kt @@ -43,18 +43,18 @@ class LabelBillsViewModel : ViewModel() { otherName == name || (name.length > 3 && otherName.contains(name)) || (otherName.length > 3 && name.contains(otherName)) } - val counts = matches.groupBy { it.categoryRemoteId } + val counts = matches.groupBy { it.categoryId } .mapValues { it.value.size } .toList() .sortedByDescending { it.second } .take(2) suggestedCategories = counts.mapNotNull { (catId, _) -> - categoriesMap[catId.toLong()] + categoriesMap[catId] } } - fun labelCurrentBill(db: CowspentSQLiteOpenHelper, categoryId: Int) { + fun labelCurrentBill(db: CowspentSQLiteOpenHelper, categoryId: Long) { currentBill?.let { bill -> db.updateBillAndSync( bill = bill, @@ -65,11 +65,11 @@ class LabelBillsViewModel : ViewModel() { newOwersIds = bill.billOwersIds, newRepeat = bill.repeat, newPaymentMode = bill.paymentMode, - newPaymentModeRemoteId = bill.paymentModeRemoteId, + newPaymentModeId = bill.paymentModeId, newCategoryId = categoryId, newComment = bill.comment ) - bill.categoryRemoteId = categoryId + bill.categoryId = categoryId onBillProcessed?.invoke(bill.id) moveToNext() } @@ -87,11 +87,11 @@ class LabelBillsViewModel : ViewModel() { val start = currentBillIndex var next = (start + 1) % billsToLabel.size - while (next != start && billsToLabel[next].categoryRemoteId != 0) { + while (next != start && billsToLabel[next].categoryId != 0L) { next = (next + 1) % billsToLabel.size } - currentBillIndex = if (billsToLabel[next].categoryRemoteId == 0) { + currentBillIndex = if (billsToLabel[next].categoryId == 0L) { next } else { billsToLabel.size diff --git a/app/src/main/java/net/helcel/cowspent/android/main/BillsListViewActivity.kt b/app/src/main/java/net/helcel/cowspent/android/main/BillsListViewActivity.kt index 2aeed56..12b78d4 100644 --- a/app/src/main/java/net/helcel/cowspent/android/main/BillsListViewActivity.kt +++ b/app/src/main/java/net/helcel/cowspent/android/main/BillsListViewActivity.kt @@ -636,13 +636,13 @@ class BillsListViewActivity : mid == null || mid == it.payerId || it.billOwersIds.contains(mid) } - viewModel.hasUnlabeledBills = bills.any { it.categoryRemoteId == 0 && it.state != DBBill.STATE_DELETED } + viewModel.hasUnlabeledBills = bills.any { it.categoryId == 0L && it.state != DBBill.STATE_DELETED } val projectMembers = db.getMembersOfProject(projId, null) val memberMap = projectMembers.associateBy { it.id } - val projectPaymentModes = db.getPaymentModes(projId).associateBy { it.remoteId } - val projectCategories = db.getCategories(projId).associateBy { it.remoteId } + val projectPaymentModes = db.getPaymentModes(projId).associateBy { it.id } + val projectCategories = db.getCategories(projId).associateBy { it.id } BillFormatter.formatBills( bills, diff --git a/app/src/main/java/net/helcel/cowspent/android/project/ProjectImportHelper.kt b/app/src/main/java/net/helcel/cowspent/android/project/ProjectImportHelper.kt index 9ef41cc..a6b0a4d 100644 --- a/app/src/main/java/net/helcel/cowspent/android/project/ProjectImportHelper.kt +++ b/app/src/main/java/net/helcel/cowspent/android/project/ProjectImportHelper.kt @@ -118,8 +118,8 @@ object ProjectImportHelper { val payerWeight = if (columns.containsKey("payer_weight")) line[columns["payer_weight"]!!].toDouble() else 1.0 val owersStr = if (columns.containsKey("owers")) line[columns["owers"]!!] else "" val payerActive = columns.containsKey("payer_active") && line[columns["payer_active"]!!] == "1" - val catId = if (columns.containsKey("categoryid") && line[columns["categoryid"]!!].isNotEmpty()) line[columns["categoryid"]!!].toInt() else 0 - val pmId = if (columns.containsKey("paymentmodeid") && line[columns["paymentmodeid"]!!].isNotEmpty()) line[columns["paymentmodeid"]!!].toInt() else 0 + val catId = if (columns.containsKey("categoryid") && line[columns["categoryid"]!!].isNotEmpty()) line[columns["categoryid"]!!].toLong() else 0L + val pmId = if (columns.containsKey("paymentmodeid") && line[columns["paymentmodeid"]!!].isNotEmpty()) line[columns["paymentmodeid"]!!].toLong() else 0L val pm = if (columns.containsKey("paymentmode")) line[columns["paymentmode"]!!] else null membersActive[payerName] = payerActive @@ -150,8 +150,16 @@ object ProjectImportHelper { val memberNameToId = mutableMapOf() val pid = db.addProject(DBProject(0, projectRemoteId, "", projectRemoteId, null, null, null, ProjectType.LOCAL, 0L, mainCurrencyName, false, DBProject.ACCESS_LEVEL_UNKNOWN, null)) - paymentModes.forEach { db.addPaymentMode(DBPaymentMode(0, it.remoteId, pid, it.name, it.icon, it.color)) } - categories.forEach { db.addCategory(DBCategory(0, it.remoteId, pid, it.name, it.icon, it.color)) } + val pmRemoteToLocal = mutableMapOf() + paymentModes.forEach { pm -> + val localId = db.addPaymentMode(DBPaymentMode(0, pm.remoteId, pid, pm.name, pm.icon, pm.color)) + pmRemoteToLocal[pm.remoteId] = localId + } + val catRemoteToLocal = mutableMapOf() + categories.forEach { cat -> + val localId = db.addCategory(DBCategory(0, cat.remoteId, pid, cat.name, cat.icon, cat.color)) + catRemoteToLocal[cat.remoteId] = localId + } currencies.forEach { db.addCurrency(DBCurrency(0, 0, pid, it.name, it.exchangeRate, DBBill.STATE_OK)) } membersWeight.keys.forEach { mName -> @@ -160,7 +168,9 @@ object ProjectImportHelper { bills.forEach { b -> val payerId = memberNameToId[billRemoteIdToPayerName[b.remoteId]] ?: 0L - val billId = db.addBill(DBBill(0, 0, pid, payerId, b.amount, b.timestamp, b.what, DBBill.STATE_OK, b.repeat, b.paymentMode, b.categoryRemoteId, b.comment, b.paymentModeRemoteId)) + val localCatId = catRemoteToLocal[b.categoryId] ?: b.categoryId + val localPmId = pmRemoteToLocal[b.paymentModeId] ?: b.paymentModeId + val billId = db.addBill(DBBill(0, 0, pid, payerId, b.amount, b.timestamp, b.what, DBBill.STATE_OK, b.repeat, b.paymentMode, localCatId, b.comment, localPmId)) billRemoteIdToOwerStr[b.remoteId]?.split(", ")?.filter { it.isNotEmpty() }?.forEach { ower -> memberNameToId[ower.trim()]?.let { owerId -> db.addBillower(billId, owerId) } } diff --git a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectSankeyDiagram.kt b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectSankeyDiagram.kt index 976fccd..951703d 100644 --- a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectSankeyDiagram.kt +++ b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectSankeyDiagram.kt @@ -97,11 +97,11 @@ fun ProjectSankeyDiagram( var expanded by remember { mutableStateOf(false) } val activeBills = remember(allBills) { - allBills.filter { it.state != DBBill.STATE_DELETED && it.categoryRemoteId != DBBill.CATEGORY_REIMBURSEMENT } + allBills.filter { it.state != DBBill.STATE_DELETED && it.categoryId != DBBill.CATEGORY_REIMBURSEMENT.toLong() } } val membersMap = remember(allMembers) { allMembers.associateBy { it.id } } - val categoriesMap = remember(customCategories) { customCategories.associateBy { it.remoteId.toInt() } } + val categoriesMap = remember(customCategories) { customCategories.associateBy { it.id } } if (activeBills.isEmpty()) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { @@ -112,13 +112,13 @@ fun ProjectSankeyDiagram( val spendings = remember(activeBills, selectedMemberId, membersMap) { val spentMap = mutableMapOf().apply { membersMap.keys.forEach { put(it, 0.0) } } - val catMap = mutableMapOf() + val catMap = mutableMapOf() activeBills.forEach { bill -> val totalWeight = bill.billOwers.sumOf { membersMap[it.memberId]?.weight ?: 1.0 } if (totalWeight > 0) { if (selectedMemberId == -1L) { - catMap[bill.categoryRemoteId] = (catMap[bill.categoryRemoteId] ?: 0.0) + bill.amount + catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + bill.amount bill.billOwers.forEach { bo -> val weight = membersMap[bo.memberId]?.weight ?: 1.0 spentMap[bo.memberId] = (spentMap[bo.memberId] ?: 0.0) + (bill.amount / totalWeight) * weight @@ -126,7 +126,7 @@ fun ProjectSankeyDiagram( } else { bill.billOwers.find { it.memberId == selectedMemberId }?.let { bo -> val weight = membersMap[bo.memberId]?.weight ?: 1.0 - catMap[bill.categoryRemoteId] = (catMap[bill.categoryRemoteId] ?: 0.0) + (bill.amount / totalWeight) * weight + catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + (bill.amount / totalWeight) * weight spentMap[selectedMemberId] = (spentMap[selectedMemberId] ?: 0.0) + (bill.amount / totalWeight) * weight } } @@ -215,9 +215,9 @@ private fun SankeyContent( selectedMemberId: Long, totalAmount: Double, displayMemberSpendings: List>, - displayCategorySpendings: List>, + displayCategorySpendings: List>, membersMap: Map, - categoriesMap: Map + categoriesMap: Map ) { val density = LocalDensity.current val scope = rememberCoroutineScope() diff --git a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsScreen.kt b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsScreen.kt index 4e90aed..d4fd63a 100644 --- a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsScreen.kt @@ -99,7 +99,7 @@ fun ProjectStatisticsScreen( val hardcoded = if (proj.type == ProjectType.LOCAL) { defaultCategories } else { - listOfNotNull(defaultCategories.find { it.remoteId.toInt() == DBBill.CATEGORY_REIMBURSEMENT }) + listOfNotNull(defaultCategories.find { it.remoteId == DBBill.CATEGORY_REIMBURSEMENT }) } (data.categories + hardcoded).distinctBy { it.remoteId } } diff --git a/app/src/main/java/net/helcel/cowspent/model/DBBill.kt b/app/src/main/java/net/helcel/cowspent/model/DBBill.kt index 2ca7d20..91fd0e5 100644 --- a/app/src/main/java/net/helcel/cowspent/model/DBBill.kt +++ b/app/src/main/java/net/helcel/cowspent/model/DBBill.kt @@ -16,9 +16,9 @@ open class DBBill( var state: Int, var repeat: String?, var paymentMode: String?, - var categoryRemoteId: Int, + var categoryId: Long, var comment: String?, - var paymentModeRemoteId: Int + var paymentModeId: Long ) : Item, Serializable { var formattedWhat: String = "" @@ -39,7 +39,6 @@ open class DBBill( get() { val cal = Calendar.getInstance() cal.timeInMillis = timestamp * 1000 - Log.v("ll", "[$what] get date ts $timestamp year ${cal[Calendar.YEAR]}") val month = cal[Calendar.MONTH] + 1 val day = cal[Calendar.DAY_OF_MONTH] return "${cal[Calendar.YEAR]}-${String.format(Locale.ROOT, "%02d", month)}-${ @@ -58,7 +57,7 @@ open class DBBill( override fun toString(): String { - return "#DBBill$id/$remoteId,$projectId, $payerId, $amount, $timestamp, $what, $state, $repeat, $paymentMode, $categoryRemoteId" + return "#DBBill$id/$remoteId,$projectId, $payerId, $amount, $timestamp, $what, $state, $repeat, $paymentMode, $categoryId" } override fun isSection(): Boolean { @@ -73,15 +72,15 @@ open class DBBill( const val PAYMODE_TRANSFER = "t" const val PAYMODE_ONLINE_SERVICE = "o" - const val PAYMODE_ID_NONE = 0 - const val PAYMODE_ID_CARD = -1 - const val PAYMODE_ID_CASH = -2 - const val PAYMODE_ID_CHECK = -3 - const val PAYMODE_ID_TRANSFER = -4 - const val PAYMODE_ID_ONLINE_SERVICE = -5 + const val PAYMODE_ID_NONE = 0L + const val PAYMODE_ID_CARD = -1L + const val PAYMODE_ID_CASH = -2L + const val PAYMODE_ID_CHECK = -3L + const val PAYMODE_ID_TRANSFER = -4L + const val PAYMODE_ID_ONLINE_SERVICE = -5L @JvmField - val oldPmIdToNew: Map = object : HashMap() { + val oldPmIdToNew: Map = object : HashMap() { init { put(PAYMODE_NONE, PAYMODE_ID_NONE) put(PAYMODE_CARD, PAYMODE_ID_CARD) @@ -92,19 +91,19 @@ open class DBBill( } } - const val CATEGORY_NONE = 0 - const val CATEGORY_GROCERIES = -1 - const val CATEGORY_LEISURE = -2 - const val CATEGORY_RENT = -3 - const val CATEGORY_BILLS = -4 - const val CATEGORY_CULTURE = -5 - const val CATEGORY_HEALTH = -6 - const val CATEGORY_SHOPPING = -10 - const val CATEGORY_REIMBURSEMENT = -11 - const val CATEGORY_RESTAURANT = -12 - const val CATEGORY_ACCOMMODATION = -13 - const val CATEGORY_TRANSPORT = -14 - const val CATEGORY_SPORT = -15 + const val CATEGORY_NONE = 0L + const val CATEGORY_GROCERIES = -1L + const val CATEGORY_LEISURE = -2L + const val CATEGORY_RENT = -3L + const val CATEGORY_BILLS = -4L + const val CATEGORY_CULTURE = -5L + const val CATEGORY_HEALTH = -6L + const val CATEGORY_SHOPPING = -10L + const val CATEGORY_REIMBURSEMENT = -11L + const val CATEGORY_RESTAURANT = -12L + const val CATEGORY_ACCOMMODATION = -13L + const val CATEGORY_TRANSPORT = -14L + const val CATEGORY_SPORT = -15L const val STATE_OK = 0 const val STATE_ADDED = 1 diff --git a/app/src/main/java/net/helcel/cowspent/model/GroupedBill.kt b/app/src/main/java/net/helcel/cowspent/model/GroupedBill.kt index 51947a4..99847c4 100644 --- a/app/src/main/java/net/helcel/cowspent/model/GroupedBill.kt +++ b/app/src/main/java/net/helcel/cowspent/model/GroupedBill.kt @@ -15,9 +15,9 @@ class GroupedBill( sourceBills.first().state, sourceBills.first().repeat, sourceBills.first().paymentMode, - sourceBills.first().categoryRemoteId, + sourceBills.first().categoryId, sourceBills.first().comment, - sourceBills.first().paymentModeRemoteId + sourceBills.first().paymentModeId ), Serializable { init { this.formattedWhat = sourceBills.first().formattedWhat diff --git a/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt b/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt index 457b6a6..e4497b6 100644 --- a/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt +++ b/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt @@ -264,6 +264,10 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen val members = dbHelper.getMembersOfProject(project.id, null) val memberIdToRemoteId = members.associate { it.id to it.remoteId } + val categories = dbHelper.getCategories(project.id) + val categoryIdToRemoteId = categories.associate { it.id to it.remoteId } + val paymentModes = dbHelper.getPaymentModes(project.id) + val paymentModeIdToRemoteId = paymentModes.associate { it.id to it.remoteId } val toDelete = dbHelper.getBillsOfProjectWithState(project.id, DBBill.STATE_DELETED) for (bToDel in toDelete) { @@ -293,7 +297,7 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen val toEdit = dbHelper.getBillsOfProjectWithState(project.id, DBBill.STATE_EDITED) for (bToEdit in toEdit) { try { - val editRemoteBillResponse = client!!.editRemoteBill(project, bToEdit, memberIdToRemoteId) + val editRemoteBillResponse = client!!.editRemoteBill(project, bToEdit, memberIdToRemoteId, categoryIdToRemoteId, paymentModeIdToRemoteId) if (editRemoteBillResponse.stringContent == bToEdit.remoteId.toString()) { dbHelper.setBillState(bToEdit.id, DBBill.STATE_OK) Log.d(TAG, "SUCCESSFUL remote bill edition (${editRemoteBillResponse.stringContent})") @@ -307,7 +311,7 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen val toAdd = dbHelper.getBillsOfProjectWithState(project.id, DBBill.STATE_ADDED) for (bToAdd in toAdd) { - val createRemoteBillResponse = client!!.createRemoteBill(project, bToAdd, memberIdToRemoteId) + val createRemoteBillResponse = client!!.createRemoteBill(project, bToAdd, memberIdToRemoteId, categoryIdToRemoteId, paymentModeIdToRemoteId) val newRemoteId = createRemoteBillResponse.stringContent.toLong() if (newRemoteId > 0) { dbHelper.updateBill( @@ -613,7 +617,15 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen val localBills = dbHelper.getBillsOfProject(project.id) val localBillsByRemoteId = localBills.associateBy { it.remoteId } + val syncedCategories = dbHelper.getCategories(project.id) + val catRemoteToLocal = syncedCategories.associate { it.remoteId to it.id } + val syncedPaymentModes = dbHelper.getPaymentModes(project.id) + val pmRemoteToLocal = syncedPaymentModes.associate { it.remoteId to it.id } + for (remoteBill in remoteBills) { + if (remoteBill.categoryId > 0) remoteBill.categoryId = catRemoteToLocal[remoteBill.categoryId] ?: 0 + if (remoteBill.paymentModeId > 0) remoteBill.paymentModeId = pmRemoteToLocal[remoteBill.paymentModeId] ?: 0 + if (!localBillsByRemoteId.containsKey(remoteBill.remoteId)) { dbHelper.addBill(remoteBill) nbPulledNewBills++ @@ -626,8 +638,8 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen localBill.id, null, remoteBill.payerId, remoteBill.amount, remoteBill.timestamp, remoteBill.what, DBBill.STATE_OK, remoteBill.repeat, - remoteBill.paymentMode, remoteBill.paymentModeRemoteId, - remoteBill.categoryRemoteId, remoteBill.comment + remoteBill.paymentMode, remoteBill.paymentModeId, + remoteBill.categoryId, remoteBill.comment ) nbPulledUpdatedBills++ updatedBillsDialogText += "✏ ${remoteBill.what}\n" @@ -1084,8 +1096,8 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen localBill.what == remoteBill.what && localBill.comment == remoteBill.comment && localBill.paymentMode == remoteBill.paymentMode && - localBill.paymentModeRemoteId == remoteBill.paymentModeRemoteId && - localBill.categoryRemoteId == remoteBill.categoryRemoteId + localBill.paymentModeId == remoteBill.paymentModeId && + localBill.categoryId == remoteBill.categoryId ) { val localRepeat = localBill.repeat ?: DBBill.NON_REPEATED val remoteRepeat = remoteBill.repeat ?: DBBill.NON_REPEATED diff --git a/app/src/main/java/net/helcel/cowspent/util/BillFormatter.kt b/app/src/main/java/net/helcel/cowspent/util/BillFormatter.kt index 3af97c3..965fb93 100644 --- a/app/src/main/java/net/helcel/cowspent/util/BillFormatter.kt +++ b/app/src/main/java/net/helcel/cowspent/util/BillFormatter.kt @@ -14,11 +14,11 @@ object BillFormatter { ) { for (bill in bills) { var whatPrefix = "" - val pm = paymentModesMap[bill.paymentModeRemoteId.toLong()] + val pm = paymentModesMap[bill.paymentModeId] if (pm != null) { whatPrefix += pm.icon + " " } else { - when (bill.paymentModeRemoteId) { + when (bill.paymentModeId) { DBBill.PAYMODE_ID_CARD -> whatPrefix += "\uD83D\uDCB3 " DBBill.PAYMODE_ID_CASH -> whatPrefix += "\uD83D\uDCB5 " DBBill.PAYMODE_ID_CHECK -> whatPrefix += "\uD83C\uDFAB " @@ -27,11 +27,11 @@ object BillFormatter { } } - val cat = categoriesMap[bill.categoryRemoteId.toLong()] + val cat = categoriesMap[bill.categoryId] if (cat != null) { whatPrefix += cat.icon + " " } else { - when (bill.categoryRemoteId) { + when (bill.categoryId) { DBBill.CATEGORY_GROCERIES -> whatPrefix += "\uD83D\uDED2 " DBBill.CATEGORY_LEISURE -> whatPrefix += "\uD83C\uDF89 " DBBill.CATEGORY_RENT -> whatPrefix += "\uD83C\uDFE0 " diff --git a/app/src/main/java/net/helcel/cowspent/util/CategoryUtils.kt b/app/src/main/java/net/helcel/cowspent/util/CategoryUtils.kt index 7711be2..e20cb7b 100644 --- a/app/src/main/java/net/helcel/cowspent/util/CategoryUtils.kt +++ b/app/src/main/java/net/helcel/cowspent/util/CategoryUtils.kt @@ -10,28 +10,29 @@ object CategoryUtils { fun getDefaultCategories(context: Context, projectId: Long): List { return listOf( - DBCategory(0, DBBill.CATEGORY_GROCERIES.toLong(), projectId, context.getString(R.string.category_groceries), "\uD83D\uDED2", "#ffaa00"), - DBCategory(0, DBBill.CATEGORY_LEISURE.toLong(), projectId, context.getString(R.string.category_leisure), "\uD83C\uDF89", "#aa55ff"), - DBCategory(0, DBBill.CATEGORY_RENT.toLong(), projectId, context.getString(R.string.category_rent), "\uD83C\uDFE0", "#da8733"), - DBCategory(0, DBBill.CATEGORY_BILLS.toLong(), projectId, context.getString(R.string.category_bills), "\uD83C\uDF29", "#4aa6b0"), - DBCategory(0, DBBill.CATEGORY_CULTURE.toLong(), projectId, context.getString(R.string.category_excursion), "\uD83D\uDEB8", "#0055ff"), - DBCategory(0, DBBill.CATEGORY_HEALTH.toLong(), projectId, context.getString(R.string.category_health), "\uD83D\uDC9A", "#bf090c"), - DBCategory(0, DBBill.CATEGORY_SHOPPING.toLong(), projectId, context.getString(R.string.category_shopping), "\uD83D\uDECD", "#e167d1"), - DBCategory(0, DBBill.CATEGORY_REIMBURSEMENT.toLong(), projectId, context.getString(R.string.category_reimbursement), "\uD83D\uDCB0", "#00ced1"), - DBCategory(0, DBBill.CATEGORY_RESTAURANT.toLong(), projectId, context.getString(R.string.category_restaurant), "\uD83C\uDF74", "#d0d5e1"), - DBCategory(0, DBBill.CATEGORY_ACCOMMODATION.toLong(), projectId, context.getString(R.string.category_accomodation), "\uD83D\uDECC", "#5de1a3"), - DBCategory(0, DBBill.CATEGORY_TRANSPORT.toLong(), projectId, context.getString(R.string.category_transport), "\uD83D\uDE8C", "#6f2ee1"), - DBCategory(0, DBBill.CATEGORY_SPORT.toLong(), projectId, context.getString(R.string.category_sport), "\uD83C\uDFBE", "#69e177") + DBCategory(0, + DBBill.CATEGORY_GROCERIES, projectId, context.getString(R.string.category_groceries), "\uD83D\uDED2", "#ffaa00"), + DBCategory(0, DBBill.CATEGORY_LEISURE, projectId, context.getString(R.string.category_leisure), "\uD83C\uDF89", "#aa55ff"), + DBCategory(0, DBBill.CATEGORY_RENT, projectId, context.getString(R.string.category_rent), "\uD83C\uDFE0", "#da8733"), + DBCategory(0, DBBill.CATEGORY_BILLS, projectId, context.getString(R.string.category_bills), "\uD83C\uDF29", "#4aa6b0"), + DBCategory(0, DBBill.CATEGORY_CULTURE, projectId, context.getString(R.string.category_excursion), "\uD83D\uDEB8", "#0055ff"), + DBCategory(0, DBBill.CATEGORY_HEALTH, projectId, context.getString(R.string.category_health), "\uD83D\uDC9A", "#bf090c"), + DBCategory(0, DBBill.CATEGORY_SHOPPING, projectId, context.getString(R.string.category_shopping), "\uD83D\uDECD", "#e167d1"), + DBCategory(0, DBBill.CATEGORY_REIMBURSEMENT, projectId, context.getString(R.string.category_reimbursement), "\uD83D\uDCB0", "#00ced1"), + DBCategory(0, DBBill.CATEGORY_RESTAURANT, projectId, context.getString(R.string.category_restaurant), "\uD83C\uDF74", "#d0d5e1"), + DBCategory(0, DBBill.CATEGORY_ACCOMMODATION, projectId, context.getString(R.string.category_accomodation), "\uD83D\uDECC", "#5de1a3"), + DBCategory(0, DBBill.CATEGORY_TRANSPORT, projectId, context.getString(R.string.category_transport), "\uD83D\uDE8C", "#6f2ee1"), + DBCategory(0, DBBill.CATEGORY_SPORT, projectId, context.getString(R.string.category_sport), "\uD83C\uDFBE", "#69e177") ) } fun getDefaultPaymentModes(context: Context, projectId: Long): List { return listOf( - DBPaymentMode(0, DBBill.PAYMODE_ID_CARD.toLong(), projectId, context.getString(R.string.payment_mode_credit_card), "\uD83D\uDCB3", "#ff7f50"), - DBPaymentMode(0, DBBill.PAYMODE_ID_CASH.toLong(), projectId, context.getString(R.string.payment_mode_cash), "\uD83D\uDCB5", "#556b2f"), - DBPaymentMode(0, DBBill.PAYMODE_ID_CHECK.toLong(), projectId, context.getString(R.string.payment_mode_check), "\uD83C\uDFAB", "#a9a9a9"), - DBPaymentMode(0, DBBill.PAYMODE_ID_TRANSFER.toLong(), projectId, context.getString(R.string.payment_mode_transfer), "⇄", "#00ced1"), - DBPaymentMode(0, DBBill.PAYMODE_ID_ONLINE_SERVICE.toLong(), projectId, context.getString(R.string.payment_mode_online), "\uD83C\uDF0E", "#9932cc") + DBPaymentMode(0, DBBill.PAYMODE_ID_CARD, projectId, context.getString(R.string.payment_mode_credit_card), "\uD83D\uDCB3", "#ff7f50"), + DBPaymentMode(0, DBBill.PAYMODE_ID_CASH, projectId, context.getString(R.string.payment_mode_cash), "\uD83D\uDCB5", "#556b2f"), + DBPaymentMode(0, DBBill.PAYMODE_ID_CHECK, projectId, context.getString(R.string.payment_mode_check), "\uD83C\uDFAB", "#a9a9a9"), + DBPaymentMode(0, DBBill.PAYMODE_ID_TRANSFER, projectId, context.getString(R.string.payment_mode_transfer), "⇄", "#00ced1"), + DBPaymentMode(0, DBBill.PAYMODE_ID_ONLINE_SERVICE, projectId, context.getString(R.string.payment_mode_online), "\uD83C\uDF0E", "#9932cc") ) } } diff --git a/app/src/main/java/net/helcel/cowspent/util/ExportUtil.kt b/app/src/main/java/net/helcel/cowspent/util/ExportUtil.kt index c3bfec4..a9df23f 100644 --- a/app/src/main/java/net/helcel/cowspent/util/ExportUtil.kt +++ b/app/src/main/java/net/helcel/cowspent/util/ExportUtil.kt @@ -48,7 +48,7 @@ object ExportUtil { } owersTxt = owersTxt.replace(",$".toRegex(), "") fileContent += "\"${b.what}\",${b.amount},${b.date},${b.timestamp},\"$payerName\"," + - "$payerWeight,$payerActive,\"$owersTxt\",${b.repeat},${b.categoryRemoteId}," + + "$payerWeight,$payerActive,\"$owersTxt\",${b.repeat},${b.categoryId}," + "${b.paymentMode}\n" } diff --git a/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt b/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt index c8416ee..3aeb6f5 100644 --- a/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt +++ b/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt @@ -599,8 +599,8 @@ open class ServerResponse( var comment = "" var repeat = DBBill.NON_REPEATED var paymentMode = DBBill.PAYMODE_NONE - var paymentModeRemoteId = DBBill.PAYMODE_ID_NONE - var categoryId = DBBill.CATEGORY_NONE + var paymentModeId = DBBill.PAYMODE_ID_NONE.toLong() + var categoryId = DBBill.CATEGORY_NONE.toLong() if (!json.isNull("id")) { remoteId = json.getLong("id") } @@ -641,21 +641,21 @@ open class ServerResponse( paymentMode = json.getString("paymentmode") } if (json.has("categoryid") && !json.isNull("categoryid")) { - categoryId = json.getInt("categoryid") + categoryId = json.getLong("categoryid") Log.d("PLOP", "LOADED CATTTTTTTTTTTT $categoryId") } if (json.has("paymentmodeid") && !json.isNull("paymentmodeid")) { - paymentModeRemoteId = json.getInt("paymentmodeid") + paymentModeId = json.getLong("paymentmodeid") } // old MB, new Cospend is ok as Cospend provides the old pm ID // new MB, old Cospend => set payment mode ID from old one - if (DBBill.PAYMODE_NONE != paymentMode && "" != paymentMode && paymentModeRemoteId == DBBill.PAYMODE_ID_NONE) { + if (DBBill.PAYMODE_NONE != paymentMode && "" != paymentMode && paymentModeId == DBBill.PAYMODE_ID_NONE.toLong()) { Log.d("PaymentMode", "old: $paymentMode and new: 0") - paymentModeRemoteId = DBBill.oldPmIdToNew[paymentMode] ?: DBBill.PAYMODE_ID_NONE + paymentModeId = (DBBill.oldPmIdToNew[paymentMode] ?: DBBill.PAYMODE_ID_NONE).toLong() } val bill = DBBill( 0, remoteId, projId, payerId, amount, timestamp, what, - DBBill.STATE_OK, repeat, paymentMode, categoryId, comment, paymentModeRemoteId + DBBill.STATE_OK, repeat, paymentMode, categoryId, comment, paymentModeId ) bill.billOwers = getBillOwersFromJson(json, memberRemoteIdToId) return bill diff --git a/app/src/main/java/net/helcel/cowspent/util/SupportUtil.kt b/app/src/main/java/net/helcel/cowspent/util/SupportUtil.kt index 74f5f5d..01e8dbf 100644 --- a/app/src/main/java/net/helcel/cowspent/util/SupportUtil.kt +++ b/app/src/main/java/net/helcel/cowspent/util/SupportUtil.kt @@ -124,9 +124,9 @@ object SupportUtil { for (b in dbBills) { // don't take deleted bills and respect category filter if (b.state != DBBill.STATE_DELETED && - ((catId == -1000 || catId == -100 || b.categoryRemoteId == catId) && - (catId != -100 || b.categoryRemoteId != DBBill.CATEGORY_REIMBURSEMENT) && - (paymentModeId == -1000 || b.paymentModeRemoteId == paymentModeId)) && + ((catId == -1000 || catId == -100 || b.categoryId == catId.toLong()) && + (catId != -100 || b.categoryId != DBBill.CATEGORY_REIMBURSEMENT.toLong()) && + (paymentModeId == -1000 || b.paymentModeId == paymentModeId.toLong())) && (dateMin == null || b.date >= dateMin) && (dateMax == null || b.date <= dateMax) ) { diff --git a/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt b/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt index 0d027bf..27c93c2 100644 --- a/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt +++ b/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt @@ -260,7 +260,13 @@ class VersatileProjectSyncClient( } @Throws(IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class) - fun editRemoteBill(project: DBProject, bill: DBBill, memberIdToRemoteId: Map): ServerResponse.EditRemoteBillResponse { + fun editRemoteBill( + project: DBProject, + bill: DBBill, + memberIdToRemoteId: Map, + categoryIdToRemoteId: Map, + paymentModeIdToRemoteId: Map + ): ServerResponse.EditRemoteBillResponse { val paramKeys: MutableList = ArrayList() val paramValues: MutableList = ArrayList() paramKeys.add("date") @@ -307,8 +313,10 @@ class VersatileProjectSyncClient( payedFor = payedFor.replace(",$".toRegex(), "") paramValues.add(payedFor) paramValues.add(bill.paymentMode ?: "") - paramValues.add(bill.categoryRemoteId.toString()) - paramValues.add(bill.paymentModeRemoteId.toString()) + val remoteCatId = if (bill.categoryId <= 0) bill.categoryId else categoryIdToRemoteId[bill.categoryId] ?: 0 + val remotePmId = if (bill.paymentModeId <= 0) bill.paymentModeId else paymentModeIdToRemoteId[bill.paymentModeId] ?: 0 + paramValues.add(remoteCatId.toString()) + paramValues.add(remotePmId.toString()) if (canAccessProjectWithNCLogin(project)) { username = this.username @@ -512,7 +520,13 @@ class VersatileProjectSyncClient( } @Throws(IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class) - fun createRemoteBill(project: DBProject, bill: DBBill, memberIdToRemoteId: Map): ServerResponse.CreateRemoteBillResponse { + fun createRemoteBill( + project: DBProject, + bill: DBBill, + memberIdToRemoteId: Map, + categoryIdToRemoteId: Map, + paymentModeIdToRemoteId: Map + ): ServerResponse.CreateRemoteBillResponse { val paramKeys: MutableList = ArrayList() val paramValues: MutableList = ArrayList() paramKeys.add("date") @@ -554,8 +568,10 @@ class VersatileProjectSyncClient( payedFor = payedFor.replace(",$".toRegex(), "") paramValues.add(payedFor) paramValues.add(bill.paymentMode ?: "") - paramValues.add(bill.categoryRemoteId.toString()) - paramValues.add(bill.paymentModeRemoteId.toString()) + val remoteCatId = if (bill.categoryId <= 0) bill.categoryId else categoryIdToRemoteId[bill.categoryId] ?: 0 + val remotePmId = if (bill.paymentModeId <= 0) bill.paymentModeId else paymentModeIdToRemoteId[bill.paymentModeId] ?: 0 + paramValues.add(remoteCatId.toString()) + paramValues.add(remotePmId.toString()) if (canAccessProjectWithNCLogin(project)) { username = this.username