diff --git a/build.gradle b/build.gradle index fa5d3f48..f1f2a2f5 100755 --- a/build.gradle +++ b/build.gradle @@ -38,8 +38,8 @@ allprojects { jcenter() } ext { - androidVersionCode = 40 - androidVersionName = "0.4.1" + androidVersionCode = 42 + androidVersionName = "0.4.2" androidBuildNumber = 1 testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" testApplicationId = 'io.forus.me.test' diff --git a/buildsystem/dependencies.gradle b/buildsystem/dependencies.gradle index 3162dfdb..673cd30e 100755 --- a/buildsystem/dependencies.gradle +++ b/buildsystem/dependencies.gradle @@ -8,7 +8,7 @@ ext { //Android androidBuildToolsVersion = "28.0.3" androidMinSdkVersion = 18 - androidTargetSdkVersion = 28 + androidTargetSdkVersion = 29 androidCompileSdkVersion = 28 //Libraries @@ -108,6 +108,7 @@ ext { ] presentationTestDependencies = [ + junit: "junit:junit:${jUnitVersion}", mockito: "org.mockito:mockito-core:${mockitoVersion}", dexmaker: "com.google.dexmaker:dexmaker:${dexmakerVersion}", dexmakerMockito: "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}", diff --git a/data/src/main/java/io/forus/me/android/data/entity/common/ApiError.java b/data/src/main/java/io/forus/me/android/data/entity/common/ApiError.java index f6d180d8..1e88f4d5 100644 --- a/data/src/main/java/io/forus/me/android/data/entity/common/ApiError.java +++ b/data/src/main/java/io/forus/me/android/data/entity/common/ApiError.java @@ -28,6 +28,9 @@ public class Errors { @SerializedName("value") private List value; + @SerializedName("email") + private List email; + public List getName() { return name; } @@ -51,5 +54,13 @@ public List getValue() { public void setValue(List value) { this.value = value; } + + public List getEmail() { + return email; + } + + public void setEmail(List email) { + this.email = email; + } } } diff --git a/data/src/main/java/io/forus/me/android/data/entity/sign/request/EmailValidateRequest.kt b/data/src/main/java/io/forus/me/android/data/entity/sign/request/EmailValidateRequest.kt new file mode 100755 index 00000000..e1518e29 --- /dev/null +++ b/data/src/main/java/io/forus/me/android/data/entity/sign/request/EmailValidateRequest.kt @@ -0,0 +1,18 @@ +package com.gigawatt.android.data.net.sign.models.request + +import com.google.gson.annotations.Expose +import com.google.gson.annotations.SerializedName +import io.forus.me.android.data.entity.sign.request.SignRecords +import java.io.Serializable + + + +class EmailValidateRequest : Serializable{ + + @SerializedName("email") + @Expose + var email: String? = null + + + +} \ No newline at end of file diff --git a/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmail.java b/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmail.java new file mode 100644 index 00000000..d6e201f1 --- /dev/null +++ b/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmail.java @@ -0,0 +1,28 @@ +package io.forus.me.android.data.entity.sign.response; + +import com.google.gson.annotations.SerializedName; + +public class ValidateEmail { + + @SerializedName("used") + private Boolean used; + + @SerializedName("valid") + private Boolean valid; + + public Boolean getUsed() { + return used; + } + + public void setUsed(Boolean used) { + this.used = used; + } + + public Boolean getValid() { + return valid; + } + + public void setValid(Boolean valid) { + this.valid = valid; + } +} diff --git a/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmailResult.java b/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmailResult.java new file mode 100644 index 00000000..071546c5 --- /dev/null +++ b/data/src/main/java/io/forus/me/android/data/entity/sign/response/ValidateEmailResult.java @@ -0,0 +1,18 @@ +package io.forus.me.android.data.entity.sign.response; + +import com.google.gson.annotations.SerializedName; + +public class ValidateEmailResult { + + @SerializedName("email") + private ValidateEmail email; + + + public ValidateEmail getEmail() { + return email; + } + + public void setEmail(ValidateEmail email) { + this.email = email; + } +} diff --git a/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/ProductAction.java b/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/ProductAction.java index 16229171..9eeffe86 100644 --- a/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/ProductAction.java +++ b/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/ProductAction.java @@ -33,8 +33,21 @@ public class ProductAction implements Serializable { @SerializedName("price_user") private BigDecimal priceUser; - //@SerializedName("price_old") - //private BigDecimal priceOld; + @SerializedName("price_old") + private BigDecimal price_old; + + + @SerializedName("no_price") + private boolean no_price; + + @SerializedName("no_price_type") + private String no_price_type; + + + @SerializedName("no_price_discount") + private BigDecimal no_price_discount; + + //@SerializedName("expire_at") //private String expireAt; @@ -56,7 +69,8 @@ public class ProductAction implements Serializable { public ProductAction() { } - public ProductAction(long id, String name, long organizationId, BigDecimal price, BigDecimal priceUser, Logo photo, Organization organization, ProductCategory productCategory) { + public ProductAction(long id, String name, long organizationId, BigDecimal price, BigDecimal priceUser,BigDecimal priceOld, boolean noPrice, + String noPriceType, BigDecimal noPriceDiscount, Logo photo, Organization organization, ProductCategory productCategory) { this.id = id; this.name = name; this.organizationId = organizationId; @@ -65,6 +79,11 @@ public ProductAction(long id, String name, long organizationId, BigDecimal price this.photo = photo; this.organization = organization; this.productCategory = productCategory; + + this.price_old = priceOld; + this.no_price = noPrice; + this.no_price_type = noPriceType; + this.no_price_discount = noPriceDiscount; } public long getId() { @@ -130,4 +149,36 @@ public ProductCategory getProductCategory() { public void setProductCategory(ProductCategory productCategory) { this.productCategory = productCategory; } + + public BigDecimal getPrice_old() { + return price_old; + } + + public void setPrice_old(BigDecimal price_old) { + this.price_old = price_old; + } + + public boolean isNo_price() { + return no_price; + } + + public void setNo_price(boolean no_price) { + this.no_price = no_price; + } + + public String getNo_price_type() { + return no_price_type; + } + + public void setNo_price_type(String no_price_type) { + this.no_price_type = no_price_type; + } + + public BigDecimal getNo_price_discount() { + return no_price_discount; + } + + public void setNo_price_discount(BigDecimal no_price_discount) { + this.no_price_discount = no_price_discount; + } } diff --git a/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/Voucher.java b/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/Voucher.java index 4a4fbe82..b34a3160 100644 --- a/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/Voucher.java +++ b/data/src/main/java/io/forus/me/android/data/entity/vouchers/response/Voucher.java @@ -32,6 +32,9 @@ public enum Type { @SerializedName("expired") private boolean expired; + @SerializedName("used") + boolean used; + @SerializedName("expire_at_locale") private String expireAtLocale; @@ -239,4 +242,12 @@ public boolean isExpired() { public void setExpired(boolean expired) { this.expired = expired; } + + public boolean isUsed() { + return used; + } + + public void setUsed(boolean used) { + this.used = used; + } } diff --git a/data/src/main/java/io/forus/me/android/data/exception/RetrofitExceptionMapper.java b/data/src/main/java/io/forus/me/android/data/exception/RetrofitExceptionMapper.java index 1020b956..38ab1e1b 100644 --- a/data/src/main/java/io/forus/me/android/data/exception/RetrofitExceptionMapper.java +++ b/data/src/main/java/io/forus/me/android/data/exception/RetrofitExceptionMapper.java @@ -10,6 +10,7 @@ import io.forus.me.android.domain.exception.RetrofitException; import io.forus.me.android.domain.models.common.DetailsApiError; import io.forus.me.android.domain.models.records.errors.BaseApiError; +import io.forus.me.android.domain.models.records.errors.EmailError; import io.forus.me.android.domain.models.records.errors.NewRecordCategoryError; import io.forus.me.android.domain.models.records.errors.NewRecordError; @@ -25,6 +26,11 @@ public NewRecordCategoryError mapToNewRecordCategoryError(RetrofitException retr return new NewRecordCategoryError(apiError.getMessage(), apiError.getErrors().getName()); } + public EmailError mapToApiError(RetrofitException retrofitException) throws IOException { + ApiError apiError = retrofitException.getErrorBodyAs(ApiError.class); + return new EmailError(apiError.getMessage(), apiError.getErrors().getEmail()); + } + @Override public BaseApiError mapToBaseApiError(RetrofitException retrofitException) throws IOException { BaseError apiError = retrofitException.getErrorBodyAs(BaseError.class); diff --git a/data/src/main/java/io/forus/me/android/data/net/sign/SignService.kt b/data/src/main/java/io/forus/me/android/data/net/sign/SignService.kt index 8d88c687..d7f7935a 100644 --- a/data/src/main/java/io/forus/me/android/data/net/sign/SignService.kt +++ b/data/src/main/java/io/forus/me/android/data/net/sign/SignService.kt @@ -1,5 +1,6 @@ package io.forus.me.android.data.net.sign +import com.gigawatt.android.data.net.sign.models.request.EmailValidateRequest import com.gigawatt.android.data.net.sign.models.request.SignUp import io.forus.me.android.data.entity.account.Account import io.forus.me.android.data.entity.common.Success @@ -35,7 +36,9 @@ interface SignService { @POST("api/v1/identity/proxy/email") fun restoreByEmail(@Body restore: RestoreByEmail) : Observable - // @GET("{{apiUrl}}/identity/validate/email") + @POST("api/v1/identity/validate/email") + fun validateEmail(@Body email: EmailValidateRequest) : Observable + @GET("api/v1/identity/proxy/email/exchange/{token}") fun restoreExchangeToken(@Path("token") token: String) : Observable diff --git a/data/src/main/java/io/forus/me/android/data/repository/account/AccountRepository.kt b/data/src/main/java/io/forus/me/android/data/repository/account/AccountRepository.kt index 219fb035..db4d7f92 100644 --- a/data/src/main/java/io/forus/me/android/data/repository/account/AccountRepository.kt +++ b/data/src/main/java/io/forus/me/android/data/repository/account/AccountRepository.kt @@ -1,6 +1,5 @@ package io.forus.me.android.data.repository.account -import android.util.Log import com.gigawatt.android.data.net.sign.models.request.SignUp import io.forus.me.android.data.entity.sign.request.SignRecords import io.forus.me.android.data.repository.account.datasource.AccountDataSource @@ -45,6 +44,13 @@ class AccountRepository(private val settingsDataSource: SettingsDataSource, return accountRemoteDataSource.restoreByEmail(email) } + override fun validateEmail(email: String): Observable { + + return accountRemoteDataSource.validateEmail(email).map { + it + } + } + override fun restoreExchangeToken(token: String): Observable { return accountRemoteDataSource.restoreExchangeToken(token) .map { diff --git a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/AccountDataSource.kt b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/AccountDataSource.kt index 9907eb4e..52c22545 100644 --- a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/AccountDataSource.kt +++ b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/AccountDataSource.kt @@ -17,6 +17,8 @@ interface AccountDataSource { fun restoreByEmail(email: String) : Observable + fun validateEmail(email: String) : Observable + fun restoreExchangeToken(token: String) : Observable diff --git a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/local/AccountLocalDataSource.java b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/local/AccountLocalDataSource.java index 3eda1a16..dd9ef9d9 100644 --- a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/local/AccountLocalDataSource.java +++ b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/local/AccountLocalDataSource.java @@ -17,8 +17,10 @@ import io.forus.me.android.data.entity.sign.response.IdentityTokenResult; import io.forus.me.android.data.entity.sign.response.ShortTokenResult; import io.forus.me.android.data.entity.sign.response.SignUpResult; +import io.forus.me.android.data.entity.sign.response.ValidateEmailResult; import io.forus.me.android.data.repository.account.datasource.AccountDataSource; import io.forus.me.android.data.repository.datasource.LocalDataSource; +import io.forus.me.android.domain.models.account.ValidateEmail; import io.reactivex.Observable; public class AccountLocalDataSource implements AccountDataSource, LocalDataSource{ @@ -166,4 +168,10 @@ public Observable registerExchangeToken(@NotNull String token) { public Observable getShortToken() { return null; } + + @NotNull + @Override + public Observable validateEmail(@NotNull String email) { + return null; + } } diff --git a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/remote/AccountRemoteDataSource.kt b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/remote/AccountRemoteDataSource.kt index 30554a52..7653be1b 100644 --- a/data/src/main/java/io/forus/me/android/data/repository/account/datasource/remote/AccountRemoteDataSource.kt +++ b/data/src/main/java/io/forus/me/android/data/repository/account/datasource/remote/AccountRemoteDataSource.kt @@ -1,18 +1,23 @@ package io.forus.me.android.data.repository.account.datasource.remote -import android.util.Log +import com.gigawatt.android.data.net.sign.models.request.EmailValidateRequest import com.gigawatt.android.data.net.sign.models.request.SignUp import io.forus.me.android.data.entity.account.Account import io.forus.me.android.data.entity.sign.request.AuthorizeCode import io.forus.me.android.data.entity.sign.request.AuthorizeToken import io.forus.me.android.data.entity.sign.request.RegisterPush import io.forus.me.android.data.entity.sign.request.RestoreByEmail -import io.forus.me.android.data.entity.sign.response.* +import io.forus.me.android.data.entity.sign.response.AccessToken +import io.forus.me.android.data.entity.sign.response.IdentityPinResult +import io.forus.me.android.data.entity.sign.response.IdentityTokenResult +import io.forus.me.android.data.entity.sign.response.ShortTokenResult import io.forus.me.android.data.net.sign.SignService import io.forus.me.android.data.repository.account.datasource.AccountDataSource import io.forus.me.android.data.repository.datasource.RemoteDataSource +import io.forus.me.android.domain.models.account.ValidateEmail import io.reactivex.Observable + class AccountRemoteDataSource(f: () -> SignService) : AccountDataSource, RemoteDataSource(f) { @@ -79,6 +84,22 @@ class AccountRemoteDataSource(f: () -> SignService) : AccountDataSource, RemoteD } } + override fun validateEmail(email: String): Observable { + val requestBody = EmailValidateRequest() + requestBody.email = email + + /* val observable: Observable = ObservableCreate(object : ObservableOnSubscribe { + override fun subscribe(emitter: ObservableEmitter) { + true + } + + })*/ + return service.validateEmail(requestBody) + .map { + io.forus.me.android.domain.models.account.ValidateEmail(it.email.used, it.email.valid) + } + } + override fun restoreExchangeToken(token: String): Observable { return service.restoreExchangeToken(token); } diff --git a/data/src/main/java/io/forus/me/android/data/repository/vouchers/VouchersRepository.kt b/data/src/main/java/io/forus/me/android/data/repository/vouchers/VouchersRepository.kt index 2b12040f..a0ee7fba 100644 --- a/data/src/main/java/io/forus/me/android/data/repository/vouchers/VouchersRepository.kt +++ b/data/src/main/java/io/forus/me/android/data/repository/vouchers/VouchersRepository.kt @@ -18,9 +18,20 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i val dateLocaleFormat = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.US) + + private fun voucherIsUsed(voucher: io.forus.me.android.data.entity.vouchers.response.Voucher): Boolean{ + return if(voucher.isUsed != null){ + voucher.isUsed + }else{ + val isProduct = voucher.type == io.forus.me.android.data.entity.vouchers.response.Voucher.Type.product + isProduct && voucher.transactions != null && voucher.transactions.isNotEmpty() + } + } + private fun mapToSimple(voucher: io.forus.me.android.data.entity.vouchers.response.Voucher): Voucher { val isProduct = voucher.type == io.forus.me.android.data.entity.vouchers.response.Voucher.Type.product - val isUsed = isProduct && voucher.transactions != null && voucher.transactions.isNotEmpty() + //val isUsed = isProduct && voucher.transactions != null && voucher.transactions.isNotEmpty() + val isUsed = voucherIsUsed(voucher) val name = if (isProduct) voucher.product.name else voucher.fund.name val organizationName = if (isProduct) voucher.product.organization.name else voucher.fund.organization.name @@ -63,6 +74,10 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i val product = if (it.product == null) { null } else { + + val logo = if(it.product.organization.logo != null){ it.product.organization.logo.sizes.thumbnail } + else{ null } + Product(it.product.id, it.product.organizationId, it.product.productCategoryId, it.product.name, it.product.description, @@ -72,7 +87,7 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i it.product.productCategory.key, it.product.productCategory.name), Organization(it.product.organization.id, it.product.organization.name, - it.product.organization.logo.sizes.thumbnail, it.product.organization.lat, + logo, it.product.organization.lat, it.product.organization.lon, it.product.organization.identityAddress, it.product.organization.phone, it.product.organization.email)) } @@ -142,12 +157,33 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i + + val offices = mutableListOf() + if (voucher.offices != null) { + voucher.offices.map { + + val schedulers = mutableListOf() + if(it.schedule != null){ + it.schedule.map { + schedulers.add(Schedule(it.id,it.officeId,it.weekDay,it.startTime,it.endTime)) + } + } + + var organization = Organization(it.organization.id, + it.organization.name, organizationLogoUrl, it.organization.lat, + it.organization.lon, it.organization.identityAddress ?: "", + it.organization.phone ?: "", it.organization.email ?: "") + offices.add(Office(it.id,it.organizationId,it.address,it.phone,it.lat,it.lon,it.phone,organization,schedulers + )) + } + } + return Voucher(isProduct, isUsed, voucher.address ?: "", name, organizationName, voucher.fund?.name ?: "", voucher.fund?.type ?: "", voucher.fund?.webShopUrl ?: "", description, createdAt!!, euro, amount, productLogoUrl, transactions, productMapped, voucher.isExpired, voucher.expireAtLocale - ?: "") + ?: "" , offices) } @@ -186,7 +222,10 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i } - return ProductAction(productAction.id, productAction.name, productAction.organizationId, productAction.price, productAction.priceUser, + return ProductAction(productAction.id, productAction.name, productAction.organizationId, + productAction.price, productAction.priceUser, + productAction.price_old, productAction.isNo_price, productAction.no_price_type, + productAction.no_price_discount, photoUrl, organization, productCategory) } @@ -242,10 +281,12 @@ class VouchersRepository(private val vouchersDataSource: VouchersDataSource) : i 0f.toBigDecimal(), 0f.toBigDecimal(), 0, 0, productCategory, organization) + val offices = mutableListOf() + val voucher = Voucher(false, false, "", "Test bedrijf", "", "", "", "", "", date, currency, 1000.toBigDecimal(), "", - transactionList, product, false, "") + transactionList, product, false, "",offices) return VoucherProvider(voucher, organizationsList, productCategoryList) } diff --git a/domain/src/main/java/io/forus/me/android/domain/exception/RetrofitExceptionMapper.java b/domain/src/main/java/io/forus/me/android/domain/exception/RetrofitExceptionMapper.java index 14dfba00..6870855a 100644 --- a/domain/src/main/java/io/forus/me/android/domain/exception/RetrofitExceptionMapper.java +++ b/domain/src/main/java/io/forus/me/android/domain/exception/RetrofitExceptionMapper.java @@ -4,11 +4,15 @@ import io.forus.me.android.domain.models.common.DetailsApiError; import io.forus.me.android.domain.models.records.errors.BaseApiError; +import io.forus.me.android.domain.models.records.errors.EmailError; import io.forus.me.android.domain.models.records.errors.NewRecordCategoryError; import io.forus.me.android.domain.models.records.errors.NewRecordError; public abstract class RetrofitExceptionMapper { + + public abstract EmailError mapToApiError(RetrofitException retrofitException) throws IOException; + public abstract NewRecordError mapToNewRecordError(RetrofitException retrofitException) throws IOException; public abstract NewRecordCategoryError mapToNewRecordCategoryError(RetrofitException retrofitException) throws IOException ; diff --git a/domain/src/main/java/io/forus/me/android/domain/models/account/ValidateEmail.kt b/domain/src/main/java/io/forus/me/android/domain/models/account/ValidateEmail.kt new file mode 100644 index 00000000..bc6be786 --- /dev/null +++ b/domain/src/main/java/io/forus/me/android/domain/models/account/ValidateEmail.kt @@ -0,0 +1,15 @@ +package io.forus.me.android.domain.models.account + +class ValidateEmail{ + + var used: Boolean + + var valid: Boolean + + constructor(used: Boolean, valid: Boolean) { + this.used = used + this.valid = valid + } + + +} \ No newline at end of file diff --git a/domain/src/main/java/io/forus/me/android/domain/models/records/errors/EmailError.java b/domain/src/main/java/io/forus/me/android/domain/models/records/errors/EmailError.java new file mode 100644 index 00000000..381ac192 --- /dev/null +++ b/domain/src/main/java/io/forus/me/android/domain/models/records/errors/EmailError.java @@ -0,0 +1,58 @@ +package io.forus.me.android.domain.models.records.errors; + +import java.util.List; + +public class EmailError { + + private String message; + + private List email; + + public EmailError(String message, List name) { + this.message = message; + this.email = name; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List getEmail() { + return email; + } + + public String getEmailFormatted() { + + if(email == null) { + return null; + }else { + if(email.size() == 0){ + return null; + }else { + + String result = ""; + for (String str : email) { + result += str; + result += "\n"; + } + return result; + } + } + } + + public void setEmail(List email) { + this.email = email; + } + + @Override + public String toString() { + return "NewRecordCategoryError{" + + "message='" + message + '\'' + + ", name=" + email + + '}'; + } +} diff --git a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Office.kt b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Office.kt new file mode 100644 index 00000000..8265e5ab --- /dev/null +++ b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Office.kt @@ -0,0 +1,11 @@ +package io.forus.me.android.domain.models.vouchers + +class Office(var id: Long, + var organizationId: Long?, + var address: String?, + var phone: String?, + var lat: Double?, + var lon: Double?, + var photo: String?, + var organization: Organization?, + var schedulers: List?) \ No newline at end of file diff --git a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/ProductAction.kt b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/ProductAction.kt index da2b0136..ded5d247 100644 --- a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/ProductAction.kt +++ b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/ProductAction.kt @@ -5,8 +5,12 @@ import java.io.Serializable import java.math.BigDecimal import java.util.* -class ProductAction(var id: Long? , var name: String?, var organizationId: Long?, var price: BigDecimal?, var priceUser: BigDecimal?, - var photoURL: String? , var organization: Organization?, var productCategory: ProductCategory?) : Serializable { +class ProductAction(var id: Long?, var name: String?, var organizationId: Long?, + var price: BigDecimal?, var priceUser: BigDecimal?, + var priceOld: BigDecimal?, var noPrice: Boolean?, + var noPriceType: String?, var noPriceDiscount: BigDecimal?, + var photoURL: String?, var organization: Organization?, + var productCategory: ProductCategory?) : Serializable { } diff --git a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Schedule.kt b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Schedule.kt new file mode 100644 index 00000000..9d1b1f3d --- /dev/null +++ b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Schedule.kt @@ -0,0 +1,7 @@ +package io.forus.me.android.domain.models.vouchers + +class Schedule(var id: Long, + var officeId: Long?, + var weekDay: Long?, + var startTime: String?, + var endTime: String?) \ No newline at end of file diff --git a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Voucher.kt b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Voucher.kt index 235f80c6..6a9242f5 100644 --- a/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Voucher.kt +++ b/domain/src/main/java/io/forus/me/android/domain/models/vouchers/Voucher.kt @@ -6,7 +6,7 @@ import java.util.* class Voucher(var isProduct: Boolean?, var isUsed: Boolean?, var address: String?, var name: String?, var organizationName: String?, var fundName: String?, var fundType: String?, var fundWebShopUrl: String?, var description: String?, var createdAt: Date?, var currency: Currency?, var amount: BigDecimal?, var logo: String, var transactions: List, var product: Product? = null, - val expired: Boolean?, val expireDate: String?) { + val expired: Boolean?, val expireDate: String?, val offices: List) { } diff --git a/domain/src/main/java/io/forus/me/android/domain/repository/account/AccountRepository.kt b/domain/src/main/java/io/forus/me/android/domain/repository/account/AccountRepository.kt index 1661c56d..823013d4 100644 --- a/domain/src/main/java/io/forus/me/android/domain/repository/account/AccountRepository.kt +++ b/domain/src/main/java/io/forus/me/android/domain/repository/account/AccountRepository.kt @@ -10,6 +10,8 @@ interface AccountRepository { fun restoreByEmail(email: String) : Observable + fun validateEmail(email: String) : Observable + fun restoreExchangeToken(token: String) : Observable diff --git a/presentation/build.gradle b/presentation/build.gradle index 61cdbe9a..e01572d4 100755 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -128,6 +128,13 @@ android { applicationId 'io.forus.me.dev' } } + sourceSets { + main { + java { + srcDirs 'src/main/java', 'src/test' + } + } + } applicationVariants.all { variant -> variant.outputs.all { output -> @@ -225,4 +232,6 @@ dependencies { transitive = true } + implementation 'com.android.support:design:28.0.0-alpha1' + } diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 05321317..e80ae788 100755 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -28,7 +28,9 @@ android:name="org.apache.http.legacy" android:required="false" /> - + - + + android:value="fe3a4b53f20261187b2c79dcd278c3ef76e6a7de" + /> + @@ -77,7 +77,7 @@ android:launchMode="singleInstance" android:noHistory="true" android:screenOrientation="unspecified" - android:theme="@android:style/Theme.NoDisplay"> + android:theme="@style/NoDisplayTheme"> @@ -105,12 +105,7 @@ android:screenOrientation="portrait" android:stateNotNeeded="true" tools:replace="android:screenOrientation" /> - + () { + + override fun transform(domainModel: OfficeDomain) = + Office(domainModel.id, domainModel.organizationId, domainModel.address ?: "", + domainModel.phone ?: "", domainModel.lat, domainModel.lon, domainModel.photo, + if (domainModel.organization != null) { + Organization(domainModel.organization!!.id, + domainModel.organization!!.name ?: "", + domainModel.organization!!.logo ?: "", + domainModel.organization!!.lat + ?: 0f.toDouble(), domainModel.organization!!.lon + ?: 0f.toDouble(), + domainModel.organization!!.address + ?: "", domainModel.organization!!.phone ?: "", + domainModel.organization!!.email ?: "") + } else { + null + }, + + shedullerDataMapper.transform(domainModel.schedulers) as List + + ) +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/mappers/SchedulerDataMapper.kt b/presentation/src/main/java/io/forus/me/android/presentation/mappers/SchedulerDataMapper.kt new file mode 100644 index 00000000..cb3327e3 --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/mappers/SchedulerDataMapper.kt @@ -0,0 +1,11 @@ +package io.forus.me.android.presentation.mappers + +import io.forus.me.android.presentation.models.vouchers.Schedule +import io.forus.me.android.domain.models.vouchers.Schedule as ScheduleDomain + +class SchedulerDataMapper : Mapper() { + + override fun transform(domainModel: ScheduleDomain) = + Schedule(domainModel.id, domainModel.officeId ?: -1L , domainModel.weekDay ?: 0, + domainModel.startTime ?: "", domainModel.endTime ?:"" ) +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/mappers/VoucherDataMapper.kt b/presentation/src/main/java/io/forus/me/android/presentation/mappers/VoucherDataMapper.kt index 2a87a06a..46f03e42 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/mappers/VoucherDataMapper.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/mappers/VoucherDataMapper.kt @@ -1,5 +1,6 @@ package io.forus.me.android.presentation.mappers +import io.forus.me.android.presentation.models.vouchers.Office import io.forus.me.android.presentation.models.vouchers.Transaction import io.forus.me.android.presentation.models.vouchers.Voucher import io.forus.me.android.domain.models.vouchers.Voucher as VoucherDomain @@ -7,7 +8,8 @@ import io.forus.me.android.domain.models.vouchers.Voucher as VoucherDomain class VoucherDataMapper(private val currencyDataMapper: CurrencyDataMapper, private val transactionDataMapper: TransactionDataMapper, - private val productDataMapper: ProductDataMapper) : Mapper() { + private val productDataMapper: ProductDataMapper, + private val officeDataMapper: OfficeDataMapper) : Mapper() { override fun transform(domainModel: VoucherDomain): Voucher { return with(domainModel) { @@ -31,7 +33,9 @@ class VoucherDataMapper(private val currencyDataMapper: CurrencyDataMapper, null }, expired ?: false, - expireDate ?: "") + expireDate ?: "", + officeDataMapper.transform(offices) as List + ) } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Office.kt b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Office.kt new file mode 100644 index 00000000..243d5bff --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Office.kt @@ -0,0 +1,54 @@ +package io.forus.me.android.presentation.models.vouchers + +import android.os.Parcel +import android.os.Parcelable + + +class Office(var id: Long = -1L, + var organizationId: Long? = -1L, + var address: String? = "", + var phone: String? = "", + var lat: Double? = 0.0, + var lon: Double? = 0.0, + var photo: String? = "", + var organization: Organization?, + var schedulers: List) : Parcelable { + constructor(parcel: Parcel) : this( + parcel.readLong(), + parcel.readLong(), + parcel.readString(), + parcel.readString(), + parcel.readDouble(), + parcel.readDouble(), + parcel.readString(), + parcel.readParcelable(Organization::class.java.classLoader) ?: Organization(), + parcel.createTypedArrayList(Schedule)) { + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeLong(id) + parcel.writeLong(organizationId ?: -1L) + parcel.writeString(address) + parcel.writeString(phone) + parcel.writeDouble(lat ?: 0.0) + parcel.writeDouble(lon ?: 0.0) + parcel.writeString(photo) + parcel.writeParcelable(organization, flags) + parcel.writeTypedList(schedulers) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): Office { + return Office(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Schedule.kt b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Schedule.kt new file mode 100644 index 00000000..6cad0dfc --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Schedule.kt @@ -0,0 +1,41 @@ +package io.forus.me.android.presentation.models.vouchers + +import android.os.Parcel +import android.os.Parcelable +import java.math.BigDecimal + +class Schedule(var id: Long = -1L, + var officeId: Long = -1L, + var weekDay: Long = -1L, + var startTime: String?, + var endTime: String?) : Parcelable { + constructor(parcel: Parcel) : this( + parcel.readLong(), + parcel.readLong(), + parcel.readLong(), + parcel.readString(), + parcel.readString()) + + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeLong(id) + parcel.writeLong(officeId) + parcel.writeLong(weekDay) + parcel.writeString(startTime) + parcel.writeString(endTime) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): Schedule { + return Schedule(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Voucher.kt b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Voucher.kt index b2364958..2cf9b87e 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Voucher.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/models/vouchers/Voucher.kt @@ -22,7 +22,8 @@ class Voucher(var isProduct: Boolean, var transactions: List, val product: Product? = null, val expired: Boolean = false, - val expireDate: String?) : Parcelable { + val expireDate: String?, + val offices: List ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), @@ -40,7 +41,8 @@ class Voucher(var isProduct: Boolean, parcel.createTypedArrayList(Transaction), parcel.readParcelable(Product::class.java.classLoader), parcel.readByte() != 0.toByte(), - parcel.readString() ?: "") + parcel.readString() ?: "", + parcel.createTypedArrayList(Office)) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeByte(if (isProduct) 1 else 0) @@ -58,6 +60,7 @@ class Voucher(var isProduct: Boolean, parcel.writeParcelable(product, flags) parcel.writeByte(if (expired) 1 else 0) parcel.writeString(expireDate) + parcel.writeTypedList(offices) } override fun describeContents(): Int { diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/Button.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/Button.kt index 2090db97..800b6db8 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/Button.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/Button.kt @@ -6,6 +6,7 @@ import android.os.Build import android.util.AttributeSet import io.forus.me.android.presentation.R import android.support.v4.content.ContextCompat +import android.support.v4.content.res.ResourcesCompat import android.util.TypedValue import io.forus.me.android.presentation.helpers.Converter import io.forus.me.android.presentation.helpers.FontCache @@ -69,7 +70,9 @@ class Button : android.support.v7.widget.AppCompatButton { setTextSize(TypedValue.COMPLEX_UNIT_DIP, customTextSize) val fontType = FontType.Bold - typeface = FontCache.getTypeface(fontType.getFontPath(), context) + // typeface = FontCache.getTypeface(fontType.getFontPath(), context) + + this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_medium) } private fun initBackground(){ diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonNext.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonNext.kt index 05b61fbf..4beca9f2 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonNext.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonNext.kt @@ -6,6 +6,7 @@ import android.os.Build import android.util.AttributeSet import io.forus.me.android.presentation.R import android.support.v4.content.ContextCompat +import android.support.v4.content.res.ResourcesCompat import android.util.TypedValue import io.forus.me.android.presentation.helpers.Converter import io.forus.me.android.presentation.helpers.FontCache @@ -70,7 +71,9 @@ class ButtonNext : android.support.v7.widget.AppCompatButton { val fontType = FontType.Regular - typeface = FontCache.getTypeface(fontType.getFontPath(), context) + // typeface = FontCache.getTypeface(fontType.getFontPath(), context) + + this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_medium) } private fun initBackground(){ diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonWhite.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonWhite.kt index 9a121164..e7f02ec3 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonWhite.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/component/buttons/ButtonWhite.kt @@ -6,6 +6,7 @@ import android.os.Build import android.util.AttributeSet import io.forus.me.android.presentation.R import android.support.v4.content.ContextCompat +import android.support.v4.content.res.ResourcesCompat import android.util.TypedValue import io.forus.me.android.presentation.helpers.Converter import io.forus.me.android.presentation.helpers.FontCache @@ -71,7 +72,9 @@ class ButtonWhite : android.support.v7.widget.AppCompatButton { setTextSize(TypedValue.COMPLEX_UNIT_DIP, customTextSize) val fontType = FontType.Bold - typeface = FontCache.getTypeface(fontType.getFontPath(), context) + //typeface = FontCache.getTypeface(fontType.getFontPath(), context) + + this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_medium) } private fun initBackground(){ diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/component/editors/EditText.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/component/editors/EditText.kt index f03b4bc0..9700c0f3 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/component/editors/EditText.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/component/editors/EditText.kt @@ -3,6 +3,7 @@ package io.forus.me.android.presentation.view.component.editors import android.content.Context import android.support.design.widget.TextInputEditText import android.support.design.widget.TextInputLayout +import android.support.v4.content.res.ResourcesCompat import android.text.Editable import android.text.Html import android.text.InputType @@ -85,6 +86,7 @@ open class EditText : FrameLayout{ if (inputType != EditorInfo.TYPE_NULL) { mTextEdit.setInputType(inputType) } + mTextEdit.typeface = ResourcesCompat.getFont(context, R.font.google_sans_regular) mTextEdit.addTextChangedListener(object: android.text.TextWatcher { override fun afterTextChanged(p0: Editable?) { } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/component/text/TextView.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/component/text/TextView.kt index 1a37a46c..1022966f 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/component/text/TextView.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/component/text/TextView.kt @@ -1,10 +1,12 @@ package io.forus.me.android.presentation.view.component.text import android.content.Context +import android.graphics.Typeface +import android.support.v4.content.res.ResourcesCompat import android.support.v7.widget.AppCompatTextView import android.util.AttributeSet +import android.util.Log import io.forus.me.android.presentation.R -import android.graphics.Typeface import io.forus.me.android.presentation.helpers.FontCache import io.forus.me.android.presentation.view.component.FontType @@ -14,6 +16,8 @@ class TextView : AppCompatTextView { var type: FontType = FontType.Regular + + constructor(context: Context) : super(context) { initUI(context, null) } @@ -49,7 +53,14 @@ class TextView : AppCompatTextView { private fun initType(context: Context) { - this.typeface = FontCache.getTypeface(type.getFontPath(), context) + when(type){ + FontType.Medium , FontType.Bold -> this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_medium) + FontType.Regular ->this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_regular) + else -> this.typeface = ResourcesCompat.getFont(context, R.font.google_sans_regular) + } + // this.typeface = FontCache.getTypeface(type.getFontPath(), context) + + } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/account/check_email/CheckEmailActivity.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/account/check_email/CheckEmailActivity.kt index 5a25e4a0..5d2d518f 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/account/check_email/CheckEmailActivity.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/account/check_email/CheckEmailActivity.kt @@ -45,7 +45,7 @@ class CheckEmailActivity : CommonActivity() { SharedPref.init(this@CheckEmailActivity) val restoreEmail = SharedPref.read(SharedPref.RESTORE_EMAIL, "") - val descriptionText = getString(R.string.check_email_description_part1) + " " + restoreEmail + " " + getString(R.string.check_email_description_part2) + val descriptionText = getString(R.string.check_email_description_part1) + " " + restoreEmail + " " + getString(R.string.check_email_description_part2) description.text = HtmlCompat.fromHtml(descriptionText, HtmlCompat.FROM_HTML_MODE_LEGACY); diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/assigndelegates/qr/RestoreByQRFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/assigndelegates/qr/RestoreByQRFragment.kt index 3481efd4..2d5b9704 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/assigndelegates/qr/RestoreByQRFragment.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/assigndelegates/qr/RestoreByQRFragment.kt @@ -71,7 +71,6 @@ class RestoreByQRFragment : LRFragment(R.id.message); + + messageTV?.setText(message); + } + + fun show(){ + dialog.show() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpFragment.kt index 7462ce1c..680880aa 100755 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpFragment.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpFragment.kt @@ -1,14 +1,19 @@ package io.forus.me.android.presentation.view.screens.account.login_signup_account import android.os.Bundle -import android.support.v4.text.HtmlCompat import android.text.Editable import android.util.DisplayMetrics +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import com.afollestad.materialdialogs.DialogAction import com.afollestad.materialdialogs.MaterialDialog +import com.google.gson.Gson +import io.forus.me.android.domain.exception.RetrofitException +import io.forus.me.android.domain.exception.RetrofitExceptionMapper import io.forus.me.android.domain.models.account.NewAccountRequest +import io.forus.me.android.domain.models.records.errors.BaseApiError import io.forus.me.android.presentation.BuildConfig import io.forus.me.android.presentation.api_config.ApiConfig import io.forus.me.android.presentation.api_config.ApiType @@ -19,12 +24,15 @@ import io.forus.me.android.presentation.api_config.dialogs.* import io.forus.me.android.presentation.helpers.SharedPref import io.forus.me.android.presentation.internal.Injection import io.forus.me.android.presentation.view.activity.BaseActivity +import io.forus.me.android.presentation.view.base.NoInternetDialog import io.forus.me.android.presentation.view.base.lr.LRViewState import io.forus.me.android.presentation.view.base.lr.LoadRefreshPanel import io.forus.me.android.presentation.view.fragment.ToolbarLRFragment +import io.forus.me.android.presentation.view.screens.qr.dialogs.ScanVoucherBaseErrorDialog import io.reactivex.Observable import io.reactivex.subjects.PublishSubject import kotlinx.android.synthetic.main.fragment_account_details.root +import java.lang.Exception /** @@ -84,8 +92,8 @@ class LogInSignUpFragment : ToolbarLRFragment() - override fun register() = registerAction + private val restoreAction = PublishSubject.create() + override fun register() = restoreAction private val exchangeToken = PublishSubject.create() override fun exchangeToken() = exchangeToken @@ -95,6 +103,14 @@ class LogInSignUpFragment : ToolbarLRFragment { + TODO("Not yet implemented") + }*/ + + private val validateEmail = PublishSubject.create() + override fun validateEmail() = validateEmail + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -142,18 +158,6 @@ class LogInSignUpFragment : ToolbarLRFragment - SharedPref.init(it1) - SharedPref.write(SharedPref.RESTORE_EMAIL, email!!.getText()); - }; - - registerAction.onNext(email!!.getText()) - } - } pair_device!!.setOnClickListener { navigator.navigateToPairDevice(context!!) @@ -172,6 +176,11 @@ class LogInSignUpFragment : ToolbarLRFragment) { super.render(vs) @@ -191,21 +200,53 @@ class LogInSignUpFragment : ToolbarLRFragment + SharedPref.init(it1) + SharedPref.write(SharedPref.RESTORE_EMAIL, email!!.getText()); + }; + + if (vs.model.validateEmail.used) { + + restoreAction.onNext(email!!.getText()) + + } else { + registerActionNewAccount.onNext(NewAccountRequest( + firstname = "", + lastname = "", + bsn = "", + phoneNumber = "", + email = email!!.getText() + )) + } + + } else { + processError(Throwable("Invalid email")) } + + } + + if (vs.model.validateEmailError != null) { + processError(vs.model.validateEmailError) + } + + + if (vs.model.sendingRestoreByEmailError != null) { + processError(vs.model.sendingRestoreByEmailError) } + + if (vs.model.exchangeTokenError != null) { showToastMessage(resources.getString(R.string.restore_email_invalid_link)) } @@ -274,8 +315,36 @@ class LogInSignUpFragment : ToolbarLRFragment { + LogInSignUpPartialChanges.ValidateEmailRequest(it) + // else LogInSignUpPartialChanges.RestoreByEmailRequestError(Exception(it.toString())) + } + .onErrorReturn { + LogInSignUpPartialChanges.ValidateEmailRequestError(it) + } + .startWith(LogInSignUpPartialChanges.RestoreByEmailRequestStart()) + + }, + intent { it.exchangeToken() } .flatMap { accountRepository.restoreExchangeToken(it) @@ -106,11 +120,20 @@ class LogInSignUpPresenter constructor(private val token: String, private val ac if (change !is LogInSignUpPartialChanges) return super.stateReducer(vs, change) return when (change) { - is LogInSignUpPartialChanges.RestoreByEmailRequestStart -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = true, sendingRestoreByEmailError = null)) - is LogInSignUpPartialChanges.RestoreByEmailRequestEnd -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = false, sendingRestoreByEmailSuccess = true)) - is LogInSignUpPartialChanges.RestoreByEmailRequestError -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = false, sendingRestoreByEmailError = change.error)) - is LogInSignUpPartialChanges.ExchangeTokenResult -> vs.copy(model = vs.model.copy(accessToken = change.accessToken, sendingRestoreByEmail = false, sendingRestoreByEmailError = null)) - is LogInSignUpPartialChanges.ExchangeTokenError -> vs.copy(model = vs.model.copy(exchangeTokenError = change.error)) + is LogInSignUpPartialChanges.RestoreByEmailRequestStart -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = true, + sendingRestoreByEmailError = null, validateEmail = null, validateEmailError = null)) + is LogInSignUpPartialChanges.RestoreByEmailRequestEnd -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = false, + sendingRestoreByEmailSuccess = true, validateEmail = null, validateEmailError = null)) + is LogInSignUpPartialChanges.RestoreByEmailRequestError -> vs.copy(model = vs.model.copy(sendingRestoreByEmail = false, + sendingRestoreByEmailError = change.error, validateEmail = null, validateEmailError = null)) + is LogInSignUpPartialChanges.ExchangeTokenResult -> vs.copy(model = vs.model.copy(accessToken = change.accessToken, sendingRestoreByEmail = false, + sendingRestoreByEmailError = null, validateEmail = null, validateEmailError = null)) + is LogInSignUpPartialChanges.ExchangeTokenError -> vs.copy(model = vs.model.copy(exchangeTokenError = change.error, + validateEmail = null, validateEmailError = null)) + is LogInSignUpPartialChanges.ValidateEmailRequest -> vs.copy(model = vs.model.copy(validateEmail = change.validateEmail, validateEmailError = null, + sendingRestoreByEmail = false,sendingRestoreByEmailError = null,sendingRestoreByEmailSuccess = false)) + is LogInSignUpPartialChanges.ValidateEmailRequestError -> vs.copy(model = vs.model.copy(validateEmailError = change.error, validateEmail = null, + sendingRestoreByEmail = false,sendingRestoreByEmailError = null, sendingRestoreByEmailSuccess = false)) } } } \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpView.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpView.kt index dc4ab954..b946839d 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpView.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/account/login_signup_account/LogInSignUpView.kt @@ -14,4 +14,6 @@ interface LogInSignUpView : LRView { fun registerNewAccount(): io.reactivex.Observable + fun validateEmail(): io.reactivex.Observable + } \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/dashboard/DashboardActivity.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/dashboard/DashboardActivity.kt index 0d859dbb..bb42104b 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/dashboard/DashboardActivity.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/dashboard/DashboardActivity.kt @@ -113,6 +113,7 @@ class DashboardActivity : SlidingPanelActivity(), DashboardContract.View { addPopupFragment(QrFragment.newIntent(address, qrHead, qrSubtitle, qrDescription), "QR code") } + override fun replaceFragment(fragment: Fragment, sharedViews: List) { super.replaceFragment(R.id.dashboard_top_content, fragment, sharedViews, true) } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/QrActionProcessor.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/QrActionProcessor.kt index 51025535..aacf55dd 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/QrActionProcessor.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/QrActionProcessor.kt @@ -15,11 +15,11 @@ import io.forus.me.android.presentation.models.vouchers.FundType import io.forus.me.android.presentation.navigation.Navigator import io.forus.me.android.presentation.view.base.NoInternetDialog import io.forus.me.android.presentation.view.screens.qr.dialogs.* +import io.forus.me.android.presentation.view.screens.records.create_record.dialog.CreateRecordSuccessDialog import io.forus.me.android.presentation.view.screens.records.dialogs.validators_list_dialog.ValidatorsListDialog import io.forus.me.android.presentation.view.screens.vouchers.provider.ProviderActivity import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers -import java.lang.Exception import java.math.BigDecimal class QrActionProcessor(private val scanner: QrScannerActivity, @@ -65,35 +65,48 @@ class QrActionProcessor(private val scanner: QrScannerActivity, } fun restoreIdentity(token: String) { + Log.d("forusQR", "restore identity $token") - if (scanner.hasWindowFocus()) - Log.d("forusQR", "restore identity 1") - RestoreIdentityDialog(scanner, - { Log.d("forusQR", "restore identity 2") - accountRepository.authorizeToken(token) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .map { - onResultIdentityRestored() - } - .onErrorReturn { - if (it is RetrofitException && it.kind == RetrofitException.Kind.HTTP && it.responseCode == 402) { - onResultTokenExpired(it) - } else { - onResultUnexpectedError() - } - } - .subscribe() - }, - reactivateDecoding) - .show() + + + val confirmLoginDeviceDialog = ConfirmLoginDeviceDialog() + confirmLoginDeviceDialog.submitClickListener = object :ConfirmLoginDeviceDialog.SubmitClickListener{ + override fun confirm(dialog: ConfirmLoginDeviceDialog?) { + confirmLoginDeviceDialog.dismiss() + accountRepository.authorizeToken(token) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .map { + onResultIdentityRestored() + } + .onErrorReturn { + if (it is RetrofitException && it.kind == RetrofitException.Kind.HTTP && it.responseCode == 402) { + onResultTokenExpired(it) + } else { + onResultUnexpectedError() + } + } + .subscribe() + + } + + override fun dismiss(dialog: ConfirmLoginDeviceDialog?) { + confirmLoginDeviceDialog.dismiss() + scanner.finish() + } + + } + confirmLoginDeviceDialog.show(scanner.supportFragmentManager, "") + + + } private var retrofitExceptionMapper: RetrofitExceptionMapper = Injection.instance.retrofitExceptionMapper fun scanVoucher(address: String, isDemoVoucher: Boolean? = false) { - Log.d("forusQR","allowReactivate....") + Log.d("forusQR", "allowReactivate....") scanner.allowReactivate() if (isDemoVoucher != null && isDemoVoucher) { navigator.navigateToVoucherProvider(scanner, address, true) diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/dialogs/ConfirmLoginDeviceDialog.java b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/dialogs/ConfirmLoginDeviceDialog.java new file mode 100644 index 00000000..88b4bf13 --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/qr/dialogs/ConfirmLoginDeviceDialog.java @@ -0,0 +1,132 @@ +package io.forus.me.android.presentation.view.screens.qr.dialogs; + +import android.app.Dialog; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentManager; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.LinearLayout; +import android.widget.TextView; + +import io.forus.me.android.presentation.R; + + +public class ConfirmLoginDeviceDialog extends DialogFragment { + + View rootView; + + + + public SubmitClickListener submitClickListener; + + public static ConfirmLoginDeviceDialog display(FragmentManager fragmentManager,SubmitClickListener submitClickListener) { + ConfirmLoginDeviceDialog dialog = new ConfirmLoginDeviceDialog(); + + dialog.submitClickListener = submitClickListener; + + dialog.show(fragmentManager, ""); + return dialog; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme_FullScreenDialog); + } + + boolean isSmallScreen = false; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + Display display = getActivity().getWindowManager().getDefaultDisplay(); + DisplayMetrics outMetrics = new DisplayMetrics(); + display.getMetrics(outMetrics); + float density = getResources().getDisplayMetrics().density; + float dpHeight = outMetrics.heightPixels / density; + float dpWidth = outMetrics.widthPixels / density; + + if (dpWidth <= 320 || dpHeight < 522){ + isSmallScreen = true; + } + + rootView = inflater.inflate(R.layout.dialog_confirm_login_device, container, false); + + + return rootView; + } + + @Override + public void onStart() { + super.onStart(); + Dialog dialog = getDialog(); + if (dialog != null) { + int width = ViewGroup.LayoutParams.MATCH_PARENT; + int height = ViewGroup.LayoutParams.MATCH_PARENT; + if (dialog.getWindow() != null) { + dialog.getWindow().setLayout(width, height); + } + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + io.forus.me.android.presentation.view.component.buttons.Button submitButton = rootView.findViewById(R.id.submitButton); + + LinearLayout imageL = rootView.findViewById(R.id.imageL); + if(isSmallScreen){ + imageL.setVisibility(View.INVISIBLE); + } + + rootView.findViewById(R.id.closeBt).setOnClickListener(view12 -> { + if (submitClickListener != null) { + submitClickListener.dismiss(ConfirmLoginDeviceDialog.this); + } + }); + + + rootView.findViewById(R.id.cancelButton).setOnClickListener(view1 -> { + if (submitClickListener != null) { + submitClickListener.dismiss(ConfirmLoginDeviceDialog.this); + } + }); + + + + + if (submitClickListener != null) { + submitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (submitClickListener != null) { + submitClickListener.confirm(ConfirmLoginDeviceDialog.this); + } + } + }); + } + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Dialog dialog = super.onCreateDialog(savedInstanceState); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + return dialog; + } + + public interface SubmitClickListener { + void confirm(ConfirmLoginDeviceDialog dialog); + void dismiss(ConfirmLoginDeviceDialog dialog); + } + + +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/records/item/RecordDetailsFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/records/item/RecordDetailsFragment.kt index 900e17cd..b8c1c6ec 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/records/item/RecordDetailsFragment.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/records/item/RecordDetailsFragment.kt @@ -127,7 +127,7 @@ class RecordDetailsFragment : ToolbarLRFragment) { super.render(vs) - Log.d("forus","vs.model.items="+vs.model.items) - Log.d("forus","showList"+showList) - Log.d("forus","itemSelectListener==null=${itemSelectListener==null}") - if(vs.model.items.isNotEmpty() && !showList && itemSelectListener != null){ + if(vs.model.items.isNotEmpty() && !showList && itemSelectListener != null){ itemSelectListener!!.onRecordTypesLoaded(vs.model.items) } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/ApplyActionTransactionDialog.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/ApplyActionTransactionDialog.kt index fc4506a1..b2e3564d 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/ApplyActionTransactionDialog.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/ApplyActionTransactionDialog.kt @@ -7,7 +7,8 @@ import com.afollestad.materialdialogs.MaterialDialog import io.forus.me.android.presentation.R -class ApplyActionTransactionDialog(private val context: Activity, private val amount: String, val isFreeProduct: Boolean, +class ApplyActionTransactionDialog(private val context: Activity, private val title: String, + private val toPayText: String, private val subtitle: String, private val positiveCallback: () -> Unit) { var dialog: MaterialDialog? = null @@ -19,20 +20,14 @@ class ApplyActionTransactionDialog(private val context: Activity, private val am val bottomTV = customLayout.findViewById(R.id.bottom) val amountTV = customLayout.findViewById(R.id.amount) - val freeGood = customLayout.findViewById(R.id.freeGood) - - titleTV.visibility = if(isFreeProduct){View.GONE}else{View.VISIBLE} - bottomTV.visibility = if(isFreeProduct){View.GONE}else{View.VISIBLE} - amountTV.visibility = if(isFreeProduct){View.GONE}else{View.VISIBLE} - freeGood.visibility = if(isFreeProduct){View.VISIBLE}else{View.GONE} - - if(isFreeProduct){ - freeGood.text = context.getString(R.string.free_product ) - }else{ - amountTV.text = amount - titleTV.text = context.getString(R.string.free_product ) - bottomTV.text = context.getString(R.string.paid_at_till) - } + + + + + amountTV.text = toPayText + titleTV.text = title + bottomTV.text = subtitle + customLayout.findViewById(R.id.submit).setOnClickListener { diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/VouchersApplySuccessDialog.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/VouchersApplySuccessDialog.kt index 873091e1..b3cda2ab 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/VouchersApplySuccessDialog.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/dialogs/VouchersApplySuccessDialog.kt @@ -9,8 +9,8 @@ class VouchersApplySuccessDialog(private val context: Context, private val positiveCallback: () -> Unit){ private val dialog: MaterialDialog = MaterialDialog.Builder(context) - .title(context.resources.getString(R.string.success)) - .content(context.resources.getString(R.string.vouchers_apply_success)) + .title(context.resources.getString(R.string.vouchers_apply_success)) + .content(context.resources.getString(R.string.vouchers_transaction_duration_of_payout)) .positiveText(context.resources.getString(R.string.me_ok)) .onPositive { dialog, which -> positiveCallback.invoke() } .build() diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/VoucherFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/VoucherFragment.kt index a9868eb5..29fadf47 100755 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/VoucherFragment.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/VoucherFragment.kt @@ -5,12 +5,9 @@ import android.content.Intent import android.graphics.BlurMaskFilter import android.net.Uri import android.os.Bundle -import android.support.customtabs.CustomTabsIntent -import android.support.design.widget.Snackbar -import android.support.v4.content.ContextCompat +import android.support.v4.view.ViewPager import android.support.v7.app.AlertDialog import android.support.v7.widget.LinearLayoutManager -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -26,26 +23,25 @@ import io.forus.me.android.data.executor.JobExecutor import io.forus.me.android.domain.interactor.LoadVoucherUseCase import io.forus.me.android.domain.interactor.SendEmailUseCase import io.forus.me.android.domain.models.qr.QrCode -import io.forus.me.android.presentation.BuildConfig import io.forus.me.android.presentation.R import io.forus.me.android.presentation.UIThread import io.forus.me.android.presentation.helpers.format import io.forus.me.android.presentation.internal.Injection import io.forus.me.android.presentation.mappers.* import io.forus.me.android.presentation.models.vouchers.FundType +import io.forus.me.android.presentation.models.vouchers.Office import io.forus.me.android.presentation.models.vouchers.Voucher import io.forus.me.android.presentation.view.base.lr.LRViewState import io.forus.me.android.presentation.view.fragment.ToolbarLRFragment import io.forus.me.android.presentation.view.screens.dashboard.DashboardActivity import io.forus.me.android.presentation.view.screens.vouchers.dialogs.FullscreenDialog -import io.forus.me.android.presentation.view.screens.vouchers.item.dialogs.SendVoucherSuccessDialog +import io.forus.me.android.presentation.view.screens.vouchers.item.offices_adapter.OfficesAdapter import io.forus.me.android.presentation.view.screens.vouchers.item.transactions.TransactionsAdapter import io.reactivex.Observable import io.reactivex.subjects.PublishSubject -import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_voucher.* +import kotlinx.android.synthetic.main.item_vouchers_list.view.* import kotlinx.android.synthetic.main.toolbar_view.* -import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* @@ -154,9 +150,8 @@ class VoucherFragment : ToolbarLRFragment) { super.render(vs) - Log.d("forus", "render") name.text = vs.model.item?.name type.text = vs.model.item?.organizationName - value.text = "${vs.model.item?.currency?.name} ${vs.model.item?.amount?.toDouble().format(2)}" + vs.model.item?.let { voucher -> - Log.d("forus", "vs.model.item") setToolbarTitle(resources.getString(if (voucher.isProduct) R.string.vouchers_item_product else R.string.vouchers_item)) - if(voucher.fundType == FundType.subsidies.name){ + if (voucher.fundType == FundType.subsidies.name) { adapter.isActionsVoucher = true } adapter.transactions = voucher.transactions @@ -299,6 +294,8 @@ class VoucherFragment : ToolbarLRFragment() + myOffices.addAll(officesList) + if (myOffices.isNotEmpty()) { + val officesAdapter = OfficesAdapter(myOffices, context!!) + officesAdapter.showMapCallback = object : OfficesAdapter.ShowMapCallback { + override fun showMap(office: Office) { + if (office.lat != null && office.lon != null) { + showGoogleMaps(office.lat!!, office.lon!!) + } + } + } + val officesCnt = myOffices.size + branchesTV.text = resources.getQuantityString(R.plurals.branches, officesCnt, officesCnt) + + viewPager.adapter = officesAdapter + viewPager.setPadding(16, 20, 130, 20) + viewPager.setOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { + val office = if (position >= 0 && position < myOffices.size) myOffices[position] else myOffices[0] + val latLng = LatLng(office.lat ?: 0.0, office.lon ?: 0.0) + organizationLatLng = latLng + setMarker(latLng) + } + + override fun onPageSelected(position: Int) {} + override fun onPageScrollStateChanged(state: Int) {} + }) + + + } else { + branchesTV.visibility = View.GONE + } } + + + if (voucher.expired) { - //val isExpired = isVoucherExpired(voucher.expireDate!!) - //Log.d("forus", "Is_voucher_expired? $isExpired") - info_button.visibility = View.INVISIBLE - btn_email.isEnabled = false - btn_email.visibility = View.INVISIBLE - iv_qr_icon.visibility = View.INVISIBLE - tv_voucher_expired.visibility = View.VISIBLE + if (voucher.isProduct && voucher.isUsed || voucher.expired) { + + info_button.visibility = View.INVISIBLE + btn_email.isEnabled = false + btn_email.visibility = View.GONE + iv_qr_icon.visibility = View.INVISIBLE + tv_voucher_expired.visibility = View.VISIBLE + + value.visibility = View.GONE + usedOrExpiredLb.visibility = View.VISIBLE + + if (voucher.isProduct && voucher.isUsed) { + + usedOrExpiredLb.text = usedOrExpiredLb.context.getString(R.string.voucher_is_used) + } else if (voucher.expired) { + + //usedOrExpiredLb.text = usedOrExpiredLb.context.getString(R.string.voucher_expired) + + if (voucher.expireDate?.isNotEmpty()!!) { + + usedOrExpiredLb.text = if (voucher.expired) String.format(resources.getString(R.string.voucher_qr_code_expired), + voucher?.expireDate) else String.format(resources.getString(R.string.voucher_qr_code_actual), + voucher?.expireDate) + + tv_voucher_expired.visibility = View.GONE + // tv_voucher_expired.text = if (voucher.expired) String.format(resources.getString(R.string.voucher_qr_code_expired), + // voucher?.expireDate) else String.format(resources.getString(R.string.voucher_qr_code_actual), + // voucher?.expireDate) + } - if (voucher.expireDate?.isNotEmpty()!!) { + tv_voucher_expired.text = if (voucher.expired) String.format(resources.getString(R.string.voucher_qr_code_expired), + voucher.expireDate) else String.format(resources.getString(R.string.voucher_qr_code_actual), + voucher.expireDate) - tv_voucher_expired.text = if (voucher.expired) String.format(resources.getString(R.string.voucher_qr_code_expired), - voucher?.expireDate) else String.format(resources.getString(R.string.voucher_qr_code_actual), - voucher?.expireDate) + } + } else { + tv_voucher_expired.visibility = View.GONE + value.visibility = View.VISIBLE + usedOrExpiredLb.visibility = View.GONE + value.text = "${vs.model.item?.currency?.name} ${vs.model.item?.amount?.toDouble().format(2)}" } - // shopkeeper_call - } else { - tv_voucher_expired.visibility = View.GONE - } - if(voucher.fundType == FundType.subsidies.name) { - info_button.visibility = View.INVISIBLE + if (voucher.fundType == FundType.subsidies.name) { + info_button.visibility = View.INVISIBLE - iv_qr_icon.visibility = View.VISIBLE - tv_voucher_expired.visibility = View.VISIBLE - tv_voucher_expired.visibility = View.GONE - value.visibility = View.GONE - } + if (voucher.fundType == FundType.subsidies.name) { + info_button.visibility = View.INVISIBLE + iv_qr_icon.visibility = View.VISIBLE - } + tv_voucher_expired.visibility = View.VISIBLE + tv_voucher_expired.visibility = View.GONE + value.visibility = View.GONE + + } - if (vs.model.shortToken != null) { - if (canShowInfo) { - val url: String = if (voucher?.fundWebShopUrl?.isNotEmpty()!! && vs.model.shortToken.isNotEmpty()) { - voucher?.fundWebShopUrl + "auth-link?token=" + vs.model.shortToken + "&target=voucher-" + voucher?.address - } else { - "https://forus.io/" } - openVoucherInfo(url) - canShowInfo = false - } - } + if (vs.model.shortToken != null) { + if (canShowInfo) { + + val url: String = if (voucher?.fundWebShopUrl?.isNotEmpty()!! && vs.model.shortToken.isNotEmpty()) { + voucher?.fundWebShopUrl + "auth-link?token=" + vs.model.shortToken + "&target=voucher-" + voucher?.address + } else { + "https://forus.io/" + } + + openVoucherInfo(url) + canShowInfo = false + } + } - when (vs.model.emailSend) { - EmailSend.SEND -> showEmailSendDialog() - EmailSend.SENT -> { - FullscreenDialog.display(fragmentManager, context!!.resources.getString(R.string.voucher_send_email_success), - context!!.resources.getString(R.string.voucher_send_email_description), - context!!.resources.getString(R.string.me_ok)) { - sentEmailDialogShown.onNext(Unit) + when (vs.model.emailSend) { + EmailSend.SEND -> showEmailSendDialog() + EmailSend.SENT -> { + FullscreenDialog.display(fragmentManager, context!!.resources.getString(R.string.voucher_send_email_success), + context!!.resources.getString(R.string.voucher_send_email_description), + context!!.resources.getString(R.string.me_ok)) { + sentEmailDialogShown.onNext(Unit) + } + } + EmailSend.NOTHING -> Unit } } - EmailSend.NOTHING -> Unit + } + } + + + private fun showGoogleMaps(lat: Double, lon: Double){ + val gmmIntentUri = Uri.parse("geo:${lat.toString()},${lon.toString()}") + val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) + mapIntent.setPackage("com.google.android.apps.maps") + if (mapIntent.resolveActivity(context!!.packageManager) != null) { + startActivity(mapIntent) } } @@ -385,9 +460,9 @@ class VoucherFragment : ToolbarLRFragment() + + fun addSchedule(schedule: Schedule) { + group.add(schedule) + } + + fun isDayCompatibleInGroup(schedule: Schedule): Boolean { + + if (group.isNotEmpty()) { + if (group[0].startTime == schedule.startTime && group[0].endTime == schedule.endTime) { + group.add(schedule) + return true + } else { + return false + } + } else { + return true + } + } + + fun scheduleText(ctx: Context): String { + return when { + group.isEmpty() -> { + "" + } + group.size == 1 -> { + val day = group.first() + getDayOfWeekName(ctx, day.weekDay.toInt()) + ": " + day.startTime + " - " + day.endTime + } + else -> { + val firstDay = group.first() + val lastDay = group.last() + (getDayOfWeekName(ctx, firstDay.weekDay.toInt()) + " - " + getDayOfWeekName(ctx, lastDay.weekDay.toInt()) + ": " + + firstDay.startTime + " - " + firstDay.endTime) + } + } + } + + fun isEmptyGroup():Boolean{ + return group.isEmpty() + } + + fun getDayOfWeekName(context: Context, day: Int): String { + + return when (day) { + 0 -> context.getString(R.string.monday) + 1 -> context.getString(R.string.tuesday) + 2 -> context.getString(R.string.wednesday) + 3 -> context.getString(R.string.thursday) + 4 -> context.getString(R.string.friday) + 5 -> context.getString(R.string.saturday) + 6 -> context.getString(R.string.sunday) + else -> "" + } + } + +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/offices_adapter/OfficesAdapter.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/offices_adapter/OfficesAdapter.kt new file mode 100644 index 00000000..fd453043 --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/item/offices_adapter/OfficesAdapter.kt @@ -0,0 +1,139 @@ +package io.forus.me.android.presentation.view.screens.vouchers.item.offices_adapter + +import android.content.Context +import android.support.v4.view.PagerAdapter +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import io.forus.me.android.presentation.R +import io.forus.me.android.presentation.models.vouchers.Office +import io.forus.me.android.presentation.models.vouchers.Schedule + +class OfficesAdapter(private val items: List, private val context: Context) : PagerAdapter() { + private var layoutInflater: LayoutInflater? = null + override fun getCount(): Int { + return items.size + } + + override fun isViewFromObject(view: View, obj: Any): Boolean { + return view == obj + } + + var showMapCallback : ShowMapCallback? = null + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + layoutInflater = LayoutInflater.from(context) + val view = layoutInflater!!.inflate(R.layout.item_office, container, false) + val addressTV: TextView = view.findViewById(R.id.addressTV) + val showMapTV: TextView = view.findViewById(R.id.showMapTV) + val phoneTV: TextView = view.findViewById(R.id.phoneTV) + val timeTV: TextView = view.findViewById(R.id.timeTV) + + + + val office = items[position] + + showMapTV.setOnClickListener { + if(showMapCallback != null){ + showMapCallback!!.showMap(office) + } + } + + + addressTV.text = office.address + phoneTV.text = office.phone + + val groupSchedulers = groupSchedulers2(office.schedulers) + var schedulersText = "" + + + + groupSchedulers.map { + schedulersText += it.scheduleText(timeTV.context) + schedulersText += "\n" + + } + + timeTV.text = schedulersText + + container.addView(view, 0) + return view + } + + //Group by schedule time only any days + fun groupSchedulers2(schedulers: List): List { + val groups = mutableListOf() + + for (i in 0 until (schedulers.size)) { + val gr = schedulers[i] + + if(gr.startTime.isNullOrEmpty() || gr.endTime.isNullOrEmpty()) { + + }else{ + + var searchCompatibleGroup = false + + for(group in groups){ + if (group.isDayCompatibleInGroup(gr)) { + group.addSchedule(gr) + searchCompatibleGroup = true + } + } + if(!searchCompatibleGroup) { + val group = DaysGroup() + groups.add(group) + group.addSchedule(gr) + } + } + } + + return groups + } + + //Group by schedule time only neighbor days + fun groupSchedulers(schedulers: List): List { + val groups = mutableListOf() + var group = DaysGroup() + groups.add(group) + for (i in 0 until (schedulers.size)) { + val gr = schedulers[i] + + if(gr.startTime.isNullOrEmpty() || gr.endTime.isNullOrEmpty()) { + if(!group.isEmptyGroup()) { + group = DaysGroup() + groups.add(group) + } + }else{ + if (group.isDayCompatibleInGroup(gr)) { + group.addSchedule(gr) + } else { + if(!group.isEmptyGroup()) { + group = DaysGroup() + groups.add(group) + } + group.addSchedule(gr) + } + } + if(i==schedulers.size-1){ + if(group.isEmptyGroup()){ + groups.remove(group) + } + } + } + + return groups + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + + + + + public interface ShowMapCallback{ + fun showMap(office: Office) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersPresenter.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersPresenter.kt index 66fc1d8b..feb22c6f 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersPresenter.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersPresenter.kt @@ -1,5 +1,6 @@ package io.forus.me.android.presentation.view.screens.vouchers.list +import io.forus.me.android.domain.models.vouchers.Schedule import io.forus.me.android.domain.repository.vouchers.VouchersRepository import io.forus.me.android.presentation.models.currency.Currency import io.forus.me.android.presentation.models.vouchers.* @@ -65,9 +66,31 @@ class VouchersPresenter constructor(val vouchersRepository: VouchersRepository) domainProduct.organization!!.address, domainProduct.organization!!.phone, domainProduct.organization!!.email)}else{null}) } + val officesList = mutableListOf() + val officesMapped = offices.map { + + val schedulers = mutableListOf() + if(it.schedulers != null){ + it.schedulers!!.map { + schedulers.add(io.forus.me.android.presentation.models.vouchers.Schedule(it.id,it.officeId ?:-1L,it.weekDay?:0,it.startTime,it.endTime)) + } + } + + + val organization = Organization(it.organization?.id ?: 0, + it.organization?.name ?: "", it.organization?.logo ?: "", + it.organization?.lat ?: 0.0, it.organization?.lon ?: 0.0, + it.organization?.address ?: "", + it.organization?.phone ?: "", + it.organization?.email ?: "") + + officesList.add(Office(it.id,it.organizationId,it.address,it.phone,it.lat,it.lon,it.photo,organization, schedulers)) + + } + Voucher(isProduct ?: false, isUsed ?: false, address, name, organizationName, fundName, fundType,fundWebShopUrl, description, createdAt, Currency(currency?.name, currency?.logoUrl), amount, logo, - transactionsMapped, product, expired ?: false, expireDate + transactionsMapped, product, expired ?: false, expireDate , officesList ) } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersVH.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersVH.kt index 65292827..13bd77c6 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersVH.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/list/VouchersVH.kt @@ -19,19 +19,36 @@ class VouchersVH(parent: ViewGroup) : RecyclerView.ViewHolder(parent.inflate(R.l if(item.fundType == FundType.subsidies.name) { name.text = item.name - organization_name.text = item.organizationName - value.text = "" - used.visibility = View.INVISIBLE - logo.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_icon)) + // organization_name.text = item.organizationName + // value.text = "" + usedOrExpiredLb.visibility = View.INVISIBLE + if (item.logo != null) { + if (item.logo!!.isNotEmpty()) { + logo.setImageUrl(item.logo) + } + } }else{ name.text = item.name organization_name.text = item.organizationName - value.text = "${item.currency?.name} ${item.amount?.toDouble().format(2)}" - used.visibility = if (item.isProduct && item.isUsed) View.VISIBLE else View.GONE logo.setImageUrl(item.logo) + if (item.isProduct && item.isUsed) { + value.visibility = View.GONE + usedOrExpiredLb.visibility = View.VISIBLE + usedOrExpiredLb.text = usedOrExpiredLb.context.getString(R.string.voucher_is_used) + } else if (item.expired) { + value.visibility = View.GONE + usedOrExpiredLb.visibility = View.VISIBLE + usedOrExpiredLb.text = usedOrExpiredLb.context.getString(R.string.voucher_expired) + + } else { + value.visibility = View.VISIBLE + usedOrExpiredLb.visibility = View.GONE + value.text = "${item.currency?.name} ${item.amount?.toDouble().format(2)}" + } + } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/product_reservation/ProductReservationPresenter.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/product_reservation/ProductReservationPresenter.kt index e40019a2..5a74c692 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/product_reservation/ProductReservationPresenter.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/product_reservation/ProductReservationPresenter.kt @@ -67,9 +67,30 @@ class ProductReservationPresenter constructor(val vouchersRepository: VouchersRe domainProduct.organization?.lon, domainProduct.organization?.address, domainProduct.organization?.phone, domainProduct.organization?.email)) } + val officesList = mutableListOf() + val officesMapped = offices.map { + + val schedulers = mutableListOf() + if(it.schedulers != null){ + it.schedulers!!.map { + schedulers.add(io.forus.me.android.presentation.models.vouchers.Schedule(it.id,it.officeId ?:-1L,it.weekDay?:0,it.startTime,it.endTime)) + } + } + + val organization = Organization(it.organization?.id ?: 0, + it.organization?.name ?: "", it.organization?.logo ?: "", + it.organization?.lat ?: 0.0, it.organization?.lon ?: 0.0, + it.organization?.address ?: "", + it.organization?.phone ?: "", + it.organization?.email ?: "") + + officesList.add(Office(it.id,it.organizationId,it.address,it.phone,it.lat,it.lon,it.photo,organization,schedulers)) + + } + Voucher(isProduct ?: false, isUsed ?: false, address, name, organizationName, fundName, fundType, fundWebShopUrl, description, createdAt, Currency(currency?.name, currency?.logoUrl), amount, logo, - transactionsMapped, product, expired ?: false, expireDate + transactionsMapped, product, expired ?: false, expireDate,officesList ) } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/provider/ProviderFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/provider/ProviderFragment.kt index 73a55c91..77648653 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/provider/ProviderFragment.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/provider/ProviderFragment.kt @@ -242,8 +242,8 @@ class ProviderFragment : ToolbarLRFragment() + return return Single.fromObservable(vouchersRepository.getTestVoucherAsProvider().map { VoucherProvider(Voucher(it.voucher?.isProduct ?: false, it.voucher?.isUsed ?: false, it.voucher.address, it.voucher.name, it.voucher.organizationName, @@ -44,7 +46,7 @@ class ProviderPresenter constructor(private val vouchersRepository: VouchersRepo transaction?.amount ?: 0f.toBigDecimal(), transaction.createdAt, Transaction.Type.valueOf(transaction.type.name), null) - }, null, it.voucher.expired ?: false,""), + }, null, it.voucher.expired ?: false,"", officesList), it.allowedOrganizations.map { organization -> Organization(organization.id, @@ -65,7 +67,26 @@ class ProviderPresenter constructor(private val vouchersRepository: VouchersRepo } else { return Single.fromObservable(vouchersRepository.getVoucherAsProvider(address).map { + val officesList = mutableListOf() + val officesMapped = it.voucher.offices.map { + + val schedulers = mutableListOf() + if(it.schedulers != null){ + it.schedulers!!.map { + schedulers.add(io.forus.me.android.presentation.models.vouchers.Schedule(it.id,it.officeId ?:-1L,it.weekDay?:0,it.startTime,it.endTime)) + } + } + + val organization = Organization(it.organization?.id ?: 0, + it.organization?.name ?: "", it.organization?.logo ?: "", + it.organization?.lat ?: 0.0, it.organization?.lon ?: 0.0, + it.organization?.address ?: "", + it.organization?.phone ?: "", + it.organization?.email ?: "") + + officesList.add(Office(it.id,it.organizationId,it.address,it.phone,it.lat,it.lon,it.photo,organization,schedulers)) + } @@ -103,7 +124,7 @@ class ProviderPresenter constructor(private val vouchersRepository: VouchersRepo transaction?.amount ?: 0f.toBigDecimal(), transaction.createdAt, Transaction.Type.valueOf(transaction.type.name), product) - }, null, it.voucher.expired ?: false,""), + }, null, it.voucher.expired ?: false,"", officesList), it.allowedOrganizations.map { organization -> Organization(organization.id, diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/transactions_log/viewmodels/TransactionsLogViewModel.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/transactions_log/viewmodels/TransactionsLogViewModel.kt index d5ab9d97..d21aaf16 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/transactions_log/viewmodels/TransactionsLogViewModel.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/transactions_log/viewmodels/TransactionsLogViewModel.kt @@ -19,8 +19,8 @@ class TransactionsLogViewModel : ViewModel() { var transactionsLiveData: MutableLiveData> = MutableLiveData() - val dateFormatForDisplay = SimpleDateFormat("d MMM YYYY", Locale.getDefault()) - val dateFormatForApi = SimpleDateFormat("YYYY-MM-dd", Locale.getDefault()) + lateinit var dateFormatForDisplay :SimpleDateFormat + lateinit var dateFormatForApi :SimpleDateFormat val progress = MutableLiveData() @@ -48,6 +48,9 @@ class TransactionsLogViewModel : ViewModel() { val cal = Calendar.getInstance() cal.add(Calendar.MONTH, -1) + dateFormatForDisplay = SimpleDateFormat("d MMM YYYY", Locale.getDefault()) + dateFormatForApi = SimpleDateFormat("YYYY-MM-dd", Locale.getDefault()) + calendarFrom.value = cal calendarStringForDisplay.value = "" calendarStringForApi.value = dateFormatForApi.format(cal.time) diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/ActionsActivity.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/ActionsActivity.kt index 2af9bee6..2103ed0a 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/ActionsActivity.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/ActionsActivity.kt @@ -27,6 +27,7 @@ import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actio import kotlinx.android.synthetic.main.activity_actions.* import kotlinx.android.synthetic.main.toolbar_view.* import java.lang.Exception +import java.math.BigDecimal class ActionsActivity : AppCompatActivity() { @@ -77,7 +78,7 @@ class ActionsActivity : AppCompatActivity() { finish() } - descrTV.text = HtmlCompat.fromHtml("" + getString(R.string.choose_an_action_note) + " " + getString(R.string.choose_an_action_descr), + descrTV.text = HtmlCompat.fromHtml(getString(R.string.choose_an_action_descr), HtmlCompat.FROM_HTML_MODE_LEGACY) @@ -85,8 +86,16 @@ class ActionsActivity : AppCompatActivity() { transactionsAdapter = ActionsAdapter(arrayListOf(), object : ActionsAdapter.Callback { override fun onItemClicked(item: ProductAction) { + + + startActivity(ActionPaymentActivity.getCallingIntent(this@ActionsActivity, - ProductSerializable(item.id!!, item.name, item.organization!!.name, item.organization!!.id, item.priceUser!!.toDouble()), voucherAddress!!)) + ProductSerializable(item.id!!, item.name, item.organization!!.name, + item.organization!!.id, item.price, + item.priceOld, + item.noPrice?:false , item.noPriceType, + item.noPriceDiscount , + item.priceUser, item.photoURL), voucherAddress!!,mainViewModel.fundName.value?:"")) } }, this@ActionsActivity) diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/adapter/ActionsAdapter.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/adapter/ActionsAdapter.kt index a1a73446..6f733857 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/adapter/ActionsAdapter.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/adapter/ActionsAdapter.kt @@ -12,6 +12,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import io.forus.me.android.domain.models.vouchers.ProductAction import io.forus.me.android.presentation.R +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.NoPriceType import java.text.NumberFormat import java.util.* import kotlin.collections.ArrayList @@ -41,13 +42,32 @@ class ActionsAdapter(var items: ArrayList, val callback: Callback fun bind(item: ProductAction) { nameTV.text = item.name - priceTV.text = if (item.priceUser!!.toDouble() == 0.0) { - context.getString(R.string.free) + + + priceTV.text = if (item.noPrice!!) { + if (item.noPriceType == NoPriceType.free.name) { + + context.getString(R.string.free) + + } else if (item.noPriceType!! == NoPriceType.discount.name) { + + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(item.noPriceDiscount!!.toDouble()) + "%" + + } else { + context.getString(R.string.price_agreement_n_v_t) + } } else { - NumberFormat.getCurrencyInstance(Locale("nl", "NL")) - .format(item.priceUser!!.toDouble()) + + if (item.priceUser != null) { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(item.priceUser!!.toDouble()) + } else { + context.getString(R.string.price_agreement_n_v_t) + } } + val url = item.photoURL if (url != null && url.isNotEmpty()) { Glide.with(context).load(url) @@ -82,7 +102,7 @@ class ActionsAdapter(var items: ArrayList, val callback: Callback fun add(item: ProductAction) { items.map { - if(item.id == it.id){ + if (item.id == it.id) { return } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentActivity.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentActivity.kt index c6407a0c..8631e1f7 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentActivity.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentActivity.kt @@ -1,44 +1,40 @@ package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment -import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context -import android.content.DialogInterface import android.content.Intent -import android.databinding.DataBindingUtil import android.os.Bundle +import android.support.v4.app.Fragment import android.support.v4.content.ContextCompat -import android.support.v4.text.HtmlCompat import android.support.v7.app.AppCompatActivity -import android.util.Log -import io.forus.me.android.domain.exception.RetrofitException -import io.forus.me.android.domain.exception.RetrofitExceptionMapper +import android.view.View +import com.sothree.slidinguppanel.SlidingUpPanelLayout import io.forus.me.android.presentation.R -import io.forus.me.android.presentation.databinding.ActivityActionPaymentBinding -import io.forus.me.android.presentation.internal.Injection -import io.forus.me.android.presentation.view.screens.qr.dialogs.ScanVoucherBaseErrorDialog -import io.forus.me.android.presentation.view.screens.vouchers.dialogs.ApplyActionTransactionDialog -import io.forus.me.android.presentation.view.screens.vouchers.dialogs.FullscreenDialog -import io.forus.me.android.presentation.view.screens.vouchers.dialogs.ThrowableErrorDialog +import io.forus.me.android.presentation.view.activity.BaseActivity +import io.forus.me.android.presentation.view.activity.SlidingPanelActivity +import io.forus.me.android.presentation.view.fragment.QrFragment import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.ActionsActivity +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.popup.PriceAgreementFragment +import kotlinx.android.synthetic.main.activity_toolbar_sliding_panel.* import kotlinx.android.synthetic.main.toolbar_view.* -import java.text.NumberFormat -import java.util.* -class ActionPaymentActivity : AppCompatActivity() { +class ActionPaymentActivity : BaseActivity() { companion object { const val ACTION_PRODUCT_EXTRA = "ACTION_PRODUCT_EXTRA" const val VOUCHER_ADDRESS_EXTRA = "VOUCHER_ADDRESS_EXTRA" + const val VOUCHER_FUND_NAME_EXTRA = "VOUCHER_FUND_NAME_EXTRA" - fun getCallingIntent(context: Context, product: ProductSerializable, voucherAddress: String): Intent { + fun getCallingIntent(context: Context, product: ProductSerializable, voucherAddress: String, fundName: String): Intent { val intent = Intent(context, ActionPaymentActivity::class.java) val bundle = Bundle() bundle.putSerializable(ACTION_PRODUCT_EXTRA, product) intent.putExtra(VOUCHER_ADDRESS_EXTRA, voucherAddress) + + intent.putExtra(VOUCHER_FUND_NAME_EXTRA, fundName) + intent.putExtras(bundle) return intent @@ -46,12 +42,9 @@ class ActionPaymentActivity : AppCompatActivity() { } - lateinit var mainViewModel: ActionPaymentViewModel - - lateinit var binding: ActivityActionPaymentBinding - var voucherAddress: String? = null var product: ProductSerializable? = null + var fundName: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -61,19 +54,15 @@ class ActionPaymentActivity : AppCompatActivity() { intent.extras.let { product = it.getSerializable(ACTION_PRODUCT_EXTRA) as ProductSerializable voucherAddress = intent.getSerializableExtra(ActionsActivity.VOUCHER_ADDRESS_EXTRA) as String - } - mainViewModel = ViewModelProviders.of(this).get(ActionPaymentViewModel::class.java) - - product.let { - mainViewModel.setProduct(it!!) - mainViewModel.voucherAddress = voucherAddress + fundName = intent.getSerializableExtra(VOUCHER_FUND_NAME_EXTRA) as String } - binding = DataBindingUtil.setContentView(this@ActionPaymentActivity, R.layout.activity_action_payment) - binding.lifecycleOwner = this - binding.model = mainViewModel + product.let { + replaceFragment(R.id.dashboard_content, ActionPaymentFragment.newIntent(product!!, voucherAddress!!,fundName!! + )) + } toolbar_title.text = getString(R.string.payment) @@ -82,33 +71,38 @@ class ActionPaymentActivity : AppCompatActivity() { finish() } - mainViewModel.confirmPayment.observe(this@ActionPaymentActivity, Observer { - if (!it!!) return@Observer - ApplyActionTransactionDialog(this@ActionPaymentActivity, NumberFormat.getCurrencyInstance(Locale("nl", "NL")) - .format(product!!.price)+"?", (product!!.price == 0.0)) { - mainViewModel.makeTransaction() - }.show() - }) - - mainViewModel.successPayment.observe(this@ActionPaymentActivity, Observer { - if (!it!!) return@Observer - FullscreenDialog.display(supportFragmentManager, getString(R.string.success), "", getString(R.string.me_ok)) { - finish() - } - }) - - mainViewModel.errorPayment.observe(this@ActionPaymentActivity, Observer { - if (it != null) { - ThrowableErrorDialog(it, this@ActionPaymentActivity, object : DialogInterface.OnDismissListener, () -> Unit { - override fun invoke() { - } - - override fun onDismiss(p0: DialogInterface?) { - } - }).show() - } - }) + } + override fun replaceFragment(fragment: Fragment, sharedViews: List) { + super.replaceFragment(R.id.dashboard_top_content, fragment, sharedViews, true) } + + + fun addPopupFragment(fragment: Fragment, title: String) { + replaceFragment(R.id.fragmentPanelContainer, fragment) + sliding_panel_title.text = title + sliding_layout.panelState = SlidingUpPanelLayout.PanelState.EXPANDED + } + + /*fun showPriceAgreementragment(address: String,qrHead: String? = null, qrSubtitle: String? = null, qrDescription: String? = null) { + addPopupFragment(PriceAgreementFragment.newIntent(address, qrHead, qrSubtitle, qrDescription), "QR code") + }*/ + +/*fun showPriceAgreementFragment(address: String,qrHead: String? = null, qrSubtitle: String? = null, qrDescription: String? = null) { + addPopupFragment(QrFragment.newIntent(address, qrHead, qrSubtitle, qrDescription), "QR code") +} + +override fun replaceFragment(fragment: Fragment, sharedViews: List) { + super.replaceFragment(R.id.dashboard_top_content, fragment, sharedViews, true) +}*/ + + + /* protected fun replaceFragment(containerViewId: Int, fragment: Fragment) { + supportFragmentManager + .beginTransaction() + .replace(containerViewId, fragment) + .commit() + }*/ + } \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentFragment.kt new file mode 100644 index 00000000..6e1d3c4a --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentFragment.kt @@ -0,0 +1,193 @@ +package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment + +import android.arch.lifecycle.Observer +import android.arch.lifecycle.ViewModelProviders +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.databinding.DataBindingUtil +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.DiskCacheStrategy +import io.forus.me.android.presentation.R +import io.forus.me.android.presentation.databinding.FragmentActionPaymentBinding +import io.forus.me.android.presentation.view.fragment.BaseFragment +import io.forus.me.android.presentation.view.screens.vouchers.dialogs.ApplyActionTransactionDialog +import io.forus.me.android.presentation.view.screens.vouchers.dialogs.FullscreenDialog +import io.forus.me.android.presentation.view.screens.vouchers.dialogs.ThrowableErrorDialog +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.popup.PriceAgreementFragment +import kotlinx.android.synthetic.main.fragment_action_payment.* +import java.text.NumberFormat +import java.util.* + + +class ActionPaymentFragment : BaseFragment() { + + companion object { + + const val ACTION_PRODUCT_EXTRA = "ACTION_PRODUCT_EXTRA" + const val VOUCHER_ADDRESS_EXTRA = "VOUCHER_ADDRESS_EXTRA" + const val VOUCHER_FUND_NAME_EXTRA = "VOUCHER_FUND_NAME_EXTRA" + + /*fun getCallingIntent(context: Context, product: ProductSerializable, voucherAddress: String, fundName: String): Intent { + val intent = Intent(context, ActionPaymentActivity::class.java) + val bundle = Bundle() + bundle.putSerializable(ACTION_PRODUCT_EXTRA, product) + intent.putExtra(VOUCHER_ADDRESS_EXTRA, voucherAddress) + intent.putExtras(bundle) + intent.putExtra(VOUCHER_FUND_NAME_EXTRA, fundName) + + return intent + }*/ + + fun newIntent(product: ProductSerializable, voucherAddress: String,fundName: String): ActionPaymentFragment = ActionPaymentFragment().also { + val bundle = Bundle() + bundle.putSerializable(ACTION_PRODUCT_EXTRA, product) + bundle.putString(VOUCHER_ADDRESS_EXTRA, voucherAddress) + bundle.putString(VOUCHER_FUND_NAME_EXTRA, fundName) + it.arguments = bundle + } + } + + + lateinit var mainViewModel: ActionPaymentViewModel + + lateinit var binding: FragmentActionPaymentBinding//ActivityActionPaymentBinding + + var voucherAddress: String? = null + var product: ProductSerializable? = null + + var fundName: String? = null + + + /* override fun getLayoutID(): Int { + return R.layout.fragment_action_payment + }*/ + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val url = product!!.photoURL + if (url != null && url.isNotEmpty()) { + Glide.with(context).load(url) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .into(iv_action_icon) + } + + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return super.onCreateView(inflater, container, savedInstanceState).also { + val bundle = this.arguments + if (bundle != null) { + voucherAddress = bundle.getString(VOUCHER_ADDRESS_EXTRA, "") + product = bundle.getSerializable(ACTION_PRODUCT_EXTRA) as ProductSerializable + + fundName = bundle.getString(VOUCHER_FUND_NAME_EXTRA, "") + + } + + mainViewModel = ViewModelProviders.of(this).get(ActionPaymentViewModel::class.java) + + product.let { + mainViewModel.setProduct(it!!) + mainViewModel.voucherAddress = voucherAddress + } + + + binding = DataBindingUtil.inflate( + inflater, R.layout.fragment_action_payment, container, false) + val view: View = binding.getRoot() + binding.model = mainViewModel + + mainViewModel.confirmPayment.observe(requireActivity(), Observer { + if (!it!!) return@Observer + + showConfirmDialog() + }) + + mainViewModel.successPayment.observe(requireActivity(), Observer { + if (!it!!) return@Observer + FullscreenDialog.display(fragmentManager, getString(R.string.vouchers_apply_success), getString(R.string.vouchers_transaction_duration_of_payout), getString(R.string.me_ok)) { + requireActivity().finish() + } + }) + + mainViewModel.errorPayment.observe(requireActivity(), Observer { + if (it != null) { + ThrowableErrorDialog(it, requireActivity(), object : DialogInterface.OnDismissListener, () -> Unit { + override fun invoke() { + } + + override fun onDismiss(p0: DialogInterface?) { + } + }).show() + } + }) + + mainViewModel.showPriceAgreement.observe(requireActivity(), Observer { + if (!it!!) return@Observer + Log.d("forus", "Click price agreement") + (requireActivity() as ActionPaymentActivity).addPopupFragment(PriceAgreementFragment.newIntent(product!!, fundName!!), "") + //showPopupQRFragment(QrCode(QrCode.Type.P2P_IDENTITY, vs.model.account.address).toJson()) + // }.show() + }) + + + + + return view + } + } + + + + + fun showConfirmDialog() { + + var title = "" + var toPay = "" + var subtitle = "" + + if (product!!.noPrice) { + if (product!!.noPriceType == NoPriceType.free.name) { + title = getString(R.string.price) + toPay = getString(R.string.free) + subtitle = "" + } else if (product!!.noPriceType == NoPriceType.discount.name) { + title = getString(R.string.discount) + toPay = if (product!!.noPriceDiscount != null) { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(product!!.noPriceDiscount.toDouble())+"%" + } else { + getString(R.string.price_agreement_n_v_t) + } + subtitle = "" + } + } else { + title = getString(R.string.submit_price_title) + toPay = if (product!!.priceUser != null) { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(product!!.priceUser.toDouble()) + } else { + getString(R.string.price_agreement_n_v_t) + } + subtitle = getString(R.string.submit_price_subtitle) + } + + ApplyActionTransactionDialog(requireActivity(), title, toPay, subtitle) { + mainViewModel.makeTransaction() + }.show() + } + + override fun initUI() { + /*if(qrHead.isNotBlank()) head.text = qrHead + if(qrSubtitle.isNotBlank()) subtitle.text = qrSubtitle + if(qrDescription.isNotBlank()) description.text = qrDescription*/ + } +} + diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentViewModel.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentViewModel.kt index d47d1e00..18a4f39d 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentViewModel.kt +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ActionPaymentViewModel.kt @@ -1,5 +1,7 @@ package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment //import io.forus.me.android.data.entity.vouchers.response.Voucher +import android.app.Application +import android.arch.lifecycle.AndroidViewModel import android.arch.lifecycle.MutableLiveData import android.arch.lifecycle.ViewModel import android.databinding.Bindable @@ -9,6 +11,7 @@ import android.util.Log import android.view.View import io.forus.me.android.domain.models.vouchers.ProductAction import io.forus.me.android.domain.repository.vouchers.VouchersRepository +import io.forus.me.android.presentation.R import io.forus.me.android.presentation.internal.Injection import io.forus.me.android.presentation.view.base.lr.PartialChange import io.forus.me.android.presentation.view.screens.vouchers.provider.ProviderPartialChanges @@ -18,7 +21,7 @@ import java.text.NumberFormat import java.util.* -class ActionPaymentViewModel : ViewModel(), Observable { +class ActionPaymentViewModel(application: Application) : AndroidViewModel(application), Observable { var vouchersRepository: VouchersRepository = Injection.instance.vouchersRepository @@ -34,6 +37,7 @@ class ActionPaymentViewModel : ViewModel(), Observable { val orgName = MutableLiveData() val confirmPayment = MutableLiveData() + val showPriceAgreement = MutableLiveData() val successPayment = MutableLiveData() val errorPayment = MutableLiveData() @@ -48,6 +52,7 @@ class ActionPaymentViewModel : ViewModel(), Observable { progress.value = false confirmPayment.value = false + showPriceAgreement.value = false successPayment.value = false errorPayment.value = null } @@ -62,9 +67,29 @@ class ActionPaymentViewModel : ViewModel(), Observable { confirmPayment.postValue(true) } + fun onPricesClick(view: View?) { + showPriceAgreement.postValue(true) + } + + private fun refreshUI() { - productPrice.postValue(NumberFormat.getCurrencyInstance(Locale("nl", "NL")) - .format(product!!.price)) + + val resources = getApplication().resources + + + val priceValue: String = if (product!!.noPrice) { + if (product!!.noPriceType == NoPriceType.free.name) { + resources.getString(R.string.free) + } else { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(product!!.priceUser) + } + } else { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")) + .format(product!!.priceUser) + } + + productPrice.postValue(priceValue) productName.postValue(product!!.name) diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/NoPriceType.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/NoPriceType.kt new file mode 100644 index 00000000..3a3ab56f --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/NoPriceType.kt @@ -0,0 +1,5 @@ +package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment + +enum class NoPriceType { + free , discount +} \ No newline at end of file diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ProductSerializable.java b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ProductSerializable.java index 013a17fb..3f08fb4e 100644 --- a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ProductSerializable.java +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/ProductSerializable.java @@ -1,22 +1,41 @@ package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment; import java.io.Serializable; +import java.math.BigDecimal; public class ProductSerializable implements Serializable { long id; String name; String companyName; - double price; + BigDecimal price; + BigDecimal oldPrice; + boolean noPrice; + String noPriceType; + BigDecimal noPriceDiscount; + + BigDecimal priceUser; long companyId; + String photoURL; + - public ProductSerializable(long id, String name, String companyName, long companyId, double price ) { + public ProductSerializable(long id, String name, String companyName, long companyId, BigDecimal price, + BigDecimal oldPrice, + boolean noPrice, String noPriceType, BigDecimal noPriceDiscount, + BigDecimal priceUser, String photoURL) { this.id = id; this.name = name; this.price = price; this.companyName = companyName; this.companyId = companyId; + this.oldPrice = oldPrice; + this.noPrice = noPrice; + this.noPriceType = noPriceType; + this.noPriceDiscount = noPriceDiscount; + this.priceUser = priceUser; + this.photoURL = photoURL; + } public long getId() { @@ -35,11 +54,11 @@ public void setName(String name) { this.name = name; } - public double getPrice() { + public BigDecimal getPrice() { return price; } - public void setPrice(double price) { + public void setPrice(BigDecimal price) { this.price = price; } @@ -52,7 +71,6 @@ public void setCompanyName(String companyName) { } - public long getCompanyId() { return companyId; } @@ -60,4 +78,28 @@ public long getCompanyId() { public void setCompanyId(long companyId) { this.companyId = companyId; } + + public BigDecimal getOldPrice() { + return oldPrice; + } + + public void setOldPrice(BigDecimal oldPrice) { + this.oldPrice = oldPrice; + } + + public BigDecimal getPriceUser() { + return priceUser; + } + + public void setPriceUser(BigDecimal priceUser) { + this.priceUser = priceUser; + } + + public String getPhotoURL() { + return photoURL; + } + + public void setPhotoURL(String photoURL) { + this.photoURL = photoURL; + } } diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementFragment.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementFragment.kt new file mode 100644 index 00000000..a66b806d --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementFragment.kt @@ -0,0 +1,109 @@ +package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.popup + +import android.arch.lifecycle.ViewModelProviders +import android.databinding.DataBindingUtil +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import io.forus.me.android.presentation.R +import io.forus.me.android.presentation.databinding.FragmentActionPaymentBinding +import io.forus.me.android.presentation.databinding.FragmentPriceAgreementBinding +import io.forus.me.android.presentation.view.fragment.BaseFragment +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.ActionPaymentFragment +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.ActionPaymentViewModel +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.ProductSerializable +import kotlinx.android.synthetic.main.fragment_popup_qr.* + + +class PriceAgreementFragment : BaseFragment() { + + lateinit var mainViewModel: PriceAgreementViewModel + + lateinit var binding: FragmentPriceAgreementBinding//ActivityActionPaymentBinding + + + companion object { + + const val ACTION_PRODUCT_EXTRA = "ACTION_PRODUCT_EXTRA" + const val VOUCHER_FUND_NAME_EXTRA = "VOUCHER_FUND_NAME_EXTRA" + + fun newIntent(product: ProductSerializable, fundName: String): PriceAgreementFragment = PriceAgreementFragment().also { + val bundle = Bundle() + bundle.putSerializable(ACTION_PRODUCT_EXTRA, product) + bundle.putString(VOUCHER_FUND_NAME_EXTRA, fundName) + it.arguments = bundle + } + } + override fun getLayoutID(): Int { + return R.layout.fragment_price_agreement + } + + + var product: ProductSerializable? = null + var fundName: String? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return super.onCreateView(inflater, container, savedInstanceState).also{ + val bundle = this.arguments + if (bundle != null) { + product = bundle.getSerializable(ActionPaymentFragment.ACTION_PRODUCT_EXTRA) as ProductSerializable + fundName = bundle.getString(ActionPaymentFragment.VOUCHER_FUND_NAME_EXTRA,"") + } + //binding = DataBindingUtil.inflate( + // inflater, R.layout.fragment_price_agreement, container, false) + + val viewRoot = LayoutInflater.from(requireContext()).inflate(R.layout.fragment_price_agreement, null) + binding = FragmentPriceAgreementBinding.bind(viewRoot)//inflate()//(inflater, viewRoot!!, false) + val view = binding.root + + return view + + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + mainViewModel = ViewModelProviders.of(this).get(PriceAgreementViewModel::class.java) + + product.let { + mainViewModel.setProduct(it!!,fundName!!) + } + + + + val view: View = binding.getRoot() + binding.lifecycleOwner = this + binding.model = mainViewModel + } + + + + /* override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + Log.d("my", "onCreateView_____") + mainViewModel = + ViewModelProviders.of(this).get(PriceAgreementViewModel::class.java) + val root = inflater.inflate(R.layout.fragment_price_agreement, container, false) + //val textView: TextView = root.findViewById(R.id.text_dashboard) + + /* mainViewModel.text.observe(viewLifecycleOwner, Observer { + // textView.text = it + })*/ + + + return root + }*/ + + override fun initUI() { + //if(qrHead.isNotBlank()) head.text = qrHead + // if(qrSubtitle.isNotBlank()) subtitle.text = qrSubtitle + // if(qrDescription.isNotBlank()) description.text = qrDescription + } +} + diff --git a/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementViewModel.kt b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementViewModel.kt new file mode 100644 index 00000000..0f212547 --- /dev/null +++ b/presentation/src/main/java/io/forus/me/android/presentation/view/screens/vouchers/voucher_with_actions/payment/popup/PriceAgreementViewModel.kt @@ -0,0 +1,145 @@ +package io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.popup +//import io.forus.me.android.data.entity.vouchers.response.Voucher +import android.app.Application +import android.arch.lifecycle.AndroidViewModel +import android.arch.lifecycle.MutableLiveData +import android.arch.lifecycle.ViewModel +import android.databinding.Bindable +import android.databinding.Observable +import android.databinding.PropertyChangeRegistry +import android.util.Log +import android.view.View +import io.forus.me.android.domain.models.vouchers.ProductAction +import io.forus.me.android.domain.repository.vouchers.VouchersRepository +import io.forus.me.android.presentation.R +import io.forus.me.android.presentation.internal.Injection +import io.forus.me.android.presentation.view.base.lr.PartialChange +import io.forus.me.android.presentation.view.screens.vouchers.item.VoucherFragment +import io.forus.me.android.presentation.view.screens.vouchers.provider.ProviderPartialChanges +import io.forus.me.android.presentation.view.screens.vouchers.voucher_with_actions.payment.ProductSerializable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import java.text.NumberFormat +import java.util.* + + +class PriceAgreementViewModel(application: Application) : AndroidViewModel(application), Observable { + + + private var product: ProductSerializable? = null + var fundName: String? = null + + val paidOutBySponsorPrice = MutableLiveData() + val paidOutBySponsorNameSubtitle = MutableLiveData() + + val totalPrice = MutableLiveData() + + val discountByProviderName = MutableLiveData() + val discountByProviderPrice = MutableLiveData() + + val contributionBySponsorName = MutableLiveData() + val contributionBySponsorPrice = MutableLiveData() + + val userPrice = MutableLiveData() + + init { + + paidOutBySponsorPrice.value = "" + paidOutBySponsorNameSubtitle.value = "" + + discountByProviderName.value = "" + discountByProviderPrice.value = "" + + contributionBySponsorName.value = "" + contributionBySponsorPrice.value = "" + + userPrice.value = "" + + } + + public fun setProduct(product: ProductSerializable, fundName: String) { + + this.product = product + this.fundName = fundName + refreshUI() + } + + + private fun refreshUI() { + + val resources = getApplication().resources + + val nvtStr = resources.getString(R.string.price_agreement_n_v_t) + + totalPrice.value = if (product!!.oldPrice == null) { + nvtStr + } else { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")).format(product!!.oldPrice.toDouble()) + } + + discountByProviderName.value = resources.getString(R.string.price_agreement_discount_by_provider_, + product!!.companyName) + + discountByProviderPrice.value = if (product!!.oldPrice == null || product!!.price == null) { + nvtStr + } else { + val providerDiscount = product!!.oldPrice!! - product!!.price + NumberFormat.getCurrencyInstance(Locale("nl", "NL")).format(providerDiscount.toDouble()) + } + + + contributionBySponsorPrice.value = if (product!!.price == null || product!!.priceUser == null) { + nvtStr + } else { + val sponsorDiscount = product!!.price!! - product!!.priceUser + NumberFormat.getCurrencyInstance(Locale("nl", "NL")).format(sponsorDiscount.toDouble()) + } + + contributionBySponsorName.value = resources.getString(R.string.price_agreement_contribution_by_sponsor_, + fundName) + + val priceUserStr = if (product!!.priceUser == null) { + nvtStr + } else { + NumberFormat.getCurrencyInstance(Locale("nl", "NL")).format(product!!.priceUser.toDouble()) + } + + userPrice.value = priceUserStr + paidOutBySponsorPrice.value = priceUserStr + + paidOutBySponsorNameSubtitle.value = resources.getString(R.string.price_agreement_paid_by_customer) + + } + + + private val callbacks: PropertyChangeRegistry by lazy { PropertyChangeRegistry() } + + override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) { + callbacks.add(callback) + } + + override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) { + callbacks.remove(callback) + } + + + /** + * Notifies listeners that all properties of this instance have changed. + */ + fun notifyChange() { + callbacks.notifyCallbacks(this, 0, null) + } + + /** + * Notifies listeners that a specific property has changed. The getter for the property + * that changes should be marked with [Bindable] to generate a field in + * `BR` to be used as `fieldId`. + * + * @param fieldId The generated BR id for the Bindable field. + */ + fun notifyPropertyChanged(fieldId: Int) { + callbacks.notifyCallbacks(this, fieldId, null) + } + + +} diff --git a/presentation/src/main/res/drawable/ic_access_time_24px_rounded.xml b/presentation/src/main/res/drawable/ic_access_time_24px_rounded.xml new file mode 100644 index 00000000..e6c6cb78 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_access_time_24px_rounded.xml @@ -0,0 +1,11 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_call_24px_rounded.xml b/presentation/src/main/res/drawable/ic_call_24px_rounded.xml new file mode 100644 index 00000000..c64993de --- /dev/null +++ b/presentation/src/main/res/drawable/ic_call_24px_rounded.xml @@ -0,0 +1,10 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_euro_1.xml b/presentation/src/main/res/drawable/ic_euro_1.xml new file mode 100644 index 00000000..a9a33189 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_euro_1.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/presentation/src/main/res/drawable/ic_room_24px_outlined.xml b/presentation/src/main/res/drawable/ic_room_24px_outlined.xml new file mode 100644 index 00000000..d75f0713 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_room_24px_outlined.xml @@ -0,0 +1,11 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_secure.xml b/presentation/src/main/res/drawable/ic_secure.xml new file mode 100644 index 00000000..bc793fc0 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_secure.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/presentation/src/main/res/layout/activity_action_payment.xml b/presentation/src/main/res/layout/activity_action_payment.xml index 5db241b7..63254d2f 100644 --- a/presentation/src/main/res/layout/activity_action_payment.xml +++ b/presentation/src/main/res/layout/activity_action_payment.xml @@ -1,247 +1,92 @@ - + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + > - - - - - - - + android:layout_height="match_parent" + android:gravity="bottom" + app:umanoPanelHeight="0dp" + app:umanoShadowHeight="0dp" - + app:umanoOverlay="true"> - + android:layout_height="match_parent"> - + + - - - - - - - - - - - + android:layout_height="match_parent" + android:layout_below="@+id/title0" + /> - + + + + - - + android:background="@drawable/corner_card_background" + android:orientation="vertical" + android:visibility="visible" + android:minHeight="480dp" + android:layout_marginTop="26dp" + + > - - - - - - + android:layout_height="wrap_content" + > - - - - - - - - - - - - - - - - - - - - - + android:textSize="20sp" + app:type="medium" + android:visibility="gone"/> - - - + - - - - - + + + + diff --git a/presentation/src/main/res/layout/activity_actions.xml b/presentation/src/main/res/layout/activity_actions.xml index 262f3962..07680169 100644 --- a/presentation/src/main/res/layout/activity_actions.xml +++ b/presentation/src/main/res/layout/activity_actions.xml @@ -305,7 +305,7 @@ android:visibility="visible" android:textSize="24sp" android:textColor="@color/body_1" - android:fontFamily="sans-serif-medium" + android:fontFamily="@font/google_sans_medium" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" tools:text="Vandaag" /> @@ -322,20 +322,9 @@ android:letterSpacing="0.01" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" + android:fontFamily="@font/google_sans_regular" tools:text="@string/choose_an_action_descr" /> - @@ -76,6 +76,7 @@ android:gravity="center_horizontal|top" android:lineSpacingExtra="0sp" android:textColor="@color/textColor" + android:fontFamily="@font/google_sans_regular" android:textSize="16sp" tools:text="Check your email" /> @@ -103,6 +104,7 @@ android:layout_marginStart="20dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" + android:elevation="6dp" android:text="@string/check_email_open_mail_app" /> diff --git a/presentation/src/main/res/layout/activity_create_category_flow.xml b/presentation/src/main/res/layout/activity_create_category_flow.xml index 744a4b3a..5284277b 100644 --- a/presentation/src/main/res/layout/activity_create_category_flow.xml +++ b/presentation/src/main/res/layout/activity_create_category_flow.xml @@ -35,6 +35,7 @@ android:text="@string/new_record" android:layout_marginTop="16dp" android:layout_marginLeft="16dp" + android:fontFamily="@font/google_sans_regular" /> diff --git a/presentation/src/main/res/layout/activity_transactions_log.xml b/presentation/src/main/res/layout/activity_transactions_log.xml index a80595dd..755d010d 100644 --- a/presentation/src/main/res/layout/activity_transactions_log.xml +++ b/presentation/src/main/res/layout/activity_transactions_log.xml @@ -74,6 +74,7 @@ android:layout_marginLeft="16dp" android:gravity="center" android:textAllCaps="true" + android:fontFamily="@font/google_sans_regular" android:text="@string/from" /> diff --git a/presentation/src/main/res/layout/dialog_apply_action.xml b/presentation/src/main/res/layout/dialog_apply_action.xml index 61d61cb0..320df97d 100644 --- a/presentation/src/main/res/layout/dialog_apply_action.xml +++ b/presentation/src/main/res/layout/dialog_apply_action.xml @@ -11,11 +11,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="26dp" - android:fontFamily="sans-serif-medium" android:gravity="center" android:letterSpacing="0.01" android:text="@string/confirm_payment" android:textColor="#28292B" + android:fontFamily="@font/google_sans_medium" android:textSize="20sp" /> - - - - - - + @@ -66,6 +52,7 @@ android:textColor="#28292B" android:letterSpacing="0.01" android:textSize="16sp" + android:fontFamily="@font/google_sans_regular" tools:text="bottom" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/dialog_create_record_success.xml b/presentation/src/main/res/layout/dialog_create_record_success.xml index a06a3a0b..370bab68 100644 --- a/presentation/src/main/res/layout/dialog_create_record_success.xml +++ b/presentation/src/main/res/layout/dialog_create_record_success.xml @@ -41,7 +41,6 @@ android:layout_marginStart="17dp" android:layout_centerVertical="true" android:layout_marginEnd="16dp" - android:fontFamily="sans-serif-medium" android:text="@string/new_record_title" android:textColor="#2E3542" android:scaleType="center" @@ -51,6 +50,7 @@ android:gravity="top" android:textAllCaps="true" android:letterSpacing="0.09" + android:fontFamily="@font/google_sans_medium" /> @@ -82,6 +82,7 @@ android:text="@string/record_created_successfully" android:textColor="@color/textColor" android:textSize="30sp" + android:fontFamily="@font/google_sans_medium" /> @@ -119,6 +120,7 @@ android:layout_marginEnd="16dp" tools:text="Record Type" android:textColor="#8D9299" + android:fontFamily="@font/google_sans_regular" android:textSize="12sp" /> diff --git a/presentation/src/main/res/layout/dialog_fullscreen.xml b/presentation/src/main/res/layout/dialog_fullscreen.xml index 8707806a..2b2cc983 100644 --- a/presentation/src/main/res/layout/dialog_fullscreen.xml +++ b/presentation/src/main/res/layout/dialog_fullscreen.xml @@ -48,10 +48,10 @@ android:layout_marginStart="30dp" android:layout_marginTop="60dp" android:layout_marginEnd="30dp" - android:fontFamily="sans-serif-medium" android:gravity="center_horizontal|top" android:text="Voucher succes action" android:textColor="@color/textColor" + android:fontFamily="@font/google_sans_medium" android:textSize="32sp" /> @@ -63,10 +63,10 @@ android:layout_marginStart="16dp" android:layout_marginTop="12dp" android:layout_marginEnd="16dp" - android:fontFamily="sans-serif-medium" android:gravity="center_horizontal|top" android:text="Voucher succes action description" android:textColor="@color/darkGrey_Text_1" + android:fontFamily="@font/google_sans_medium" android:textSize="16sp" /> @@ -50,6 +51,7 @@ android:lineSpacingExtra="6sp" android:text="@string/profile_about_me_text" android:textColor="@color/body_1_87" + android:fontFamily="@font/google_sans_regular" android:textSize="15sp" /> @@ -83,6 +86,7 @@ android:layout_height="wrap_content" android:lineSpacingExtra="4sp" android:text="Forus, 2018-2020" + android:fontFamily="@font/google_sans_regular" android:textColor="#6e7072" android:textSize="14sp" /> diff --git a/presentation/src/main/res/layout/fragment_account_restore_success.xml b/presentation/src/main/res/layout/fragment_account_restore_success.xml index 0539e4ca..d6b1d3ec 100644 --- a/presentation/src/main/res/layout/fragment_account_restore_success.xml +++ b/presentation/src/main/res/layout/fragment_account_restore_success.xml @@ -40,9 +40,9 @@ android:layout_marginStart="30dp" android:layout_marginTop="0dp" android:layout_marginEnd="30dp" - android:fontFamily="sans-serif-medium" android:gravity="center_horizontal|top" android:text="@string/restore_account_head" + android:fontFamily="@font/google_sans_medium" android:textColor="@color/textColor" android:textSize="32sp" /> diff --git a/presentation/src/main/res/layout/fragment_action_payment.xml b/presentation/src/main/res/layout/fragment_action_payment.xml new file mode 100644 index 00000000..9b42a93d --- /dev/null +++ b/presentation/src/main/res/layout/fragment_action_payment.xml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/layout/fragment_confirm_registration.xml b/presentation/src/main/res/layout/fragment_confirm_registration.xml index 307e3a06..fa74d189 100644 --- a/presentation/src/main/res/layout/fragment_confirm_registration.xml +++ b/presentation/src/main/res/layout/fragment_confirm_registration.xml @@ -45,7 +45,7 @@ app:layout_constraintTop_toBottomOf="@id/titleLayout" android:textSize="32sp" android:textColor="@color/textColor" - android:fontFamily="sans-serif-medium" + android:fontFamily="@font/google_sans_medium" /> diff --git a/presentation/src/main/res/layout/fragment_create_record.xml b/presentation/src/main/res/layout/fragment_create_record.xml index 486d5aae..3eb77360 100644 --- a/presentation/src/main/res/layout/fragment_create_record.xml +++ b/presentation/src/main/res/layout/fragment_create_record.xml @@ -20,6 +20,7 @@ android:layout_centerInParent="true" android:paddingRight="6dp" android:paddingLeft="6dp" + android:fontFamily="@font/google_sans_regular" /> @@ -39,6 +40,7 @@ android:focusable="true" android:imeOptions="actionDone" android:inputType="text" + android:fontFamily="@font/google_sans_regular" /> diff --git a/presentation/src/main/res/layout/fragment_first.xml b/presentation/src/main/res/layout/fragment_first.xml deleted file mode 100644 index ac2e5158..00000000 --- a/presentation/src/main/res/layout/fragment_first.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -