diff --git a/app/src/main/java/org/swm/att/di/NetworkModule.kt b/app/src/main/java/org/swm/att/di/NetworkModule.kt index 126356d8..82947ff9 100644 --- a/app/src/main/java/org/swm/att/di/NetworkModule.kt +++ b/app/src/main/java/org/swm/att/di/NetworkModule.kt @@ -8,6 +8,7 @@ import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import org.swm.att.BuildConfig +import org.swm.att.data.json_adapter.JsonAdapter import org.swm.att.data.remote.datasource.AttEncryptedPrefDataSource import org.swm.att.data.remote.datasource.AttEncryptedPrefDataSource.Companion.PreferenceKey.ACCESS_TOKEN import retrofit2.Retrofit @@ -55,10 +56,10 @@ object NetworkModule { @Singleton fun providePingRetrofit(okHttpClient: OkHttpClient): Retrofit { return Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create()) + .addConverterFactory(MoshiConverterFactory.create(JsonAdapter.moshi)) .client(okHttpClient) .baseUrl(BuildConfig.ATT_BASE_URL) .build() } +} -} \ No newline at end of file diff --git a/common-ui/build.gradle.kts b/common-ui/build.gradle.kts index e872868e..5a974e6e 100644 --- a/common-ui/build.gradle.kts +++ b/common-ui/build.gradle.kts @@ -43,5 +43,6 @@ dependencies { implementation(libs.material) testImplementation(libs.bundles.basic.test) implementation(libs.hilt) + implementation(libs.mpandroidchart) kapt(libs.hilt.kapt) } \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/adapter/SduiReportAdapter.kt b/common-ui/src/main/java/org/swm/att/common_ui/adapter/SduiReportAdapter.kt new file mode 100644 index 00000000..9bf6fb09 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/adapter/SduiReportAdapter.kt @@ -0,0 +1,29 @@ +package org.swm.att.common_ui.adapter + +import android.view.ViewGroup +import androidx.recyclerview.widget.ListAdapter +import org.swm.att.common_ui.util.ItemDiffCallback +import org.swm.att.common_ui.viewholder.BaseSduiViewHolder +import org.swm.att.common_ui.viewholder.getSduiViewHolder +import org.swm.att.domain.entity.response.SduiReportItemVO +import org.swm.att.domain.sever_driven_ui.SduiViewType + +class SduiReportAdapter: ListAdapter( + ItemDiffCallback( + onContentTheSame = { old, new -> old == new }, + onItemsTheSame = { old, new -> old.content == new.content } + ) +) { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseSduiViewHolder { + return getSduiViewHolder(parent, SduiViewType.getViewTypeByOrdinal(viewType)) + } + + override fun onBindViewHolder(holder: BaseSduiViewHolder, position: Int) { + val item = getItem(position) + holder.bind(item.content) + } + + override fun getItemViewType(position: Int): Int { + return getItem(position).viewType.ordinal + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/richtext/RichTextSpannable.kt b/common-ui/src/main/java/org/swm/att/common_ui/richtext/RichTextSpannable.kt new file mode 100644 index 00000000..948786e7 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/richtext/RichTextSpannable.kt @@ -0,0 +1,41 @@ +package org.swm.att.common_ui.richtext + +import android.graphics.Color +import android.text.SpannableString +import android.text.style.ForegroundColorSpan +import android.text.style.RelativeSizeSpan +import org.swm.att.domain.sever_driven_ui.response.text.ReportTextItemVO + +class RichTextSpannable(richText: ReportTextItemVO): SpannableString(richText.text) { + class Builder(private val richText: ReportTextItemVO) { + private val spannableString = SpannableString(richText.text) + + fun setTextColor(color: String?): Builder { + color?.let { + Color.parseColor(it).let { + spannableString.setSpan( + ForegroundColorSpan(it), + 0, + richText.text?.length ?: 0, + SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + return this + } + + fun setFontSize(size: Float?): Builder { + size?.let { + spannableString.setSpan( + RelativeSizeSpan(it), + 0, + richText.text?.length ?: 0, + SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + return this + } + + fun build() = spannableString + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/BaseSduiViewHolder.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/BaseSduiViewHolder.kt new file mode 100644 index 00000000..f1d03763 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/BaseSduiViewHolder.kt @@ -0,0 +1,11 @@ +package org.swm.att.common_ui.viewholder + +import androidx.databinding.ViewDataBinding +import androidx.recyclerview.widget.RecyclerView +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +sealed class BaseSduiViewHolder( + binding: ViewDataBinding +): RecyclerView.ViewHolder(binding.root) { + abstract fun bind(reportContent: SduiReportContent) +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiGraphViewHolder.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiGraphViewHolder.kt new file mode 100644 index 00000000..ba81777a --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiGraphViewHolder.kt @@ -0,0 +1,97 @@ +package org.swm.att.common_ui.viewholder + +import android.annotation.SuppressLint +import android.graphics.Color +import android.graphics.DashPathEffect +import com.github.mikephil.charting.animation.Easing +import com.github.mikephil.charting.components.Legend +import com.github.mikephil.charting.components.XAxis +import com.github.mikephil.charting.components.YAxis +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import org.swm.att.common_ui.databinding.ItemSduiGraphBinding +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent +import org.swm.att.domain.sever_driven_ui.response.graph.ReportGraphVO + + +class SduiGraphViewHolder( + private val binding: ItemSduiGraphBinding +): BaseSduiViewHolder(binding) { + override fun bind(reportContent: SduiReportContent) { + initGraph() + setGraph(reportContent as ReportGraphVO) + } + + @SuppressLint("ResourceAsColor") + private fun initGraph() { + with(binding.reportLineChart) { + setGridBackgroundColor(Color.parseColor("#F5F5F5")) + animateX(1200, Easing.EaseInSine) + description.isEnabled = false + + val xAxis: XAxis = binding.reportLineChart.getXAxis() + xAxis.setDrawAxisLine(false) + xAxis.setDrawGridLines(false) + xAxis.position = XAxis.XAxisPosition.BOTTOM // x축 데이터 표시 위치 + xAxis.granularity = 1f + xAxis.textSize = 14f + xAxis.textColor = Color.rgb(118, 118, 118) + xAxis.spaceMin = 0.1f + xAxis.spaceMax = 0.1f + + val yAxisLeft: YAxis = binding.reportLineChart.getAxisLeft() + yAxisLeft.textSize = 14f + yAxisLeft.textColor = Color.rgb(163, 163, 163) + yAxisLeft.setDrawAxisLine(false) + yAxisLeft.axisLineWidth = 2f + yAxisLeft.axisMinimum = 0f + + val yAxis: YAxis = binding.reportLineChart.getAxisRight() + yAxis.setDrawLabels(false) + yAxis.textColor = Color.rgb(163, 163, 163) + yAxis.setDrawAxisLine(false) + yAxis.axisLineWidth = 2f + yAxis.axisMinimum = 0f + + legend.orientation = Legend.LegendOrientation.VERTICAL + legend.verticalAlignment = Legend.LegendVerticalAlignment.TOP + legend.horizontalAlignment = Legend.LegendHorizontalAlignment.CENTER + legend.textSize = 15F + legend.form = Legend.LegendForm.LINE + } + } + + private fun setGraph(reportGraphData: ReportGraphVO) { + binding.chartTitle = reportGraphData.graphTitle + + // entries 구하기 + val entries = ArrayList() + reportGraphData.graphItems.map { reportGraphItemVO -> + entries.add(Entry(reportGraphItemVO.graphKey.toFloat(), reportGraphItemVO.graphValue.toFloat())) + } + + // lineDataSet 설정 + val lineDataSet = LineDataSet(entries, null) + lineDataSet.apply { + valueTextSize = 15f + mode = LineDataSet.Mode.CUBIC_BEZIER + color = Color.parseColor(reportGraphData.graphColor) + setCircleColor(Color.parseColor(reportGraphData.graphColor)) + setDrawCircleHole(true) + circleRadius = 5f + setFormLineDashEffect(DashPathEffect(floatArrayOf(10f, 5f), 0f)) + valueTextColor = Color.BLACK + } + + // lineData 설정 + val dataSet: List = arrayListOf(lineDataSet, lineDataSet) + val lineData = LineData(dataSet) + binding.reportLineChart.apply { + setDrawGridBackground(true) + data = lineData + } + + binding.reportLineChart.invalidate() + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiPieChartViewHolder.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiPieChartViewHolder.kt new file mode 100644 index 00000000..bdf3a639 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiPieChartViewHolder.kt @@ -0,0 +1,45 @@ +package org.swm.att.common_ui.viewholder + +import android.graphics.Color +import com.github.mikephil.charting.animation.Easing +import com.github.mikephil.charting.components.Legend +import com.github.mikephil.charting.data.PieData +import com.github.mikephil.charting.data.PieDataSet +import com.github.mikephil.charting.data.PieEntry +import org.swm.att.common_ui.databinding.ItemSduiPiechartBinding +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent +import org.swm.att.domain.sever_driven_ui.response.piechart.ReportPieChartVO + + +class SduiPieChartViewHolder( + private val binding: ItemSduiPiechartBinding +): BaseSduiViewHolder(binding) { + override fun bind(reportContent: SduiReportContent) { + setPieChart(reportContent as ReportPieChartVO) + } + + private fun setPieChart(reportPieChartData: ReportPieChartVO) { + binding.chartTitle = reportPieChartData.pieChartTitle + val dataList = mutableListOf() + val colorList = mutableListOf() + for (item in (reportPieChartData).pieChartItems) { + dataList.add(PieEntry(item.categoryCount.toFloat(), item.categoryName)) + colorList.add(Color.parseColor(item.chartColor)) + } + val dataSet = PieDataSet(dataList, null) + dataSet.colors = colorList + val pieData = PieData(dataSet) + + binding.reportPieChart.apply { + data = pieData + description.isEnabled = false + isRotationEnabled = false + isDrawHoleEnabled = true + holeRadius = 60f + setEntryLabelTextSize(10f) + setEntryLabelColor(Color.BLACK) + animateY(1400, Easing.EaseInOutQuad) + animate() + } + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiTextViewHolder.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiTextViewHolder.kt new file mode 100644 index 00000000..e3149ac6 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiTextViewHolder.kt @@ -0,0 +1,34 @@ +package org.swm.att.common_ui.viewholder + +import android.text.SpannableStringBuilder +import android.view.Gravity +import org.swm.att.common_ui.databinding.ItemSduiTextBinding +import org.swm.att.common_ui.richtext.RichTextSpannable +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent +import org.swm.att.domain.sever_driven_ui.response.text.ReportTextVO + +class SduiTextViewHolder( + private val binding: ItemSduiTextBinding +): BaseSduiViewHolder(binding) { + private var spanTextList = SpannableStringBuilder() + + override fun bind(reportContent: SduiReportContent) { + reportContent as ReportTextVO + + reportContent.textItems.forEach { + val spannableString = RichTextSpannable.Builder(it) + .setTextColor(it.color) + .setFontSize(it.size) + .build() + + spanTextList.append(spannableString) + } + + binding.tvSdui.text = spanTextList + when(reportContent.align) { + "LEFT" -> binding.tvSdui.setGravity(Gravity.START) + "RIGHT" -> binding.tvSdui.setGravity(Gravity.END) + "CENTER" -> binding.tvSdui.setGravity(Gravity.CENTER) + } + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiUnknownViewHolder.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiUnknownViewHolder.kt new file mode 100644 index 00000000..7ee81f39 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiUnknownViewHolder.kt @@ -0,0 +1,13 @@ +package org.swm.att.common_ui.viewholder + +import android.util.Log +import org.swm.att.common_ui.databinding.ItemSduiUnknownBinding +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +class SduiUnknownViewHolder( + private val binding: ItemSduiUnknownBinding +): BaseSduiViewHolder(binding) { + override fun bind(reportContent: SduiReportContent) { + Log.d("SduiUnknownViewHolder", "bind: $reportContent") + } +} \ No newline at end of file diff --git a/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiViewHolderFactory.kt b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiViewHolderFactory.kt new file mode 100644 index 00000000..141bb9c9 --- /dev/null +++ b/common-ui/src/main/java/org/swm/att/common_ui/viewholder/SduiViewHolderFactory.kt @@ -0,0 +1,34 @@ +package org.swm.att.common_ui.viewholder + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.databinding.ViewDataBinding +import org.swm.att.common_ui.R +import org.swm.att.common_ui.databinding.ItemSduiGraphBinding +import org.swm.att.common_ui.databinding.ItemSduiPiechartBinding +import org.swm.att.common_ui.databinding.ItemSduiTextBinding +import org.swm.att.common_ui.databinding.ItemSduiUnknownBinding +import org.swm.att.domain.sever_driven_ui.SduiViewType + +fun getSduiViewHolder(parent: ViewGroup, viewType: SduiViewType): BaseSduiViewHolder { + val layout = getLayoutByViewType(viewType) + val binding: ViewDataBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), layout, parent, false) + + //수정해야 함. + return when(viewType) { + SduiViewType.PIECHART -> SduiPieChartViewHolder(binding as ItemSduiPiechartBinding) + SduiViewType.GRAPH -> SduiGraphViewHolder(binding as ItemSduiGraphBinding) + SduiViewType.TEXT -> SduiTextViewHolder(binding as ItemSduiTextBinding) + SduiViewType.UNKNOWN -> SduiUnknownViewHolder(binding as ItemSduiUnknownBinding) + } +} + +fun getLayoutByViewType(viewType: SduiViewType): Int { + return when(viewType) { + SduiViewType.PIECHART -> R.layout.item_sdui_piechart + SduiViewType.GRAPH -> R.layout.item_sdui_graph + SduiViewType.TEXT -> R.layout.item_sdui_text + SduiViewType.UNKNOWN -> R.layout.item_sdui_unknown + } +} \ No newline at end of file diff --git a/common-ui/src/main/res/layout/item_sdui_graph.xml b/common-ui/src/main/res/layout/item_sdui_graph.xml new file mode 100644 index 00000000..18f69085 --- /dev/null +++ b/common-ui/src/main/res/layout/item_sdui_graph.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common-ui/src/main/res/layout/item_sdui_piechart.xml b/common-ui/src/main/res/layout/item_sdui_piechart.xml new file mode 100644 index 00000000..8745dc68 --- /dev/null +++ b/common-ui/src/main/res/layout/item_sdui_piechart.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common-ui/src/main/res/layout/item_sdui_text.xml b/common-ui/src/main/res/layout/item_sdui_text.xml new file mode 100644 index 00000000..47947fee --- /dev/null +++ b/common-ui/src/main/res/layout/item_sdui_text.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common-ui/src/main/res/layout/item_sdui_unknown.xml b/common-ui/src/main/res/layout/item_sdui_unknown.xml new file mode 100644 index 00000000..dad773ce --- /dev/null +++ b/common-ui/src/main/res/layout/item_sdui_unknown.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/common-ui/src/main/res/values/strings.xml b/common-ui/src/main/res/values/strings.xml index e217fc45..c543fa8d 100644 --- a/common-ui/src/main/res/values/strings.xml +++ b/common-ui/src/main/res/values/strings.xml @@ -219,6 +219,7 @@ 추가적인 가게 정보를 알려주세요! ← 전화번호를 재인증 하시겠습니까? 로그아웃 + 매출 리포트 g diff --git a/data/build.gradle.kts b/data/build.gradle.kts index a60dbd4d..a6ea5643 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -40,8 +40,7 @@ dependencies { implementation(libs.hilt) kapt(libs.hilt.kapt) implementation(libs.bundles.basic.test) - implementation(libs.moshi) - implementation(libs.moshi.kotlin) + implementation(libs.bundles.moshi) kapt(libs.moshi.kapt) implementation(libs.preferences.datastore) implementation(libs.kotlin.coroutines) diff --git a/data/src/main/java/org/swm/att/data/json_adapter/JsonAdapter.kt b/data/src/main/java/org/swm/att/data/json_adapter/JsonAdapter.kt new file mode 100644 index 00000000..29be0367 --- /dev/null +++ b/data/src/main/java/org/swm/att/data/json_adapter/JsonAdapter.kt @@ -0,0 +1,21 @@ +package org.swm.att.data.json_adapter + +import com.squareup.moshi.Moshi +import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory +import org.swm.att.domain.entity.response.SduiReportGraphItemVO +import org.swm.att.domain.entity.response.SduiReportItemVO +import org.swm.att.domain.entity.response.SduiReportPieChartItemVO +import org.swm.att.domain.entity.response.SduiReportTextItemVO + +object JsonAdapter { + private val sduiJsonAdapter: PolymorphicJsonAdapterFactory = PolymorphicJsonAdapterFactory.of(SduiReportItemVO::class.java, "viewType") + .withSubtype(SduiReportPieChartItemVO::class.java, "PIECHART") + .withSubtype(SduiReportGraphItemVO::class.java, "GRAPH") + .withSubtype(SduiReportTextItemVO::class.java, "TEXT") + + val moshi: Moshi = Moshi.Builder() + .add(sduiJsonAdapter) + .add(KotlinJsonAdapterFactory()) + .build() +} \ No newline at end of file diff --git a/data/src/main/java/org/swm/att/data/remote/datasource/UserDataSource.kt b/data/src/main/java/org/swm/att/data/remote/datasource/UserDataSource.kt index d81f458e..3af09125 100644 --- a/data/src/main/java/org/swm/att/data/remote/datasource/UserDataSource.kt +++ b/data/src/main/java/org/swm/att/data/remote/datasource/UserDataSource.kt @@ -11,6 +11,8 @@ import javax.inject.Inject class UserDataSource @Inject constructor( private val attPosUserService: AttPosUserService ): BaseNetworkDataSource() { + suspend fun getUserReport() = checkResponse(attPosUserService.getUserReport()) + suspend fun refreshToken(refreshToken: String) = checkResponse(attPosUserService.refreshToken(refreshToken)) diff --git a/data/src/main/java/org/swm/att/data/remote/response/SduiBaseResponseDTO.kt b/data/src/main/java/org/swm/att/data/remote/response/SduiBaseResponseDTO.kt new file mode 100644 index 00000000..0f7dea69 --- /dev/null +++ b/data/src/main/java/org/swm/att/data/remote/response/SduiBaseResponseDTO.kt @@ -0,0 +1,16 @@ +package org.swm.att.data.remote.response + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import org.swm.att.domain.entity.response.SduiBaseResponseVO +import org.swm.att.domain.entity.response.SduiReportVO + +@JsonClass(generateAdapter = true) +data class SduiBaseResponseDTO( + @Json(name = "responseData") + val responseData: SduiReportVO?, +) { + fun toVO() = SduiBaseResponseVO( + responseData = responseData ?: SduiReportVO("unknown", listOf()) + ) +} \ No newline at end of file diff --git a/data/src/main/java/org/swm/att/data/remote/service/AttPosUserService.kt b/data/src/main/java/org/swm/att/data/remote/service/AttPosUserService.kt index 125ea1e6..256a8513 100644 --- a/data/src/main/java/org/swm/att/data/remote/service/AttPosUserService.kt +++ b/data/src/main/java/org/swm/att/data/remote/service/AttPosUserService.kt @@ -7,6 +7,7 @@ import org.swm.att.data.remote.request.StoreDTO import org.swm.att.data.remote.response.CertificatedPhoneTokenDTO import org.swm.att.data.remote.response.MileageDTO import org.swm.att.data.remote.response.MileageIdDTO +import org.swm.att.data.remote.response.SduiBaseResponseDTO import org.swm.att.data.remote.response.StoreIdDTO import org.swm.att.data.remote.response.StoreListDTO import org.swm.att.data.remote.response.TokenDTO @@ -21,6 +22,9 @@ import retrofit2.http.Query interface AttPosUserService { + @GET("report") + suspend fun getUserReport(): Response + @POST("user/refresh") suspend fun refreshToken( @Header("Authorization") refreshToken: String diff --git a/data/src/main/java/org/swm/att/data/repository/AttPosUserRepositoryImpl.kt b/data/src/main/java/org/swm/att/data/repository/AttPosUserRepositoryImpl.kt index ccfc0645..cd1a2b7f 100644 --- a/data/src/main/java/org/swm/att/data/repository/AttPosUserRepositoryImpl.kt +++ b/data/src/main/java/org/swm/att/data/repository/AttPosUserRepositoryImpl.kt @@ -18,6 +18,7 @@ import org.swm.att.domain.entity.request.StoreVO import org.swm.att.domain.entity.response.CertificatedPhoneTokenVO import org.swm.att.domain.entity.response.MileageIdVO import org.swm.att.domain.entity.response.MileageVO +import org.swm.att.domain.entity.response.SduiBaseResponseVO import org.swm.att.domain.entity.response.StoreIdVO import org.swm.att.domain.entity.response.StoreListVO import org.swm.att.domain.entity.response.TokenForCertificationPhoneVO @@ -29,6 +30,16 @@ class AttPosUserRepositoryImpl @Inject constructor( private val userDataSource: UserDataSource, private val attEncryptedPrefDataSource: AttEncryptedPrefDataSource ): AttPosUserRepository { + override fun getUserReport(): Flow> = flow { + try { + userDataSource.getUserReport().collect { + emit(Result.success(it.toVO())) + } + } catch (e: Exception) { + emit(Result.failure(e)) + } + } + override fun refreshToken(refreshToken: String): Flow> = flow { userDataSource.refreshToken(refreshToken).collect { emit(Result.success(it.toVO())) @@ -202,6 +213,5 @@ class AttPosUserRepositoryImpl @Inject constructor( } catch (e: Exception) { emit(Result.failure(e)) } - } } \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/entity/response/SduiBaseResponseVO.kt b/domain/src/main/java/org/swm/att/domain/entity/response/SduiBaseResponseVO.kt new file mode 100644 index 00000000..9e382604 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/entity/response/SduiBaseResponseVO.kt @@ -0,0 +1,5 @@ +package org.swm.att.domain.entity.response + +data class SduiBaseResponseVO( + val responseData: SduiReportVO +) \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportItemVO.kt b/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportItemVO.kt new file mode 100644 index 00000000..84f58957 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportItemVO.kt @@ -0,0 +1,27 @@ +package org.swm.att.domain.entity.response + +import org.swm.att.domain.sever_driven_ui.SduiViewType +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent +import org.swm.att.domain.sever_driven_ui.response.graph.ReportGraphVO +import org.swm.att.domain.sever_driven_ui.response.piechart.ReportPieChartVO +import org.swm.att.domain.sever_driven_ui.response.text.ReportTextVO + +interface SduiReportItemVO { + val viewType: SduiViewType + val content: SduiReportContent +} + +data class SduiReportGraphItemVO( + override val viewType: SduiViewType, + override val content: ReportGraphVO +): SduiReportItemVO + +data class SduiReportPieChartItemVO( + override val viewType: SduiViewType, + override val content: ReportPieChartVO +): SduiReportItemVO + +data class SduiReportTextItemVO( + override val viewType: SduiViewType, + override val content: ReportTextVO +): SduiReportItemVO \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportVO.kt b/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportVO.kt new file mode 100644 index 00000000..10ace736 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/entity/response/SduiReportVO.kt @@ -0,0 +1,6 @@ +package org.swm.att.domain.entity.response + +data class SduiReportVO( + val screenName: String, + val viewContents: List +) \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/repository/AttPosUserRepository.kt b/domain/src/main/java/org/swm/att/domain/repository/AttPosUserRepository.kt index 5ac4c0e8..cfc47239 100644 --- a/domain/src/main/java/org/swm/att/domain/repository/AttPosUserRepository.kt +++ b/domain/src/main/java/org/swm/att/domain/repository/AttPosUserRepository.kt @@ -8,12 +8,15 @@ import org.swm.att.domain.entity.request.StoreVO import org.swm.att.domain.entity.response.CertificatedPhoneTokenVO import org.swm.att.domain.entity.response.MileageIdVO import org.swm.att.domain.entity.response.MileageVO +import org.swm.att.domain.entity.response.SduiBaseResponseVO +import org.swm.att.domain.entity.response.SduiReportVO import org.swm.att.domain.entity.response.StoreIdVO import org.swm.att.domain.entity.response.StoreListVO import org.swm.att.domain.entity.response.TokenForCertificationPhoneVO import org.swm.att.domain.entity.response.TokenVO interface AttPosUserRepository { + fun getUserReport(): Flow> fun refreshToken(refreshToken: String): Flow> fun saveAccessToken(accessToken: String) fun saveRefreshToken(refreshToken: String) diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/SduiViewType.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/SduiViewType.kt new file mode 100644 index 00000000..29d4e503 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/SduiViewType.kt @@ -0,0 +1,32 @@ +package org.swm.att.domain.sever_driven_ui + +import org.swm.att.domain.sever_driven_ui.response.ReportUnknownVO +import org.swm.att.domain.sever_driven_ui.response.graph.ReportGraphVO +import org.swm.att.domain.sever_driven_ui.response.piechart.ReportPieChartVO +import org.swm.att.domain.sever_driven_ui.response.text.ReportTextVO +import java.lang.reflect.Type + +enum class SduiViewType( + val viewType: String, private val viewTypeClass: Type +) { + PIECHART("piechart", ReportPieChartVO::class.java), + GRAPH("graph", ReportGraphVO::class.java), + TEXT("text", ReportTextVO::class.java), + UNKNOWN("unknown", ReportUnknownVO::class.java); + + companion object { + fun getViewTypeByOrdinal(ordinalNum: Int): SduiViewType { + return values()[ordinalNum] + } + + fun SduiViewType.getViewTypeClass(): Type { + return this.viewTypeClass + } + + fun findClassByItsName(viewTypeString: String?): SduiViewType { + values().find { it.viewType == viewTypeString }?.let { + return it + } ?: return UNKNOWN + } + } +} \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/ReportUnknownVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/ReportUnknownVO.kt new file mode 100644 index 00000000..2d377a9a --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/ReportUnknownVO.kt @@ -0,0 +1,3 @@ +package org.swm.att.domain.sever_driven_ui.response + +object ReportUnknownVO: SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/SduiReportContent.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/SduiReportContent.kt new file mode 100644 index 00000000..875e2aa8 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/SduiReportContent.kt @@ -0,0 +1,3 @@ +package org.swm.att.domain.sever_driven_ui.response + +interface SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarItemVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarItemVO.kt new file mode 100644 index 00000000..63a95f5f --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarItemVO.kt @@ -0,0 +1,8 @@ +package org.swm.att.domain.sever_driven_ui.response.calendar + +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +data class ReportCalendarItemVO( + val contentDate: String, + val value: String +): SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarVO.kt new file mode 100644 index 00000000..3c8f6030 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/calendar/ReportCalendarVO.kt @@ -0,0 +1,9 @@ +package org.swm.att.domain.sever_driven_ui.response.calendar + +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +data class ReportCalendarVO( + val calendarTitle: String, + val calendarDate: String, + val calendarItems: List +): SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphItemVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphItemVO.kt new file mode 100644 index 00000000..6e10cc3f --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphItemVO.kt @@ -0,0 +1,6 @@ +package org.swm.att.domain.sever_driven_ui.response.graph + +data class ReportGraphItemVO ( + val graphKey: Int, + val graphValue: Int +) \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphVO.kt new file mode 100644 index 00000000..e632af7d --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/graph/ReportGraphVO.kt @@ -0,0 +1,9 @@ +package org.swm.att.domain.sever_driven_ui.response.graph + +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +data class ReportGraphVO( + val graphTitle: String, + val graphColor: String, + val graphItems: List +): SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartItemVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartItemVO.kt new file mode 100644 index 00000000..cc3262d4 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartItemVO.kt @@ -0,0 +1,7 @@ +package org.swm.att.domain.sever_driven_ui.response.piechart + +data class ReportPieChartItemVO( + val categoryName: String, + val chartColor: String, + val categoryCount: Int +) \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartVO.kt new file mode 100644 index 00000000..d12dc819 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/piechart/ReportPieChartVO.kt @@ -0,0 +1,9 @@ +package org.swm.att.domain.sever_driven_ui.response.piechart + +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +data class ReportPieChartVO ( + val pieChartTitle: String, + val totalCount: Int, + val pieChartItems: List +): SduiReportContent \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextItemVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextItemVO.kt new file mode 100644 index 00000000..0d4ca2ec --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextItemVO.kt @@ -0,0 +1,7 @@ +package org.swm.att.domain.sever_driven_ui.response.text + +data class ReportTextItemVO ( + val text: String?, + val color: String?, + val size: Float? +) \ No newline at end of file diff --git a/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextVO.kt b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextVO.kt new file mode 100644 index 00000000..a2529160 --- /dev/null +++ b/domain/src/main/java/org/swm/att/domain/sever_driven_ui/response/text/ReportTextVO.kt @@ -0,0 +1,8 @@ +package org.swm.att.domain.sever_driven_ui.response.text + +import org.swm.att.domain.sever_driven_ui.response.SduiReportContent + +data class ReportTextVO ( + val align: String, + val textItems: List +): SduiReportContent \ No newline at end of file diff --git a/feature/login/build.gradle.kts b/feature/login/build.gradle.kts index d88dfbb9..3e581e10 100644 --- a/feature/login/build.gradle.kts +++ b/feature/login/build.gradle.kts @@ -46,9 +46,6 @@ dependencies { implementation(libs.material) implementation(libs.hilt) kapt(libs.hilt.kapt) - implementation(libs.moshi) - implementation(libs.moshi.kotlin) - kapt(libs.moshi.kapt) implementation(libs.bundles.navigation) implementation(libs.sentry) implementation(libs.kotlin.coroutines) diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index 0444da06..971b5e9b 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -45,9 +45,6 @@ dependencies { implementation(libs.material) implementation(libs.hilt) kapt(libs.hilt.kapt) - implementation(libs.moshi) - implementation(libs.moshi.kotlin) - kapt(libs.moshi.kapt) implementation(libs.bundles.navigation) implementation(libs.flexbox) implementation(libs.sentry) diff --git a/feature/main/src/main/java/org/swm/att/home/constant/NavDestinationType.kt b/feature/main/src/main/java/org/swm/att/home/constant/NavDestinationType.kt index 3e1d15c8..d333eea4 100644 --- a/feature/main/src/main/java/org/swm/att/home/constant/NavDestinationType.kt +++ b/feature/main/src/main/java/org/swm/att/home/constant/NavDestinationType.kt @@ -12,7 +12,6 @@ enum class NavDestinationType( Preorder(R.id.action_global_fragment_preorder, R.id.btn_preorder), Stock(R.id.action_global_fragment_stock, R.id.btn_stock), Recipe(R.id.action_global_fragment_recipe, R.id.btn_recipe), - Worker(R.id.action_global_fragment_worker, R.id.btn_worker), Sales(R.id.action_global_fragment_sales, R.id.btn_sales), Setting(R.id.action_global_fragment_setting, R.id.btn_setting); } \ No newline at end of file diff --git a/feature/main/src/main/java/org/swm/att/home/home/keypad_dialog/EarnMileageViewModel.kt b/feature/main/src/main/java/org/swm/att/home/home/keypad_dialog/EarnMileageViewModel.kt index 9a7ba670..f58e80df 100644 --- a/feature/main/src/main/java/org/swm/att/home/home/keypad_dialog/EarnMileageViewModel.kt +++ b/feature/main/src/main/java/org/swm/att/home/home/keypad_dialog/EarnMileageViewModel.kt @@ -1,6 +1,5 @@ package org.swm.att.home.home.keypad_dialog -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope @@ -27,17 +26,16 @@ class EarnMileageViewModel @Inject constructor( val getMileageState: StateFlow> = _getMileageState private val _registerCustomerState = MutableStateFlow>(UiState.Loading) val registerCustomerState: StateFlow> = _registerCustomerState + private var storeId: Int? = null fun getMileage(phone: String) { viewModelScope.launch(attExceptionHandler) { - attPosUserRepository.getMileage(1, phone).collect { result -> + attPosUserRepository.getMileage(getStoreId(), phone).collect { result -> result.onSuccess { _getMileageState.value = UiState.Success(it) _mileage.postValue(it) }.onFailure { - //추후 에러처리 필요 val errorMsg = if (it is HttpResponseException) it.message else "없는 회원입니다." - Log.d("setRegisterBtnVisibility", "getMileage: $errorMsg") _getMileageState.value = UiState.Error(errorMsg) } } @@ -47,7 +45,7 @@ class EarnMileageViewModel @Inject constructor( fun registerCustomer(phone: String) { viewModelScope.launch(attExceptionHandler) { attPosUserRepository.registerCustomer( - 1, + getStoreId(), PhoneNumVO( phone = phone ) @@ -71,4 +69,12 @@ class EarnMileageViewModel @Inject constructor( _getMileageState.value = UiState.Loading _mileage.postValue(null) } + + private fun getStoreId(): Int { + if (storeId == null) { + storeId = attPosUserRepository.getStoreId() + } + return storeId as Int + } + } \ No newline at end of file diff --git a/feature/main/src/main/java/org/swm/att/home/sale/SaleFragment.kt b/feature/main/src/main/java/org/swm/att/home/sale/SaleFragment.kt index 72702753..7141ac1a 100644 --- a/feature/main/src/main/java/org/swm/att/home/sale/SaleFragment.kt +++ b/feature/main/src/main/java/org/swm/att/home/sale/SaleFragment.kt @@ -1,9 +1,60 @@ package org.swm.att.home.sale +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import org.swm.att.common_ui.adapter.SduiReportAdapter import org.swm.att.common_ui.presenter.base.BaseFragment +import org.swm.att.common_ui.state.UiState import org.swm.att.home.R import org.swm.att.home.databinding.FragmentSaleBinding +@AndroidEntryPoint class SaleFragment : BaseFragment(R.layout.fragment_sale) { - //todo + private lateinit var sduiReportAdapter: SduiReportAdapter + private val saleViewModel by viewModels() + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initSduiReportRecyclerView() + setReportDataObserver() + setReportData() + } + + private fun initSduiReportRecyclerView() { + sduiReportAdapter = SduiReportAdapter() + binding.rvSduiReport.apply { + adapter = sduiReportAdapter + layoutManager = LinearLayoutManager(requireContext()) + } + } + + private fun setReportDataObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + saleViewModel.getSduiReportDataState.collect() { uiState -> + when(uiState) { + is UiState.Success -> { + uiState.data?.let { + sduiReportAdapter.submitList(it.responseData.viewContents) + } + } + is UiState.Loading -> { /* nothing */ } + is UiState.Error -> Toast.makeText(requireContext(), uiState.errorMsg, Toast.LENGTH_SHORT).show() + } + } + } + } + } + + private fun setReportData() { + saleViewModel.getSduiReportData() + } } \ No newline at end of file diff --git a/feature/main/src/main/java/org/swm/att/home/sale/SaleViewModel.kt b/feature/main/src/main/java/org/swm/att/home/sale/SaleViewModel.kt new file mode 100644 index 00000000..2da8012a --- /dev/null +++ b/feature/main/src/main/java/org/swm/att/home/sale/SaleViewModel.kt @@ -0,0 +1,33 @@ +package org.swm.att.home.sale + +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import org.swm.att.common_ui.presenter.base.BaseViewModel +import org.swm.att.common_ui.state.UiState +import org.swm.att.domain.entity.HttpResponseException +import org.swm.att.domain.entity.response.SduiBaseResponseVO +import org.swm.att.domain.repository.AttPosUserRepository +import javax.inject.Inject + +@HiltViewModel +class SaleViewModel @Inject constructor( + private val attPosUserRepository: AttPosUserRepository +): BaseViewModel() { + private val _getSduiReportDataState: MutableStateFlow> = MutableStateFlow(UiState.Loading) + val getSduiReportDataState = _getSduiReportDataState + + fun getSduiReportData() { + viewModelScope.launch(attExceptionHandler) { + attPosUserRepository.getUserReport().collect() { result -> + result.onSuccess { + _getSduiReportDataState.value = UiState.Success(it) + }.onFailure { + val errorMsg = if (it is HttpResponseException) it.message else "매출 리포트를 가져오는 데 오류가 발생했습니다." + _getSduiReportDataState.value = UiState.Error(errorMsg) + } + } + } + } +} \ No newline at end of file diff --git a/feature/main/src/main/java/org/swm/att/home/worker/WorkerFragment.kt b/feature/main/src/main/java/org/swm/att/home/worker/WorkerFragment.kt deleted file mode 100644 index b9f24ba6..00000000 --- a/feature/main/src/main/java/org/swm/att/home/worker/WorkerFragment.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.swm.att.home.worker - -import org.swm.att.common_ui.presenter.base.BaseFragment -import org.swm.att.home.R -import org.swm.att.home.databinding.FragmentWorkerBinding - -class WorkerFragment : BaseFragment(R.layout.fragment_worker) { - //todo -} \ No newline at end of file diff --git a/feature/main/src/main/res/layout/activity_main.xml b/feature/main/src/main/res/layout/activity_main.xml index 3fe85241..6d9ef2cf 100644 --- a/feature/main/src/main/res/layout/activity_main.xml +++ b/feature/main/src/main/res/layout/activity_main.xml @@ -390,46 +390,7 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toTopOf="@id/menu_worker"/> - - - - - - - - + app:layout_constraintBottom_toTopOf="@id/menu_sales"/> diff --git a/feature/main/src/main/res/layout/fragment_sale.xml b/feature/main/src/main/res/layout/fragment_sale.xml index de103196..313747f0 100644 --- a/feature/main/src/main/res/layout/fragment_sale.xml +++ b/feature/main/src/main/res/layout/fragment_sale.xml @@ -1,6 +1,7 @@ - + android:background="@drawable/shape_round_10" + android:backgroundTint="@color/white" + android:layout_marginStart="50dp" + android:layout_marginEnd="50dp" + android:layout_marginBottom="50dp"> + + + + + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aa8f0c73..0b68d270 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -55,6 +55,9 @@ setnry = "6.29.0" #mock for test mockk = "1.13.7" +#chart +mpandroidchart = "v3.1.0" + [libraries] kotlin-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } kotlin-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlin-serialization" } @@ -90,6 +93,7 @@ retrofit-moshi-converter = { module = "com.squareup.retrofit2:converter-moshi", moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" } moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } +moshi-adapter = { module = "com.squareup.moshi:moshi-adapters", version.ref = "moshi" } moshi-kapt = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" } navigation-fragment = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" } @@ -103,10 +107,13 @@ mockk = { module = "io.mockk:mockk", version.ref = "mockk" } androidx-monitor = { group = "androidx.test", name = "monitor", version = "1.6.1" } androidx-junit-ktx = { group = "androidx.test.ext", name = "junit-ktx", version = "1.1.5" } +mpandroidchart = { module = "com.github.PhilJay:MPAndroidChart", version.ref = "mpandroidchart" } + [bundles] androidx-ui-foundation = ["core-ktx", "appcompat", "constraintlayout", "lifecycle-viewmodel", "fragment"] okhttp = ["okhttp", "okhttp-bom", "okhttp-logging-interceptor"] retrofit = ["retrofit", "retrofit-moshi-converter"] +moshi = ["moshi", "moshi-kotlin", "moshi-adapter"] navigation = ["navigation-fragment", "navigation-ui"] basic-test = ["junit", "androidx-test-junit", "androidx-test-espresso"] diff --git a/settings.gradle b/settings.gradle index deb43809..a63f8c8e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,6 +10,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { url "https://jitpack.io" } } } rootProject.name = "POS-Android"