Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
893 changes: 893 additions & 0 deletions api.yaml

Large diffs are not rendered by default.

320 changes: 93 additions & 227 deletions app/openapi/api.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package info.nukoneko.cuc.android.kidspos.di.module
import info.nukoneko.cuc.android.kidspos.api.APIService
import info.nukoneko.cuc.android.kidspos.entity.Item
import info.nukoneko.cuc.android.kidspos.entity.Sale
import info.nukoneko.cuc.android.kidspos.entity.Staff
import info.nukoneko.cuc.android.kidspos.entity.Store
import org.koin.dsl.module
import java.util.*
Expand All @@ -15,15 +14,13 @@ import java.util.*
class DemoAPIService : APIService(
itemsApi = throw NotImplementedError("Demo mode - itemsApi not used"),
salesApi = throw NotImplementedError("Demo mode - salesApi not used"),
staffApi = throw NotImplementedError("Demo mode - staffApi not used"),
storesApi = throw NotImplementedError("Demo mode - storesApi not used"),
settingsApi = throw NotImplementedError("Demo mode - settingsApi not used")
) {
override suspend fun getStatus(): Any = mapOf("status" to "OK", "mode" to "demo")

override suspend fun createSale(
storeId: Int,
staffBarcode: String,
deposit: Int,
itemIds: String
): Sale = Sale(
Expand Down Expand Up @@ -52,9 +49,6 @@ class DemoAPIService : APIService(
storeId = 1,
genreId = 1
)

override suspend fun getStaff(staffBarcode: String): Staff =
Staff(staffBarcode, "DemoStaff")
}

val apiModule = module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import info.nukoneko.cuc.android.kidspos.api.generated.*
import info.nukoneko.cuc.android.kidspos.api.generated.model.*
import info.nukoneko.cuc.android.kidspos.entity.Item
import info.nukoneko.cuc.android.kidspos.entity.Sale
import info.nukoneko.cuc.android.kidspos.entity.Staff
import info.nukoneko.cuc.android.kidspos.entity.Store
import retrofit2.Response

Expand All @@ -14,7 +13,6 @@ import retrofit2.Response
open class APIService(
private val itemsApi: ItemsApi,
private val salesApi: SalesApi,
private val staffApi: StaffApi,
private val storesApi: StoresApi,
private val settingsApi: SettingsApi
) {
Expand All @@ -36,38 +34,27 @@ open class APIService(

open suspend fun createSale(
storeId: Int,
staffBarcode: String,
deposit: Int,
itemIds: String
): Sale {
// itemIdsをカンマ区切りからリストに変換
// 注意: 新しいAPIではitemIdではなくバーコードを使用
val itemBarcodes = itemIds.split(",")

val request = CreateSaleRequest(
storeId = storeId,
staffBarcode = staffBarcode,
deposit = deposit,
items = itemBarcodes.map { barcode ->
CreateSaleRequestItemsInner(
barcode = barcode,
quantity = 1 // デフォルトで1個とする
)
}
itemIds = itemIds,
deposit = deposit
)

val response = salesApi.createSale(request)
return if (response.isSuccessful) {
val saleResponse = response.body()!!
Sale(
id = saleResponse.saleId ?: 0,
barcode = saleResponse.saleId?.toString() ?: "", // バーコードはIDから生成
createdAt = java.util.Date().toString(), // 現在時刻を設定
points = 0, // ポイントは新APIにない
price = saleResponse.totalAmount ?: 0,
items = itemIds, // 元のitemIdsをそのまま使用
storeId = storeId,
staffId = 0 // スタッフIDは取得できないため仮値
id = saleResponse.id ?: 0,
barcode = saleResponse.id?.toString() ?: "",
createdAt = java.util.Date().toString(),
points = 0,
price = saleResponse.amount ?: 0,
items = itemIds,
storeId = saleResponse.storeId ?: storeId,
staffId = 0
)
} else {
throw Exception("Failed to create sale: ${response.code()}")
Expand All @@ -91,19 +78,6 @@ open class APIService(
}
}

open suspend fun getStaff(staffBarcode: String): Staff {
val response = staffApi.getStaffByBarcode(staffBarcode)
return if (response.isSuccessful) {
val staffResponse = response.body()!!
Staff(
barcode = staffResponse.barcode ?: staffBarcode,
name = staffResponse.name ?: ""
)
} else {
throw Exception("Failed to get staff: ${response.code()}")
}
}

open suspend fun getStatus(): Any {
val response = settingsApi.getStatus()
return if (response.isSuccessful) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package info.nukoneko.cuc.android.kidspos.di
import android.content.Context
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import info.nukoneko.cuc.android.kidspos.entity.Staff
import info.nukoneko.cuc.android.kidspos.entity.Store
import info.nukoneko.cuc.android.kidspos.event.EventBus
import info.nukoneko.cuc.android.kidspos.event.SystemEvent
Expand Down Expand Up @@ -54,23 +53,10 @@ class GlobalConfig(context: Context, private val eventBus: EventBus, private val
eventBus.post(SystemEvent.SelectShop(value))
}

var currentStaff: Staff?
get() {
return preference.getString(KEY_STAFF, null)?.let {
return json.decodeFromString<Staff>(it)
}
}
set(value) {
preference.edit {
putString(KEY_STAFF, json.encodeToString(value))
}
}

companion object {
const val KEY_SERVER_INFO = "setting_server_info"
const val KEY_RUNNING_MODE = "setting_running_mode"
const val DEFAULT_SERVER_INFO = "http://192.168.0.220:8080"
const val KEY_STORE = "store"
const val KEY_STAFF = "staff"
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
package info.nukoneko.cuc.android.kidspos.di

import com.orhanobut.logger.Logger
import okhttp3.Interceptor
import okhttp3.Response

class ServerSelectionInterceptor(var serverAddress: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
if (serverAddress.isNotEmpty()) {
val url = "$serverAddress/api/${request.url.pathSegments.joinToString("/")}"
val url = "$serverAddress/${request.url.pathSegments.joinToString("/")}"
request = request.newBuilder().url(url).build()
}
return chain.proceed(request)

// リクエスト情報をダンプ
Logger.d("HTTP Request: ${request.method} ${request.url}")
Logger.d(" Headers: ${request.headers}")
if (request.url.querySize > 0) {
Logger.d(" Query params: ${request.url.query}")
}
request.body?.let { body ->
val buffer = okio.Buffer()
body.writeTo(buffer)
val bodyString = buffer.readUtf8()
Logger.d(" Body: content-type=${body.contentType()}")
Logger.d(" Body content: $bodyString")
}

val startTime = System.currentTimeMillis()
val response = chain.proceed(request)
val duration = System.currentTimeMillis() - startTime

Logger.i("HTTP Response: ${response.code} ${request.method} ${request.url} (${duration}ms)")

return response
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ val coreModule = module {
single<Interceptor>(named("serverSelection")) {
ServerSelectionInterceptor((get<GlobalConfig>().currentServerAddress))
}
single<Interceptor>(named("logging")) {
okhttp3.logging.HttpLoggingInterceptor().apply {
level = okhttp3.logging.HttpLoggingInterceptor.Level.BODY
}
}
single {
OkHttpClient.Builder().addInterceptor(get<Interceptor>(named("serverSelection"))).build()
OkHttpClient.Builder()
.addInterceptor(get<Interceptor>(named("serverSelection")))
.addInterceptor(get<Interceptor>(named("logging")))
.build()
}
single {
val contentType = "application/json".toMediaType()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1 @@
package info.nukoneko.cuc.android.kidspos.entity

import kotlinx.serialization.Serializable

@Serializable
data class Staff(val barcode: String, val name: String) {
companion object {
fun create(barcode: String): Staff {
return Staff(barcode, "Dummy")
}
}
}
// This file is deprecated and will be removed
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package info.nukoneko.cuc.android.kidspos.event

import info.nukoneko.cuc.android.kidspos.entity.Item
import info.nukoneko.cuc.android.kidspos.entity.Staff

sealed class BarcodeEvent : Event {
data class ReadReceiptFailed(val error: Throwable) : BarcodeEvent()
data class ReadItemSuccess(val item: Item) : BarcodeEvent()
data class ReadItemFailed(val error: Throwable) : BarcodeEvent()
data class ReadStaffSuccess(val staff: Staff) : BarcodeEvent()
data class ReadStaffFailed(val error: Throwable) : BarcodeEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.view.KeyEvent
import androidx.appcompat.app.AppCompatActivity
import com.orhanobut.logger.Logger
import info.nukoneko.cuc.android.kidspos.error.IllegalBarcodeException
import info.nukoneko.cuc.android.kidspos.util.BarcodeKind
import info.nukoneko.cuc.android.kidspos.util.BarcodeReadDelegate

abstract class BaseBarcodeReadableActivity : AppCompatActivity() {
Expand All @@ -14,14 +13,14 @@ abstract class BaseBarcodeReadableActivity : AppCompatActivity() {
Logger.e(e, "onReadFailed")
}

override fun onReadSuccess(barcode: String, kind: BarcodeKind) {
onBarcodeInput(barcode, kind)
override fun onReadSuccess(barcode: String) {
onBarcodeInput(barcode)
}
}

private val barcodeDelegate = BarcodeReadDelegate(onBarcodeReadListener)

abstract fun onBarcodeInput(barcode: String, prefix: BarcodeKind)
abstract fun onBarcodeInput(barcode: String)

final override fun dispatchKeyEvent(event: KeyEvent): Boolean {
return barcodeDelegate.onKeyEvent(event)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import info.nukoneko.cuc.android.kidspos.ui.common.ErrorDialogFragment
import info.nukoneko.cuc.android.kidspos.ui.main.itemlist.ItemListFragment
import info.nukoneko.cuc.android.kidspos.ui.main.storelist.StoreListDialogFragment
import info.nukoneko.cuc.android.kidspos.ui.setting.SettingActivity
import info.nukoneko.cuc.android.kidspos.util.BarcodeKind
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -33,8 +32,8 @@ class MainActivity : BaseBarcodeReadableActivity(), CoroutineScope {
Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show()
}

override fun onNotReachableServer() {
showNotReachableErrorDialog()
override fun onNotReachableServer(errorMessage: String) {
showNotReachableErrorDialog(errorMessage)
}

override fun onShouldChangeTitleSuffix(titleSuffix: String) {
Expand All @@ -50,8 +49,8 @@ class MainActivity : BaseBarcodeReadableActivity(), CoroutineScope {
fragment.isCancelable = false
fragment.show(supportFragmentManager, "changeStore")
}
R.id.input_dummy_item -> onBarcodeInput("1234567890", BarcodeKind.ITEM)
R.id.input_dummy_store -> onBarcodeInput("1234567890", BarcodeKind.STAFF)

R.id.input_dummy_item -> onBarcodeInput("1234567890")
}
binding.drawerLayout.closeDrawer(GravityCompat.START)
true
Expand Down Expand Up @@ -91,18 +90,19 @@ class MainActivity : BaseBarcodeReadableActivity(), CoroutineScope {
override fun onResume() {
super.onResume()
myViewModel.onResume()
@Suppress("KotlinConstantConditions")
binding.navView.menu.setGroupVisible(R.id.beta_test, ProjectSettings.DEMO_MODE)
}

override fun onBarcodeInput(barcode: String, prefix: BarcodeKind) {
myViewModel.onBarcodeInput(barcode, prefix)
override fun onBarcodeInput(barcode: String) {
myViewModel.onBarcodeInput(barcode)
}

private fun showNotReachableErrorDialog() {
private fun showNotReachableErrorDialog(errorMessage: String) {
launch {
val result = ErrorDialogFragment.showWithSuspend(
supportFragmentManager,
"サーバーとの接続に失敗しました\n・ネットワーク接続を確認してください\n・設定画面で設定を確認をしてください"
errorMessage
)
when (result) {
ErrorDialogFragment.DialogResult.OK -> SettingActivity.createIntent(this@MainActivity)
Expand Down
Loading