Skip to content

Commit d62eddc

Browse files
frist commit
1 parent 93834a9 commit d62eddc

9 files changed

Lines changed: 138 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ name: SwiftPOS CI
22

33
on:
44
push:
5-
branches: [ "main", "develop" ]
5+
branches: [ "master", "main", "develop" ]
66
pull_request:
7-
branches: [ "main", "develop" ]
7+
branches: [ "master", "main", "develop" ]
8+
workflow_dispatch:
89

910
concurrency:
1011
group: ${{ github.workflow }}-${{ github.ref }}
@@ -62,4 +63,4 @@ jobs:
6263
uses: actions/upload-artifact@v4
6364
with:
6465
name: swiftpos-debug
65-
path: app/build/outputs/apk/debug/*.apk
66+
path: app/build/outputs/apk/debug/*.apk

app/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ dependencies {
6363
implementation(libs.androidx.core.ktx)
6464
implementation(libs.androidx.lifecycle.runtime.ktx)
6565

66+
implementation(libs.androidx.work.runtime.ktx)
67+
implementation(libs.androidx.hilt.work)
68+
ksp(libs.androidx.hilt.compiler)
69+
6670
// Tests
6771
testImplementation(libs.junit)
6872
androidTestImplementation(platform(libs.androidx.compose.bom))
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
package com.example.swiftpos
22

33
import android.app.Application
4+
import androidx.hilt.work.HiltWorkerFactory
5+
import androidx.work.Configuration
46
import dagger.hilt.android.HiltAndroidApp
7+
import javax.inject.Inject
58

69
@HiltAndroidApp
7-
class SwiftPosApp : Application()
10+
class SwiftPosApp : Application(), Configuration.Provider {
11+
12+
@Inject
13+
lateinit var workerFactory: HiltWorkerFactory
14+
15+
override val workManagerConfiguration: Configuration
16+
get() = Configuration.Builder()
17+
.setWorkerFactory(workerFactory)
18+
.build()
19+
}

core/core-data/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@ dependencies {
4444
implementation(platform(libs.okhttp.bom))
4545
implementation(libs.okhttp)
4646
implementation(libs.okhttp.logging)
47+
implementation(libs.androidx.work.runtime.ktx)
48+
implementation(libs.androidx.hilt.work)
49+
ksp(libs.androidx.hilt.compiler)
4750
testImplementation(libs.junit)
4851
}

core/core-data/src/main/kotlin/com/swiftpos/core/data/di/DataModule.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import com.swiftpos.core.data.repository.ProductRepositoryImpl
1111
import com.swiftpos.core.data.repository.TransactionRepositoryImpl
1212
import com.swiftpos.core.domain.repository.ProductRepository
1313
import com.swiftpos.core.domain.repository.TransactionRepository
14+
import com.swiftpos.core.data.remote.SyncApi
15+
import retrofit2.Retrofit
16+
import retrofit2.converter.gson.GsonConverterFactory
1417
import dagger.Binds
1518
import dagger.Module
1619
import dagger.Provides
@@ -51,4 +54,15 @@ object DataModule {
5154
@Provides
5255
@Singleton
5356
fun provideTransactionRepository(impl: TransactionRepositoryImpl): TransactionRepository = impl
57+
58+
@Provides
59+
@Singleton
60+
fun provideRetrofit(gson: Gson): Retrofit = Retrofit.Builder()
61+
.baseUrl("https://api.swiftpos.com/") // Stub URL
62+
.addConverterFactory(GsonConverterFactory.create(gson))
63+
.build()
64+
65+
@Provides
66+
@Singleton
67+
fun provideSyncApi(retrofit: Retrofit): SyncApi = retrofit.create(SyncApi::class.java)
5468
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.swiftpos.core.data.remote
2+
3+
import com.swiftpos.core.domain.model.Transaction
4+
import retrofit2.http.Body
5+
import retrofit2.http.POST
6+
7+
interface SyncApi {
8+
@POST("v1/sync/transactions")
9+
suspend fun syncTransactions(@Body transactions: List<Transaction>)
10+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.swiftpos.core.data.sync
2+
3+
import android.content.Context
4+
import androidx.hilt.work.HiltWorker
5+
import androidx.work.CoroutineWorker
6+
import androidx.work.WorkerParameters
7+
import com.swiftpos.core.data.local.TransactionDao
8+
import com.swiftpos.core.data.remote.SyncApi
9+
import com.swiftpos.core.data.repository.toDomain
10+
import dagger.assisted.Assisted
11+
import dagger.assisted.AssistedInject
12+
13+
@HiltWorker
14+
class TransactionSyncWorker @AssistedInject constructor(
15+
@Assisted context: Context,
16+
@Assisted workerParams: WorkerParameters,
17+
private val transactionDao: TransactionDao,
18+
private val syncApi: SyncApi
19+
) : CoroutineWorker(context, workerParams) {
20+
21+
override suspend fun doWork(): Result {
22+
return try {
23+
val unsyncedEntities = transactionDao.getUnsyncedTransactions()
24+
25+
if (unsyncedEntities.isEmpty()) {
26+
return Result.success()
27+
}
28+
29+
// Map entities to domain model
30+
val transactions = unsyncedEntities.map { it.toDomain() }
31+
32+
// Push to remote API
33+
syncApi.syncTransactions(transactions)
34+
35+
// Mark as synced locally
36+
val syncedIds = unsyncedEntities.map { it.id }
37+
transactionDao.markAsSynced(syncedIds)
38+
39+
Result.success()
40+
} catch (e: Exception) {
41+
Result.retry()
42+
}
43+
}
44+
}

gradle/libs.versions.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ hiltNavigationCompose = "1.2.0"
1919
lifecycleViewmodelCompose = "2.8.5"
2020
mockk = "1.13.10"
2121
turbine = "1.1.0"
22+
work = "2.10.0"
23+
hiltWork = "1.2.0"
2224

2325
[libraries]
2426
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -54,6 +56,9 @@ androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "l
5456
mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
5557
turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" }
5658
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
59+
androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
60+
androidx-hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltWork" }
61+
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltWork" }
5762

5863
[plugins]
5964
android-application = { id = "com.android.application", version.ref = "agp" }
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,43 @@
11
package com.swiftpos.peripheral.di
22

3+
import android.bluetooth.BluetoothAdapter
4+
import android.bluetooth.BluetoothManager
5+
import android.content.Context
6+
import com.swiftpos.peripheral.bluetooth.BluetoothPrinterImpl
7+
import com.swiftpos.peripheral.domain.DrawerPort
8+
import com.swiftpos.peripheral.domain.PrinterPort
9+
import dagger.Binds
10+
import dagger.Module
11+
import dagger.Provides
12+
import dagger.hilt.InstallIn
13+
import dagger.hilt.android.qualifiers.ApplicationContext
14+
import dagger.hilt.components.SingletonComponent
15+
import javax.inject.Singleton
16+
17+
@Module
18+
@InstallIn(SingletonComponent::class)
19+
abstract class PeripheralModule {
20+
21+
@Binds
22+
@Singleton
23+
abstract fun bindPrinterPort(
24+
bluetoothPrinterImpl: BluetoothPrinterImpl
25+
): PrinterPort
26+
27+
@Binds
28+
@Singleton
29+
abstract fun bindDrawerPort(
30+
bluetoothPrinterImpl: BluetoothPrinterImpl
31+
): DrawerPort
32+
33+
companion object {
34+
@Provides
35+
@Singleton
36+
fun provideBluetoothAdapter(
37+
@ApplicationContext context: Context
38+
): BluetoothAdapter? {
39+
val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
40+
return bluetoothManager?.adapter
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)